前言
小时候经常能在网页上看到一些酷炫的动态效果,让整个页面的展示效果得到很好的升华,后来知道了那些效果都是使用flash实现的。而flash虽然在制作动态效果上非常的强大与全能,但其在IOS的移动端得不到有效的支持。如果没有flash,我们就不能制作好看的特效动画了吗?答案当然是我们可以通过其它手段来实现酷炫动效的实现。
W3C一直致力于提升WEB的性能和技术规范,在HTML5中,有一个新的标签<canvas>专门用来定义图形,这个标签还提供了一系列的API,即我们可以通过HTML5+CSS+JS的组合来完成图形的绘制、动态效果的实现。
<canvas> 标签简介
1.定义
<canvas> 标签的定义非常的简单,但我们一定要明白一个事实:<canvas> 标签只是一个画布容器,图形绘制的所有工作都是由JS脚本完成的。
官方定义 | 说明 |
<canvas> 标签定义图形,比如图表和其他图像 | 使用这个标签,我们可以用来定义图形,比如一条直线、一个三角形、一个矩形等,或者是他们组合在一起的复杂图形 |
<canvas> 标签只是图形容器,您必须使用脚本来绘制图形 | <canvas> 标签仅仅是提供了一个绘制图形的容器,它不提供绘画的功能。通俗的说,我们在现实里面画画,通常需要有画布、画笔等,<canvas> 标签就是其中的画布,而想要在这个<canvas> 标签上绘制我们想要的图形,还需要画笔来完成。而这个画笔就是JS代码。也就是说,我们的绘图工作全部是在JS中完成的,<canvas> 标签只是给我们框定了一个图形的大小和位置而已。 |
2.属性
<canvas> 标签只有2个属性,具体如下:
属性名 | 值 | 描述 |
height | pixels | 设置canvas的高度 |
width | pixels | 设置canvas的宽度 |
<canvas> 标签虽然也是HTML元素,但是和普通的HTML元素最大的区别就在这个宽高的设置上。通常我们设置一个元素的宽高,都习惯使用CSS里面的width和height属性来控制,但<canvas> 标签有自己的宽高属性,其宽高必须通过这两个属性来设置才有效。
为什么使用CSS来设置<canvas>标签的宽高是不正确的呢?
当我们在HTML中建立一个空的<div>标签且不对它进行任何CSS设置时,那么这个<div>标签会默认宽度为0,高度为0,也就是它不会占据页面中的一丁点空间,仿佛不存在。这个情况适用于大部分的HTML标签,但<canvas>标签不吃这一套。
当我们在HTML中建立一个空的<canvas>标签且不对它进行任何CSS设置时,它的默认宽度是350px,高度则是150px。也就是说<canvas>标签一旦创建,那么就会在页面中占据350*150的空间,这个大小可以通过它自己提供的两个属性来修改。如果我们不是通过它自己提供的两个属性来修改,而是使用CSS来修改宽高,实际上并不是改变画布的容器大小,而是对这个画布进行了横向和纵向的拉伸,就比如一个图片的宽高是350*150,我们通过CSS设置它的宽变成800,高变成600。那么你会发现整个图片都变形了,不再是原来的比例了。这也是为什么我们不要通过CSS来设置<canvas>标签的宽高的原因。
使用<canvas>标签进行基础图形绘制的方法
在此只列举一些基础的应用方法,更多详细的API接口可通过该网址了解:
1.绘制矩形
矩形是唯一可以直接在2D上下文中绘制的形状。与矩形有关的方法包括fillRect()、strokeRect()、clearRect()。这三个方法都接受4个参数,即矩形的x坐标,y坐标,矩形的宽度,矩形的高度。(x,y)指矩形的左上角位置。
绘制图形如下:
代码如下:
以上代码是canvas最基本的使用形式,首先在HTML中创建一个<canvas> 标签,然后在js脚本中通过ID获取这个容器元素。之后的这一步很重要,正如前面所述,<canvas> 标签本身并不具有绘制的功能,它只是提供一个容器或者说一个画布的功能,真正负责进行图形绘制的是画笔,这个画笔就是通过getContext()方法进行创建的。代码中的canvas.getContext('2d')就是指获取canvas这个画布元素的2d绘图上下文环境,之后通过这个上下文环境上定义的各种绘图API进行图形的绘制。
(注:getContext('2d')中的'2d'表示调用的是绘制二维平面图形的API)
2.绘制路径
2D绘制上下文支持很多在画布上绘制路径的方法。通过路径可以创造出复杂的形状和线条。要绘制路径必须首先调用beginPath()方法,表示要开始绘制新的路径。然后再通过调用下列方法来实际绘制路径。
- arc(x,y,radius,startAngle,endAngle,counterclockwise):以(x,y)作为圆心绘制一条弧线,弧线的半径是radius,起始角度是starAngle,结束角度是endAngle,最后一个参数表示是顺时针还是逆时针绘制(值为false时表示顺时针绘制)。
- arcTo(x1,y1,x2,y2,radius):从上一点开始绘制一条弧线,到(x2,y2)为止,并且以给定的半径radius穿过(x1,y1)。
- lineTo(x,y):从上一点开始绘制一条直线,到(x,y)为止。
- moveTo(x,y):将绘图游标移动到(x,y),不画线。
- rect(x,y,width,height):从点(x,y)开始绘制一个矩形,宽度和高度分别由width和height指定。这个方法绘制的是矩形路径,而不是strokeRect()和fillRect()所绘制的独立的形状
创建了路径后,接下来有几种可能的选择。如果想绘制一条连接到路径起点的线条,可以调用closePath()。如果路径已经完成,你想用fillStyle()填充它,可以调用fill()方法。另外,还可以调用stroke()方法对路径描边,描边使用的是strokeStyle。最后还可以调用clip(),这个方法可以在路径上创建一个剪切局域。
路径绘制如下:
代码如下:
3.绘制文本
文本与图形总是如影随形。为此,2D绘图上下文也提供了绘制文本的方法。绘制文本主要有两个方法:fillText()、strokeText()。这两个方法也可以接受4个参数:要绘制的文本字符串、x坐标、y坐标、可选的最大像素宽度。而且,这两个方法都以下列3个属性为基础。
- font:表示文本样式、大小及字体,用CSS中指定字体格式来指定,例如“10px Arial”。
- textAlign:表示文本的对齐方式。可能的值有"start"、"end"、"left"、"right"、"center"。(建议使用"start"、"end",不要使用"left" 和"right",因为前两者的意思更稳妥,能同时适合从左到右和从右到左显示的语言)
- textBaseline:表示文本的基线。可能的值有"top"、"hanging"、"middle"、"alphabetic"、"ideographic"和"bottom"。
这几个属性都有默认值,因此没有必要每次使用它们都重新设置一遍值。fillText()方法使用fillStyle属性绘制文本,而strokeText()方法使用strokeStyle属性为文本描边。相对来说,还是使用fillStyle()的时候更多。
文字绘制如下:
代码如下:
4.绘制图像
2D绘图上下文内置了对图像的支持。如果你想把一幅图像绘制到画布上,可以使用drawImage()方法。根据期望的最终结果不同,调用这个方法时,可以使用三种不同的参数组合。最简单的调用方式是传入一个HTML<img>元素,以及绘制该图像的起点的x和y坐标。例如:
var image=document.images[0];ctx.drawImage(image,10,10);
这两行代码取得了文档中的第一幅图像(也可以传入另一个canvas,这样就会将另一个canvas上的图形绘制到此处),然后将它绘制到上下文中,起点为(10,10)。绘制到画布上的图像大小和原始大小一样。如果你想改变绘制后图像的大小,可以再多传入两个参数,分别表示目标宽度和目标高度。通过这种方式来缩放图像并不会影响上下文的变换矩阵。例如:
ctx.drawImage(image,50,10,20,30);
上面代码中的50表示原图的宽,10表示原图的高,后面的20和30表示绘制出来的图像宽高为20和30像素。
drawImage()非常的灵活,根据参数的设置,可以实现很多的功能,从左到右可以传入9个参数:要绘制的图像、源图像的x坐标、源图像的y坐标、源图像的宽度、源图像的高度、目标图像的x坐标、目标图像的y坐标、目标图像的宽度、目标图像的高度。例如:
ctx.drawImage(image,0,10,50,50,0,100,40,60);
上面的代码表示,将image图像中坐标(0,10)位置,大小为50*50的图像绘制到画布中(0,100)位置,大小为40*60的区域中。(单位皆为像素)。
效果如下:
以上即为canvas的四种基本绘制方式,通过组合它们以及调用更多进阶的api功能,我们能够实现非常复杂的图形绘制,甚至进行动效的制作。