下面是用HTML5的<canvas>标签写的一个视差滚动动画的示例。采用了制作动画或者游戏编程中常用的双缓冲技术:获取到页面中的Canvas对象之后,创建了一个与页面Canvas同样大小的Canvas对象。绘图时先将图像绘制到缓冲Canvas中,等到每一桢的图像绘制完全后在把整个缓冲Canvas绘制到页面Canvas中。前景、中景、远景的视差通过控制移动速度来实现。整个动画的绘制部分只使用了Context对象的drawImage()方法。
HTML code:
- <canvas id="canvas" width="600" height="400">
- <p>Your browser does not support the canvas element</p>
- </canvas>
JavaScript code:
- const FPS = 30;
- const SECONDS_BETWEEN_FRAMES = 1 / FPS;
- var bg0 = new Image();
- var bg1 = new Image();
- var bg2 = new Image();
- var x = 0;
- const RATE = 50 * SECONDS_BETWEEN_FRAMES;
- const WIDTH = 600;
- const HEIGHT = 320;
- var canvas;
- var canvasBuffer;
- var context;
- var contextBuffer;
- window.onload = init;
- function init() {
- bg0.src = "b0.png";
- bg1.src = "b1.png";
- bg2.src = "b2.png";
- canvas = document.getElementById("canvas");
- canvasBuffer = document.createElement("canvas");
- canvasBuffer.width = canvas.width;
- canvasBuffer.height = canvas.height;
- context = canvas.getContext("2d");
- contextBuffer = canvasBuffer.getContext("2d");
- context.clearRect(0, 0, canvas.width, canvas.height)
- contextBuffer.clearRect(0, 0, canvasBuffer.width, canvasBuffer.height);
- setInterval(animation, SECONDS_BETWEEN_FRAMES);
- }
- function animation() {
- x += RATE;
- context.clearRect(0, 0, canvas.width, canvas.height)
- contextBuffer.clearRect(0, 0, canvasBuffer.width, canvasBuffer.height);
- drawBuffer(bg0, 0, 0, 0.5);
- drawBuffer(bg1, 0, 100, 0.75);
- drawBuffer(bg2, 0, 100, 1);
- context.drawImage(canvasBuffer, 0, 0);
- }
- function drawBuffer(image, dx, dy, factor) {
- var left = (x * factor) % image.width;
- if (left + WIDTH >= image.width) {
- var d0 = image.width - left;
- var d1 = WIDTH - d0;
- contextBuffer.drawImage(image, left, 0, d0, HEIGHT, dx, dy, d0, HEIGHT);
- contextBuffer.drawImage(image, 0, 0, d1, HEIGHT, dx + d0, dy, d1, HEIGHT);
- }
- else {
- contextBuffer.drawImage(image, left, 0, WIDTH, HEIGHT, dx, dy, WIDTH, HEIGHT);
- }
- }
其中的setInternal()方法是动画动起来的核心方法。其原型如下:
int setInternal(code, millisec[, lang]);
其中code表示需要循环执行的代码或者方法(名),必需;millisec表示周期性循环的周期,单位是毫秒,必需;lang表示脚本语言的类型,如JScript、VBScript、JavaScript,可选,不过一般都直接忽略。返回值为一个可以传递给clearInternal()方法的值,从而取消循环。
setInternal()方法是HTML DOM的一个内建方法,其作用是按照指定的周期循环调用某一段代码或者某个方法,直到窗口关闭或者调用clearInternal()方法结束循环。
顺带一提的是在Canvas画布中绘制图形,一般情况下后绘制的会覆盖先绘制的,所以在绘制图像的时候需要先绘制远景b0,再绘制中景b1,最后绘制近景b2。
转自:http://www.html5china.com/HTML5features/canvas/20111207_3183.html