在HTML5 Canvas中拖放多个对象

时间:2014-07-24 05:50:27

标签: javascript html5 canvas drag-and-drop

我正在尝试实现一个应用程序,用户可以在给定区域内拖放多个对象。我正在使用html5 canvas标签来实现这个...当只有一个对象可以拖放到里面时画布然后代码工作正常,但当我尝试在画布内独立拖动多个对象时,我没有得到所需的输出..

以下是使用绘图函数拖放一个对象的工作示例

http://jsfiddle.net/KZ99q/

function draw() {
clear();
ctx.fillStyle = "#FAF7F8";
rect(0,0,WIDTH,HEIGHT);
ctx.fillStyle = "#444444";
rect(x - 15, y - 15, 30, 30);

}

我认为在draw()函数中添加更多对象会这样做我在draw()函数中为新对象添加了代码,如此链接所示

http://jsfiddle.net/KZ99q/1/

  function draw() {
  clear();
  ctx.fillStyle = "#FAF7F8";
  rect(0,0,WIDTH,HEIGHT);
  ctx.fillStyle = "#444444";
  rect(x - 15, y - 15, 30, 30);
  ctx.fillStyle = "#ff550d";
  rect(x - 25, y - 25, 30, 30);
 ctx.fillStyle = "#800080";
  rect(x - 35, y - 35, 30, 30);
  ctx.fillStyle = "#0c64e8";
 rect(x - 45, y - 45, 30, 30);
}

我似乎无法理解我需要在MyMove(),MyUp()和MyDown()函数中做出哪些更改才能使对象彼此独立移动。 请帮忙

1 个答案:

答案 0 :(得分:12)

当移动1个(或更多)形状时,程序为:

创建定义每个形状的对象:

// an array of objects that define different rectangles
var rects=[];
rects.push({x:75-15,y:50-15,width:30,height:30,fill:"#444444",isDragging:false});
rects.push({x:75-25,y:50-25,width:30,height:30,fill:"#ff550d",isDragging:false});
rects.push({x:75-35,y:50-35,width:30,height:30,fill:"#800080",isDragging:false});
rects.push({x:75-45,y:50-45,width:30,height:30,fill:"#0c64e8",isDragging:false});

在mousedown:

  • 获取当前鼠标位置
  • 在鼠标
  • 下的任何形状上设置isDragging标志
  • 保存当前鼠标位置

在mousemove中:

  • 获取当前鼠标位置
  • 计算鼠标移动的距离(distance = newMousePosition-oldMousePosition)
  • 将距离添加到任何形状为“拖拽”的位置
  • 保存当前鼠标位置
  • 使用新位置的形状重绘场景

在mouseup中:

  • 清除所有isDragging标志

这是带注释的代码和演示:http://jsfiddle.net/m1erickson/qm9Eb/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
</style>

<script>
window.onload=function(){

    // get canvas related references
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var BB=canvas.getBoundingClientRect();
    var offsetX=BB.left;
    var offsetY=BB.top;
    var WIDTH = canvas.width;
    var HEIGHT = canvas.height;

    // drag related variables
    var dragok = false;
    var startX;
    var startY;

    // an array of objects that define different rectangles
    var rects=[];
    rects.push({x:75-15,y:50-15,width:30,height:30,fill:"#444444",isDragging:false});
    rects.push({x:75-25,y:50-25,width:30,height:30,fill:"#ff550d",isDragging:false});
    rects.push({x:75-35,y:50-35,width:30,height:30,fill:"#800080",isDragging:false});
    rects.push({x:75-45,y:50-45,width:30,height:30,fill:"#0c64e8",isDragging:false});

    // listen for mouse events
    canvas.onmousedown = myDown;
    canvas.onmouseup = myUp;
    canvas.onmousemove = myMove;

    // call to draw the scene
    draw();

    // draw a single rect
    function rect(x,y,w,h) {
     ctx.beginPath();
     ctx.rect(x,y,w,h);
     ctx.closePath();
     ctx.fill();
    }

    // clear the canvas
    function clear() {
     ctx.clearRect(0, 0, WIDTH, HEIGHT);
    }

    // redraw the scene
    function draw() {
        clear();
        ctx.fillStyle = "#FAF7F8";
        rect(0,0,WIDTH,HEIGHT);
        // redraw each rect in the rects[] array
        for(var i=0;i<rects.length;i++){
            var r=rects[i];
            ctx.fillStyle=r.fill;
            rect(r.x,r.y,r.width,r.height);
        }
    }


    // handle mousedown events
    function myDown(e){

        // tell the browser we're handling this mouse event
        e.preventDefault();
        e.stopPropagation();

        // get the current mouse position
        var mx=parseInt(e.clientX-offsetX);
        var my=parseInt(e.clientY-offsetY);

        // test each rect to see if mouse is inside
        dragok=false;
        for(var i=0;i<rects.length;i++){
            var r=rects[i];
            if(mx>r.x && mx<r.x+r.width && my>r.y && my<r.y+r.height){
                // if yes, set that rects isDragging=true
                dragok=true;
                r.isDragging=true;
            }
        }
        // save the current mouse position
        startX=mx;
        startY=my;
    }


    // handle mouseup events
    function myUp(e){
        // tell the browser we're handling this mouse event
        e.preventDefault();
        e.stopPropagation();

        // clear all the dragging flags
        dragok = false;
        for(var i=0;i<rects.length;i++){
            rects[i].isDragging=false;
        }
    }


    // handle mouse moves
    function myMove(e){
        // if we're dragging anything...
        if (dragok){

          // tell the browser we're handling this mouse event
          e.preventDefault();
          e.stopPropagation();

          // get the current mouse position
          var mx=parseInt(e.clientX-offsetX);
          var my=parseInt(e.clientY-offsetY);

          // calculate the distance the mouse has moved
          // since the last mousemove
          var dx=mx-startX;
          var dy=my-startY;

          // move each rect that isDragging 
          // by the distance the mouse has moved
          // since the last mousemove
          for(var i=0;i<rects.length;i++){
              var r=rects[i];
              if(r.isDragging){
                  r.x+=dx;
                  r.y+=dy;
              }
          }

          // redraw the scene with the new rect positions
          draw();

          // reset the starting mouse position for the next mousemove
          startX=mx;
          startY=my;

        }
    }

}; // end $(function(){});
</script>
</head>
<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>