使用 mousedown 在 canvas 上拖动一个圆圈
Dragging a circle on a canvas using mousedown
现在,我有 2 个圆圈和中间的一条线。我希望能够拖动其中一个仍然连接着线的圆圈,并且在我移动它时它会保持与圆圈的连接。
node1 和 node2 是圆形维度。 line/muscle 连接到node1 和node2 的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();
}
项目到目前为止的情况
下面的代码是基于你的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>
现在,我有 2 个圆圈和中间的一条线。我希望能够拖动其中一个仍然连接着线的圆圈,并且在我移动它时它会保持与圆圈的连接。 node1 和 node2 是圆形维度。 line/muscle 连接到node1 和node2 的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();
}
项目到目前为止的情况
下面的代码是基于你的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>