使用mousedown在画布上拖动圆圈

时间:2017-08-01 23:33:48

标签: javascript html canvas automatic-ref-counting draw

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

14861 root      20   0       0      0      0 S   0.0  0.0   0:00.00 [kworker/1+
14864 root      20   0       0      0      0 S   0.0  0.0   0:00.02 [kworker/0+
15120 root      39  19  102488   3344   2656 S   0.0  0.1   0:00.09 /usr/bin/m+
16904 root      20   0       0      0      0 S   0.0  0.0   0:00.00 [kworker/0+
19031 root      20   0       0      0      0 S   0.0  0.0   0:00.00 [kworker/u+
21500 root      20   0       0      0      0 Z   0.0  0.0   0:00.00 [dsc] <def+
22571 root      20   0       0      0      0 S   0.0  0.0   0:00.00 [kworker/0+

该项目到目前为止的表现如何 enter image description here

1 个答案:

答案 0 :(得分:1)

以下代码基于您的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>