看到canvas的章节,想到可以用它来画个图。然后选了幅由简单线条组成的卡通火箭图,准备动手画。画的过程中遇到了些问题,这里整理一下。下面是找来的图:
没上色前,还感觉不出什么问题。就是使用lineTo画直线,quadraticCurveTo画曲线。附个没上色的图:
到上色了,就遇到问题了:一个颜色怎么覆盖到另外一个颜色上面去?
其实也没有很复杂,主要关键点在闭合路径。我刚开始画的无颜色的图,是按自己平时画画的顺序画的,从火箭头部开始画起,左一条线,右一条线,再补一个下面的线,一个缺了一截的类似橄榄球的形状的火箭外壳出来了。这个顺序就错了,填充颜色就不能很好的完全填充了里面的全部。应该要类似一笔画一样,连续地把整个外壳画出来,再填色,得到这样的图:
到其它部分了,canvas里面,一个路径填色后,如果另外一个路径也需要填色的话,在这与PS不同,不是填充,而是覆盖。后绘画的路径会覆盖到前面的路径上,路径填充的颜色也同样可以。例如火箭尾部中间的那个尾翼,就应该把这路径放在最后,以便能覆盖在前面画好的部分上。里面重要的要注意的点,还是上面说过的“闭合路径”。不过一般以画完上一条线的终点作为起点来画下一条线,不使用closePath()也可以,好像并不会出现什么问题,反正都是要被覆盖到下面的。看别人博客说的一句话,放出来记一下:
" 如果我们不希望路径闭合,比如三角形我们只画两条边,不希望第三条边出现,那么就不要写closePath(),而样式也不会发生混乱。需要注意:closePath()这个函数对fill()是不起作用的,即使没有closePath(),fill()也同样会找到到首尾相接的路径进行填充。"
我前面在说“闭合路径”,可是后面又说不需要闭合也可以,是不是有点矛盾?需不需要在绘画的时候闭合路径是要区分不同的情况的。
第一种情况,不需要闭合也可以:
例如火箭尾部两边的尾翼,正常来说要画一边的尾翼,则需要画两笔就可以了,因为前面已经把外轮廓给画好了,相当于已经是一个封闭的图形了。这里说的不需要闭合,就是因为上面引用别人博客上面说的:即使没有闭合路径,fill()也会自动找到首尾相接的路径进行填充。前提是画路径的时候顺序没有错,看下面左边那张图,是以这个顺序画的,使用fill()的时候会自动帮你补全,只是没有那条路径线,但不阻碍fill()填充的时候是直线填充回路径原点,如下面右边那张图。再加上火箭的外形是往外凸的,更加能遮掩我们这补全的部分,没露馅,所以这时候闭不闭合路径都无所谓,反正能遮住。
第二种情况,需要闭合路径:
这个情况就看火箭头部红色类似三角形的部分,这里可没地方给我们遮掩,这部分内容得放在最上面(就是在语句的最后面)。如果是在图片编辑软件里面,是不是直接画两条线分隔开就好啦?然后填充上面红色,中间深蓝色。可是canvas里面不行,没有一个路径可以完全的闭合。拿开其它绘制好的部分,其实就剩下这两条线。
这两条线还没有相交的点,如果真的直接这样填充的话,估计只能填充出这样的效果:
这时候就需要另外补充一个完整的闭合路径,盖到上面去。相当于给笔套上笔盖?在适当的位置,再给加上两个类似下面这样的火箭头,稍大一点的深蓝色,稍短一点的红色,覆盖到原来的银灰色机身头部上。
当然,中间卡着的那个深蓝色部分,你也可以选择不画一个完整的类似上图的这样,画一个弯曲的四边形?这样的东西。不过我觉得画一个稍大点,再画个稍小点的套上去比较好画,好控制。当然啦,随自己高兴。
不过我还真觉得在这幅图上加不加closePath()都没什么影响。毕竟我说的闭合路径不是使用closePath()方法来闭合,而是手动闭合呀。
最后放下画好的图: