填补区域中的空洞

3
我有一个画布,上面有很多东西,现在我想填充一个定义为整个画布但不包括一些洞(我的洞是由弧形组成的复杂形状)的区域。
对于只有一个洞的情况,很简单:我首先用整个画布矩形创建一个子路径,然后再创建一个相反方向的子路径。因此,当我填充生成的路径时,我实际上填充了除洞以外的画布。
对于几个洞,只要我的洞不相交,它也能这样工作:如果相交,此方法会填充洞的相交部分,这不是所需的结果。
所以问题来了:如何填充带有相交洞的形状?
目前,我更愿意不尝试显式计算我的形状的联合,因为它们很复杂(涉及到弧线)。这就是为什么我没有使用getImageData()的原因。
下面是图形解释:
这应该非常快,因为源画布和洞都是动画的,但屏幕上几乎永远不会出现超过3个洞。

1
你看过合成吗?https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Compositing - Alex Turpin
是的,但我没有找到解决方案。你认为你有吗? - Denys Séguret
事实上,重新考虑后,我可能会使用第二个(未显示)画布来绘制我的遮罩,用目标-出方式绘制我的孔。这似乎很昂贵,但我找不到更好的方法... - Denys Séguret
1个回答

2
我不确定我看到了什么问题。你只是想在某个东西上面画路径并填充路径的联合吗?
这在Canvas上很容易做到。Canvas可以绘制路径和子路径,您需要绘制一系列多个子路径(但仅一个路径)。为避免缠绕,您需要以相同的方向(顺时针或逆时针)绘制所有子路径。
这是一个示例,其中一个路径实际上是两个子路径的联合,形成一个“孔”:

http://jsfiddle.net/KX8Xf/

请注意,我只调用了一次BeginPath,然后使用closePathmoveTo来开始我的新子路径。
如果您想填充此图形的反向区域,可以填充一个内存画布,在内存画布上将路径作为剪切区域绘制,将普通画布绘制到内存画布上,然后将内存画布绘制回普通画布。这是一个示例

这个解决方案基本上就是我们与Xeon06评论中定义的一样。但是当只是为了解决交叉问题时,不得不使用第二个内存画布来解决问题感觉不太好。我会去尝试一下并查看是否有更好的解决方案,以确保其速度足够快且达到可接受的水平。 - Denys Séguret
如果你需要安慰的话,随着时间的推移,情况会变得更好。尽管我们在过去几年中看到了速度的惊人增长,但JavaScript引擎仍远远落后于其他语言。至少V8很快。 - Alex Turpin
把你的代码放在某个地方,我会找时间来优化它。 - Simon Sarris
我不能发布它。但唯一缓慢的操作是在源画布上绘制大透明孔图像的drawImage。由于画布是全屏的,这是一个已知在FF上很慢的操作。我的主要优化是计算孔的数量,并尽可能回到我的第一种方法(不使用其他画布)。 - Denys Séguret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接