【发布时间】:2018-02-08 17:37:03
【问题描述】:
我可以使用 sn-p 中的代码用鼠标重塑多边形。绘制多边形后,用户可以通过移动点来改变形状。但我想在不改变线长的情况下修改形状。点将尽可能改变,但线的长度将保持不变。
我该怎么做?
var canvas, ctx;
var canvasIsMouseDown = false;
var radius = 6;
var pointIndex = -1;
var points = [
{ x: 10, y: 10 },
{ x: 100, y: 50 },
{ x: 150, y: 100 },
{ x: 60, y: 110 },
{ x: 30, y: 160 }
];
function start() {
canvas = document.getElementById("cnPolygon");
ctx = canvas.getContext("2d");
canvas.addEventListener("mousemove", canvasMouseMove);
canvas.addEventListener("mousedown", canvasMouseDown);
canvas.addEventListener("mouseup", canvasMouseUp);
draw();
}
function canvasMouseMove(ev) {
if (!canvasIsMouseDown || pointIndex === -1) return;
points[pointIndex].x = ev.pageX - this.offsetLeft;
points[pointIndex].y = ev.pageY - this.offsetTop;
draw();
}
function canvasMouseDown(ev) {
canvasIsMouseDown = true;
var x = ev.pageX - this.offsetLeft;
var y = ev.pageY - this.offsetTop;
pointIndex = -1;
var dist;
for (var i = 0; i < points.length; i++) {
dist = Math.sqrt(Math.pow((x - points[i].x), 2) + Math.pow((y - points[i].y), 2));
if (dist <= radius) {
pointIndex = i;
break;
}
}
}
function canvasMouseUp(ev) {
canvasIsMouseDown = false;
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(points[0].x, points[0].y);
for (var i = 0; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.closePath();
ctx.stroke();
for (var i = 0; i < points.length; i++) {
ctx.beginPath();
ctx.arc(points[i].x, points[i].y, radius, 0, Math.PI * 2);
ctx.stroke();
}
}
document.addEventListener("DOMContentLoaded", start);
<canvas id="cnPolygon" width="200" height="200" style="border:solid 1px silver"></canvas>
【问题讨论】:
-
你是指线宽还是线长?您在问题中使用了这两个短语。当您说线宽时,我将其理解为线宽,而线长是两点之间的距离。
-
我的意思是行长。我更正了文字。谢谢。
-
这是一个有趣的问题。在某些多边形中,不可能在不改变线条长度的情况下移动单个点,例如考虑三角形。在其他情况下,例如正方形,您可以同时移动两个点。我会通过使用刚体模拟器来解决这个问题,例如brm.io/matter-js
-
matterjs 看起来令人印象深刻!
标签: javascript polygon