canvassvg 里面进行填充渲染,填充当前或已经存在的路径,采用 奇偶或非零环绕规则
Even-odd_and_non-zero_winding_fill_rules.png
左为奇偶环绕,右为非零环绕

image.png

奇偶(Even-odd Rule)

奇偶就是 路径包围的区域任意点P向外做一条射线,如果相交的边总数是奇数填充,反之不填充

  1. var canvas=document.getElementById("myCanvas");
  2. var context=canvas.getContext("2d");
  3. context.strokeStyle = "rgb(0,0,0)";
  4. context.fillStyle = "rgb(250,0,0)"
  5. context.beginPath();
  6. context.moveTo(100, 0);
  7. context.lineTo(100+Math.cos(Math.PI*3/10)*100, 100+Math.sin(Math.PI*3/10)*100);
  8. context.lineTo(100-Math.cos(Math.PI*1/10)*100, 100-Math.sin(Math.PI*1/10)*100);
  9. context.lineTo(100+Math.cos(Math.PI*1/10)*100, 100-Math.sin(Math.PI*1/10)*100);
  10. context.lineTo(100-Math.cos(Math.PI*3/10)*100, 100+Math.sin(Math.PI*3/10)*100);
  11. context.lineTo(100, 0);
  12. context.fill('evenodd');
  13. context.stroke();
  14. context.closePath();

image.png

非零(Nonzero Rule)

非零就是 路径包围的区域任意点P向外做一条射线,环绕数为0,如果相交的边是从左向右环绕数减1,从右向左环绕数加1,环绕数不为零填充,反之不填充

  1. var canvas=document.getElementById("myCanvas");
  2. var context=canvas.getContext("2d");
  3. context.strokeStyle = "rgb(0,0,0)";
  4. context.fillStyle = "rgb(250,0,0)"
  5. context.beginPath();
  6. context.moveTo(100, 0);
  7. context.lineTo(100+Math.cos(Math.PI*3/10)*100, 100+Math.sin(Math.PI*3/10)*100);
  8. context.lineTo(100-Math.cos(Math.PI*1/10)*100, 100-Math.sin(Math.PI*1/10)*100);
  9. context.lineTo(100+Math.cos(Math.PI*1/10)*100, 100-Math.sin(Math.PI*1/10)*100);
  10. context.lineTo(100-Math.cos(Math.PI*3/10)*100, 100+Math.sin(Math.PI*3/10)*100);
  11. context.lineTo(100, 0);
  12. context.fill('nonzero');
  13. context.stroke();
  14. context.closePath();

image.png

总结

为什么2种方式渲染出来的图形不一样?

image.png
因为 lineTo 默认按照顺时针,无法像 arc 方法一样控制方向, 奇偶环绕时2个相交的边,不填充,非零环绕相交2个从左向右的边,是-2,填充