27-渐变动画
3.7 渐变动画
在本章结束之前,再介绍一下如何给文本添加动画。本章之前的内容介绍的是静态文本,但在HTML5的Canvas里,只需要在标准的HTML基础上做一些简单的变动,就可以显示很酷的文本。静态文本是静态的,当不使用CSS时(Canvas目前暂不支持CSS样式),可选择一个纯文本应用程序作为替代方案。
然而,在动画效果方面,Canvas远远超过标准的HTML。例如,通过使用渐变效果,不仅能编辑静态文本,还能创造出动态的文本。通过改变填充值,可以让文本“动起来”。这种效果跟以前的视频游戏或计算机系统(尤其是Atari公司的产品)里显示的动态文字很相似。
图3-12所示为Canvas里动态文字动画的某一帧。

创造渐变动画的关键在于函数createLinearGradient()和本章之前介绍的函数gradient. addColorStop以及第1章所讲的循环函数setTimeout()。用一个渐变的“线”来代表颜色的渐变方向,然后创建一些“颜色起止”值,代表渐变动画的颜色。
首先,要先启动循环动画。
function drawScreen() {
}
function gameLoop() {
window.setTimeout(gameLoop, 20);
drawScreen()
}
接下来,创造一个简单的数组,存放代表渐变颜色值以及渐变范围的对象。这是一个非常简单的颜色“显示列表”。由于Canvas处于即时模式下,且没有显示列表的控件,因此需要模拟此功能。
“颜色起止值”代表渐变动画的百分比。在下面的代码中,将在红、黄、蓝、绿、紫、红中循环地转变颜色。在首尾处都使用红色,是为了让动画更加流畅。可以注意到,两个红色的范围都仅仅是其他颜色值范围的一半(是.125,而不是 .25)。
var colorStops = new Array(
{color:"#FF0000", stopPercent:0},
{color:"#FFFF00", stopPercent:.125},
{color:"#00FF00", stopPercent:.375},
{color:"#0000FF", stopPercent:.625},
{color:"#FF00FF", stopPercent:.875},
{color:"#FF0000", stopPercent:1});
接着,在函数drawScreen()中,生成渐变梯度gradient。首先,在当前路径上生成一个渐变梯度。函数createLinerGradient()的参数代表着渐变线。因为需要一个垂直的渐变线,所以将该线置于Canvas中心,直接绘制到底部。
var gradient = context.createLinearGradient(
theCanvas.width/2,
0,
theCanvas.width/2,
theCanvas.height);
然后,遍历颜色数组里的每一个颜色,并对其调用gradient.addColorStop()。该函数有两个参数:颜色和百分比。由于已经在数组中初始化,因此可以直接将它们添加到循环中。
添加完渐变色后,再将所有颜色所占百分比按.015递增,这样能有效地将各个颜色变暗。占比越大,渐变范围越大若同时修改所有颜色的渐变范围,则会导致所有颜色混合在一起,显得更暗。当颜色渐变范围增到到1时,再将其设置为0,这样就回到了渐变的初始状态。
for (var i=0; i < colorStops.length; i++) {
var tempColorStop = colorStops[i];
var tempColor = tempColorStop.color;
var tempStopPercent = tempColorStop.stopPercent;
gradient.addColorStop(tempStopPercent,tempColor);
tempStopPercent += .015;
if (tempStopPercent > 1) {
tempStopPercent = 0;
}
tempColorStop.stopPercent = tempStopPercent;;
colorStops[i] = tempColorStop;
}
实际上,梯度gradient并没有发生变化,只是通过改变渐变范围来改变颜色的位置。不过效果是一样的,就像颜色一直在循环。
最后,将gradient作为颜色的fillStyle来显示文本。
context.fillStyle = gradient;
context.fillText ( message, xPosition ,yPosition);
将下面的代码或者CH3EX4.html放入浏览器中,可以查看动画的效果。
例3-2 颜色循环跑马灯示例代码
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH.3 EX. 4: Color Cycle</title>
<script src="modernizr.js"></script>
<script type="text/javascript">
window.addEventListener("load", eventWindowLoaded, false);
function eventWindowLoaded() {
canvasApp();
}
function canvasSupport () {
return Modernizr.canvas;
}
function canvasApp() {
if (!canvasSupport()) {
return;
}
var message = "HTML5 Canvas";
var theCanvas = document.getElementById("canvasOne");
var context = theCanvas.getContext("2d");
function drawScreen() {
//背景
context.fillStyle = "#000000";
context.fillRect(0, 0, theCanvas.width, theCanvas.height);
//文本
context.font = "90px impact"
context.textAlign = "center";
context.textBaseline = "middle";
var metrics = context.measureText(message);
var textWidth = metrics.width;
var xPosition = (theCanvas.width/2);
var yPosition = (theCanvas.height/2);
var gradient = context.createLinearGradient( theCanvas.width/2,0,
theCanvas.width/2,theCanvas.height);
for (var i=0; i < colorStops.length; i++) {
var tempColorStop = colorStops[i];
var tempColor = tempColorStop.color;
var tempStopPercent = tempColorStop.stopPercent;
gradient.addColorStop(tempStopPercent,tempColor);
tempStopPercent += .015;
if (tempStopPercent > 1) {
tempStopPercent = 0;
}
tempColorStop.stopPercent = tempStopPercent;;
colorStops[i] = tempColorStop;
}
context.fillStyle = gradient;
context.fillText ( message, xPosition ,yPosition);
}
function gameLoop() {
window.setTimeout(gameLoop, 20);
drawScreen()
}
var colorStops = new Array(
{color:"#FF0000", stopPercent:0},
{color:"#FFFF00", stopPercent:.125},
{color:"#00FF00", stopPercent:.375},
{color:"#0000FF", stopPercent:.625},
{color:"#FF00FF", stopPercent:.875},
{color:"#FF0000", stopPercent:1});
gameLoop();
}
</script>
</head>
<body>
<canvas id="canvasOne" width="600" height="200">
Your browser does not support HTML 5 Canvas.
</canvas>
</div>
</body>
</html>