可以通过裁剪选中的区域来改变图像。要在画布上进行裁剪,则需要重载
drawImage()
方法。
drawImage()
方法有 3 个选项。您可以使用 3 个、5 个或 9 个参数。
3 个参数配置,即
drawImage(image, dx, dy)
,可将图像绘制在画布的目标坐标
(dx, dy)
上。该坐标构成图像的左上角。
5 个参数配置,即
drawImage(image, dx, dy, dw, dh)
,可为目标坐标提供宽度和高度。将缩放图像以适合目标宽度和高度。
9 个参数配置,即
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
,可从一个图像中剪切一个矩形区域,该区域的原坐标为
(sx,sy)
,宽度和高度为
(sw,sh)
,然后缩放该区域使之适合于目标宽度和高度
(dw,dh)
,并将其放置到画布的
(dx,dy)
位置上。
图 7 显示了要剪切的图像。
图 7. 剪切图像
以图 7 中的图像为背景将一组图像放到画布上。选用与画布大小相同的图像作为背景。另一个要创建的图像则应更小一些,将插入画布的右下角。第三个图像是拿破仑头部的剪切,放置于画布的左上角。图 8 显示了裁剪之后的图像。
图 8. 裁剪之后的图像
图 8 由清单 6 中的代码创建。在运行该代码之前,确保下载本例中要使用的 Napolean.png 图像。
清单 6. 裁剪实例图像的代码
双击代码全选
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
<!doctype>
< html >
< head >
< title >Crop Example</ title >
< script type = "text/javascript" >
window.onload = function() {
var canvas=document.getElementById("cropNapolean");
var context=canvas.getContext("2d");
var imageObj = new Image();
imageObj.onload = function() {
// draw image to cover the entire canvas
context.drawImage(imageObj,0,0, 600, 400);
// draw small image in bottom right corner
var sourceX = 0;
var sourceY = 0;
var sourceWidth = 1200;
var sourceHeight = 801;
var destX = 300;
var destY = 200;
var destWidth = sourceWidth - 900;
var destHeight = sourceHeight - 600;
context.drawImage(imageObj, sourceX, sourceY, sourceWidth,
sourceHeight, destX, destY, destWidth, destHeight);
//draw Napolean's head only
var sourceNapoleanX = 460;
var sourceNapoleanY = 25;
var sourceNapoleanWidth = 250;
var sourceNapoleanHeight = 175;
var destNapoleanX = 0;
var destNapoleanY = 0;
var destNapoleanWidth = sourceNapoleanWidth - 150 ;
var destNapoleanHeight = sourceNapoleanHeight - 100;
context.drawImage(imageObj, sourceNapoleanX, sourceNapoleanY,
sourceNapoleanWidth, sourceNapoleanHeight,
destNapoleanX, destNapoleanY,
destNapoleanWidth, destNapoleanHeight);
}
imageObj.src = "Napoleon.png";
}
</ script >
</ head >
< body >
< div >
< p >< canvas id = "cropNapolean" width = "600" height = "400" ></ canvas ></ p >
</ div >
</ body >
</ html >
|
动画和多个画布
在处理动画时,层是经常遇到问题的地方。层允许隔离组件,使编写和调试代码变得更容易、更高效。Canvas API 没有层,但它可以创建多个画布。
必须通过时间来控制动画。因此,要创建动画必须实现动画的每个帧。Canvas API 在动画方面有一个主要的局限性:一旦在画布上创建了图形,将无法再改变它。要移动该图形,就必须重新绘制它。
创建动画的流程:
-
清除先前在画布上绘制的所有形状。
-
保存画布状态,确保每次绘制帧是使用的都是最初状态。
-
执行呈现帧的步骤。
-
如果已保存了状态,请在绘制新的帧之前恢复它。
可以通过两种方式来控制动画:使用
setInterval
或
setTimeout
函数,两个函数均可在固定的时间段内调用函数。
setInterval
函数重复执行所提供的代码。
setTimeout
函数仅在所提供的时间段到达时调用一次。
图 9 显示了游泳者的多画布动画中的一帧。水在一个画布上,而游泳者在另一个画布上。
图 9. 在多个画布上使用图像的动画
使用清单 7 中的代码来创建游泳者 (swimmer)。游泳者使用线性渐变来创建水 (water)。水有 4 种蓝色阴影,这就产生了类似水的视觉。然后可以使用
positionX
和
positionY
值来创建游泳者的动画,这将改变图像的姿势。使用
arc()
方法来创建游泳者的头部。通过绘制直线创建游泳者的胳膊和腿,然后在改变它们的
lineTo()
位置。再通过改变
moveTo()
的位置来改变躯干。由于这是动画,所以必须运行代码才能看到游泳者的游泳动作。
清单 7. 动画示例
双击代码全选
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
<!DOCTYPE HTML>
< html >
< head >
< title >Animation & Multiple Canvas Example</ title >
< script >
// Water canvas
function drawWater() {
var canvasWater = document.getElementById("myWaterCanvas");
var contextWater = canvasWater.getContext("2d");
contextWater.globalAlpha = .50 ;
// Create a linear gradient fill
var linearGrad = contextWater.createLinearGradient(0,0,400,400);
linearGrad.addColorStop(0, '#0000ff'); // sets the first color
linearGrad.addColorStop(.25, '#0099ff'); // sets the second color
linearGrad.addColorStop(.50, '#00ccff'); // sets the third color
linearGrad.addColorStop(.75, '#00ffff'); // sets the fourth color
contextWater.fillStyle = linearGrad;
contextWater.fillRect(0,0,400,400);
}
// Swimmer canvas
setInterval(drawSwimmer, 30);
var positionX = 0;
var positionY = 0;
function drawSwimmer(){
var canvasSwimmer = document.getElementById("mySwimmerCanvas");
var contextSwimmer = canvasSwimmer.getContext("2d");
contextSwimmer.clearRect(0,0,400,400);
if (positionX < 30 )
{
positionX += 1;
positionY += 1;
}
else
{
positionX = 0 ;
positionY = 0 ;
}
contextSwimmer.save();
// draw circle for head
var centerX = 200 ;
var centerY = 50 ;
var radius = 20 ;
contextSwimmer.beginPath();
contextSwimmer.arc(centerX, centerY+positionY,
radius, 0, 2 * Math.PI, false);
contextSwimmer.fillStyle = "#000000" ;
contextSwimmer.fill();
contextSwimmer.lineWidth = 5 ;
// torso
contextSwimmer.beginPath();
contextSwimmer.moveTo(200,70+positionY);
contextSwimmer.lineTo(200,175);
contextSwimmer.lineWidth = 10 ;
contextSwimmer.strokeStyle = "#000000" ;
contextSwimmer.lineCap = "round" ;
contextSwimmer.stroke();
// image right arm
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 100);
contextSwimmer.lineTo(175-positionX,140-positionY);
contextSwimmer.lineWidth = 10 ;
contextSwimmer.strokeStyle = "#000000" ;
contextSwimmer.lineCap = "round" ;
contextSwimmer.stroke();
// image left arm
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 100);
contextSwimmer.lineTo(225+positionX,140-positionY);
contextSwimmer.lineWidth = 10 ;
contextSwimmer.strokeStyle = "#000000" ;
contextSwimmer.lineCap = "round" ;
contextSwimmer.stroke();
// image right leg
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 175);
contextSwimmer.lineTo(190-positionX,250-positionY);
contextSwimmer.lineWidth = 10 ;
contextSwimmer.strokeStyle = "#000000" ;
contextSwimmer.lineCap = "round" ;
contextSwimmer.stroke();
// image left leg
contextSwimmer.beginPath();
contextSwimmer.moveTo(200, 175);
contextSwimmer.lineTo(210+positionX,250-positionY);
contextSwimmer.lineWidth = 10 ;
contextSwimmer.strokeStyle = "#000000" ;
contextSwimmer.lineCap = "round" ;
contextSwimmer.stroke();
contextSwimmer.restore();
};
</script>
</ head >
< body onload = "drawWater();" >
< canvas id = "myWaterCanvas" width = "400" height = "400" style="z-index: 2;
position:absolute;left:0px;top:0px;">
</ canvas >
< canvas id = "mySwimmerCanvas" width = "400" height = "400" style="z-index: 1;
position:absolute;left:0px;top:0px;">
</ canvas >
</ body >
</ html >
|
结束语
HTML5 画布对于构建基于浏览器的 RIA 至关重要。它提供受 JavaScript 支持的实用绘制环境,便于您施展自己的想象力。HTML5 学习起来并不困难,并且网上有许多支持工具能够满足培训和学习需要,包括解答、博客、在线文章、视频和非视频教程和样例应用程序。
能够以可视的方式修改文本、图像和模拟动画,这些让 Canvas 成为极有价值的工具。不管是设计者还是开发人员,也不管是使用 Canvas 构建运行在移动设备上的游戏应用程序,还是仅仅使用它改善网页的布局,Canvas 都是 HTML5 体验的重头戏。
下载
描述 |
名字 |
大小 |
下载方法 |
Napoleon 图像 |
Napoleon.zip |
2045KB |
HTTP |
(责任编辑:12图资源库)