2012-11-27 48 views
3

我修改了一个页面,可以将图像拖放到画布上。它做我想要的一切,除了一个。我已经尝试了多种方法(包括脚本,例如Kinetic和Raphael,我仍然认为这可能是路线),但已经结束:如何将图像拖放到HTML5 Canvas后拖动?

一旦图像被丢弃,我无法将其拖动到帆布到一个新的位置。

function drag(e) 
{ 
    //store the position of the mouse relativly to the image position 
    e.dataTransfer.setData("mouse_position_x",e.clientX - e.target.offsetLeft); 
    e.dataTransfer.setData("mouse_position_y",e.clientY - e.target.offsetTop ); 

    e.dataTransfer.setData("image_id",e.target.id); 
} 

function drop(e) 
{ 
    e.preventDefault(); 
    var image = document.getElementById(e.dataTransfer.getData("image_id")); 

    var mouse_position_x = e.dataTransfer.getData("mouse_position_x"); 
    var mouse_position_y = e.dataTransfer.getData("mouse_position_y"); 

    var canvas = document.getElementById('canvas'); 
    var ctx = canvas.getContext('2d'); 

    // the image is drawn on the canvas at the position of the mouse when we lifted the mouse button 
    ctx.drawImage(image , e.clientX - canvas.offsetLeft - mouse_position_x , e.clientY - canvas.offsetTop - mouse_position_y); 
} 

function convertCanvasToImage() { 
    var canvas = document.getElementById('canvas'); 

    var image_src = canvas.toDataURL("image/png"); 
    window.open(image_src); 

} 

这里是一个的jsfiddle,我作为我最初的起点 - http://fiddle.jshell.net/gael/GF96n/4/(拖动的jsfiddle标志到画布上,然后尝试将其移动)。我已经在我的工作页面中添加了CSS,标签,内容等。我不想失去的功能是能够将单个图像多次(克隆)拖到画布上。

有关如何创建此功能的任何想法/示例/指针?

+0

我做了同样的功能。为此,您需要在拖动的位置一次又一次地绘制图像。 – MJQ

回答

6

您需要对代码进行一些更改,而不是立即将图像绘制到画布上,您需要跟踪掉落的所有图像。 imagesOnCanvas将填满所有丢弃的图像。

var imagesOnCanvas = []; 

function drop(e) 
{ 
    e.preventDefault(); 
    var image = document.getElementById(e.dataTransfer.getData("image_id")); 

    var mouse_position_x = e.dataTransfer.getData("mouse_position_x"); 
    var mouse_position_y = e.dataTransfer.getData("mouse_position_y"); 

    var canvas = document.getElementById('canvas'); 
    var ctx = canvas.getContext('2d'); 

    imagesOnCanvas.push({ 
     context: ctx, 
     image: image, 
     x:e.clientX - canvas.offsetLeft - mouse_position_x, 
     y:e.clientY - canvas.offsetTop - mouse_position_y, 
     width: image.offsetWidth, 
     height: image.offsetHeight 
    }); 

} 

您还需要一个动画循环,这将通过所有图像imagesOnCanvas和顺序绘制它们。​​用于实现此目的。

function renderScene() { 
    requestAnimationFrame(renderScene); 

    var canvas = document.getElementById('canvas'); 
    var ctx = canvas.getContext('2d'); 
    ctx.clearRect(0,0, 
     canvas.width, 
     canvas.height 
    ); 


    for(var x = 0,len = imagesOnCanvas.length; x < len; x++) { 
     var obj = imagesOnCanvas[x]; 
     obj.context.drawImage(obj.image,obj.x,obj.y); 

    } 
} 

requestAnimationFrame(renderScene); 

接下来,您必须监控在画布上mousedown事件,以及事件是否与图像startMove动作可以被称为上发生

canvas.onmousedown = function(e) { 
    var downX = e.offsetX,downY = e.offsetY; 

    // scan images on canvas to determine if event hit an object 
    for(var x = 0,len = imagesOnCanvas.length; x < len; x++) { 
     var obj = imagesOnCanvas[x]; 
     if(!isPointInRange(downX,downY,obj)) { 
      continue; 
     } 

     startMove(obj,downX,downY); 
     break; 
    } 

} 

如果发生在鼠标事件的isPointInRange函数返回true一个图像对象

function isPointInRange(x,y,obj) { 
    return !(x < obj.x || 
     x > obj.x + obj.width || 
     y < obj.y || 
     y > obj.y + obj.height); 
} 

一旦“移动模式”处于活动状态,对象的x/y坐标将发生变化以反映新的鼠标位置

function startMove(obj,downX,downY) { 
    var canvas = document.getElementById('canvas'); 

    var origX = obj.x, origY = obj.y; 
    canvas.onmousemove = function(e) { 
     var moveX = e.offsetX, moveY = e.offsetY; 
     var diffX = moveX-downX, diffY = moveY-downY; 


     obj.x = origX+diffX; 
     obj.y = origY+diffY; 
    } 

    canvas.onmouseup = function() { 
     // stop moving 
     canvas.onmousemove = function(){}; 
    } 
} 

工作示例这里:

http://jsfiddle.net/XU2a3/41/

+0

感谢您的快速响应! –

+0

感谢您的快速响应!试用了以下代码,并在JSFiddle中看到几乎相同的结果:IE 8.0 - 无画布显示。什么都没有FF 17.0 - 第一张图像拖放。尝试移动时消失。后续图像拖放但不移动。生成图像不起作用。 Chrome 23 - 拖放工程。可以在画布上放置图像后移动图像。生成图像不起作用。 Safari 5.1.7 - 拖放不起作用。生成图像将打开一个新窗口,但无法分辨图像是否完全正常工作。有关如何解决问题的任何建议? –

+0

lostsource - 你的jsfiddle似乎与jsfiddle上的chrome一起工作,但是当我复制代码(有或没有关闭)并从文件或网络服务器运行它时,它不会。你有没有做出改变(我没有看到),我做错了什么?谢谢。 –

0

我知道它已经像2年,但我会试试看......在答复@lostsource提供,Opera浏览器不支持dataTransfer对象,并且jsfiddle不起作用。我非常需要这个答案,那就是我一直在寻找的东西,但它不起作用!