本篇内容
  • 基本用法
  • 2D上下文

<canvas>元素负责在页面中设定一个区域,然后就可以通过JavaScript动态地在这个区域中绘制图形,IE9+、Firefox1.5+、Safari2+、Opera9+、Chrome、iOS版Safari以及Android版WebKit都在某种程度上支持<canvas>

与浏览器环境中的其他组件类似,<canvas>由几组API构成,但并非所有浏览器都支持所有这些API。除了具备基本绘图能力的2D上下文,<canvas>还建议了一个名为WebGL的3D上下文。目前,支持该元素的浏览器都支持2D上下文及文本API,但对WebGL的支持还不够好。

1 基本用法

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


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

与其他元素一样,<canvas>元素对应的DOM元素对象也有width和 height属性,可以随意修改。而且,也能通过css为该元素添加样式,如果不添加任何样式或者不绘制任何图形,在页面中是看不到该元素的。
要在这块画布(canvas)上绘图,需要取得绘图上下文。而取得绘图上下文对象的引用,需要调用getContext()方法并传人上下文的名字。传人”2d” ,就可以取得2D上下文对象。


1
2
3
4
var drawing = document.getElementById('drawing');
if (drawing.getContext) {
var context = drawing.getContext('2d');
}

使用toDataURL()方法,可以导出在<canvas>元素上绘制的图像。这个方法接受一个参数,即图像的MIME类型格式.而且适合用于创建图像的任何上下文。比如,要取得画布中的一幅PNG格式的图像,可以使用以下代码。

1
2
3
4
5
6
7
8
var drawing = document.getElementById('drawing');
if (drawing.getContext) {
var imgURI = drawing.toDataURL('image/png');

var image = document.createElement('img');
image.src = imgURI;
document.body.appendChild(image);
}

默认情况下,浏览器会将图像编码为PNG格式(除非另行指定)。Firefox和Opera也支持基于”image/jpeg”参数的JPEG编码格式。由于这个方法是后来才追加的,所以支持<canvas>的浏览器也是在较新的版本中才加入了对它的支持,比如IE9、Firefox3.5和Opera10。

2 2D上下文

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

2.1 填充和描边

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

这两个属性的值可以是字符串、渐变对象或模式对象,而且它们的默认值都是”#000000” 。如果为它们指定表示颜色的字符串值,可以使用css中指定颜色值的任何格式,包括颜色名、十六进制码、rgb、rgba、hsl或hsla。

1
2
3
4
5
6
var drawing = document.getElementById('drawing');
if (drawing.getContext) {
var context = drawing.getContext('2d');
context.strokeStyle = 'red';
context.fillStyle = '#0000ff';
}

2.2 绘制矩形

矩形是唯一一种可以直接在2D上下文中绘制的形状。 与矩形有关的方法包括fillRect()、strokeRect()和clearRect()。这三个方法都能接收4个参数:矩形的x坐标、矩形的y坐标、矩形宽度和矩形高度。这些参数的单位都是像素。
首先,fillRect()方法在画布上绘制的矩形会填充指定的颜色。填充的颜色通过fillStyle属性指定,比如:

1
2
3
4
5
6
7
8
9
10
var drawing = document.getElementById('drawing');

if (drawing.getContext) {
var context = drawing.getContext('2d');

context.fillStyle = '#f00';
context.fillRect(10, 10, 50, 50);
context.fillStyle = 'rgba(0, 0, 255, 0.5)';
context.fillRect(30, 30, 50, 50);
}

以上代码首先将fillStyle设置为红色,然后从(10,10)处开始绘制矩形,矩形的宽和高均为50像素。然后,通过rgba()格式再将fillStyle设置为半透明的蓝色,在第-个矩形上面绘制第二个短形。结果就是可以透过蓝色的矩形看到红色的矩形。

strokeRect()方法在画布上绘制的矩形会使用指定的颜色捕边。描边颜色通过strokeStyle属性指定。

描边线条的宽度由lineWidth属性控制,该属性的钱可以是任意整数。另外,通过lineCap属性可以控制线条末端的形状是平头、圆头还是方头(”butt”、”round”或”square”),通过lineJoin属性可以控制线条相交的方式是圆交、斜交还是斜接(”round”、”bevel”或”miter”)。

最后clearRect()方法用于消除画布上的矩形区域。本质上,这个方法可以把绘制上下文中的某一矩形区域变透明。通过绘制形状然后再清除指定区域,就可以生成有意思的效果,例如把某个形状切掉一块。下面看一个例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var drawing = document.getElementById('drawing');

if (drawing.getContext) {
var context = drawing.getContext('2d');

// 绘制红色矩形
context.fillStyle = '#f00';
context.fillRect(10, 10, 50, 50);
// 绘制半透明的蓝色矩形
context.fillStyle = 'rgba(0, 0, 255, 0.5)';
context.fillRect(30, 30, 50, 50);
// 在两个矩形重叠的地方清除一个小矩形
context.clearRect(40, 40, 10, 10);
}

