http://jsfiddle.net/m1erickson/2Us2S/
**I am using this code , how can I make dropped images as draggable . I have tried with jquery but I need to drag the same within the canvas . Enlighten me . **
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var image1 = new Image();
image1.src = "https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house32x32transparent.png";
var $house = $("#house");
var $canvas = $("#canvas");
$house.draggable({
helper: 'clone',
});
// set the data payload
$house.data("image", image1); // key-value pair
$canvas.droppable({
drop: dragDrop,
});
function dragDrop(e, ui) {
var element = ui.draggable;
var data = element.data("url");
var x = parseInt(ui.offset.left - offsetX);
var y = parseInt(ui.offset.top - offsetY);
ctx.drawImage(element.data("image"), x - 1, y);
}
Once you drawImage onto the canvas, the house becomes unremembered, unmovable pixels on the canvas. You can't use jQuery to drag the house any more.
Canvas "moves" things by erasing the canvas and redrawing the contents in their changed positions.
Canvas "drags" by listening for mouse events:
In mousedown
, check if the mouse is over any house that was drawn on the canvas. You do this by remembering where the house was drawn and then use the bounding box of the house to hit test using the mouse position. Set an isDragging
flag to indicate the house was hit by the mouse and should be dragged.
In mousemove
, redraw the house moved by the distance that the mouse has moved since the last mousemove.
In mouseup & mouseout
, the drag operation is over so clear the isDragging
flag.
To create a bounding box to hit test against, you need to keep track of at least the width & height of the house image and the x,y of where it was dropped on the canvas. You typically save this information in a javascript object.
Here's annotated code and a Demo:
// canvas related stuff
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
var WIDTH = canvas.width;
var HEIGHT = canvas.height;
ctx.fillStyle = "#A0DCE5";
$myCanvas=$('#myCanvas');
//drag
var isDragging = false;
var startX;
var startY;
//array of image objects
var images=[];
var NUM_IMAGES=0;
// queue up 4 test images
addImage(20,20,0.50,'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg');
addImage(240,20,0.50,'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-2.jpg');
addImage(20,220,0.50,'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg');
addImage(240,220,0.50,'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg');
// trigger all images to load
for(var i=0;i<images.length;i++){
images[i].image.src=images[i].url;
}
//////////////////////////////
// functions
//////////////////////////////
// queue up another image
function addImage(x,y,scaleFactor,imgURL){
var img=new Image();
img.crossOrigin='anonymous';
img.onload=startInteraction;
images.push({image:img,x:x,y:y,scale:scaleFactor,isDragging:false,url:imgURL});
NUM_IMAGES++;
}
// called after each image fully loads
function startInteraction() {
// return until all images are loaded
if(--NUM_IMAGES>0){return;}
// set all images width/height
for(var i=0;i<images.length;i++){
var img=images[i];
img.width=img.image.width*img.scale;
img.height=img.image.height*img.scale;
}
// render all images
renderAll();
// listen for mouse events
$myCanvas.mousedown(onMouseDown);
$myCanvas.mouseup(onMouseUp);
$myCanvas.mouseout(onMouseUp);
$myCanvas.mousemove(onMouseMove);
}
// flood fill canvas and
// redraw all images in their assigned positions
function renderAll() {
ctx.fillRect(0,0,WIDTH,HEIGHT);
for(var i=0;i<images.length;i++){
var r=images[i];
ctx.drawImage(r.image,r.x,r.y,r.width,r.height);
}
}
// handle mousedown events
function onMouseDown(e){
// tell browser we're handling this mouse event
e.preventDefault();
e.stopPropagation();
//get current position
var mx=parseInt(e.clientX-$myCanvas.offset().left);
var my=parseInt(e.clientY-$myCanvas.offset().top);
//test to see if mouse is in 1+ images
isDragging = false;
for(var i=0;i<images.length;i++){
var r=images[i];
if(mx>r.x && mx<r.x+r.width && my>r.y && my<r.y+r.height){
//if true set r.isDragging=true
r.isDragging=true;
isDragging=true;
}
}
//save mouse position
startX=mx;
startY=my;
}
// handle mouseup and mouseout events
function onMouseUp(e){
//tell browser we're handling this mouse event
e.preventDefault();
e.stopPropagation();
// clear all the dragging flags
isDragging = false;
for(var i=0;i<images.length;i++){
images[i].isDragging=false;
}
}
// handle mousemove events
function onMouseMove(e){
// do nothing if we're not dragging
if(!isDragging){return;}
//tell browser we're handling this mouse event
e.preventDefault
e.stopPropagation
//get current mouseposition
var mx = parseInt(e.clientX-$myCanvas.offset().left);
var my = parseInt(e.clientY-$myCanvas.offset().top);
//calculate how far the mouse has moved;
var dx = mx - startX;
var dy = my - startY;
//move each image by how far the mouse moved
for(var i=0;i<images.length;i++){
var r=images[i];
if(r.isDragging){
r.x+=dx;
r.y+=dy;
}
}
//reset the mouse positions for next mouse move;
startX = mx;
startY = my;
//re render the images
renderAll();
}
body{ background-color: ivory; }
canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Drag a house with the mouse.</h4>
<canvas id="myCanvas" width=400 height=400></canvas>