canvas入门

canvas可以说是HTML5中最受欢迎的一个元素。这个元素负责在页面中设定一个区域,然后就可以通过 javascript 动态地在这个区域绘制图形。

基本用法

要使用<canvas>元素,必须先设置其 width 和 height,指定可以绘图的区域大小。出现在开始和结束标签中的内容是后备信息,如果浏览器不支持<canvas>,就会显示这些信息。

1
<canvas id="drawing" width="200" height="200">你的浏览器不支持canvas绘图,请更换浏览器重试。</canvas>

要在这块画布上绘图,需要取得绘图上下文。而取得绘图上下文的引用,需要调用 getContext() 方法并传入上下文的名字。传入‘2d’,就可以取得 2D 上下文对象。
使用 toDataURL() 方法,可以导出在 <canvas> 元素上绘制的图像。这个方法接受一个参数,即图像的 MIME 类型格式(默认为PNG格式),而且适合用于创建图像的任何上下文。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var drawing = document.getElementById('drawing');
//确定浏览器支持
if(drawing.getContext){
//取得绘图 2D 上下文
var context = drawing.getContext('2d');
//取得图像的数据URI
var imgURI = drawing.toDataURL('image/png');
//显示图像
var image = doucment.createElement('img');
image.src = imgURI;
document.body.appendChild(image);
}

2D 上下文

使用 2D 绘图上下文提供的方法,可以绘制简单的 2D 图形。2D 上下文的坐标开始于<canvas>元素的左上角,原点坐标是(0,0)。所有坐标值都基于这个原点计算,x值越大表示越靠右,y值越大表示越靠下。

填充和描边

1
2
3
4
5
6
7
8
9
10
//fillStyle 填充:用指定的样式(颜色、渐变或图像)填充图形
//strokeStyle 描边:就是只在图形的边缘画线
var drawing = document.getElementById('drawing');
if(drawing.getContext){
var context = drawing.getContext('2d');
context.strokeStyle = 'red';
context.fillStyle = '#0000ff';
}

绘制矩形

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//fillRect() 在画布上绘制的矩形会填充指定的颜色
//strokeRect() 在画布上绘制的矩形会使用指定的颜色描边
//clearRect() 清除画布上的矩形区域
//以上三个方法都能接收四个参数:矩形的x坐标、矩形的y坐标、矩形的宽度和矩形的高度。
//描边线条宽度由 lineWidh 属性控制,可以是任意数值。
//通过 lineCap 属性可以控制线条末端的形状是平头、圆头还是方头('butt','round'或'square')
//通过 lineJoin 属性可以控制线条相交的方式是圆交、斜角还是斜接('round','bevel'或'miter')
var drawing = document.getElementById('drawing');
if(drawing.getContext){
var context = drawing.getContext('2d');
//绘制红色矩形
context.fillStyle = 'red';
context.fillRect(10, 10, 50, 50);
//绘制红色描边
context.strokeStyle = '#ff0000';
conteext.strokeRect(20, 20, 50, 50);
//在画布上清除一个矩形
context.clearRect(30, 30, 10, 10);
}

绘制路径

