熟悉html5的程序员们肯定都知道<canvas>元素,该元素是用来在页面中规定一块区域,然后由js在该区域内绘制图形。canvas支持2D绘图和名为WebGL的3D绘图。
<canvas>元素用法
<canvas id="draw" width="300" height="300">Your browser can't support canvas tag</canvas>
<canvas>元素需要通过width和height属性指定绘图区域大小。且标签中间的内容在浏览器不支持<canvas>元素时会显示。
JS绘图
要在这块画布上绘图,首先要通过getContext()方法取得绘图上下文。参数为“2d”,就可以取得2D上下文对象。
var myDraw = document.getElementById("draw");
if(myDraw.getContext) {
var context = myDraw.getContext("2d");
//更多代码
}
2D上下文的坐标原点(0,0)是<canvas>元素的左上角。x值越大表示越靠右,y值越大表示越靠下。
2D上下文中两种基本绘图操作为填充和描边,可以通过
fillStyle
属性设置填充样式,通过strokeStyle
属性设置描边样式,这两个属性的值可以是字符串、渐变对象或模式对象,默认值为“#000000”
。如果为它们指定表示颜色的字符串值,可以使用CSS中指定颜色值的任何格式。
var myDraw = document.getElementById("draw");
if(myDraw.getContext) {
var context = myDraw.getContext("2d");
context.fillStyle = "#eeeeee";
context.strokeStyle = "yellow";
}
渐变对象和模式对象,后面会讨论。
2D上下文可以绘制简单的2D图形,如矩形、路径和文本等。
绘制矩形
矩形是唯一一种可以直接在2D上下文中绘制的形状。与矩形有关的方法包括:fillRect()
、strokeRect()
和clearRect()
。这三个方法都能接受4个参数:矩形左上角的X坐标、矩形左上角的Y坐标、矩形的宽度和矩形的高度。fillRect()
方法填充指定矩形区域。填充的样式通过属性fillStyle
设置。
var canvas = document.getElementById("draw");
if(canvas.getContext) {
var context = canvas.getContext("2d");
context.fillStyle = "#f361ee";
context.fillRect(50, 50, 100, 100);
context.fillStyle = "rgba(0, 0, 255, 0.5)";
context.fillRect(100, 100, 100, 100);
}
fillRect()示例图
strokeRect()
方法为指定的矩形描边,用法类似于fillRect()
,且描边样式通过strokeStyle
属性定义。clearRect()
方法用于清除画布上的矩形区域,会将指定区域变透明。基于fillRect()
的示例,在增加一行代码,便会产生有意思的效果。
context.clearRect(110, 110, 30, 30);
clearRect()示例图
绘制路径
2D上下文支持很多在画布上绘制路径的方法,通过这些路径可以创造出复杂的形状和线条。在绘制路径之前,首先必须调用beginPath()方法,表示要开始绘制新路径。绘制路径的方法包括:
- arc(x, y, radius, startAngle, endAngle, counterclockwise),以(x, y)为圆心绘制一条弧线,radius表示弧形半径,startAngle和endAngle分别表示开始角度和结束角度,counterclockwise表示是否逆时针,值为false时表示顺时针;
- arcTo(x1, y1, x2, y2, radius), 从上一点开始以给定的radius为半径绘制一条弧线,终点为(x2, y2),且穿过(x1, y1);
- bezierCurveTo(c1x, c1y, c2x, c2y, x, y), 从上一点看是绘制一条曲线,到(x, y)为止,且(c1x, c1y) 和( c2x, c2y)为控制点;
- lineTo(x, y) 从上一点开始绘制一条到(x, y)的直线;
- moveTo(x, y) 将绘图游标移动到(x, y),不画线;
- quadraticCurveTo(cx, cy, x, y) 从上一点开始绘制一条二次曲线, 到(x, y)为止,并且以(cx, cy)作为控制点;
- rect(x, y, width, height) 从点(x, y)开始绘制一个矩形,宽度和高度分别由width和height指定。这个方法绘制的是矩形路径,而不是strokeRect()和fillRect()所绘制的形状;
如果想绘制一条连接到起始点的路径,可以调用closePath()来形成封闭路径。如果想用fillStyle填充它,可调用fill()方法,也可调用stroke()方法对路径进行描边,描边样式有strokeStyle属性指定。
var canvas = document.getElementById("myCanvas");
if(canvas.getContext) {
var context = canvas.getContext("2d");
context.beginPath();
context.arc(150, 150, 100, 0, 2 * Math.PI, false);
context.moveTo(240, 150);
context.arc(150, 150, 90, 0, 2 * Math.PI, false);
context.moveTo(150, 150);
context.lineTo(150, 80);
context.moveTo(150, 150);
context.lineTo(200, 150);
context.stroke();
}
绘制文本
绘制文本主要有两个方法: fillText()
和strokeText()
。这两个方法都能接受4个参数:要绘制的文本字符串、x坐标、y坐标和可选的最大像素宽度。文本的样式通过下面的属性指定:
- font: 表示文本样式、大小及字体;
- textAlign:表示文本对其方式;
- textBaseline:表示文本的基线;
context.font = "bold 14px Arial";
context.textAlign = "center";
context.textBaseline = "middle";
context.fillText("12", 150, 70);
绘制文本示例
由于绘制文本比较复杂,特别是需要把文本控制在某一区域中时,2D上下文提供了辅助确定文本大小的方法
measureText()
。这个方法接受一个参数,即要绘制的文本,返回一个TextMetric对象,该对象有width属性。
绘制图像
2D上下文还支持绘制图像,可以调用drawImage()
方法将一幅图像绘制到画布上。可使用下面3中方式调用drawImage()方法。
- 绘制整个图像,且绘制到画布上的图像与原图像大小一致,需要传入的参数为:要绘制的图像,开始位置的x和y坐标。
var image = document.images[0];
context.drawImage(image, 10, 10)
- 绘制整个图像,且用户定义绘制到画布上的图像尺寸,在上一种情况的基础上,再多传入两个参数,即绘制后图像的宽度和高度。
context.drawImage(image, 50, 10, 20, 30)
- 绘制图像的指定区域到画布上,且用户定义绘制到画布上图像的大小,这种情况需要传入9个参数,分别为要绘制的图像、源图像的x坐标、源图像的y坐标、源图像的宽度、源图像的高度、目标图像的x坐标、目标图像的y坐标、目标图像的宽度、目标图像的高度。
context.drawImage(image, 0, 10, 50, 50, 0, 100, 40, 60)
即从image图像上选取以(0, 10)为起点,长宽分别为50的矩形区域,并将这块区域的图像绘制到画布上,绘制后的图形的起点为(0, 100), 宽度为40, 长度为60。
也可以将另一个<canvas>元素作为drawImage()方法的第一个参数。
渐变和模式
前面提到,fillStyle
和strokeStyle
的值可为渐变对象和模式对象。渐变分为两种:线性渐变和径向渐变。
可使用createLinearGradient()
方法创建线性渐变,接收4个参数:起点的x坐标、起点的y坐标、终点的x坐标、终点的y坐标,并返回CanvasGradient对象的实例。它会创建一个指定大小的渐变。
创建渐变对象后,下一步就是调用渐变对象的addColorStop()
方法指定渐变开始的颜色和渐变终止的颜色,色标位置的一个0到1之间的数字。
var gradient = context.createLinearGradient(50, 50, 250, 250);
gradient.addColorStop(0, "white");
gradient.addColorStop(0.5, "red");
gradient.addColorStop(1, "black");
context.fillStyle = gradient;
context.fillRect(50, 50, 200, 200);
使用渐变进行填充
可是使用
createRadialGradient()
方法创建径向渐变,该方法接受6个参数,前三个参数分别表示起点圆的圆心坐标和半径,后三个参数分别表示终点圆的圆心坐标和半径。
var gradient = context.createRadialGradient(150, 150, 50, 150, 150, 120);
gradient.addColorStop(0, "white");
gradient.addColorStop(0.5, "red");
gradient.addColorStop(1, "black");
context.fillStyle = gradient;
context.fillRect(30, 30, 240, 240);
径向渐变填充示例图
模式其实就是以何种方式重复图像,可使用createPattern()
方法创建模式,参数为图像元素和表示图像重复方式的字符串,包括"repeat"、"repeat-x"、"repeat-y"和"no-repeat"。
阴影
2D上下文支持为图形或者路径设置阴影,涉及的属性值:
- shadowColor:阴影颜色,默认为黑色;
- shadowOffsetX:阴影在x轴方向的偏移量,默认为0;
- shadowOffsetY:阴影在Y轴方向的偏移量,默认为0;
- shadowBlur:模糊的像素数,默认为0,即不模糊;
context.shadowColor = "#000";
context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
context.shadowBlur = 10;
context.fillStyle = "rgb(0, 0, 255)";
context.fillRect(100, 100, 100, 100);
阴影效果图
变换
2D绘制上下文支持各种基本的绘制变换,可旋转、缩放、移动坐标原点等,包括:
- rotate(angle): 围绕原点旋转图像angle度。
- scale(scaleX, scaleY):缩放图像,在x轴方向上缩放scaleX倍,在y轴方向上缩放scaleY倍。scaleX和scaleY默认值都是1.0;
- translate(x, y):将坐标原点移动到(x, y);
- transform(m1_1, m1_2, m2_1, m2_2, dx, dy):使用如下矩阵进行变换
m1_1 m1_2 dx
m2_1 m2_2 dy
0 0 1
- setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy):现将变换矩阵设置为默认状态,然后再调用transform();
以前面绘制表盘为例:
var canvas = document.getElementById("myCanvas");
if(canvas.getContext) {
var context = canvas.getContext("2d");
context.beginPath();
context.arc(150, 150, 100, 0, 2 * Math.PI, false);
context.moveTo(240, 150);
context.arc(150, 150, 90, 0, 2 * Math.PI, false);
context.translate(150, 150);
context.moveTo(0, 0);
context.lineTo(0, -70);
context.moveTo(0, 0);
context.lineTo(50, 0);
context.stroke();
}
在进行重新设置填充、描边或变换后,如果想使用之前的某组属性与变换组合,可以在重置之前调用save()方法将这组属性和变换保存。有一个栈结构来保存这些记录,为先进后出。如果想回到之前保存的设置时,可以调用restore()方法。
context.fillStyle = "#ff0000";//红色
context.save();
context.fillStyle = "#00ff00";//绿色
context.fillRect(50, 50, 50, 50);
context.restore();
context.fillRect(120, 120, 50, 50);
save()和restore()
网友评论