如何在画布中拖放可拖动的图像?

时间:2015-01-11 22:05:16

标签: jquery html5 jquery-ui canvas jcanvas

http://jsfiddle.net/m1erickson/2Us2S/

**我正在使用此代码,如何将拖放的图像作为可拖动的图像。我试过jquery但我需要在画布中拖动它。开导我 。 **

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);
}

1 个答案:

答案 0 :(得分:2)

一旦你将画像画到画布上,画面上的房子就会变成未被遮挡的,不可移动的像素。你不能再使用jQuery拖动房子了。

Canvas"移动"通过擦除画布并在更改的位置重新绘制内容来完成的事情。

Canvas" drags"通过听老鼠事件:

  • In mousedown,检查鼠标是否在画布上绘制的任何房屋上方。你可以通过记住房子的绘制位置来做到这一点,然后使用房子的边界框来使用鼠标位置进行测试。设置一个isDragging标志,表示房子被鼠标击中,应该被拖动。

  • In mousemove,重新移动自上次鼠标移动后鼠标移动距离的房屋。

  • In mouseup & mouseout,拖动操作已完全清除isDragging标记。

要创建一个边界框以进行测试,您需要至少跟踪宽度和宽度。房屋图像的高度以及在画布上放置的位置的x,y。您通常将此信息保存在javascript对象中。

这里带注释的代码和演示:



// 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();

}
&#13;
body{ background-color: ivory; }
canvas{border:1px solid red;}
&#13;
<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>
&#13;
&#13;
&#13;