2.3 绘制路径

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

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

如,绘制一个时钟

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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();
}

在2D绘图上下文中,路径是一种主要的绘图方式,因为路径能为要绘制的图形提供更多控制。由于路径的使用很频繁,所以就有了一个名为isPointinPath()的方法。这个方法接收x和y坐标作为参数,用于在路径被关闭之前确定画布上的某一点是否位于路径上。

1
2
3
if (context.isPointInPath(100, 100)) {
alert('point (100, 100) is in the path');
}

2D上下文中的路径API已经非常稳定, 可以利用它们结合不同的填充和捕边样式,绘制出非常复杂的图形来。

2.4 绘制文本

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

  • font:表示文本样式、大小及字体,用css中指定字体的格式来指定,例如”lOpx Arial”。
  • textAlign:表示文本对齐方式。可能的值有 ”start”、”end”、”left”、” right”和”center”。
    (建议使用”start”和”end”,不要使用”left”和”right”,因为前两者的意思更稳妥)
  • textBaseline:表示文本的基线。可能的值有”top”、”hanging”、”middle”、”alphabetic”、”ideographic”和”bottom”。
    这几个属性都有默认值,因此没有必要每次使用它们都重新设置一遍值。 fillText()方法使用fillStyle属性绘制文本,而strokeText()方法使用strokeStyle属性为文本捕边。相对来说,还是使用fillText()的时候更多,因为该方法,模仿了在网页中正常显示文本。例如,下面的代码在前一节创建的表盘上方绘制了数字12:
1
2
3
4
context.font = 'bold 14px Arial';
context.textAlign = 'center';
context.textBaseline = 'middle';
context.fillText('12', 100, 20);

由于绘制文本比较复杂,特别是需要把文本控制在某一区域中的时候,2D上下文提供了辅助确定文本大小的方法measureText()。这个方法接收一个参数,即要绘制的文本;返回一个TextMetrics对象。返回的对象目前只有一个width属性,但将来还会增加更多度量属性。

measureText()方法利用font、textAlign和textBaseline的当前值讨饵指定文本的大小。比如,假设你想在一个140像素宽的矩形区域中绘制文本Hello world!,下面的代码从100像素的字体大小开始递减,最终会找到合适的字体大小。

1
2
3
4
5
6
7
8
9
var fontSize = 100;
context.font = fontSize + 'px Arial';

while (context.measureText('Hello world!').width > 140) {
fontSize--;
context.font = fontSize + 'px Arial';
}
context.fillText('Helllo world!', 10, 10);
context.fillText('font size is :' + fontSize + 'px', 10, 50);

前面提到过,fillText和strokeText()方法都可以接收第四个参数,也就是文本的最大像素宽度。不过,这个可选的参数尚未得到所有浏览器支持。提供这个参数后,调用fillText()或strokeText()时如果传入的字将串大于最大宽度,则绘制的文本字符的高度正确,但宽度会收缩以适应最大宽度。

2.5 变换

通过上下文的变换,可以把处理后的图像绘制到画布上。2D绘制上下文支持各种基本的绘制变换。 创建绘制上下文时,会以默认值初始化变换矩阵,在默认的变换矩阵下,所有处理都按描述直接绘制。 为绘制上下文应用变换,会导致使用不同的变换矩阵应用处理,从而产生不同的结果。

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

  • 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):直接修改变换矩阵,方式是乘以如下矩阵。

    1
    2
    3
    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()。

变换有可能很简单,但也可能很复杂,这都要视情况而定。比如,就拿前面例子中绘制表针来说,如果把原点变换到表盘的中心,然后再绘制表针就容易多了。请看下面的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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.translate(100, 100);
context.moveTo(0, 0);
context.lineTo(0, -85);

context.moveTo(0, 0);
context.lineTo(-65, 0);

context.stroke();
}

还可以更进一步,像下面这样使用rotate()方法旋转时钟的表针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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.translate(100, 100);

context.rotate(1);

context.moveTo(0, 0);
context.lineTo(0, -85);

context.moveTo(0, 0);
context.lineTo(-65, 0);

context.stroke();
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
context.fillStyle = '#ff0000';
context.save();

context.fillStyle = '#00ff00';
context.translate(100, 100);
context.save();

context.fillStyle = '#0000ff';
context.fillRect(0, 0, 100, 200);

context.restore();
context.fillRect(10, 10, 100, 200);
context.restore();
context.fillRect(0, 0, 100, 200);

