我在画布上画了两条线,并且有一个鼠标按下事件来监听画布, 单击该行时,该行的颜色应更改。我已经实现了这种方法 使用画布的isPointInStroke方法,但问题是所有绘制的线条都被突出显示。
我不知道我哪里错了。有人可以解决此问题吗? 链接到有效的demo 这是我尝试过的,
const c = document.getElementById('c');
var ctx = c.getContext("2d");
var onLine = false; // state (for demo)
ctx.moveTo(10, 10); // store a line on path
ctx.lineTo(220, 0);
ctx.moveTo(50, 20); // store a line on path
ctx.lineTo(200, 100);
ctx.lineWidth = 16;
// line width
render(); // initial render
function render() {
ctx.clearRect(0,0,300,150);
ctx.strokeStyle = onLine ? "red" : "green"; // color based on state
ctx.stroke(); // stroke path
}
c.onmousedown = function(e) {
const rect = c.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
onLine = ctx.isPointInStroke(x, y);
render();
};
答案 0 :(得分:1)
这是一个使用两个Path2D对象表示所绘制线条的解决方案。这样一来,使用ctx.isPointInStroke(path, x, y)
而不是ctx.isPointInStroke(x, y)
请注意,此解决方案不假定点击是互斥的。因此,如果线条确实重叠(在这种情况下它们不会重叠),那么如果单击重叠区域,两条线的颜色都会改变。
此外,请注意,仅当单击一行时才切换颜色。如果未单击,则线条的颜色保持不变。
const c = document.getElementById('c');
const START_COLOR = "green";
var ctx = c.getContext("2d");
/*Path2D objects representing the two lines */
var pathA = new Path2D();
var pathB = new Path2D();
/*Build the paths */
pathA.moveTo(10, 10); // store a line on path A
pathA.lineTo(220, 0);
pathB.moveTo(50, 20); // store a line on path B
pathB.lineTo(200, 100);
ctx.strokeStyle = START_COLOR;
/*Booleans tracking the click state of each line */
var clickedA = false;
var clickedB = false;
/*Both lines initially set to the start color */
var colorA = START_COLOR;
var colorB = START_COLOR;
ctx.lineWidth = 16; // line width
render(); // initial render
function render() {
ctx.clearRect(0,0, 150, 300);
/*Check if A was clicked, and toggle its color by setting context strokeStyle*/
if (clickedA === true)
{
colorA = (colorA == "red" ? "green" : "red");
}
/*Set correct color for A and draw it to canvas */
ctx.strokeStyle = colorA;
ctx.stroke(pathA);
/*Check if B was clicked, and toggle its color */
if (clickedB === true)
{
colorB = (colorB == "red" ? "green" : "red");
}
/*Set correct color for B and draw it to canvas */
ctx.strokeStyle = colorB;
ctx.stroke(pathB);
/*Reset values of clickedA and clickedB to false */
clickedA = false;
clickedB = false;
}
c.onmousedown = function(e) {
const rect = c.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
/*Here we use the other version of isPointInStroke which has path2D
as first param to detect click within either stroke */
clickedA = ctx.isPointInStroke(pathA, x, y);
/*Check for click within path B for a click in pathB */
clickedB = ctx.isPointInStroke(pathB, x, y);
render();
}