4.2.1 如何使用路径
在Canvas中绘图,其实就是先按照一定顺序定义一些坐标点,再通过指定的方式,用画笔将这些坐标点连接起来,就形成我们所需要的图形。
Canvas中的所有基本图形,包括线段、矩形、圆弧、贝塞尔曲线等,都是基于路径进行绘制的。
Canvas中,把从绘制起点到绘制终点所经过的这些点,就称为路径。一个路径可以包含多个子路径,子路径又是由两个或多个点组成。在某一时刻,canvas中只能有一条路径存在,canvas规范把它称为“当前路径”。使用路径时,绘制图形的一般步骤为:
- 调用beginPath()方法开始一条新的路径。
- 调用moveTo(x, y)方法以(x, y)为起点开始一条新的子路径,并把画笔移动到该起点。
- 定义子路径的内容。如,rect()方法定义矩形路径,arc()方法定义圆弧路径,等等。
- 调用closePath()方法关闭路径,使该路径闭合。
- 每调用一次beginPath()方法,会新定义一条路径,该方法会把当前路径中的所有子路径全部清除;每调用一次moveTo (x, y)方法,会新定义一条子路径。
说明:
在 Canvas 中定义子路径,一般是不需要指定起点的。第一条子路径的默认起点是画布的原点,其它子路径的起点是上一次定义路径的终点。因此,只有在需要重新定义起点的时候,才要调用 moveTo ()方法。
关闭路径就是把路径的起点自动作为终点,并把起点和终点用直线连接起来,形成一个闭合区域。如果不需要绘制封闭图形,则不必调用closePath()方法。
canvas中有几个特殊的方法,如rect()方法,被称作路径方法,它们会自动调用moveTo()和closePath()方法。使用路径方法绘制图形时,可以省略步骤2和步骤4。
为了简单起见,下面举一个使用路径方法绘制两个矩形的例子,本章后面几节会给出使用moveTo()和closePath()的实例。
context.beginPath();
context.rect(50, 20, 120, 100);
context.stroke();
context.beginPath();
context.rect(220, 20, 120, 100);
context.fill();
上述代码通过调用beginPath()开始一条新路径,然后调用rect()方法向当前路径中增加一个包含4个点的子路径,最后调用stroke()方法,该路径进行描边,使其在画布中显示出来。
接下来,又一次调用beginPath()方法,该方法会清除上一次调用rect()方法创建的子路径,然后再调用rect()方法向当前路径中增加一个包含4个点的子路径,最后调用fill()方法,对该路径进行填充,使第二个矩形也在画布中显示出来。本例的运行效果如图 4‑3 所示:
如果在绘制第二个矩形时,不调用beginPath()方法,结果会怎样呢?我们先看看运行效果,如图 4‑4 所示:
从上图可知,第一个矩形也是使用填充而不是描边的,为什么会这样呢?
因为canvas中的绘制方法,都是以上一次beginPath ()之后的所有路径为基础进行绘制,因此每次开始绘制路径前,都要调用一次 beginPath ()方法,以通知canvas将要开始绘制一个新图形了。否则,之后添加的所有子路径都是添加在已有的子路径上,每次绘制,都会把之前的子路径重新绘制一遍。这样,不但影响绘图效果,还会严重影响性能。