第3章〓HTML5画布 HTML5画布即HTML5 canvas,是现代浏览器都支持的HTML5非插件绘图的功能。HTML5 canvas是HTML5新增的专门用于绘制图形的元素。在页面上放置一个canvas元素就相当于放置了一块画布,可以在其中进行图形的绘制。在canvas元素内绘制图形需要结合JavaScript脚本。利用canvas可以进行跨平台的动画和游戏的开发,能够实现对图像进行像素级别的操作。 观看视频 3.1HTML5的canvas元素 canvas元素的外观与img元素相似,但是没有img元素的src属性和alt属性。canvas元素的height属性和width属性分别用来设置画布的高度和宽度,单位是像素。默认的画布高度是150像素,宽度是300像素。id属性为canvas元素的标识,在JavaScript脚本中需要根据id值来寻找canvas元素。标签必须成对使用。默认的canvas元素在页面上会显示一块空白的没有边框的矩形。可以通过CSS来设置canvas元素的外观,例如canvas.html,为canvas元素添加一个实心的边框,宽度为3px。 canvas.html的代码如下: canvas元素示例 canvas.html的显示结果如图31所示。 图31canvas元素在Chrome浏览器中的显示结果 观看视频 3.2绘制简单的图形 canvas元素本身并不能实现图形绘制,需要和JavaScript脚本结合起来。首先,给canvas元素添加一个id属性, 在JavaScript脚本中通过id属性寻找对应的canvas元素。然后通过canvas元素的getContext()方法获取其上下文, 图32canvas元素的坐标 即创建Context对象,以获取允许进行绘制的2D环境。最后通过Context对象的相关方法完成绘制,例如fillStyle()方法、fillRect()方法等。 进行绘制时,需要指定确定的坐标位置,坐标原点(0,0)位于canvas的左上角,x轴水平方向向右延伸,y轴垂直向下延伸,如图32所示。 3.2.1绘制直线 Context对象的moveTo(x,y)方法是将画笔移动到指定的坐标点(x,y),lineTo(x,y)方法是从落笔点绘制路径到坐标点(x,y)。只使用以上两个方法是无法在画布上看到直线的,lineTo(x,y)方法用于绘制路径,要使路径在画布上显示出来,还需要进行描边。可以连续地绘制多条路径,然后使用stroke()方法一次性描边。可以使用CSS设置绘制直线的样式,例如line.html。 line.html的代码如下: 绘制直线 图33line.html的显示结果 line.html在浏览器中的显示结果如图33所示。 3.2.2绘制矩形 canvas元素可以绘制两种矩形: 一种是填充矩形,另一种是矩形轮廓。Context对象的fillRect()方法用来绘制填充矩形,strokeRect()方法用来绘制矩形轮廓。 fillRect()方法的前两个参数为矩形的左上角的坐标,后两个参数为矩形的宽度和高度。strokeRect()方法的参数与fillRect()方法的参数含义相同。设置矩形的外观可以使用fillStyle属性和strokeStyle属性。fillStyle属性用来设置矩形区域的填充颜色,strokeStyle属性用来设置矩形轮廓的颜色。例如rect.html,绘制一个填充矩形和一个矩形轮廓。 rect.html的代码如下: 绘制矩形 rect.html在浏览器中的显示结果如图34所示。 图34rect.html的显示结果 3.2.3绘制圆或圆弧 canvas元素可以用来绘制圆或圆弧,使用的方法有beginPath()、arc()、closePath()、fill()。 1. beginPath() 开始一条路径或重置路径。 2. arc(x,y,r,sAngle,eAngle,counterclockwise) x、y为圆心的坐标; r为圆的半径; sAngle为以弧度计的起始角; eAngle为以弧度计的结束角; counterclockwise参数可选,规定逆时针或顺时针绘图,true为逆时针,false为顺时针。 3. closePath() 闭合路径,如果图形本来就是闭合的,则此方法不起作用。 4. fill() 填充当前的路径或图像,默认的颜色是黑色。 例如arc.html,绘制一个圆和若干条圆弧。 arc.html的代码如下: 绘制圆或圆弧 arc.html在浏览器中的显示结果如图35所示。 3.2.4绘制三角形 使用绘制路径的方法可以自由绘制出三角形等多边形。例如triangle.html,绘制一个填充色为绿色的三角形。 triangle.html的代码如下: 绘制三角形 triangle.html在浏览器中的显示结果如图36所示。 图35arc.html的显示结果 图36triangle.html的显示结果 观看视频 3.3绘制文字 可以使用fillText()方法和strokeText()方法来绘制文字,其中fillText()方法用来绘制填充文字,strokeText()方法用来绘制轮廓文字。 3.3.1绘制填充文字 绘制填充文字时,fillText()方法的用法如下: context.fillText(text, x, y, [max Width]); 其中,text为要绘制的文字; x、y为绘制文字的坐标; maxWidth为可选参数,表示显示文字时的最大宽度。如果要绘制的文字大于最大宽度,则字体会被调整成更小的字号或者更瘦的字体。例如filledText.html。 filledText.html的代码如下: 绘制填充文字 图37filledText.html的显示结果 filledText.html在浏览器中的显示结果如图37所示。 3.3.2绘制轮廓文字 绘制轮廓文字时,strokeText()方法的用法如下: context.strokeText(text, x, y, [max Width]); 其中,text为要绘制的文字; x、y为绘制文字的坐标; maxWidth为可选参数,表示显示文字时的最大宽度。例如hollowText.html。 hollowText.html的代码如下: 绘制轮廓文字 hollowText.html在浏览器中的显示结果如图38所示。 图38hollowText.html的显示结果 观看视频 3.4图形变换 利用图形的变换可以绘制出大量复杂多变的图形。图形的变换主要包括移动、缩放、旋转、变形等。 3.4.1保存与恢复 在绘画时,本来使用绿色笔画,突然需要用红色笔画,但画完之后又要使用绿色笔画。如果是现实中的作画,可以使用不同的笔蘸上不同的墨水,根据颜色选择画笔。但是在canvas中画笔只有一支。如果要更换画笔的颜色,就需要保存和恢复状态,状态其实就是画布当前属性的一个快照,包括图形的属性、当前裁切路径、当前应用的变换。canvas中使用save()方法来保存状态,使用restore()方法来恢复状态。canvas状态是用栈来保存的,每次调用save()方法,就把当前状态入栈保存,当前状态成为栈顶; 每次调用restore()方法,就把栈顶的状态取出来,并将画布恢复到这个状态。例如saveAndRestore.html,利用状态的保存与恢复画颜色不同的填充矩形。 saveAndRestore.html的代码如下: 状态的保存和恢复 saveAndRestore.html在浏览器中的显示结果如图39所示。 图39saveAndRestore.html的显示结果 3.4.2移动 在绘制图形时,可以使用Context对象的translate()方法移动坐标空间,使画布的坐标空间发生水平和垂直方向的偏移,translate(dx,dy)中dx为水平方向的偏移量,dy为垂直方向的偏移量。例如translate.html,利用移动绘制一排圆。 translate.html的代码如下: 移动 translate.html在浏览器中的显示结果如图310所示。 图310translate.html的显示结果 3.4.3缩放 Context对象的scale()方法用于增减canvas上下文对象中的像素数目,从而实现图形或图像的放大或缩小,context.scale(sx,sy)中的sx为x轴的缩放因子,sy为y轴的缩放因子,它们的值必须是正数,如果值大于1,则为放大图形,如果值小于1,则为缩小图形。例如scale.html,绘制逐渐缩小的圆。 scale.html的代码如下: 缩放 scale.html在浏览器中的显示结果如图311所示。 图311scale.html在浏览器中的显示结果 3.4.4旋转 Context对象的rotate()方法用于以原点为中心旋转上下文对象的坐标空间,context.rotate(angle)方法中的angle参数指以弧度计的顺时针方向旋转的角度。例如rotate.html利用旋转绘制环状排列的圆。 rotate.html的代码如下: 旋转 图312rotate.html在浏览器中的显示结果 rotate.html在浏览器中的显示结果如图312所示。 3.4.5变形 Context对象的transform()方法用于直接修改变换矩阵。矩阵变换常用于坐标变换不能达到预期效果的情况,能够实现比普通的坐标变换更加复杂的效果。transform()方法的用法如下: context.transform(a, b, c, d, e, f); 各参数的含义如下。  a: 水平缩放绘图。  b: 水平倾斜绘图。  c: 垂直倾斜绘图。  d: 垂直缩放绘图。  e: 水平移动绘图。  f: 垂直移动绘图。 可见,可以在transform()方法中同时实现平移、缩放、旋转,也可以使用transform()方法实现以上3种变换中的一种。 画布上的每一个对象都拥有一个当前的变换矩阵,Context对象的setTransform()方法用于将当前的变换矩阵重置为最初的矩阵,即单位矩阵,然后以相同的参数运行transform()方法,也就是说setTransform()方法允许缩放、旋转、移动并倾斜当前的环境。该变换只会影响setTransform()方法之后的绘图。例如transform.html,利用变形和旋转在画布上显示呈螺旋状排列的半透明的半圆。 transform.html的代码如下: 矩阵变换 transform.html在浏览器中的显示结果如图313所示。 图313transform.html在浏览器中的显示结果 3.5操作图像 利用canvas元素不仅可以绘制各种各样的图形,而且可以引入外部图像,并对图像进行各种操作,例如改变图像大小、图像切片、图像合成等。canvas支持多种常见的图像格式。向canvas元素引入图像分以下3步。 观看视频 1. 创建image对象 var image = new Image(); 2. 设定image对象的onload属性 image.onload = function(){ } 3. 在function()中绘制图像 可以使用以下方法:  context.drawImage(image,x,y): 在画布的指定位置绘制图像。  context.drawImage(image,x,y,width,height): 按参数指定的位置和大小绘制图像。  context.drawImage(image,x,y,sWidth,sHeight,dx,dy,dWidth,dHeight): 裁剪图像,并在画布上绘制图像。 例如image.html,在画布上绘制图像,并绘制轮廓文字。 image.html的代码如下: 引入图像 image.html在浏览器中的显示结果如图314所示。 图314image.html的显示结果 观看视频 3.6其他颜色和样式 前面使用canvas元素绘制图形时,使用的是Context对象的fillStyle()方法和strokeStyle()方法,除此之外,canvas元素还支持更多的颜色和样式,包括线型、渐变、图案、透明度和阴影。合理利用这些颜色和样式,可以绘制出更加复杂多变、丰富多彩的图形。 3.6.1线型 Context对象的lineWidth、lineCap、lineJoin、miterLimit属性分别用于设置线条的粗细、端点样式、两条线段连接处的样式以及绘制交点的方式。 1. lineWidth lineWidth属性的值必须为正数,单位为像素,默认值为1.0。 2. lineCap lineCap属性可取值butt、round、square,默认值为butt。butt表示向线条的每个末端添加平直的边缘; round表示向线条的每个末端添加圆形线帽; square表示向线条的每个末端添加正方形线帽。例如widthAndCap.html分别绘制圆形线帽但粗细不同的线型。 widthAndCap.html的代码如下: 线型示例 图315widthAndCap.html在浏览器中的 显示结果 widthAndCap.html在浏览器中的显示结果如图315所示。 3. lineJoin lineJoin属性用于设置两条线段连接处的样式,可取值round、bevel、miter,默认值为miter。round为圆角,bevel为边角,miter为尖角。 4. miterLimit miterLimit属性用来设置或返回最大斜接长度,斜接长度指的是在两条线交汇处内角和外角之间的距离。只有当lineJoin属性为miter时,miterLimit属性才有效。边角的角度越小,斜接长度就会越大,为了避免斜接长度太大,可以使用miterLimit属性进行限制。如果斜接长度超过了miterLimit属性设置的值,则边角会以bevel(即边角)的形式显示。 3.6.2渐变 canvas元素在绘制图形时除了可以指定固定的颜色之外,还可以指定渐变色。渐变分为线性渐变和径向渐变。 1. 绘制线性渐变 要绘制线性渐变,首先需要使用Context对象的createLinearGradient()方法创建 canvasGradient对象,然后使用addColorStop()方法上色。createLinearGradient()方法定义如下: context.createLinearGradient(x1, y1, x2, y2); 其中,x1和y1为渐变的起点,x2和y2为渐变的终点。 addColorStop()方法定义如下: context.addColorStop(position, color); 其中,position为渐变中色标的相对位置,为0~1的浮点值,渐变起点的相对位置为0,终点的相对位置为1。例如linearGradient.html,在矩形中添加3种颜色,起点为红色,中间点为黄色,终点为白色。 linearGradient.html的代码如下: 线性渐变 图316linearGradient.html的显示结果 linearGradient.html在浏览器中的显示结果如图316所示。 2. 绘制径向渐变 径向渐变也称为扩散性渐变,首先需要使用Context对象的createRadialGradient()方法创建canvasGradient对象,然后使用addColors()方法上色。createRadialGradient()的使用方法如下: context.createRadialGradient(x1, y1, r1, x2, y2, r2); 其中,x1和y1定义一个以(x1,y1)为圆心、以r1为半径的开始圆,x2和y2定义一个以(x2,y2)为圆心、以r2为半径的结束圆。这两个圆描述了渐变的方向及起止位置,也描述了渐变的形状。例如radialGradient.html。 radialGradient.html的代码如下: 径向渐变 图317radialGradient.html的显示结果 radialGradient.html在浏览器中的显示结果如图317所示。 3.6.3绘制图案 Context对象的createPattern()方法可以用来填充图像,其用法如下: context.createPattern(image, type); 其中,image为要引用的image对象或者另一个Canvas对象; type是填充图像的方式,可取值如下。  repeat: 同时沿x轴方向和y轴方向平铺。  repeatx: 只沿x轴方向平铺。  repeaty: 只沿y轴方向平铺。  norepeat: 不平铺。 例如pattern.html,在canvas元素内沿x轴方向和y轴方向平铺图像。 pattern.html的代码如下: 平铺图像 图318pattern.html在浏览器中的显示 结果 pattern.html在浏览器中的显示结果如图318所示。 3.6.4透明度 除了可以使用Context对象的globalAlpha属性设置图形的透明度外,还可以利用rgba()方法设置色彩的透明度。rgba()的使用方法如下: rgba(R, G, B, A) 其中,R、G、B分别是颜色的红、绿、蓝分量,A为不透明值,为0~1的浮点数,0为完全透明,1为完全不透明。例如"rgba(0,255,0,0.5)"表示半透明的绿色。例如alpha.html,在画布上画一排透明度不同的圆。 alpha.html的代码如下: 透明度 alpha.html在浏览器中的显示结果如图319所示。 图319alpha.html在浏览器中的显示结果 3.6.5阴影 可以使用Context对象的属性对绘制的图形或文字添加阴影效果,设置阴影的主要属性如下。  shadowOffsetX: 设置或返回形状与阴影的水平距离,默认值为0。  shadowOffsetY: 设置或返回形状与阴影的垂直距离,默认值为0。  shadowBlur: 设置或返回阴影的模糊级数,取值为整数值。  shadowColor: 设置或返回阴影的颜色。 例如shadow.html,为画布中的文字添加阴影。 shadow.html的代码如下: 阴影 shadow.html在浏览器中的显示结果如图320所示。 图320shadow.html在浏览器中的显示结果 小结  利用HTML5中的canvas元素可以实现图形的绘制,能够对图像进行像素级别的操作。  利用canvas元素可以绘制直线、矩形、圆或圆弧、多边形等图形。  利用canvas元素可以绘制填充文字或轮廓文字。  利用canvas元素可以实现状态的保存与恢复、图形的平移、图形的缩放、图形的旋转、图形的变形等。  利用canvas元素可以操作外部图像,将其引入网页中。  canvas元素还支持更多的颜色和样式,包括线型、渐变、图案、透明度和阴影。 习题 1. Context对象的()方法将画笔移动到指定的坐标点。 A. moveTo() B. lineTo() C. fill() D. stroke() 2. canvas元素使用()方法获取上下文对象。 A. stroke() B. getContext() C. fill() D. controller() 3. 以下关于线条属性的说法中,()是正确的。 A. lineCap属性设置或返回线条末端线帽的样式 B. butt值为向线条末端添加平直的边缘 C. round值为向线条末端添加圆形线帽 D. 以上都正确 4. Context对象的()方法可以绘制矩阵轮廓。 A. fillRect() B. strokeRect() C. fillStyle() D. strokeStyle() 5. Context对象的()方法用于绘制填充文字。 A. fillText() B. strokeText() C. fillStyle() D. strokeStyle() 6. Context对象的()方法可以实现坐标空间的移动。 A. scale() B. translate() C. transform() D. rotate() 7. Context对象的()方法可以实现旋转坐标空间。 A. scale() B. translate() C. transform() D. rotate() 8. 使用canvas绘制一个填充矩形,要求矩形的填充色为红色,再绘制一个矩形轮廓,要求矩形为圆角矩形,边框的颜色为蓝色,边框的宽度为10px。