此文讲一个之前提都没提但功能强大的方法,即clip
clip的字面意思是切割,实际上他的功能也差不多这么个意思,但如果你学过flash,那我说他的功能相当于“遮罩”,那你估计就理解了。
clip的作用是依照前面创建的路径进行一次切割,然后所有在clip之后画的图形都只有在被切割的路径内才会显示,路径外的则不得显示。
比如我们先照常画一个矩形:
1
2
3
|
ctx.beginPath();
ctx.rect(100,100,100,100);
ctx.fill();
|
效果如下:
但如果在画矩形之前,我们先创建一个clip路径:
1
2
3
4
5
|
ctx.arc(100,100,50,0,Math.PI*2);
ctx.clip();
ctx.beginPath();
ctx.rect(100,100,100,100);
ctx.fill();
|
懂了吧?
而且,clip是一直存在的,不论你后面画多少路径:
1
2
3
4
5
6
7
8
9
|
ctx.arc(100,100,50,0,Math.PI*2);
ctx.clip();
ctx.beginPath();
ctx.rect(100,100,100,100);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = "#F00";
ctx.arc(100,100,100,0,Math.PI*2);
ctx.fill();
|
图中的圆依然被限制在clip的范围中
那么怎么废除clip呢?还是用前面说的save与restore方法:
1
2
3
4
5
6
7
8
9
10
11
|
ctx.save();
ctx.arc(100,100,50,0,Math.PI*2);
ctx.clip();
ctx.beginPath();
ctx.rect(100,100,100,100);
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.fillStyle = "#F00";
ctx.arc(100,100,100,0,Math.PI*2);
ctx.fill();
|
还原之后,大圆就显示出他的真面目了。
另外,clip不只是对画出的图形生效,也可以用来保证路径外的图形不被清除,比如我想在一个大矩形上挖一个洞:
1
2
3
4
5
|
ctx.fillRect(10,10,100,100);
ctx.beginPath();
ctx.arc(30,30,20,0,Math.PI*2);
ctx.clip();
ctx.clearRect(10,10,100,100);
|
这一个功能很好,通常我们可以用来保留画布的大部分内容而只清除那一小部分我们不要的。
那么,如果我想挖几个洞而不是一个,怎么办呢?连续画几个路径再clip即可。
1
2
3
4
5
6
7
|
ctx.fillRect(10,10,100,100);
ctx.beginPath();
ctx.arc(30,30,20,0,Math.PI*2);
ctx.arc(50,30,20,0,Math.PI*2); //多出来的一个
ctx.fill();
ctx.clip();
ctx.clearRect(10,10,100,100);
|
由实践得知:clip会以上一个beginPath()后面所绘的所有路径进行一个切割,即使你已经对这些路径进行过操作(如fill)。这一点请牢记。
通常我们在用canvas做一个游戏的时候,需要清除某些小区域——这些区域通常是不规则的,以前我还抱怨过canvas只能按矩形区域清空,很不灵活,自从有了clip,就不用担心这个问题了。