要绘制路径,首先必须调用 beginPath() 方法,表示开始绘制新路径。然后通过调用下列方法来实际绘制路径。

  • arc(x, y, radius, startAngle, endAngle, counterclockwise):以(x, y)为圆心绘制一条弧线,弧线半径为 radius,起始和结束角度(用弧度表示)分别为 startAngle 和 endAngle。最后一个参数表示 startAngle 和 endAngle 是否按逆时针方向计算,值为 false 表示按顺时针方向计算。
  • arcTo(x1, y1, x2, y2, radius):从上一点开始绘制一条曲线,到(x2, y2)为止,并且以给定的半径 radius 穿过 (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。最后还可以调用 clip(),这个方法可以在路径上创建一个剪切区域。

可以利用 isPointInPath() 的方法在路径关闭之前确定画布上的某一点是否位于路径上。这个方法接收 x 坐标和 y 坐标作为参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
var drawing = document.getElementById('drawing');
if(drawing.getContext){
var context = drawing.getContext('2d');
//开始路径
context.beginPath();
//绘制外圆
context.arc(100, 100, 99, 0, 2 * Math.PI, false);
//绘制内圆
context.moveTo(194, 100);
context.arc(100, 100, 94, 0, 2 * Math.PI, false);
//绘制分针
context.moveTo(100, 100);
context.lineTo(100, 15);
//绘制时针
context.moveTo(100, 100);
context.lineTo(35, 100);
//描边路径
context.stroke();
}

绘制文本

绘制文本主要有两个方法:fillText()和strokeText()。这两个方法都可以接收四个参数:要绘制的文本字符串、x坐标、y坐标和可选的最大像素宽度。而且,这两个方法都以下列3个属性为基础。

  • font:表示文本样式、大小和字体,用css中的格式来指定。
  • textAlign:表示文本对齐方式。值有left、right、start、end、和center。建议使用 start 和 end。
    *textBaseline:表示文本的基线。值有top、hanging、middle、alphabetic、ideographic 和 bottom。

2D 上下文提供了辅助确定文本大小的方法 measureText()。这个方法接收一个参数,即要绘制的文本;返回一个 TextMetrics 对象。返回的对象目前只有一个 width 属性。

1
2
3
4
context.font = 'bold 14px Arial';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText('hello', 100, 20);

变换

可以通过如下方法修改变换矩阵。

  • rotate(angle):围绕原点旋转图像 angle 弧度。
  • scale(scaleX, scaleY):缩放图像,在x方向乘以scaleX,在y方向乘以scaleY。scaleX和scaleY的默认值都是1.0。
  • translate(x, y):将坐标原点移动到(x, y)。执行这个变换之后,坐标(0, 0)会变成之前由(x, y)表示的点。
  • transform(m1_1, m1_2, m2_1, m2_2, dx, dy):直接修改变换矩阵。
  • setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy):将变换矩阵重置为默认状态,然后再调用 transform()。

save()方法可以保存当前绘图上下文的设置和变换。
restore()方法可以在save()保存的设置中向前返回一级。

绘制图像

drawImage():调用此方法可以把一幅图绘制到画布上。

1
2
3
4
5
6
7
8
9
//传入三个参数 一个img元素,以及绘制起点的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);

除了给drawImage()方法传入HTML中的img元素外,还可以传入另一个canvas元素作为第一参数,这样就可以把另一画布内容绘制到当前画布上。

阴影

2D 上下文会根据以下几个属性的值,自动为形状或路径绘制出阴影。这些属性都可以通过context对象修改。只要在绘制前为它们设置适当的值,就会自定应用。

  • shadowColor:用CSS颜色格式表示的阴影颜色,默认黑色
  • shadowOffsetX:形状或路径x轴的阴影偏移量,默认0
  • shadowOffsetY:形状或路径y轴的阴影偏移量,默认0
  • shadowBlur:模糊的像素数,默认0,即不模糊

渐变

渐变由 CanvasGradient 实例表示。要插件一个新的线性渐变,可以调用 createLinearGradient()。这个方法接收4个参数:起点的x坐标、起点的y坐标、终点的x坐标、终点的y坐标。调用这个方法后,它就会创建一个指定大小的渐变,并返回CanvasGradient对象的实例。
有了渐变对象后,下一步就是使用addColorStop()方法来指定色标。接收2个参数:色标位置(0-1)和css颜色值。

1
2
3
4
5
6
7
8
var gradient = context.createLinearGradient(30, 30, 70, 70);
gradient.addColorStop(0, 'white');
gradient.addColorStop(1, 'black');
//绘制渐变矩形
context.fillStyle = gradient;
context.fillRect(30, 30, 50, 50);

模式

模式其实就是重复的图像,可以用来填充和描边图形。要创建一个新模式,可以调用createPattern()方法并传入两个参数:一个HTML中的img元素和一个表示如果重复图形的字符串。第二个参数的值包含:repeat、repeat-x、repeat-y、no-repeat。

1
2
3
4
5
6
var image = document.images[0];
var pattern = context.createPattern(image, 'repeat');
//绘制矩形
context.fillStyle = pattern;
context.fillRect(10, 10, 150, 150);

使用图像数据

getImageData():使用此方法可以取得原始图像数据。这个方法接收4个参数:要取得其数据的画面区域的x坐标和y坐标以及该区域的像素宽度和高度。
这里返回的对象是ImageData()的实例。每个ImageData()对象都有三个属性:width、height和data。其中data属性是一个数组,保存着图像每个像素的数据。在data数组中,每个像素用4个原始来保存,分别表示红、绿、蓝和透明度。

1
2
3
4
5
6
var imageData = context.getImageData(10, 5, 50, 50);
var data = imageData.data,
red = data[0],
green = data[1],
blue = data[2],
alpha = data[3];

合成

globalAlpha 设置全局透明度
globalCompositionOperation 表示后绘制的图形怎样与先绘制的图形结合。

WebGL