HTML5 Canvas非零环绕填充规则疑问:交叉子路径为何空白?
你混淆了非零环绕填充规则与奇偶填充规则的效果
哈哈,这个误区其实挺常见的——你预期交叉区域会出现空白,但那其实是**奇偶填充规则(even-odd)**的表现,而非Canvas默认的非零环绕规则。
先拆解下你的代码细节:你画的两个条形都是顺时针绘制的矩形子路径:
- 水平条形:从
(10,100)出发,向右→向下→向左→向上回到起点,标准顺时针走向 - 垂直条形:从
(100,10)出发,向下→向右→向上→向左回到起点,同样是顺时针走向
非零环绕规则的实际逻辑
非零规则的核心是看区域的环绕数:
- 随便找区域里一点,向外画一条无限长的射线
- 数这条射线穿过路径的次数,同时看路径的走向:
- 如果路径是逆时针穿过射线,环绕数加1
- 如果是顺时针穿过,环绕数减1
- 只要最终环绕数不等于0,这个区域就会被填充
回到你的交叉图形:
- 四个角落的非交叉区域:只被一个顺时针路径覆盖,环绕数是1(不为0),所以会被填充
- 中心交叉区域:两个顺时针路径都穿过射线,环绕数是2(依然不为0),所以也会被完全填充——这就是你看到的“全填充”结果
想要中心空白?换奇偶填充规则就行
如果想实现你预期的“交叉处空白”效果,只需要在fill()方法里显式指定evenodd规则:
ctx.fill('evenodd');
奇偶规则的逻辑简单粗暴:只统计射线穿过路径的次数,奇数就填充,偶数就不填充。交叉区域会被两条路径各穿过一次,总次数是2(偶数),所以就会留下空白啦。
内容的提问来源于stack exchange,提问作者Martin
相关产品推荐
相关产品推荐

