为什么fillRect命令不允许创建命中区域,而rect和fill的组合允许创建命中区域?

Why doesn't fillRect command allow to create a hit region while a combination of rect and fill does?

本文关键字:区域 创建 许创建 组合 rect 不允许 命令 fillRect 为什么 fill      更新时间:2023-09-26

我在使用CanvasRenderingContext2D.addHitRegion()时偶然发现了这个问题,我试图理解这是否是一种预期的行为,如果是,这背后的原因是什么。

这是我的工作JSFIDDLE,我创建了一个画布,点击区域,可以显示点击区域的id。

我是这样添加hit区域的:

ctx.beginPath();
ctx.rect(0, i, canvasWidth, itemHeight);
ctx.fill();
ctx.addHitRegion({'id': count, 'cursor': 'pointer'});

这里是同样的例子,只有一个小的改变(,这就是我最初尝试这样做的方式-当我可以使用一个命令来做同样的事情时,为什么要使用两个命令?)

ctx.fillRect(0, i, canvasWidth, itemHeight);
ctx.addHitRegion({'id': count, 'cursor': 'pointer'});

不幸的是,它不起作用,如下所示JSFIDDLE

控制台显示以下错误:

未捕获NotSupportedError:未能执行'addHitRegion''CanvasRenderingContext2D':指定的路径没有像素。

所以似乎为了创建命中区域,你不能使用fillRect命令-我找不到任何解释这个行为。

很高兴听到任何想法!

fillRectContext2D的直接命令之一:它创建一个"幕后"路径并立即填充它。
这意味着当命中区域需要路径时,它不会像rect那样构建路径。
请注意,您不需要填充它,所以只有在需要时才这样做。

作为旁注,浏览器对hit区域的支持不是那么好,正如你在这里看到的:https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/addHitRegion,它仍然是实验性的,所以如果你想要/需要广泛的支持,请查看此

正如@MarkE引用的那样,实现击中区域的安全方法是自己处理鼠标(getBoundingClientRect是你的朋友!),你的路径集合,并使用isPointInPath检查坐标。
再次注意,isPointInPath需要一个路径,所以它不能用于直接命令(fillXXX/strokeXXX/ImageData之类的)。