首先,将fillStyle设置为红色,并调用save()保存上下文状态。接下来,把fillStyle修改为绿色,把坐标原点变换到(100,100),再调用save()保存上下文状态。然后,把fillStyle修改为蓝色并绘制蓝色的矩形。因为此时的坐标原点已经变了,所以矩形的左上角坐标实际上是(100,100)。然后调用restore(),之后fillStyle变回了绿色,因而第二个矩形就是绿色。之所以第二个矩形的起点坐标是(110,110),是因为坐标位置的变换仍然起作用。再调用一次restore(),变换就被取消了,而fillStyle也返回了红色。所以最后一个矩形是红色的,而且,绘制的起点是(0,0)。

需要注意的是,save()方法保存的只是对绘图上下文的设置和变换,不会保存绘圄上下文的内容。

2.6 绘制图像

2D绘图上下文内置了对图像的支持。如果你想把一幅图像绘制到画布上,可以使用drawimage()方法。根据期望的最终结果不同,调用这个方法时,可以使用三种不同的参数组合。最简单的调用方式是传入个HTML<img>元素,以及绘制该图像的起点的x和y坐标。例如:

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

这两行代码取得了文档中的第一幅图像,然后将它绘制到上下文中,起点为(10,10)。绘制到画布上的图像大小与原始大小一样。如果你想改变绘制后图像的大小,可以再多传入两个参数,分别表示目标宽度和目标高度。通过这种方式来缩放图像并不影响上下文的变换矩阵。例如:

1
context.drawImage(image, 50, 10, 20, 30);

执行代码后,绘制出来的图像大小会变成20x30像素。

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

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

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

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

结合使用drawimage()和其他方法,可以对图像进行各种基本操作。而操作的结果可以通过toDataURL()方法获得。不过,有一个例外,即图像不能来自其他域。如果图像来自其他域,调用toDataURL()会抛出一个错误。打个比方,假如位于www.example.com上的页面绘制的图像来自于www.wrox.com,那当前上下文就会被认为“不干净”,因而会抛出错误。

2.7 阴影

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

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

这些属性都可以通过context对象来修改。只要在绘制前为它们设置适当的值, 就能自动产生阴影。

1
2
3
4
5
6
7
8
9
10
11
12
var context = drawing.getContext("2d"); 

context.shadowOffsetX = 5;
context.shadowOffsetY = 5;
context.shadowBlur = 4;
context.shadowColor = 'rgba(0, 0, 0, 0.5)';

context.fillStyle = '#ff00000';
context.fillRect(10, 10, 50, 50);

context.fillStyle = 'rgba(0, 0, 255, 1)';
context.fillRect(30, 30, 50, 50);

不同浏览器对阴影的支持有一些差异。

2.8 渐变

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

  • 色标位置和css颜色值。色标位置是一个0(开始的颜色)到1(结束的颜色)之间的数字。例如:
1
2
3
4
var gradient = context.createLinearGradient(30, 30, 70, 70);

gradient.addColorStop(0, 'white');
gradient.addColorStop(1, 'black');

此时,gradient对象表示的是一个从画布上点(30,30)到点(70,70)的渐变。起点的色标是白色,终点的色标是黑色。然后就可以把fillStyle或strokeStyle设置为这个对象,从而使用渐变来绘制形状或描边:

1
2
3
4
5
context.fillStyle = '#ff0000';
context.fillRect(10, 10, 50, 50);

context.fillStyle = gradient;
context.fillRect(30, 30, 50, 50);

了让渐变覆盖整个矩形,而不是仅应用到矩形的一部分,矩形和渐变对象的坐标必须匹配才行。

使用画布的时候,确保坐标匹配很重要,也需要一些技巧。类似createRectLinearGradient()这样的辅助方法可以让控制坐标更容易一些。
要创建径向渐变(或放射渐变),可以使用createRadialGradient()方法。这个方法接收6个参数,对应着两个圆的圆心和半径。
前三个参数指定的是起点圆的原心(x和y)及半径,后三个参数指定的是终点圆的原心( x和y)及半径。可以把径向渐变想象成一个长圆桶,而这6个参数定义的正是这个桶的两个圆形开口的位置。如果把一个圆形开口定义得比另一个小-些,那这个圆桶就变成了圆锥体,而通过移动每个圆形开口的位置,就可达到像旋转这个圆锥体一样的效果。
如果想从某个形状的中心点开始创建一个向外扩散的径向渐变效果,就要将两个圆定义为同心圆。 比如,就拿前面创建的矩形来说,径向渐变的两个圆的圆心都应该在(55,55),因为矩形的区域是从(30,30)到(80,80)。请看代码:

1
2
3
4
5
6
7
8
9
10
var gradient = context.createRadialGradient(55, 55, 10, 55, 55, 30);

gradient.addColorStop(0, 'white');
gradient.addColorStop(1, 'black');

context.fillStyle = '#ff0000';
context.fillRect(10, 10, 50, 50);

