2012-11-27 49 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不起作用。我非常需要這個答案,那就是我一直在尋找的東西,但它不起作用!