我有一条线是按不同方向画的。我保存路径,然后检查是否悬停在点上:
这条线是如何形成的:
let path = new Path2D();
ctx.lineWidth = 20; // this doesn't seem to affect the hitbox of the liine
ctx.globalAlpha = 1;
ctx.beginPath();
path.moveTo(start.x + (width / 2), start.y);
path.lineTo(start.x + (width / 2) + linePadding, start.y);
path.lineTo(mid, start.y);
path.lineTo(mid, end.y);
path.lineTo(end.x - (width / 2) - linePadding, end.y);
ctx.stroke(path);
ctx.closePath();当我检查是否撞上了这条路时:
path_Arrows.some(element => {
if (ctx.isPointInStroke(element.path, mouseLocation.x, mouseLocation.y)) {它似乎没有探测到整个中风,只是微小的一笔。更改lineWidth确实会在视觉上改变行,但不会改变isPointInStroke。调整mouseLocation.x, mouseLocation.y以调整hitbox的范围在技术上是可能的,但是由于这些行是如此动态和程序化,所以很难解释每个潜在的位置(除非我认为这是错误的)。
我还考虑过用所需的lineWidth (如5)改变一条线的主存方式,然后从它们移动和检查isPointInPath的点开始,用0 alpha绘制矩形。
编辑:
这个问题来自一个函数,用于创建一个形状,然后在函数中检查是否需要从该形状绘制一条线,如果需要,则绘制直线,然后继续绘制该形状。
例如:
drawLine(ctx, from, to);
let box = new Path2D();
ctx.beginPath();
ctx.strokeStyle = "black";
ctx.lineWidth = 1;
ctx.fillStyle = "blue";
box.rect(x, y, rWidth, rHeight);
ctx.fill(box);
ctx.strokeRect(x, y, rWidth, rHeight);
ctx.closePath();该行的创建非常类似于我在drawLine()中编辑之前显示它的方式,然后在调用后继续撤回该框。在lineWidth & drawLine()中设置颜色在视觉上是正确的,在框中设置的lineWidth在颜色和大小上也是正确的。
尽管isPointInStroke正在检测框内的行集的大小,而不是在drawLine()中。
我可以将线宽增加到很大的数目,比如50,并且增加了盒子的行程,线的行程不是,但是它检测到捕捉到的点就像它那么大。
我在看什么?
发布于 2021-02-18 03:34:31
ctx.isPointInStroke() 将使用当前的lineWidth值来设置笔划的命中框.双重检查--在调用它时,它仍然被设置为正确的值。
还要注意,它甚至会受到当前转换矩阵的影响。
const ctx = document.querySelector("canvas").getContext("2d");
const path = new Path2D();
path.moveTo( 10, 10 );
path.lineTo( 80, 10 );
path.lineTo( 80, 50 );
path.lineTo( 30, 50 );
path.lineTo( 10, 30 );
ctx.lineWidth = 20;
ctx.strokeStyle = "green";
ctx.stroke(path);
ctx.lineWidth = 2;
ctx.strokeStyle = "red";
ctx.stroke( path );
function isOverStroke( line_width, x, y ) {
ctx.lineWidth = line_width;
return ctx.isPointInStroke( path, x, y );
}
onmousemove = (evt) => {
const rect = ctx.canvas.getBoundingClientRect();
const x = evt.clientX - rect.left;
const y = evt.clientY - rect.top;
let hovered_color = "transparent";
if( isOverStroke( 2, x, y ) ) {
hovered_color = "red";
}
else if( isOverStroke( 20, x, y ) ) {
hovered_color = "green";
}
color_logger.style.backgroundColor = hovered_color;
};#color_logger {
vertical-align: top;
display: inline-block;
border: 1px solid;
width: 30px;
height: 30px;
}<canvas width="150"></canvas>
<div id="color_logger"></div>
https://stackoverflow.com/questions/66253031
复制相似问题