5

canvas的时候,纠结的不是各种图形如何绘制 ,反而是beginPath()closePath()这两个函数什么时候用,它们到底做了什么。

首先,这里说的是2D渲染的情况, 即CanvasRenderingContext2D对象(2D渲染上下文, 这个翻译感觉好拗口)。

要明确的一点是,用canvas画图的思路:通过绘制路径来绘制图形,路径是一系列点的集合 。PS里有个钢笔工具,跟这个就很像,我们会先用钢笔工具把路径画出来,然后可以选择填充或者描边。

搞不清楚概念的时候就仔细去看概念:

beginPath()

CanvasRenderingContext2D.beginPath() 是 Canvas 2D API 通过清空子路径列表开始一个新路径的方法。 当你想创建一个新的路径时,调用此方法。

在我们绘制路径的时候,实际上会有一个路径列表帮我们纪录当前所画的的子路径,而这整一个列表就是我们当前绘制的路径。那么子路径是什么鬼呢?意思就是比如你东画一条线,西画一条线,中间还画了一条线,这三条线就是子路径,它们不必首尾相连,可以相交也可以不相交。当你调用beginPath()方法的时候,就会把这整个列表清空,无论你有没有fill()或者stroke(),统统死啦死啦地。

closePath()

CanvasRenderingContext2D.closePath() 是 Canvas 2D API 将笔点返回到当前子路径起始点的方法。它尝试从当前点到起始点绘制一条直线。 如果图形已经是封闭的或者只有一个点,那么此方法不会做任何操作。

注意,是子路径。这里的定义已经说得比较清楚了,就没什么必要赘述了。

绘制路径

理解了它们的定义后,怎么用的话心里应该也有一个大致的概念了。还有必要说一下moveTo()的定义

CanvasRenderingContext2D.moveTo()是 Canvas 2D API 将一个新的子路径的起始点移动到(x,y)坐标的方法。

注意,是子路径。所以绘制一条路径(可以包括多条子路径)的规则就是:

  1. beginPath()一下

  2. 先绘制一条子路径。有必要moveTo()的就moveTo,然后调用相应绘制函数,最后有必要closePath()的就closePath。绘制多条就如法炮制。

  3. 填充fill()或者描边stroke(), 或者两者一起用。

  • 对规则2的解释:为什么说有必要moveTo和closePath才做相应的操作呢?closePath好理解,我就是想单纯的画一条路径出来而已,那就没必要闭合了。至于moveTo,这取决于你想要画的效果,就是字面的你想从哪个点开始画呢?比如用arc()画一个扇形,你就得先把起始点移到原点,不然就会画成一个像拱桥的弓形了,点击查看相关实例

  • 对规则3的解释:因为之前画的路径只是纪录了一系列点的位置,并没有真正画出来,所以最后要调用函数来渲染

最后,注意有些方法会自动闭合路径,比如fill()clip()。这也很好理解,因为这两个方法都是作用于一块区域,不闭合的话计算机哪里知道你要对哪块区域进行操作呢?这时候就可以不用调用closePath()了。stroke()不会自动闭合路径。点击查看相关实例

注:以上api的定义均来自MDN


acfasj
124 声望11 粉丝

又不是不能用