在画布上拖动元素

时间:2014-02-06 14:42:38

标签: jquery canvas kineticjs easeljs

我将一个元素作为字符串绘制到画布上。然后,我希望能够单击该元素(或点击移动设备)并将其拖动。我现在拥有的是:

<!DOCTYPE html>
<html>
    <head>
         <link rel="stylesheet" href="bootstrap.min.css" />
        <link type="text/css" rel="stylesheet" href="stylesheet.css"/>
        <script src="jquery-1.11.0.js"></script>
    </head>
    <body>
         <canvas id="canvas1" width="662" height="983">
             <script src="jquery-1.11.0.js"></script>
        </canvas>

        <script>
            var chosenChord=""; //this gets updated at various times by excluded code, but that code works, because the chord does always print correctly below
    `       $("button").click(function() {
                canvas = document.getElementById('canvas1');
                canvas1.addEventListener('click', on_canvas_click, false);

                function on_canvas_click(ev) {
                    x = ev.clientX - canvas1.offsetLeft-40;
                    y = ev.clientY - canvas1.offsetTop;

                   //add to canvas
                    var canvas = document.getElementById("canvas1");
                    var context = canvas.getContext("2d");
                    context.fillStyle = "blue";
                    context.font = "bold 16px Arial";
                    context.fillText([theString], [x], [y]);
                });
            });
        </script>   
    </body>
</html>

为了启用此拖动功能,我需要添加什么?

2 个答案:

答案 0 :(得分:1)

以下是如何在画布上拖动元素的大纲

演示:http://jsfiddle.net/m1erickson/AGd6u/

侦听鼠标事件:mousedown,mousemove,mouseup,mouseout

    // listen for mouse events
    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});

将您的文本片段定义为数组中的对象

    // some text objects
    var texts=[];

    // some test texts
    texts.push({text:"Hello",x:20,y:20});
    texts.push({text:"World",x:20,y:70});

在mousedown:

  • 测试鼠标是否在文本上
  • 如果是,请选择要拖动的文字

    // handle mousedown events
    // iterate through texts[] and see if the user
    // mousedown'ed on one of them
    // If yes, set the selectedText to the index of that text
    function handleMouseDown(e){
      e.preventDefault();
      startX=parseInt(e.clientX-offsetX);
      startY=parseInt(e.clientY-offsetY);
      // Put your mousedown stuff here
      for(var i=0;i<texts.length;i++){
          if(textHittest(startX,startY,i)){
              selectedText=i;
          }
      }
    }
    

在mousemove中:

  • 根据用户拖动的距离更改所选文本的位置
  • 重绘画布

    // handle mousemove events
    // calc how far the mouse has been dragged since
    // the last mousemove event and move the selected text
    // by that distance
    function handleMouseMove(e){
      if(selectedText<0){return;}
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);
    
      // Put your mousemove stuff here
      var dx=mouseX-startX;
      var dy=mouseY-startY;
      startX=mouseX;
      startY=mouseY;
    
      var text=texts[selectedText];
      text.x+=dx;
      text.y+=dy;
      draw();
    }
    

在mouseup中:

  • 拖动结束,因此取消选择文本

    // done dragging
    function handleMouseUp(e){
      e.preventDefault();
      selectedText=-1;
    }
    

示例代码:

<!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>
$(function(){

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

    // variables used to get mouse position on the canvas
    var $canvas=$("#canvas");
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();

    // variables to save last mouse position
    // used to see how far the user dragged the mouse
    // and then move the text by that distance
    var startX;
    var startY;

    // some text objects
    var texts=[];

    // some test texts
    texts.push({text:"Hello",x:20,y:20});
    texts.push({text:"World",x:20,y:70});

    // calculate width of each text for hit-testing purposes
    ctx.font="16px verdana";
    for(var i=0;i<texts.length;i++){
        var text=texts[i];
        text.width=ctx.measureText(text.text).width;
        text.height=16;
    }

    // this var will hold the index of the selected text
    var selectedText=-1;

    // START: draw all texts to the canvas
    draw();

    // clear the canvas draw all texts
    function draw(){
        ctx.clearRect(0,0,canvas.width,canvas.height);
        for(var i=0;i<texts.length;i++){
            var text=texts[i];
            ctx.fillText(text.text,text.x,text.y);
        }
    }

    // test if x,y is inside the bounding box of texts[textIndex]
    function textHittest(x,y,textIndex){
        var text=texts[textIndex];
        return(x>=text.x && 
            x<=text.x+text.width &&
            y>=text.y-text.height && 
            y<=text.y);
    }

    // handle mousedown events
    // iterate through texts[] and see if the user
    // mousedown'ed on one of them
    // If yes, set the selectedText to the index of that text
    function handleMouseDown(e){
      e.preventDefault();
      startX=parseInt(e.clientX-offsetX);
      startY=parseInt(e.clientY-offsetY);

      // Put your mousedown stuff here
      for(var i=0;i<texts.length;i++){
          if(textHittest(startX,startY,i)){
              selectedText=i;
          }
      }
    }

    // done dragging
    function handleMouseUp(e){
      e.preventDefault();
      selectedText=-1;
    }

    // also done dragging
    function handleMouseOut(e){
      e.preventDefault();
      selectedText=-1;
    }

    // handle mousemove events
    // calc how far the mouse has been dragged since
    // the last mousemove event and move the selected text
    // by that distance
    function handleMouseMove(e){
      if(selectedText<0){return;}
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      // Put your mousemove stuff here
      var dx=mouseX-startX;
      var dy=mouseY-startY;
      startX=mouseX;
      startY=mouseY;

      var text=texts[selectedText];
      text.x+=dx;
      text.y+=dy;
      draw();
    }

    // listen for mouse events
    $("#canvas").mousedown(function(e){handleMouseDown(e);});
    $("#canvas").mousemove(function(e){handleMouseMove(e);});
    $("#canvas").mouseup(function(e){handleMouseUp(e);});
    $("#canvas").mouseout(function(e){handleMouseOut(e);});

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

答案 1 :(得分:0)

我认为@markE的答案非常好。我只想添加我的2c。

直接使用画布可能会很快变得令人生畏,因为您必须自己进行各种状态管理。

我认为,当你想做这样的事情时,更明智地利用其中许多令人惊叹的框架之一,旨在使画布上的矢量绘图更容易。

仅举几例: