HTML5中添加了很多新的标签,canvas就是其中之一,它被用来进行图形的绘制,关于图形的绘制我们需要通过javascript来完成,canvas标签仅是一个图形的容器。
IE9及其他现代浏览器基本都支持这个标签。
canvas由几组API组成,除了绘制基本图形的2D上下文,还有一个名为WebGL的3D上下文,不过浏览器支持还不够好,
基本用法
使用\
这是我们的画布,也是我们绘制的图像的一个载体,要在画布上绘图,我们需要先通过getContext()方法取得绘图上下文:
使用toDataUrl()方法可以导出在canvas上绘制的图像。该方法接受一个MIME类型参数,如果我们需要取得画布中的一幅png图像,可以这样做:
默认情况下,MIME类型为PNG格式。
canvas坐标系
canvas以左上角为原点(0,0),坐标值都以原点为参照进行计算,与background背景图片的位置计算方法相同。第一个值代表离左边框的距离,第二个值代表离上边框的距离。
填充和描边
通过2D绘图上下文提供的方法,我们可以绘制矩形,弧线等2D图形。对于这些图形,我们可以选择绘制的方式。这里有两个属性,来决定是进行填充还是进行描边:fillStyle和strokeStyle
这两个属性的值可以是字符串、渐变对象、或模式对象,默认值都是“#000000”。我们可以用任何的颜色格式(rgb、rgba、hsl、hsla)来定义样式:
这样设置后,下面涉及到填充和描边的操作都会使用这两个样式,绘制过程中样式可更改。
绘制矩形
与绘制矩形相关的方法有:fillRect()、strokeRect()、clearRect(),这些参数都接受4个参数:矩形x坐标、矩形y坐标、矩形宽度、矩形高度,单位都为像素。
绘制图形前都应先指定填充或者描边的样式:
此外,还有以下属性能够控制线条和线条末端的形状:
- lineWidth:线条宽度
- lineCap:用于控制线条末端的形状,取值有butt(平头),round(圆头),square(方头)
- lineJoin:控制线条相交的方式,取值有round(圆交),bevel(斜交),miter(斜接)
绘制路径
2D绘图上下文提供了很多用于绘制路径的方法。在绘制之前,需要先调用beginPath(),表示要开始绘制新路径。然后再调用下面的方法绘制实际路径。
绘制圆弧
arc(x,y,radius,startAngle,endAngle,conterclockwise):以(x,y)为圆心,radius为半径,起始和结束弧度分别为startAngle,endAngle来画圆弧,counterclockwise为false代表按逆时针计算角度。
我们用这个方法来绘制一个圆形:
绘制完一个图形要关闭路径,并且最后需要调用fill()和stroke()才能将图形绘制到画布上。
画圆弧还有另外一个方法,arcTo(x1,y1,x2,y2,radius):传入弧起点和终点的坐标以及弧的半径。
moveTo()和lineTo()
- moveTo(x,y):将绘图游标移动到(x,y),不画线
- lineTo(x,y):在上一点和(x,y)之间绘制一条直线
注意:
每次画线都是从moveTo的点到lineTo的点
如果没有moveTo,第一次lineTo的效果和moveTo相同
每次lineTo后如果没有moveTo,下次会从上次lineTo的终点开始画线
结合上面和圆弧来写一个时钟表盘的例子:
效果:
贝塞尔曲线(bezier)
我们可以通过bezierCurveTo()方法来画贝塞尔曲线,该方法有6个参数:clx,cly,c2x,c2y,x,y。该方法会从上一点到(x,y)之间绘制一条曲线,并以(c1x,c1y)和(c2x,c2y)为控制点。
还有一个跟这个方法类似的方法–quadraticCurveTo(c1x,c2y,x,y),用法相同,区别在于只有一个控制点(c1x,c1y),这是一个二次曲线的绘制方法。
如下例:
效果:
绘制文本
绘制文本主要有两个方法:fillText()和strokeText()。这两个方法都接收4个参数:要绘制的字符串,x坐标,y坐标,最大像素宽度。
同时,这两个方法都以下面3个属性为基础:
- font:表示文本样式、大小和字体,如”bold 14px Arial“
- textAlign:表示文本对齐方式,取值有start、end、left、right、center。建议使用start和end,而不是left、right
- textBaseline:表示文本的基线(垂直对齐方式),取值有top、hanging、middle、alphabetic、ideographic、bottom
这几个属性值都有默认值,fillText()会使用fillStyle来填充文字,strokeText()则使用strokeStyle为文字描边。
绘制文本比较复杂,特别是但我们需要将文本控制在某个区域中时,为此,2d上下文为我们提供了一个确定文本你大小的方法measureText(),返回的是个包含width属性的对象。
现在,如果我们想在一个150px宽度的矩形中绘制“hello canvas!”,我们可以这样做:
上面代码会从30像素开始递减,直到文本的宽度小于150px,即找到合适的字体大小。
渐变
canvas中的渐变我们通过canvasGradient实例来实现,生成渐变对象的方法有两个:
- createLinearGradient(x1,y1,x2,y2):接收渐变的起点(x1,y1)和终点和(x2,y2)
- createRadialGradient(x1,y1,r1,x2,y2,r2):跟上面方法类似,前三个参数定义一个以(x1,y1)为圆心,r1为半径的圆,后三个参数定义一个以(x2,y2)为圆心,r2为半径的圆
通过上述方法创建好实例后,需要用addColorStop方法来上色,
addColorStop()有两个参数:色标位置以及css颜色值,色标位置介于0到1之间。
可以根据需要添加多个色标。
来看2个例子:
效果:
阴影
2D上下文提供了几个绘制阴影的属性,这些属性会自动为图形或者路径添加阴影。
- shadowColor:css颜色值形式的阴影颜色
- shadowOffsetX:沿x轴的偏移量
- shadowOffsetY:沿y轴的偏移量
- shadowBlur:模糊的像素数,默认为0
看一个例子:
效果:
变形
2D绘制上下文支持我们对图像进行绘制变换,变换时我们需要用到变换矩阵,下面的方法会改变变换矩阵,从而导致不同的效果。
save()和restore()
了解变形之前需要先知道两个在绘制图形时必不可少的方法–save()和restore(),他们是用来保存和回复canvas状态的,不需要传入参数。
canvas状态存储在栈中,当save()方法被调用时,当前的状态就会被保存到栈中。
canvas状态包括的内容有:
- 当前应用的变形(scale,translate,rotate)
- strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation 的值
- 当前的裁剪路径(clipping path)
而restore()方法被调用时,则会从栈中弹出上一个保存的状态,恢复所有设定。
translate()
translate(x,y)方法接收新位置的坐标,x是左右偏移量,y是上下偏移量,表示将坐标原点移到(x,y)。
这里需要牢记偏移的是坐标原点,实际上所有变形操作的都是坐标原点。
在变形之前用save()保存状态是一个好的习惯,因为在一个循环中做位移但没有保存和回复canvas状态,最后有些东西会不见,因为它很可能超出了canvas范围之外了。
rotate()
rotate()方法接收一个angle参数,通过这个方法我们可以围绕原点旋转图像。
通过旋转,我们可以绘制有趣的图形:
|
|
效果:
scale()
变形的另外一个方法是scale(x,y),即缩放。它接收两个参数,分别为x轴和y轴的缩放因子,默认都是1.
transform
变形的最后一个方法是transform(m11,m12,m21,m22,dx,dy),这个方法会讲当前的变形矩阵乘上一个基于自身参数的矩阵,各个参数的意义如下:
- m11:水平方向的缩放
- m12:水平方向的偏移
- m21:垂直方向的偏移
- m22:垂直方向的缩放
- dx:水平方向的移动
- dy:垂直方向的移动
setTransform(m11,m12,m21,m22,dx,dy)会将变化矩阵重置为单位矩阵然后再调用transform()。
resetTransform(m11,m12,m21,m22,dx,dy)将当前变形为单位矩阵。
tranlate()、scale()、rotate()三个方法调用的先后顺序不同,最后出现的效果也不同,但是只要记住这三个方法都是操作的坐标轴,就会好理解得多了。
|
|
效果:
(平移,缩放,旋转)和(平移,旋转,缩放)效果一样,(缩放,旋转,平移)和(旋转,缩放,平移)一样