左为奇偶环绕,右为非零环绕javascript
2D图形不一样系统不一样浏览器使用图形库可能都不同。java
chrome
使用的是 skia
图形函数库firefox
使用的是 cairo
图形函数库skia
和 cairo
是对后端(backend)的封装,因此能够跨平台,虽然 chrome
使用的图形库是 skia
,可是在不一样系统上底层图形库仍是可能不同,好比默认系统:chrome
Quartz 2D
图形库GDI
、 GDI+
,Windows Vista后使用 Direct2D
Windows Vistacanvas
在 canvas
和 svg
里面进行填充渲染, CanvasRenderingContext2D.fill()
就是 Canvas 2D API 根据当前填充的样式,填充当前或已经存在的路径,采用 奇偶或非零环绕规则 。windows
奇偶就是 路径包围的区域任意点P向外作一条射线,若是相交的边总数是奇数填充,反之不填充 。后端
var canvas=document.getElementById("myCanvas"); var context=canvas.getContext("2d"); context.strokeStyle = "rgb(0,0,0)"; context.fillStyle = "rgb(250,0,0)" context.beginPath(); context.moveTo(100, 0); context.lineTo(100+Math.cos(Math.PI*3/10)*100, 100+Math.sin(Math.PI*3/10)*100); context.lineTo(100-Math.cos(Math.PI*1/10)*100, 100-Math.sin(Math.PI*1/10)*100); context.lineTo(100+Math.cos(Math.PI*1/10)*100, 100-Math.sin(Math.PI*1/10)*100); context.lineTo(100-Math.cos(Math.PI*3/10)*100, 100+Math.sin(Math.PI*3/10)*100); context.lineTo(100, 0); context.fill('evenodd'); context.stroke(); context.closePath();
非零就是 路径包围的区域任意点P向外作一条射线,环绕数为0,若是相交的边是从左向右环绕数减1,从右向左环绕数加1,环绕数不为零填充,反之不填充 。浏览器
var canvas=document.getElementById("myCanvas"); var context=canvas.getContext("2d"); context.strokeStyle = "rgb(0,0,0)"; context.fillStyle = "rgb(250,0,0)" context.beginPath(); context.moveTo(100, 0); context.lineTo(100+Math.cos(Math.PI*3/10)*100, 100+Math.sin(Math.PI*3/10)*100); context.lineTo(100-Math.cos(Math.PI*1/10)*100, 100-Math.sin(Math.PI*1/10)*100); context.lineTo(100+Math.cos(Math.PI*1/10)*100, 100-Math.sin(Math.PI*1/10)*100); context.lineTo(100-Math.cos(Math.PI*3/10)*100, 100+Math.sin(Math.PI*3/10)*100); context.lineTo(100, 0); context.fill('nonzero'); context.stroke(); context.closePath();
为何2种方式渲染出来的图形不同?svg
由于 lineTo
默认按照顺时针,没法像 arc
方法同样控制方向, 奇偶环绕时2个相交的边,不填充,非零环绕相交2个从左向右的边,是-2,填充 函数