HTML5 Canvas 起步(2) - 路径

有人这样描绘四姑娘山:四姑娘山孕育着银色冬天的梦幻,绿色春天的生命,金色秋天的希望,蓝色夏天的憧憬。四姑娘山,走进她,靠近她,你才知道什么是美,这种美带给你的是各种不同的感受,四季轮转中也无改她的美丽,四姑娘山如婉约的少女,又如豪壮的勇士,伫立在天地间,无比的圣洁,不愧是蜀山之后,东方的阿尔卑斯。
这篇将要介绍一下Canvas中的基本图形。

图形的基础-路径

在Canvas中,所有基本图形都是以路径为基础的,也就是说,我们在调用2dContext的lineTo、rect等方法时,其实就是往已经的context路径集合中再添加一些路径点,在最后使用fill或stroke方法进行绘制时,都是依据这些路径点来进行填充或画线。

在每次开始绘制路径前,都应该使用context.beginPath()方法来告诉Context对象开始绘制一个新的路径,否则接下来绘制的路径会与之前绘制的路径叠加,在填充或画边框时就会出现问题。在绘制完成路径后,可以直接使用context.closePath()方法来关闭路径,或者手动关闭路径。另外,如果在填充时路径没有关闭,那么Context会自动调用closePath方法将路径关闭。

基本路径方法

1.beginPath,closePath

这两个方法在前面已经介绍过,分别用来通知Context开始一个新的路径和关闭当前的路径。

在Canvas中使用路径时,应该要保持一个良好的习惯,每次开始绘制路径前都要调用一次beginPath方法,否则画出来的效果难看不说,还会严重影响性能。

在下面这张图中,左边的图形在每次绘制矩形前都调用了一次beginPath来清除之前的路径并重新开始绘制新的路径,而后面的图形则就只在绘制所有图形前调用了一次beginPath来清除路径,因此,虽然这里是使用的边框色是#666,但是右边的图形颜色比左边的深一些,因为每次使用stroke绘制边框时,会把之前的路径再次绘制一遍,叠加起来颜色就比原来深一些。


<script language="JavaScript">ffcod = delpost.runcode13 .value; ffcod = ffcod.replace(/
/g,''); delpost.runcode13 .value = ffcod;</script> 提示:您可以先修改部分代码再运行

在Context中路径数较少时,如果不考虑显示效果,性能上还可以接受,但是如果Context中的路径数很多时,在开始绘制新路径前不使用beginPath的话,因为每次绘制都要将之前的路径重新绘制一遍,这时性能会以指数下降。

因此,除非有特殊需要,每次开始绘制路径前都要调用beginPath来开始新路径。

2.移动与直线moveTo,lineTo,rect


<script language="JavaScript">ffcod = delpost.runcode14 .value; ffcod = ffcod.replace(/
/g,''); delpost.runcode14 .value = ffcod;</script> 提示:您可以先修改部分代码再运行

voidmoveTo(infloatx,infloaty);

在Canvas中绘制路径,一般是不需要指定起点的,默认的起点就是上一次绘制路径的终点,因此,如果需要指定起点的话,就需要使用moveTo方法来指定要移动到的位置。

voidlineTo(infloatx,infloaty);

lineTo方法则是绘制一条直接路径到指定的位置。在调用完lineTo方法后,Context内部的绘制起点会移动到直线的终点。

voidrect(infloatx,infloaty,infloatw,infloath);

rect方法用来绘制一个矩形路径,通过参数指定左上角位置以及宽和高。在调用rect后,Context的绘制起点会移动到rect绘制的矩形的左上角。

rect方法与后面要介绍的arc方法与其他路径方法有一点不同,它们是使用参数指定起点的,而不是使用Context内部维护的起点。

3.曲线arcTo,arc,quadraticCurveTo,bezierCurveTo

voidarcTo(infloatx1,infloaty1,infloatx2,infloaty2,infloatradius);

按照WHATWG文档的说明,这个方法是画一个与两条射线相切的的圆弧,两条射线其中一条为穿过Context绘制起点,终点为(x1,y1),另外一条为穿过(x2,y2),终点为(x1,y1),这条圆弧为最小的与这两条射线相切的圆弧。在调用完arcTo方法后,将圆弧与射线(x1,y1)-(x2,y2)的切点添加到当前路径中,做为下次绘制的起点。

在测试中发现,Firefox和Opera目前对这个方法的支持并不好,只有Chrome和Safari4能绘制出正确的路径。

图中的的两条灰色直线是偏移4个像素后的两条射线所在的位置。

<script language="JavaScript">ffcod = delpost.runcode15 .value; ffcod = ffcod.replace(/
/g,''); delpost.runcode15 .value = ffcod;</script> 提示:您可以先修改部分代码再运行

voidarc(infloatx,infloaty,infloatradius,infloatstartAngle,infloatendAngle,inbooleananticlockwise);

arc方法用来绘制一段圆弧路径,通过圆心位置、起始弧度、终止弧度来指定圆弧的位置和大小,这个方法也依赖于Context维护的绘制起点。而在画圆弧时的旋转方向则由最后一个参数anticlockwise来指定,如果为true就是逆时针,false则为顺时针。

voidquadraticCurveTo(infloatcpx,infloatcpy,infloatx,infloaty);

quadraticCurveTo方法用来绘制二次样条曲线路径,参数中cpx与cpy指定控制点的位置,x和y指定终点的位置,起点则是由Context维护的绘制起点。

voidbezierCurveTo(infloatcp1x,infloatcp1y,infloatcp2x,infloatcp2y,infloatx,infloaty);

bezierCurveTo方法用来绘制贝塞尔曲线路径,它与quadraticCurveTo相似,不过贝塞尔曲线有两个控制点,因此参数中的cp1x,cp1y,cp2x,cp2y用来指定两个控制点的位置,而x和y指定绺的位置。


<script language="JavaScript">ffcod = delpost.runcode16 .value; ffcod = ffcod.replace(/
/g,''); delpost.runcode16 .value = ffcod;</script> 提示:您可以先修改部分代码再运行

4.fill,stroke,clip

fill与stroke这两个方法很好理解,分别用来填充路径与绘制路径线条。

clip方法用来给Canvas设置一个剪辑区域,在调用clip方法之后的代码只对这个设定的剪辑区域有效,不会影响其他地方,这个方法在要进行局部更新时很有用。默认情况下,剪辑区域是一个左上角在(0,0),宽和高分别等于Canvas元素的宽和高的矩形。

在画这个图时,虽然两次都是使用fillRect(0,0,100,100)填充了一个100x100大小矩形,但是显示的结果却是第二次填充的只是中间的一小块,这是因为在两次填充之间使用clip方法设定了剪辑区域,这样第二次填充时只会影响到所设定的中间那一小部分区域。

<script language="JavaScript">ffcod = delpost.runcode17 .value; ffcod = ffcod.replace(/
/g,''); delpost.runcode17 .value = ffcod;</script> 提示:您可以先修改部分代码再运行

5.clearRect,fillRect,strokeRect

这三个方法并不是路径方法,而是用来直接处理Canvas上的内容,相当于Canvas的背景,调用这三个方法也不会影响Context绘图的起点。

要清除Canvas上的所有内容时,可以直接调用context.clearRect(0,0,width,height)来直接清除,而不需要使用路径方法绘制一个与Canvas同等大小的矩形路径再使用fill方法去清除。

结语

通过Canvas的路径方法,可以使用Canvas处理一些简单的矢量图形,这样在缩放时也不会失真。不过Canvas的路径方法也不是很强大,至少连个椭圆的路径都没有……

这篇写得有点长了,Cnavas中路径相关的内容就写这么多,后面再讲讲Canvas其他的东西。

参考资料

1.TheCanvasElement,WHATWG

到此这篇关于HTML5 Canvas 起步(2) - 路径就介绍到这了。当你的才华还撑不起你的野心时,那你就应该静下心来学习。更多相关HTML5 Canvas 起步(2) - 路径内容请查看相关栏目,小编编辑不易,再次感谢大家的支持!

标签: Canvas