求知 文章 文库 Lib 视频 iProcess 课程 角色 咨询 工具 讲座 Modeler   Code  
会员   
 
  
每天15篇文章
不仅获得谋生技能
更可以追随信仰
 
 
     
   
分享到
在HTML5 2维画布上显示3维效果
 

发布于2013-5-27

 

简介

在 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 推文。

相关文章 相关文档 相关课程



深度解析:清理烂代码
如何编写出拥抱变化的代码
重构-使代码更简洁优美
团队项目开发"编码规范"系列文章
重构-改善既有代码的设计
软件重构v2
代码整洁之道
高质量编程规范
基于HTML5客户端、Web端的应用开发
HTML 5+CSS 开发
嵌入式C高质量编程
C++高级编程
 
分享到
 
 


十天学会DIV+CSS(WEB标准)
HTML 5的革新:结构之美
介绍27款经典的CSS框架
35个有创意的404错误页面
最容易犯的13个JavaScript错误
设计易理解和操作的网站
更多...   


设计模式原理与应用
从需求过渡到设计
软件设计原理与实践
如何编写高质量代码
单元测试、重构及持续集成
软件开发过程指南


东软集团 代码重构
某金融软件服务商 技术文档
中达电通 设计模式原理与实践
法国电信 技术文档编写与管理
西门子 嵌入式设计模式
中新大东方人寿 技术文档编写
更多...   
 
 
 
 
 
每天2个文档/视频
扫描微信二维码订阅
订阅技术月刊
获得每月300个技术资源
 
 

关于我们 | 联系我们 | 京ICP备10020922号 京公海网安备110108001071号