【发布时间】:2021-11-10 22:34:33
【问题描述】:
我在画布上绘制多个多边形时遇到问题。
我画了两个多边形, 当我将鼠标移动到第二个多边形时,它变成红色,第一个多边形也是如此(第一个多边形应该是蓝色的)。当我将鼠标移动到第一个多边形时,它会变成红色,第二个多边形也会变成红色(第二个多边形应该是蓝色的)。
我在研究每个画布调用时发现了问题;添加一个 ctx.beginPath() 解决了这个问题。见下文:
<canvas id="myCanvas" width=600 height=600 ></canvas>
<script>
canvas = document.getElementById('myCanvas');
ctx = canvas.getContext('2d');
myimage = new Image();
myimage.src = 'https://i.postimg.cc/SNjPPZGJ/farms-map.png';
myimage.onload = draw
const rect = canvas.getBoundingClientRect();
const polypoints1 = [{x: 200, y: 29}, {x: 500, y: 19}, {x: 465, y: 146}, {x: 130, y: 150}];
const polypoints2 = [{x: 200, y: 229}, {x: 500, y: 219}, {x: 465, y: 346}, {x: 130, y: 350}];
var polyColor = [];
var dragPoint = null;
draw();
canvas.addEventListener('mousedown', onMouseDown);
canvas.addEventListener('mousemove', function(evt) {
polyColor[0]="blue";
polyColor[1]="blue";
if (inside({x:evt.clientX - rect.left, y:(evt.clientY + window.scrollY) - rect.top}, polypoints1)){
polyColor[0]="red";
polyColor[1]="blue";}
if (inside({x:evt.clientX - rect.left, y:(evt.clientY + window.scrollY) - rect.top}, polypoints2)){
polyColor[0]="blue";
polyColor[1]="red";}
draw()
}, false);
function inside(p, vs) {
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i].x, yi = vs[i].y;
var xj = vs[j].x, yj = vs[j].y;
var intersect = ((yi > p.y) != (yj > p.y)) && (p.x < (xj - xi) * (p.y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (myimage) {
ctx.drawImage(myimage, 1, 1)
}
drawLines();
polypoints1.forEach(p => drawPoint(p));
polypoints2.forEach(p => drawPoint(p));
}
function drawPoint(p) {
ctx.beginPath();
ctx.globalAlpha = 1
ctx.fillStyle = "black";
ctx.lineWidth = 2;
ctx.arc(p.x, p.y, 5, 0, 2 * Math.PI, false);
ctx.stroke();
ctx.fill();
}
function drawLines() {
ctx.beginPath();
ctx.lineWidth = 2;
polypoints1.forEach(p => ctx.lineTo(p.x, p.y));
ctx.lineTo(polypoints1[0].x, polypoints1[0].y);
ctx.stroke();
if (!dragPoint) {
ctx.globalAlpha = 0.2
ctx.fillStyle = polyColor[0];
ctx.fill();
}
ctx.beginPath();
ctx.lineWidth = 2;
polypoints2.forEach(p => ctx.lineTo(p.x, p.y));
ctx.lineTo(polypoints2[0].x, polypoints2[0].y);
ctx.stroke();
if (!dragPoint) {
ctx.globalAlpha = 0.2
ctx.fillStyle = polyColor[1];
ctx.fill();
}
}
function findDragPoint(x, y) {
for (i = 0; i < polypoints1.length; i++) {
if (hitTest(polypoints1[i], x, y)) return polypoints1[i];
if (hitTest(polypoints2[i], x, y)) return polypoints2[i];
};
return null;
}
function onMouseDown(event) {
dragPoint = findDragPoint(event.clientX - canvas.offsetLeft, event.clientY - canvas.offsetTop + window.scrollY);
if (dragPoint) {
dragPoint.x = event.clientX - canvas.offsetLeft;
dragPoint.y = event.clientY - canvas.offsetTop + window.scrollY;
draw();
canvas.addEventListener("mousemove", onMouseMove);
canvas.addEventListener("mouseup", onMouseUp);
}
}
function onMouseMove(event) {
dragPoint.x = event.clientX - canvas.offsetLeft;
dragPoint.y = event.clientY - canvas.offsetTop+ window.scrollY;
draw();
}
function onMouseUp() {
dragPoint = null;
draw();
canvas.removeEventListener("mousemove", onMouseMove);
canvas.removeEventListener("mouseup", onMouseUp);
}
function hitTest(p, x, y) {
var dx = p.x - x, dy = p.y - y;
return Math.sqrt(dx * dx + dy * dy) <= 10;
}
</script>
【问题讨论】:
-
请参阅How to Ask。你需要把你的代码放在这里。您(可能是不经意间)通过将您的列表格式化为代码来规避该规则。
-
记得关注posting guidelines:一题一题,并在您的帖子中显示与该单个问题相关的代码(最好是可运行的 sn-p),即使您也有带有该代码的第三方网站的链接。如果该第三方网站从互联网上掉线,您的帖子应该仍然有意义。
-
记得将你的代码缩减为minimal reproducible example:现在代码中有很多与问题无关的内容。这听起来可能有点学究气,但让你组建 MCVE 的全部意义在于,它几乎总是会让你自己发现问题所在,而在极少数情况下它不会,你有完美的代码 用于放置任何论坛帖子。
-
好的。感谢您的反馈。让我用多种多边形颜色来创建问题。我需要大约 2 小时。
-
我已根据从 isherwood 和 Mike Kamermans 收到的反馈更新了帖子。让我知道是否还有更多工作可以解决问题。
标签: javascript html html5-canvas polygon