javascript - 用鼠标移动 Canvas 形状

标签 javascript jquery html canvas

按下按钮后,我想在 Canvas 上的鼠标指针尖端绘制一个圆圈,然后在用户再次单击时放置它。这是我到目前为止所得到的:

$("#button").click(function(e){
          var canvas = document.getElementById('MyCanvas');
          var context = canvas.getContext('2d');
          canvas.addEventListener('mousemove', function(evt) {
            var mousePos = getMousePos(canvas, evt);
            var message = 'Mouse position: ' + mousePos.x + ',' + mousePos.y;
            console.log(message);
            var nodehandle = document.getElementById('circle');
            if(mousePos.x && mousePos.y) {        
        nodehandle.x = mousePos.x;
        nodehandle.y = mousePos.y;
        flag = 1;
    }
          }, false);
    });

function getMousePos(canvas, evt) {
        var rect = canvas.getBoundingClientRect();
        return {
          x: evt.clientX - rect.left,
          y: evt.clientY - rect.top
        };
      }

我的问题是,当我画这样的圆圈时:

function drawCircle(mouseX, mouseY){
  var c = document.getElementById("grid");
  var ctx = c.getContext("2d");
  ctx.beginPath();
  ctx.arc(95,50,5,0,2*Math.PI);
  ctx.stroke();
}

我不知道如何选择该圆圈(即使我将 ctx.id='circle' 添加到 drawCircle 函数, getElementById('circle') 也会返回 null )。每次鼠标移动时,我还需要删除并重新绘制圆圈,我确信有一个很好的方法可以做到这一点,但我不知道。

最佳答案

您在 Canvas 上绘制的任何东西(例如圆圈)就像 Canvas 上干燥的油漆一样。

您的圈子无法像 html 元素一样被选择或移动。

要移动圆圈,您必须清除 Canvas 并在不同位置重新绘制圆圈。

在对象中存储有关圆的信息很方便。

var circle1 = { centerX:100, centerY=100, radius=20 }

您可以使用该信息绘制circle1:

ctx.beginPath();
ctx.arc(circle1.centerX, circle1.centerY, circle1.radius, 0,Math.PI*2);
ctx.closePath();
ctx.fill();

对于超过 1 个圆,您可以创建一个 Circles 数组并将每个圆对象放入该数组中

var circles=[];
circles.push(circle1);

然后,要“移动”一个圆,只需将对象的 centerX/centerY 更改为鼠标位置,然后在 Canvas 上重新绘制所有圆即可。

circle1.centerX=mouseX;
circle1.centerY=mouseY;

// Clear the canvas and redraw all circles
// The "moved" circle will be redrawn at its new position

function drawAll(){
    ctx.clearRect(0,0,canvas.width,canvas.height);
    for(var i=0;i<circles.length;i++){
        var c=circles[i];
        ctx.beginPath();
        ctx.arc(c.centerX,c.centerY,c.radius,0,Math.PI*2);
        ctx.closePath();
        ctx.fillStyle=c.color;
        ctx.fill();
    }
}

您可以使用 Html 单选按钮来确定鼠标单击将执行的操作:

  • 在鼠标位置创建一个新圆圈,或者
  • 选择鼠标位置下的圆圈,或
  • “移动”当前选定的圆圈

这里是示例代码和演示:http://jsfiddle.net/m1erickson/CEB7T/

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

    // get references to the canvas and its context
    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var $canvas=$("#canvas");

    // get the canvas position on the page
    // used to get mouse position
    var canvasOffset=$canvas.offset();
    var offsetX=canvasOffset.left;
    var offsetY=canvasOffset.top;
    var scrollX=$canvas.scrollLeft();
    var scrollY=$canvas.scrollTop();
    ctx.lineWidth=3;

    // save info about each circle in an object
    var circles=[];
    var selectedCircle=-1;

    // the html radio buttons indicating what action to do upon mousedown
    var $create=$("#rCreate")[0];
    var $select=$("#rSelect")[0];
    var $move=$("#rMove")[0];

    // draw all circles[]
    function drawAll(){
        ctx.clearRect(0,0,canvas.width,canvas.height);
        for(var i=0;i<circles.length;i++){
            var c=circles[i];
            ctx.beginPath();
            ctx.arc(c.cx,c.cy,c.radius,0,Math.PI*2);
            ctx.closePath();
            ctx.fillStyle=c.color;
            ctx.fill();
            // if this is the selected circle, highlight it
            if(selectedCircle==i){
                ctx.strokeStyle="red";
                ctx.stroke();
            }
        }
    }

    function handleMouseDown(e){
      e.preventDefault();
      mouseX=parseInt(e.clientX-offsetX);
      mouseY=parseInt(e.clientY-offsetY);

      if($create.checked){
          // create a new circle a the mouse position and select it
          circles.push({cx:mouseX,cy:mouseY,radius:10,color:randomColor()});
          selectedCircle=circles.length-1;
      }
      if($select.checked){
          // unselect any selected circle
          selectedCircle=-1;
          // iterate circles[] and select a circle under the mouse
          for(var i=0;i<circles.length;i++){
              var c=circles[i];
              var dx=mouseX-c.cx;
              var dy=mouseY-c.cy;
              var rr=c.radius*c.radius;
              if(dx*dx+dy*dy<rr){ selectedCircle=i; }
          }
      }
      if($move.checked && selectedCircle>=0){
          // move the selected circle to the mouse position
          var c=circles[selectedCircle];
          c.cx=mouseX;
          c.cy=mouseY;
      }

      // redraw all circles
      drawAll();
    }

    // return a random color
    function randomColor(){ 
        return('#'+Math.floor(Math.random()*16777215).toString(16));
    }

    // handle mousedown events
    $("#canvas").mousedown(function(e){handleMouseDown(e);});

}); // end $(function(){});
</script>
</head>
<body>
    <input type="radio" name="grp1" id="rCreate" checked>Click will create a new circle.<br>
    <input type="radio" name="grp1" id="rSelect">Click will select an existing circle.<br>
    <input type="radio" name="grp1" id="rMove">Click will move selected circle.<br>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

关于javascript - 用鼠标移动 Canvas 形状,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22134815/

相关文章:

javascript - 从便士更改计算器 - js

javascript - 检测脚本列表何时全部加载到 javascript 中(使用命名空间)。

IE 中 CSS 类的 Jquery 选择器确实很慢 - 有解决方法吗?

javascript - 如何在不将所有 & 替换为 & 的情况下替换 href url

iphone - 如何在 iphone 应用程序中解析 HTML 页面数据?

javascript - 使用正则表达式格式化输入

javascript - boxslider 插件在 sitecore 预览模式下不工作

javascript - 从元素复制 HTML,用 jQuery 替换文本,然后附加到元素

javascript - MongoDB:使用 $map 更新查询管道中的对象

html - 摆脱CSS中的不可见空间