Fork me on GitHub

canvas入门(一)

图片

理解canvas元素

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

要使用canvas元素,必须先设置其width和height属性,指定可以绘图的区域大小。与其他元素一样,canvas也能通过css为该元素添加样式,如果不添加任何样式或者不绘制任何图形在页面中是看不到该元素的。

1
<canvas id = "drawing" width="200" height="200">A drawing of something.</canvas>

要在这块画布上绘图,需要取得绘图上下文。而取得绘图上下文对象的引用,需要调用getcontext()方法并传入上下文的名字。

1
2
3
4
5
6
var drawing = document.getElementById("drawing");
//确定浏览器支持<canvas>元素
if(drawing.getContext){
var context = drawing.getContext("2d");
//代码
}

在使用canvas元素之前,首先要检测getcontext()方法是否存在,这一步非常重要。

2D上下文

使用2D绘图上下文提供的方法,可以绘制简单的2D图形,如矩形、弧线和路径等。2D上下文的坐标开始于元素的左上角,原点坐标是(0,0)。所有坐标都基于这个原点计算,x值越大表示越靠右,y值越大表示越靠下。默认情况下,width和height表示水平和垂直方向上可用的像素数目。

填充和描边

2D上下文的基本绘图操作是填充和描边。填充,就是用指定的样式(颜色、渐变和图像)填充图形;描边,就是只在图形的边缘画线。大多数2D上下文操作都会细分为填充和描边两个操作,而操作的结果取决于两个属性:fillStyle和strokeStyle。

绘制矩形

矩形是唯一一种可以直接在2D上下文中绘制的形状。与矩形有关的方法包括fillRect()、strokeRect()和clearRect()。这三个方法都能接收4个参数:矩形的x坐标、矩形的y坐标、矩形的宽度和高度。这些参数的单位都是像素。

绘制路径

2D上下文支持很多在画布上绘制路径的方法。通过路径可以创造出复杂的形状和线条。要绘制路径,首先必须调用beginPath()方法,表示要开始绘制新路径。然后,在调用以下方法来实际地绘制路径。

  • arc(x,y,radius,startAngle,endAngle,counterclockwise):以(x,y)为圆心绘制一条弧线,弧线半径为radius,起始和结束角度分别为startAngle和endAngle。最后一个参数表示是否按照逆时针方向计算,值为false表示按顺时针方向计算。
  • arcTo(x1,y1,x2,y2,radius):从上一点开始绘制一条弧线,到(x2,y2)为止,并且以给定的半径radius穿过(x1,y1)。
  • lineTo(x,y):从上一点开始绘制一条直线,到(x,y)为止。
  • moveTo(x,y):将绘图游标移动到(x,y),不画线。

创建了路径之后,接下来有几种可能的选择。如果想绘制一条连接到路径起点的线条,可以调用closePath()。如果路径已经完成,你想用fillStyle填充它,可以调用fill方法。另外,还可以调用stroke()方法对路径描边,描边使用的是strokeStyle。最后还可以调用cilp()方法,这个方法可以在路径上创建一个剪切区域。

下面看一个例子,绘制一个不带数字的时钟表盘。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var drawing = document.getElementById("drawing");
//确定浏览器支持<canvas>元素
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);
//描边路径
//调用stroke()方法,这样才能把图形绘制到画布上
context.stroke();
}

绘制文本

文本与图形总是如影随行。为此,2D绘图上下文也提供了绘制文本的方法。绘制文本主要有两个方法:fillText()和strokeText()。这两个方法都可以接受4个参数:要绘制的文本字符串、x坐标、y坐标和可选的最大像素宽度。而且,这两个方法都以下列3个属性为基础。

  • font:表示文本样式、大小及字体。
  • textAlign:表示文本对齐方式。
  • textBaseline:表示文本额基线。

变换

2D绘制上下文支持各种基本的绘制变换。创建绘制上下文时,会以默认值初始化变换矩阵,在默认的变换矩阵下,所有的处理都按描述直接绘制。可通过如下方法来修改变换矩阵:

  • rotate(angle): 围绕原点旋转图像angle角度。旋转角度,以弧度计。如需将角度转换为弧度,须使用公式degressmath.pi/180公式进行计算。例:如需旋转5度,可按如下公式进行计算:5math.pi/180 。
  • scale(scalex,scaley):缩放图像。
  • transate(x,y):将坐标原点移动到(x,y)。
  • transform(m1_1,m1_2,m2_1,m2_2, x,y): 直接修改变换矩阵,方式是乘以如下矩阵。

    m1_1 m1_2 dx

    m2_1 m2_2 dy

    0 0 1

  • setTransform(m1_1,m1_2,m2_1,m2_2,x,y): 将变换矩阵重置为默认状态,然后再调用transform()方法。

变换有可能很简单,但也可能很复杂,这都要视情况而定。

无论是刚才执行的变换,还是fillStyle、strokeStyle等属性,都会在当前上下文中一直有效,除非再对上下文进行什么修改。虽然没有什么办法把上下文中的一切都重置为默认值,但有两个方法可以跟踪上下文的状态变化。如果你知道将来还要返回某组属性与变换的组合,可以调用save()方法。调用这个方法后,当时的所有设置都会进入一个栈结构,得以妥善保存。然后可以对上下文进行其他修改。等想要回到之前保存的设置时,可以调用restore()方法,在保存设置的栈结构中向前返回一级,恢复之前的状态。连续调用save()可以把更多的设置保存到栈结构中,之后再连续调用restore()则得以一级一级返回。需要注意的是,save()方法保存的只是对绘图上下文的设置和变换,不会保存绘图上下文的内容。

绘制图像

2d绘制上下文内置了对图像的支持。如果你先想把一幅图像绘制到画布上,可以使用drawimage()方法。最简单的调用方式是传入一个html<img>元素,以及绘制该图像的起点的x和y坐标。例如:

1
2
var image = document.images[0];
context.drawImage(img,10,10);

这两行代码取得了文档中的第一幅图像,然后将它绘制到上下文中,起点为(10,10)。

还可以选择把图像中的某个区域绘制到上下文中。drawimage()方法的这种调用总共需要传入9个参数:要绘制的图像,源图像的x坐标,源图像的y坐标,源图像的宽度,源图像的高度,目标图像的x坐标,目标图像的y坐标,目标图像的宽度,目标图像的高度。这样调用drawimage()方法可以获得最多的控制。例如:

1
context.drawImage(img,0,10,50,50,0,100,40,60);

这行代码只会把原始图像的一部分绘制到画布上。原始图像的这一部分的起点为(0,10),宽和高都是50像素。最终绘制到上下文中的图像的起点是(0,100),而大小变成了40×60像素。

阴影

2D上下文会根据以下几个属性的值,自动为形状或路径绘制出阴影。

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

渐变

渐变由CanvasGradient实例表示,很容易通过2D上下文来创建和修改。要创建一个新的线性渐变,可以调用createGradient()方法。这个方法接受4个参数:起点的x坐标、起点的y坐标、终点的x坐标、终点的y坐标。调用这个方法后,它会创建一个指定大小的渐变,并返回CanvasGradient对象的实例。

创建了渐变对象之后,下一步就是使用addColorStop()方法来指定色标。这个方法接收两个参数:色标位置和CSS颜色值。色标位置是一个0(开始的颜色)到1(结束的颜色)之间的数字。例如:

1
2
3
var gradient = context.createLinearGradient(30,30,70,70);
gradient.addColor(0,"white");
gradient.addColor(1,"black");