context.fillStyle = gradient;
context.fillRect(30, 30, 50, 50);

2.9 模式

模式其实就是重复的图像,可以用来填充或捕边图形。要创建一个新模式,可以调用createPattern()方法并传入两个参数:一个HTML<img>元索和一个表示如何重复图像的字符串。其中,第二个参数的值与css的background-repeat属性值相同,包括"repeat”、”repeat-x“、”repeat-y“和”no-repeat“。

1
2
3
4
5
var image = document.images[0],
pattern = context.createPattern(image, 'repeat');

context.fillStyle = pattern;
context.fillRect(10, 10, 150, 150);

需要注意的是,模式与渐变一样,都是从画布的原点(O,O)开始的。将填充样式(fillStyle)设置为模式对象,只表示在某个特定的区域内显示重复的图像,而不是要从某个位置开始绘制重复的图像。

createPattern()方法的第一个参数也可以是一个<video>元素,或者另一个<canvas>元素。

2.10 使用图像数据

2D上下文的一个明显的长处就是,可以通过getimageData()取得原始图像数据。这个方法接收4个参数:要取得其数据的画面区域的x和y坐标以及该区域的像素宽度和高度。例如,要取得左上角坐标为(10,5)、大小为50x50像素的区域的图像数据,可以使用以下代码:

1
var imageData = context.getImageData(lO, 5, 50, 50);

这里返回的对象是ImageData的实例。每个IrnageData对象都有三个属性:width、height和data。其中data属性是一个数缀,保存着图像中每一个像素的数据。在data数组中,每一个像素用4个元素来保存,分别表示红、绿、蓝和透明度值。因此,第一个像素的数据就保存在数组的第0到第3个元素中,例如:

1
2
3
4
5
var data = imageData.data,
red = data[0],
green = data[1],
blue = data[2],
alpha = data[3];

数组中每个元素的值都介于0到255之间(包括o和255)。能够直接访问到原始图像数据,就能够以各种方式来操作这些数据。例如,通过修改图像数据,可以像下面这样创建一个简单的灰阶过滤器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
context.drawImage(image, 0, 0);

imageData = context.getImageData(0, 0, image.width, image.height);
data = imageData.data;

for (var i = 0, len = data.length; i < len; i+=4) {
red = data[0];
green = data[1];
blue = data[2];
alpha = data[3];

average = Math.floor((red + green + blue) / 3);

data[i] = average;
data[i + 1] = average;
data[i + 2] = average;
}

imageData.data = data;
context.putImageData(imageData, 0, 0);

只有在画布“干净”的情况下(即图像并非来自其他域),才可以取得图像数据,否则报错。

2.11 合成

还有两个会应用到20上下文中所有绘制操作的属性:globalAlpha和globalCompositionOperation。其中,globalAlpha是-个介于0和1之间的值(包括0和1),用于指定所有绘制的透明度。默认值为0。如果所有后续操作都要基于相同的透明度,就可以先把globalAlpha设置为适当值,然后绘制,最后再把它设置四默认值。下面来看一个例子。

1
2
3
4
5
6
7
context.fillStyle = '#ff0000';
context.fillRect(10, 10, 50, 50);
context.globalAlpha = 0.5;

context.fillStyle = 'rgba(0, 0, 255, 1)';
context.fillRect(30, 30, 50, 50);
context.globalAlpha = 0;

第二个属性globalCornpositionOperation表示后绘制的图形怎样与先绘制的图形结合。这个属性的值是字符串,可能的值如下。

  • sourceover(默认值):后绘制的图形位于先绘制的图形上方。
  • source-in:后绘制的图形与先绘制的图形重叠的部分可见,两者其他部分完全透明。
  • source-out:后绘制的图形与先绘制的图形不重叠的部分可见,先绘制的图形完全透明。
  • source-atop:后绘制的图形与先绘制的图形重叠的部分可见,先绘制的图形不受影响。
  • destination-over:后绘制的图形位于先绘制的图形下方,只有之前透明像素下的部分才可见。
  • destination-in:后绘制的图形位于先绘制的图形下方,两者不重叠的部分完全透明。
  • destination-out:后绘制的图形擦除与先绘制的图形重叠的部分。
  • destination-atop:后绘制的图形位于先绘制的图形下方,在两者不重叠的地方,先绘制的图形会变透明。
  • lighter:后绘制的图形与先绘制的图形重叠部分的值相加,使该部分变亮。
  • copy:后绘制的图形完全替代与之重叠的先绘制图形。
  • xor:后绘制的图形与先绘制的图形重叠的部分执行”异或“操作。

至于canvas 3d(webGL)将会单独介绍。

温习:

  • canvas的使用
  • 填充和描边
  • 绘制矩形、绘制路径、绘制文本
  • 变换
  • 图像处理
  • 阴影和渐变

(完)