4.5.5 裁剪区域
Canvas中的剪辑区域,是由路径所定义的一块区域,浏览器会把所有的绘图操作都限制在该区域内执行。
Canvas中,使用clip()方法来设定剪辑区域,一旦设定好裁剪区域,则只有落在裁剪区域内的图形才能绘制出来,在裁剪区域以外进行绘制将没有任何效果。默认的剪辑区域是整个画布。
由于剪辑区域是由路径所定义的区域,所以,必须先调用beginPath()方法绘制一个路径,然后,才能通过clip()方法把该路径设置为裁剪区域。定义裁剪区域的步骤为:
- 调用beginPath()方法开始一个路径。
- 调用arc()、rect()等方法定义路径。
- 调用clip()方法,把该路径设置为裁剪区域。
下面以绘制两个圆形区域为例,来说明裁剪区域的使用方法。首先,不设置裁剪区域,绘制两个圆形区域:
context.lineWidth = 12;
context.strokeStyle = "#444";
context.beginPath();
context.arc(100, 100, 50, 0, Math.PI*2);
context.closePath();
context.stroke();
context.beginPath();
context.arc(100, 100, 30, 0, Math.PI*2);
context.closePath();
context.stroke();
由于未设置裁剪区域,两个圆都被完整的绘制出来,运行结果如图 4‑25 所示:
调用rect()方法,在画布的左上角定义一个100×100的矩形路径,再调用clip()方法把该路径设置为裁剪区域。
context.lineWidth = 12;
context.strokeStyle = "#444";
context.rect(0,0,100,100); // 定义裁剪区域
context.clip();
context.beginPath();
context.arc(100, 100, 50, 0, Math.PI*2);
context.closePath();
context.stroke();
context.beginPath();
context.arc(100, 100, 30, 0, Math.PI*2);
context.closePath();
context.stroke();
上述代码设置了一个矩形的裁剪区域,所以,只有落在该裁剪区域内的部分被绘制出来。运行效果如图 4‑26 所示:
从上图可以看出,两个圆均只绘制出其左上角部分,其余部分没有被绘制。
当然,也可以设置多个裁剪区域。如果要定义多个裁剪区域,只需要在该路径中定义多条路径,再调用clip()方法把它们设置为裁剪区域即可。
context.lineWidth = 12;
context.strokeStyle = "#444";
context.rect(0,0,100,100); // 定义第一个裁剪区域
context.rect(100,100,100,100); // 定义第二个裁剪区域
context.clip();
context.beginPath();
context.arc(100, 100, 50, 0, Math.PI*2);
context.closePath();
context.stroke();
context.beginPath();
context.arc(100, 100, 30, 0, Math.PI*2);
context.closePath();
context.stroke();
上述代码在原来的基础上,又增加了右下侧的裁剪区域。由于现在有两个矩形的裁剪区域,此时,左上角和右下角的圆弧都被绘制出来。运行结果如图 4‑27 所示:
当使用裁选区进行绘画后,有时需要取消该裁选区或重新定义裁选区。此时,可以在需要保存状态的地方调用save()方法,在需要恢复状态的地方调用restore()方法。
context.lineWidth = 12;
context.strokeStyle = "#444";
context.save(); // 保存状态
context.rect(0,0,100,100);
context.clip();
context.beginPath();
context.arc(100, 100, 60, 0, Math.PI*2);
context.closePath();
context.stroke();
context.restore(); // 恢复状态
context.beginPath();
context.arc(100, 100, 40, 0, Math.PI*2);
context.closePath();
context.stroke();
上述代码中,第一个圆被局限在裁选区域内。由于在绘制第二个圆之前,调用了restore()方法恢复状态,取消了裁选区域,因此第二个圆是完整的。运行结果如图 4‑28 所示: