
7.2 绘制图形
本节将介绍一些基本图形的绘制,如矩形、直线、路径等,以及样式设置。
7.2.1 矩形
canvas仅支持一种原生的图形绘制—矩形。绘制其他图形都需要生成至少一条路径。不过,使用多个路径可以轻松绘制复杂的图形。
canvas提供了3种方法绘制矩形:
fillRect(x, y, width, height):绘制一个填充的矩形。
strokeRect(x, y, width, height):绘制一个矩形的边框。
clearRect(x, y, width, height):清除指定矩形区域,让清除部分完全透明。
参数说明如下。
x:矩形左上角的x坐标。
y:矩形左上角的y坐标。
width:矩形的宽度,以像素为单位。
height:矩形的高度,以像素为单位。
【示例】本示例分别使用上述3种方法绘制了3个嵌套的矩形,预览效果如图7.4所示。


图7.4 绘制矩形
在上面的代码中,fillRect()方法绘制了一个边长为100像素的黑色正方形。clearRect()方法从正方形的中心开始擦除了一个60*60像素的正方形,接着strokeRect()在清除区域内生成一个50*50像素的正方形边框。
提示:不同于7.2.2节所要介绍的路径函数,以上3个函数在绘制之后会马上显现在canvas上,即刻生效。
7.2.2 路径
图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形的步骤如下。
第1步,创建路径起始点。
第2步,使用画图命令绘制路径。
第3步,封闭路径。
第4步,生成路径之后,可以通过描边或填充路径区域来渲染图形。
需要调用的方法说明如下。
beginPath():开始路径。新建一条路径,生成之后,图形绘制命令被指向到路径,生成路径。
closePath():闭合路径。闭合路径之后图形绘制命令又重新指向上下文中。
stroke():描边路径。通过线条来绘制图形轮廓。
fill():填充路径。通过填充路径的内容区域生成实心的图形。
提示:生成路径的第一步是调用beginPath()方法。每次调用这个方法都表示开始重新绘制新的图形。闭合路径closePath()不是必需的。当调用fill()方法时,所有没有闭合的形状都会自动闭合,所以不需要调用closePath()方法,但是调用stroke()时不会自动闭合。
【示例1】本示例绘制一个三角形,效果如图7.5所示。代码仅提供绘图函数draw(),完整代码可以参考7.2.1节的示例,后面各节示例类似。


图7.5 绘制三角形
使用moveTo(x, y)方法可以将笔触移动到指定的坐标x和y上。初始化canvas或者调用beginPath()方法后,通常会使用moveTo()方法重新设置起点。
【示例2】用户可以使用moveTo()方法绘制一些不连续的路径。本示例绘制了一个笑脸图形,效果如图7.6所示。

图7.6 绘制笑脸

上面的代码使用了arc()方法,调用它可以绘制圆形,在后面的小节中将详细说明。
7.2.3 直线
使用lineTo()方法可以绘制直线,用法如下。
lineTo(x,y)
参数x和y分别表示终点位置的x坐标和y坐标。lineTo(x, y)将绘制一条从当前位置到指定(x, y)位置的直线。
【示例】本示例将绘制两个三角形,一个是填充的,另一个是描边的,效果如图7.7所示。


图7.7 绘制三角形
上面示例的代码调用beginPath()方法准备绘制一个新的形状路径,使用moveTo()方法移动到目标位,两条线段绘制后构成三角形的两条边。使用填充(filled)时,路径自动闭合;而使用描边(stroked)则不会闭合路径。如果没有添加闭合路径closePath()到描边三角形中,则只绘制了两条线段,并不能构成一个完整的三角形。
7.2.4 定义颜色
使用fillStyle和strokeStyle属性可以给图形上色。其中,fillStyle设置图形的填充颜色,strokeStyle设置图形轮廓的颜色。
颜色值可以是表示CSS颜色值的字符串,也可以是渐变对象或者图案对象(参考下面小节的介绍)。默认情况下,线条和填充颜色都是黑色,CSS颜色值为#000000。
一旦设置了strokeStyle或fillStyle的值,那么这个新值就会成为新绘制的图形的默认值。如果要给每个图形定义不同的颜色,就需要重新设置fillStyle或strokeStyle的值。
【示例1】本例使用嵌套for循环绘制方格阵列,为每个方格填充不同的颜色,效果如图7.8所示。


图7.8 绘制渐变色块
在嵌套for结构中,使用变量i和j为每个方格填充唯一的RGB色彩值,其中仅修改红色和绿色通道的值,而保持蓝色通道的值不变。可以通过修改这些颜色通道的值来产生各种各样的色板。通过增加渐变的频率,可以绘制出类似Photoshop调色板的效果。
【示例2】本例和示例1有点类似,使用strokeStyle属性,但画的不是方格,而是用arc()方法画圆,效果如图7.9所示。


图7.9 绘制渐变圆圈
7.2.5 定义透明度
使用globalAlpha全局属性可以设置绘制图形的透明度,另外也可以通过色彩的透明度参数来为图形设置透明度,这种方法相对于使用globalAlpha属性来说,会更灵活些。
使用rgba()方法可以设置具有透明度的颜色,用法如下。
rgba(R,G,B,A)
其中R、G、B将颜色的红色、绿色和蓝色成分指定为0~255的十进制整数,A把alpha(透明)成分指定为0.0~1.0的一个浮点数值,0.0为完全透明,1.0为完全不透明。例如,可以用rgba(255,0,0,0.5)表示半透明的完全红色。
【示例1】本示例使用四色格作为背景,设置globalAlpha为0.2后,在上面画一系列半径递增的半透明圆,最终结果是一个径向渐变效果,如图7.10所示。圆叠加得越多,原先所画的圆的透明度会越低。通过增加循环次数,画更多的圆,背景图的中心部分会完全消失。


图7.10 用globalAlpha设置不透明度
【示例2】本例与示例1类似,不过不是画圆,而是画矩形。这里还可以看出,rgba()可以分别设置轮廓和填充样式,因而具有更好的可操作性和使用灵活性,效果如图7.11所示。


图7.11 用rgba()方法设置不同的透明度
7.2.6 定义线性渐变
要绘制线性渐变,首先使用createLinearGradient()方法创建canvasGradient对象,然后使用addColorStop()方法进行上色。
createLinearGradient()方法的用法如下:
context.createLinearGradient(x0,y0,x1,y1);
参数说明如下。
x0:渐变开始点的x坐标。
y0:渐变开始点的y坐标。
x1:渐变结束点的x坐标。
y1:渐变结束点的y坐标。
addColorStop()方法的用法如下:
gradient.addColorStop(stop,color);
参数说明如下。
stop:介于0.0~1.0的值,表示渐变中开始与结束之间的相对位置。渐变起点的偏移值为0,终点的偏移值为1。如果position值为0.5,表示色标会出现在渐变的正中间。
color:结束位置显示的CSS颜色值。
【示例】本示例演示如何绘制线性渐变。本例共添加了8个色标,分别为红、橙、黄、绿、青、蓝、紫和红,预览效果如图7.12所示。


图7.12 绘制线性渐变
使用addColorStop可以添加多个色标,色标可以在0~1任意位置添加,例如,在0.3处开始设置一个蓝色色标,再在0.5处设置一个红色色标,则0~0.3都会填充为蓝色。0.3~0.5为蓝色到红色的渐变,0.5~1则填充为红色。
7.2.7 定义径向渐变
要绘制径向渐变,首先需要使用createRadialGradient()方法创建canvasGradient对象,然后使用addColorStop()方法上色。
createRadialGradient()方法的用法如下。
context.createRadialGradient(x0,y0,r0,x1,y1,r1);
参数说明如下。
x0:渐变地开始圆的x坐标。
y0:渐变地开始圆的y坐标。
r0:开始圆的半径。
x1:渐变地结束圆的x坐标。
y1:渐变地结束圆的y坐标。
r1:结束圆的半径。
【示例】本示例使用径向渐变在画布中央绘制一个圆球形状,预览效果如图7.13所示。


图7.13 绘制径向渐变
7.2.8 定义阴影
创建阴影需要4个属性,简单说明如下。
shadowColor:设置阴影颜色。
shadowBlur:设置阴影的模糊级别。
shadowOffsetX:设置阴影在x轴的偏移距离。
shadowOffsetY:设置阴影在y轴的偏移距离。
【示例】本示例演示了如何创建文字阴影效果,如图7.14所示。


图7.14 为文字设置阴影效果