javascript - 使用 mousedown 在 Canvas 上拖动圆圈

标签 javascript html canvas automatic-ref-counting draw

现在,我有 2 个圆圈,中间有一条线。我希望能够拖动其中一个仍带有线的圆圈,并且当我移动它时它将保持与圆圈的连接。 节点 1 和节点 2 是圆的尺寸。线/肌肉连接到节点 1 和节点 2 的 x 和 y 位置。

function draw() {
    //draw in the container
    c.fillStyle = "#000000";
    c.fillRect(container.y, container.x, container.width, container.height);

    //draw first node
    c.arc(node1.x, node1.y, node1.r, 0, 2*Math.PI);
    c.fillStyle = node1.color;
    c.fill();

    //draw second node
    c.arc(node2.x, node2.y, node2.r, 0, 2*Math.PI);
    c.strokeStyle = node2.color;
    c.fillStyle = node2.color;
    c.fill();

    //draw muscle
    c.beginPath();
    c.moveTo(muscle.node1x, muscle.node1y);
    c.lineTo(muscle.node2x, muscle.node2y);
    c.strokeStyle = muscle.color;
    c.lineWidth = muscle.width;
    c.stroke();
}

目前该项目的情况如何 enter image description here

最佳答案

以下代码基于您的draw函数并实现了拖动功能。

function draw(container, c, node1, node2, muscle) {
  //draw in the container
  c.fillStyle = "#000000";
  c.fillRect(container.y, container.x, container.width, container.height);

  //draw first node
  c.arc(node1.x, node1.y, node1.r, 0, 2 * Math.PI);
  c.fillStyle = node1.color;
  c.closePath();
  c.fill();

  //draw second node
  c.arc(node2.x, node2.y, node2.r, 0, 2 * Math.PI);
  c.strokeStyle = node2.color;
  c.fillStyle = node2.color;
  c.closePath();
  c.fill();

  //draw muscle
  c.beginPath();
  c.moveTo(muscle.node1x, muscle.node1y);
  c.lineTo(muscle.node2x, muscle.node2y);
  c.strokeStyle = muscle.color;
  c.lineWidth = muscle.width;
  c.closePath();
  c.stroke();
}

function Node(x, y, r, color) {
  this.x = x;
  this.y = y;
  this.r = r || 20;
  this.color = color || "#ff0";
}

function Muscle(node1, node2, width, color) {
  this.node1 = node1;
  this.node2 = node2;
  this.width = width || 5;
  this.color = color || "#f00";
  Object.defineProperties(this, {
    node1x: {
      "get": () => this.node1.x,
      "set": x => { this.node1.x = x }
    },
    node1y: {
      "get": () => this.node1.y,
      "set": y => { this.node1.y = y }
    },
    node2x: {
      "get": () => this.node2.x,
      "set": x => { this.node2.x = x }
    },
    node2y: {
      "get": () => this.node2.y,
      "set": y => { this.node2.y = y }
    }
  })
}


function handleMouseDrag(canvas, nodes) {
  var isDrag = false;
  var offset = { x: 0, y: 0, x0: 0, y0: 0 };
  var dragNode = undefined;
  canvas.addEventListener("mousedown", function (e) {
    var x = e.offsetX, y = e.offsetY;
    for (var i in nodes) {
      if (Math.pow(x - nodes[i].x, 2) + Math.pow(y - nodes[i].y, 2) < Math.pow(nodes[i].r, 2)) {
        isDrag = true;
        dragNode = nodes[i];
        offset = { x: dragNode.x, y: dragNode.y, x0: x, y0: y };
        return;
      }
    }
  });
  canvas.addEventListener("mousemove", function (e) {
    if (isDrag) {
      dragNode.x = e.offsetX - offset.x0 + offset.x;
      dragNode.y = e.offsetY - offset.y0 + offset.y;
    }
  });
  canvas.addEventListener("mouseup", function (e) {
    isDrag = false;
  });
  canvas.addEventListener("mouseleave", function (e) {
    isDrag = false;
  });
}

function main() {
  var node1 = new Node(40, 40);
  var node2 = new Node(120, 120);
  var muscle = new Muscle(node1, node2);

  var canvas = document.getElementById("canvas");
  var container = { x: 0, y: 0, get width() { return canvas.width }, get height() { return canvas.height } }
  var ctx = canvas.getContext("2d");

  handleMouseDrag(canvas, [node1, node2]);

  function updateFrame() {
    ctx.save();
    draw(container, ctx, node1, node2, muscle);
    ctx.restore();
    requestAnimationFrame(updateFrame)
  };
  updateFrame();
}

main();
<canvas width="400" height="400" id="canvas"></canvas>

关于javascript - 使用 mousedown 在 Canvas 上拖动圆圈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45449177/

相关文章:

javascript - 如何让 Flot 在 x 轴上绘制多个点?

javascript - 如何打开一个弹出文本框要求用户提交评论?

java - Android 翻译的 Canvas 矩形碰撞

javascript - WebGL VS Canvas 二维硬件加速

javascript - 当我使用 lineTo 和 moveTo 绘制桨时,如何使用 Javascript 在 Breakout 中移动桨?

javascript - 'typeof define === ' function' && define ['amd' ]' 的用途是什么?

javascript - 调用函数 onPress React Native

javascript - 简单请求: Uncaught TypeError: Cannot read property 'length' of undefined

html - 使用 bootstrap 3 调整图像周围的文本

jquery - 单击使 div 出现并在再次单击时使其消失