简介
在 HTML 画布上使用视差处理,就可以在一个 2 维 (2D) 的绘图容器中显示
3 维 (3D) 的滚动效果。基本理念是通过使用分层效果(其中每个图层以不同的速度滚动)制作一个显示 3D
效果的动画。例如,图层可以通过前景、中景和背景来产生距离错觉。这种视觉错觉类似于开车时看到的场景:距您较近的物体移动得很快,远处的物体似乎移动得要慢得多。有几种方法可以实现
3D 滚动视觉效果。
在本文中,我们将了解如何使用 HTML 画布在一个 2D 绘图容器中创建一个
3D 错觉。可以先创建图层,然后将它们结合起来,使得在一个图形中产生距离错觉。然后,本文将展示如何使用
HTML5、jQuery 和 JavaScript 组合来创建一个视差动画。
视差处理图层
本文示例包括创建一辆位于山前天空下的四轮驱动汽车,以及向其添加动画效果。第一步是创建在动画中用作图层的图形。使用视差处理,就会产生一个分层效果,其中图层以不同的速度滚动。视差环境中图形的选择是产生视觉效果的关键。这些图形必须被分离并以某种方式保存,这样才能产生深度错觉,并增加以不同速度滚动的动画效果。
创建一组图形实现视差错觉时,需要考虑以下几点:
您要创建的图层深度是多少?本文示例使用 3 个图层。
您的所有图层,除了背景图层外,都应该是透明的。在本例中,天空背景应该是一个
.jpg 文件,而山脉和四轮驱动汽车都应该是透明的 .png 文件。
考虑到互补和对比图形产生预期视觉效果(附近事物移动得更快)或者某些更为前卫的效果(图层几乎是独立的)。在我们的示例中,期望产生视觉效果,而非前卫效果。
您的图形应该具有无缝边缘。
背景
首先打开您选择的图像编辑软件。本文示例所用的是 Adobe Photoshop。
要创建的第一个图形是天空,天空图形不需要透明,因为它将被用作场景的背景图层。其他所有图层位于天空图形之前,而它下面什么都没有。天空图形的大小应该是
800x300 像素,这为您在最终的 HTML5 画布(400 像素宽)中为该图形添加动画效果留有一定空间。本例中,用作背景的天空插图大小设定为
800x300 像素,保存为 sky.jpg,如 图 1 所示。
图 1. 动画场景背景图层
中景
接下来您需要创建的图形,中景图层,是一个山脉插图。山脉图形的大小也是 800x300
像素。然而,山脉只覆盖此图形的底部,所以山脉上的背景是透明的。要呈现天空背景的透明性,需将山脉图形保存为一个透明的
PNG 文件。您不能使用 GIF,因为抗锯齿功能将创建一个锯齿边缘效果,而不是一个光滑的无缝边缘。图 2
显示山脉图形,正如在 Photoshop 中显示的那样具有透明性。您可以看到空像素(正如在 Photoshop
中表现的)。
图 2. 山脉图形中间图层
前景
最后要创建的是前景图形。本例使用一个四轮驱动汽车,因为它非常适合该示例的动画场景。这个图形有一些特点;它没有也无需与背景和中景图形有相同的宽度。要使它看起来有一定真实感,您需要为该动画汽车创建几个不同阶段。图
3 显示该汽车的 3 个阶段,每个实例中车轮和轮毂都有轻微旋转。
图 3. 四轮驱动汽车图形前景图层
在视差动画中使用时,汽车图形将被裁切,一次仅显示一个汽车实例。随着动画的继续进行,通过在创建的裁切窗口内重新定位面板上
x 来更改实例。
现在图形已经准备就绪,下一步就是创建视差错觉效果。
创建视差处理函数
本文中用于完成视差错觉效果的语言是 HTML5 和 jQuery(以及少许
JavaScript)。HTML5 仅用于 HTML 页面,因为它只包含 HTML <canvas>
元素,正如 清单 1 所示。
清单 1. 使用 <canvas> 元素的 HTML5 文件结构
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <title>Parallax Processing</title> </head>
<body>
<canvas id="parallax-canvas" width="400"
height="300">
Sorry, your browser does not support HTML5 Canvas.
</canvas>
<script type="text/javascript"
src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
</script>
<script type="text/javascript" src="assets/js/parallax-processing.js"></script>
</body>
</html> |
清单 1 包括一个关于 Google 内容交付网络 (CDN) 的 jQuery
库引用。它也包含一个 parallax-processing.js 文件引用,用于编写自定义 jQuery
来实现视差效果。
在视差处理文件中,您必须做的第一件事就是定义用于整个脚本的所有变量值。
设置 HTML 的视差需要为 <canvas> 添加宽度和高度的元素。因为这些变量将用于整个脚本,将其命名为
w 和 h,并减少访问它们所用的代码。
创建完成后,Image 对象的 src 属性值为一个可以将图像引用到 Web
服务器上的文件路径。
对于每个创建的图像,设置几个定位值来实现放置和动画。天空图像有两个相关变量:skydx,定义在每个动画间隔之间移动天空图像的距离(如下所述),以及
skyx,定义从其中分割天空图像的 x 坐标。山脉图形也有两个变量,它们的目的相同,惟一的不同之处是它们特定于山脉图形:mountainsdx
和 mountainsx。
汽车图形有点不同,有 4 个相关变量:
jeepx 是 x 坐标,在本例中,x 坐标设置为 100,这样在 400
像素宽的画布中就可将其定位在稍微偏离中心的位置。
坐标设置为 210,将汽车定位在靠近画布底部,这样汽车看起来就像是位于山脉正前方。
jeepsx 设置图形的 x 坐标。
jeepsXWidth 是 x 坐标偏移量,调节每个汽车实例的宽度。
清单 2. 视差处理文件中的
JavaScript 变量
var w = $("#parallax-canvas").width(); var h = $("#parallax-canvas").height();
var sky = new Image();
sky.src = "assets/img/sky.jpg";
var skydx = 2; // Distance to move sky image
var skyx = 0; // x coord to slice sky image
var mountains = new Image();
mountains.src ="assets/img/mountains.png";
var mountainsdx = 10; // Amount to move mountain
image
var mountainsx = 0; // x coord to slice mountain
image
var jeep = new Image();
jeep.src ="assets/img/jeep.png";
var jeepx = 100; // x coord of jeep image
var jeepy = 210; // y coord of jeep image
var jeepsx = 0; // x coord to slice jeep image
var jeepsxWidth = 155; // x coord offset for slice
jeep width
var cntx = $("#parallax-canvas")[0].getContext("2d");
setInterval(draw, 10, cntx); |
cntx 变量是 <canvas> 元素 getContext
方法的一个引用。在 HTML5 中,<canvas> 元素是一个自身拥有许多方法和属性的对象。getContext
方法是其中一个属性,需要使用 JavaScript 来绘制一个矩形。这个矩形将被用作 “场景” 的绘图板。最后,setInterval
调用设置为每 10 毫秒一次,调用一个自定义 draw 函数并将其传递给 contx 变量。
setInterval,是本例中视差处理的一个重要部分,将定期更新汽车、山脉以及天空图形的位置,这就是自定义
draw 函数起作用的地方。draw 函数接收一个 cntx 参数,参阅您之前引用的上下文对象(参见 清单
3)。第一个函数调用一个自定义 drawRectangle 方法,根据您之前指定的宽度和高度在画布上绘制一个矩形。
清单 3. 自定义 draw
和 drawRectangle 函数
function draw(_cntx) { drawRectangle(_cntx, 0, 0, w, h); _cntx.drawImage(sky, skyx, 0, 300, 300, 0, 0, w, 300); _cntx.drawImage(mountains, mountainsx, 0, 300, 300, 0, 0, w, 300); _cntx.drawImage(jeep, jeepsx, 0, jeepsxWidth, 60, jeepx, jeepy, 155, 60); }
function drawRectangle(_cntx, x, y, w, h) {
_cntx.beginPath();
_cntx.rect(x,y,w,h);
_cntx.closePath();
_cntx.fill();
_cntx.stroke();
} |
然后,使用 Context 对象的 drawImage 方法绘制每个图像,drawImage
方法包括几个参数,如 表 1 所述。
表 1. 参数、值和 drawImage 描述
参数 |
值 |
描述 |
img |
image、video 或 canvas |
表示绘图中所用的图像对象。 |
x |
x-coordinate |
相当于 x 坐标,定位图像左上角位置。 |
y |
y-coordinate |
相当于 y 坐标,定位图像左上角位置。 |
width |
width |
图像的像素宽度。 |
height |
height |
图像的像素高度。 |
dx |
x-coordinate |
相当于图像裁切部分的 x 坐标。 |
dy |
y-coordinate |
相当于图像裁切部分的 y 坐标。 |
dwidth |
width |
图形裁切部分的宽度。 |
dwidth |
height |
图形裁切部分的高度。 |
图像最初使用自定义 draw 函数在画布上进行绘制时,绘制结果看起来像 图 4 所示,天空是背景,山脉是中景,而四轮驱动汽车是前景
图 4. 用于视差处理的整套图层
动画
最后一步是为图形添加动画,创建视差错觉效果。有几种方法可以启动动画。例如,将鼠标移动到图形左边或右边、或者在键盘上按箭头键时汽车会出现运动。本文示例是基于键盘左右箭头来运作的。要创建这些功能,使用
jQuery 将 keydown 事件应用到 window 对象。每当用户在 Web 页面上时,将 keydown
事件应用到 window 对象是为了确保捕获按键。
keydown 事件接收一个 event 对象参数,通过检查 keyCode
属性确定用户键盘上按下了哪个键。左箭头的 keyCode 属性值为 37,右箭头的 keyCode 属性值为
39。按下其中一个键时,进行计算,根据每个新 Image 对象的初始变量集,更新天空、山脉和汽车相关变量,如
清单 4 所示。这些计算更新变量,并将最终以不同的速度为每个图层添加动画。
清单 4. 用于计算图层位置的
Keydown 事件
$(window).keydown(function(evt) { switch (evt.keyCode) { case 37: // Left arrow if ((skyx + skydx) > skydx) skyx -= skydx; else skyx = w; if ((mountainsx + mountainsdx) > mountainsdx) mountainsx -= mountainsdx; else mountainsx = 398; if (jeepsx > 0) jeepsx -= jeepsxWidth; else jeepsx = (jeepsxWidth*2); break; case 39: // Right arrow if ((skyx + skydx) < (w - skydx)) skyx += skydx; else skyx = 0; if ((mountainsx + mountainsdx) < (w - mountainsdx)) mountainsx += mountainsdx; else mountainsx = 0; if (jeepsx < (jeepsxWidth*2)) jeepsx += jeepsxWidth; else jeepsx = 0; break; } }); |
图形运动实际上在自定义 draw 函数中出现,但是,所有变量值在 keydown
事件中更新,这取决于用户的意图。更新值与 draw 函数共同创建真实的视差效果,从而产生深度上的错觉和真实世界的运动。这些都完成后,重要的是将所有脚本包装到一个文档
ready 事件中,从而确保在尝试操作之前文档已准备好,且所有 HTML 元素都可用于操作。
结束语
创建视差动画的选择有无限种,但您的创造力是有限的。例如,您可以创造一个纵向动画,类似于示例中的横向动画,都是基于鼠标移动、浏览器滚动或者键盘来运作。参考资料
部分包含一些使用不同技术和小部件轻松实现视差处理的其他示例。
参考资料
jParallax:使用该 JavaScript 库来帮助您的视差开发。
<canvas>:了解如何使用 HTML5 <canvas>
在一个 Web 页面中绘制动态图形。
“实现 HTML5 和 CSS3 的跨浏览器功能”(developerWorks,2011
年 2 月):了解能够在所有主要浏览器的最新版本上使用的特定 HTML5 和 CSS3 技术,这些浏览器包括
Safari、Internet Explorer、Firefox 和 Chrome。
developerWorks jQuery 库:查找有关 jQuery
的文章、博客和论坛。
Google Libraries API:获取 jQuery 库的 CDN
版本。
developerWorks 中国网站 Web 开发专区:查找涵盖各种基于
Web 解决方案的文章。查看 Web 开发技术库,获取广泛的技术文章和技巧、教程、标准和 IBM 红皮书。
developerWorksLive! 技术讲座:快速了解 IBM 产品和工具,以及
IT 行业趋势。
developerWorks 演示中心:观看面向初学者的产品安装和设置演示,以及为经验丰富的开发人员提供的高级功能。
Twitter 上的 developerWorks:立即加入并关注 developerWorks
推文。
|