学习 《HTML5 Canvas 核心技术图形、动画与游戏开发》笔记 二:
“非零环绕规则” 实现如下圆环效果:
canvas 中可通过 beginPath() 来开始一段新的路径,如果当前路径是循环的,或者包含多个相交的子路径时,当fill()方法被调用时,canvas 绘图环境变量就会判断,应该如何对当前路径进行填充。canvas在填充那种互相有交叉的路径时,使用"非零环绕规则"。
非零环绕原理:
如图1所示:假如有两条子路径,里面的路径是逆时针,外面一条是顺时针。当计算里面一条区域时,按照箭头方直到没有子路径为止向往外计数,遇到顺时针则加 1,遇到逆时针则减 1。若计数最终值不是 0,那么此区域,在调用fill()方法时,浏览器会对其进行填充。如果是 0,那么此区域相当于不在路径中,浏览器不会对其进行填充。最终填充效果如图2所示。
图1中第一个圆区域里面往外计算遇到第一条子路径为逆时针所以减 1,遇到第二条子路径为顺时针加1,最后得到0,所以浏览器不会对其进行填充。第二个区域往外计算只有一条子路径,所以不会为0,浏览器对其进行填充,最后形成图2所示。
当有更多复杂的子路径相交时也是以此类推的。
画出圆环代码:
<span style="font-size:14px;"><!doctype html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>canvas画图实例</title>
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<meta name="keywords" content="" />
<meta name="description" content="" />
</head>
<body>
<canvas id="canvas1" width="500" height="480">您的浏览器不支持 canvas 标签</canvas>
</div>
<script>
window.onload = function(){
var can = document.getElementById('canvas1');
var ctx = can.getContext('2d');
function draw(){
ctx.save();
ctx.fillStyle = 'rgba(100,140,230,0.5)';
ctx.strokeStyle= ctx.fillStyle;
ctx.shadowColor = 'rgba(0,0,0,0.8)';
ctx.shadowOffsetX = 12;
ctx.shadowOffsetY = 12;
ctx.shadowBlur = 15;
ctx.beginPath();
/* 绘制的两个圆,绘制路径是相反的。一个顺时针,一个逆时针 */
ctx.arc(can.width/2,can.height/2,150,0,Math.PI*2,false);
ctx.arc(can.width/2,can.height/2,100,0,Math.PI*2,true);
ctx.fill();
ctx.restore();
}
draw();
}
</script>
</body>
</html></span>