《HTML5 2D游戏编程核心技术》——第3章,第3.2节实现平滑的HTML5动画

简介:

本节书摘来自华章出版社《HTML5 2D游戏编程核心技术》一书中的第3章,第3.2节,作者[美] 戴维·吉尔里,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.2 实现平滑的HTML5动画
简单地说,编程实现动画效果是简单的:你不断地绘制一个图像序列,产生图像正在以某种方式运动的效果。同样,这也意味着你需要实现一个能够持续绘制图像的循环。
传统的做法是,动画循环在JavaScript中使用setTimeout()函数或者使用程序清单3.4描述的setInterval()函数来实现。
如果实现了一个draw()函数来绘制下一个动画帧,程序清单3.4中的代码将会通过持续地调用这个函数来绘制一段动画。但是,你可能会对这个结果感到不满意,因为setInterval()函数和setTimeout()函数根本不知道如何完成动画,而且也不能精确到毫秒。
程序清单3.4 使用setInterval()函数绘制动画


7a5842c880e8a992dd4b373e0a5c412147c46d28

程序清单3.4中的代码每1000/60毫秒调用一次draw()函数,等价于每秒60帧。这个速率是帧速率的一个最优估计,既然是一个估计,它就不是很精确。
我们必须能够预估绘制下一个动画帧的最佳时间,因为setInterval()函数和setTimeout()函数并不知道任何关于动画的事情,因此需要开发人员来确定帧速率。如果浏览器知道什么时候绘制下一个动画帧,而不是依赖于开发人员,就更完美了。
使用setTimeout()和setInterval()有一个更为严重的问题。尽管你向这些函数提供了毫秒级的时间间隔,但是这些函数的精确度达不到毫秒级。事实上,根据HTML指南,为了节约资源,这些方法会慷慨地向你提供所要求的时间间隔。
为了确保动画的平滑度,你不应该使用setTimeout()和setInterval()来完成对时间有苛刻要求的动画,你应该使用requestAnimationFrame()来代替,这将在下一节讨论。
连环画
在讲解动画和电影之前,我们先聊聊“连环画”。假如书的每一页都包含一些图像,这些图像和前一页相比都有微小的变化,当你翻书时,就会产生出运动的假象。连环画最早是因为Cracker Jack(爆米花和坚果混合的甜食)流行起来的,在Cracker Jack食品的包装盒里会包含它作为奖品。
今天我们在视频游戏中实现动画的技术和连环画类似。但它不像一本书包含有限的页数,视频游戏会有一个永不停止的动画帧流,同连环画一样,游戏的动画帧在毫秒级的时间间隔里显示一个静态的图片,随着时间的流逝,这个图片会逐渐改变内容。

对时间要求苛刻的动画,应使用requestAnimationFrame()函数,而不是使用setTime-out()或者setInterval()函数。

3.2.1 requestAnimationFrame()方法
一个名为“Timing Control for Script-based Animations”的W3C说明定义了request-AnimationFrame()窗口对象的方法。不同于setTimeout()和setInterval(),requestAnimation-Frame()是专门用来实现动画的。因此不会存在上面提到的有关setTimeout()和setInterval()的缺点。它也很容易使用,如程序清单3.5所示。
传递给requestAnimationFrame()一个回调函数的引用,当浏览器准备绘制下一个动画帧时,它会回调该回调函数。为了维护动画,回调函数也会调用requestAnimationFrame(),用于在函数绘制下一帧时把自己标识为函数。
程序清单3.5 使用requestAnimationFrame()绘制动画


14420abfa1f729ae8e33dad6f7fdd772a0ef3de6

正如程序清单3.5所示,浏览器会传递给回调函数一个名为now的参数。你或许会对now参数的作用有疑惑。它是代表当前时间的字符串,还是代表自1970年1月1日以来过了多少秒,或者代表其他什么?
但是让人奇怪的是,这个时间没有一个统一的定义。唯一确定的是对于任何浏览器来说,它代表了相同的东西,因此你可以使用它来计算两个动画帧之间的时间间隔,3.4节将对此进行更详细的讲述。
3.2.2 requestAnimationFrame()的polyfill实现
从许多方面来看,HTML5都是开发者的乌托邦。因为有各种免费的专用API可以使用,开发人员使用HTML5实现的应用可以在各种浏览器平台和设备上运行。技术进步得非常快,会持续地增加新技术,并且重新定义已有的功能。
在实现新的技术标准时,不同的浏览器往往会因为浏览器自身固有的特性而采用不同的实现方法。因此浏览器开发商经常会在这个新功能的名字前面加上一个前缀,这样就不会妨碍其他浏览器实现类似的功能;例如,requestAnimationFrame()最早是由Mozilla实现的,称为mozRequestAnimationFrame()。之后其他浏览器厂商也实现了这个功能,如WebKit内核,其实现了webkitRequestAnimationFrame()函数。最后,W3C组织将它标准化为requestAnimationFrame()。
带有前缀的函数以及标准实现的不同支持情况让新功能很难被广泛应用,因此HTML5社区开发了一个名为polyf?ill的机制。polyf?ill机制也可以称为shim机制或者shiv机制,它决定了浏览器支持特定功能的能力。如果浏览器实现了该功能,它们会提供接口;如果没有实现该功能,则提供一个替代解决方案,用于模拟标准功能。
polyf?ills使用简单,但是很难开发。程序清单3.6显示了一个使用polyf?ill实现的request-AnimationFrame()。
程序清单3.6 requestAnimationFrame()的polyfill实现


3c47e4dd6791154576f4b7b9f45da60f6e20e1e6


6b40bf0cb58d2e8646643972daa233692550615b

程序清单3.6所示代码基于polyf?ill机制,在窗口对象中封装了一个名为requestNext-AnimationFrame()的函数。函数名字中的Next把它同默认的名字requestAnimationFrame()区分开来。
polyf?ill机制指向requestNextAnimationFrame()函数或者requestAnimationFrame()函数,又或是浏览器厂商已经实现的功能。如果浏览器不支持任何一个功能,函数将会调用函数setTimeout()来尽可能地模拟requestAnimationFrame()。
polyf?ill机制中几乎所有的复杂操作,包括对两个bug的处理,都在程序清单3.6中代码结尾处的return声明之前完成。第一个bug涉及Chrome 10,它传递了一个未定义的时间值。第二个bug涉及Firefox 4.0,它将帧速率限制在每秒35到40帧之间。
尽管polyf?ill机制中的requestNextAnimationFrame()函数实现很有趣,但你没有必要理解实现过程,你只需要了解如何使用就可以,这将在下一节中讲述。
对未来的规划,使用polyfills机制编程
过去,开发跨平台软件一直是开发人员的共同愿望。polyf?ill机制可以实现这个想法,在更高版本存在时,给你提供接口,不存在时,可以降低版本来完成最基本的功能。

+new Date()

+new Date()是JavaScript中获取当前时间的方法之一。加号将日期强制转换为数字。

requestAnimationFrame()与requestNextAnimationFrame()

这本书中,我们使用前面讨论的requestNextAnimationFrame()的polyf?ill实现,如果浏览器存在默认的requestAnimationFrame()就使用它,如果不存在,polyf?ill机制就会使用备用的解决方案运行。

相关文章
|
1月前
|
XML 编解码 前端开发
编程笔记 html5&css&js 033 HTML SVG
编程笔记 html5&css&js 033 HTML SVG
|
2天前
|
前端开发 搜索推荐 数据安全/隐私保护
HTML标签详解 HTML5+CSS3+移动web 前端开发入门笔记(四)
HTML标签详解 HTML5+CSS3+移动web 前端开发入门笔记(四)
13 1
|
1月前
|
移动开发 定位技术 API
编程笔记 html5&css&js 035 HTML 地理定位
编程笔记 html5&css&js 035 HTML 地理定位
|
1月前
|
XML 移动开发 数据格式
编程笔记 html5&css&js 034 HTML MathML
编程笔记 html5&css&js 034 HTML MathML
|
1月前
|
前端开发 JavaScript 容器
编程笔记 html5&css&js 032 HTML Canvas
编程笔记 html5&css&js 032 HTML Canvas
|
7天前
|
前端开发 JavaScript 开发工具
【HTML/CSS】入门导学篇
【HTML/CSS】入门导学篇
17 0
|
2天前
|
PHP
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
web简易开发——通过php与HTML+css+mysql实现用户的登录,注册
|
10天前
|
XML 前端开发 JavaScript
css和html
【4月更文挑战第7天】css和html
11 0
|
1月前
使用html+css制作一个发光立方体特效
使用html+css制作一个发光立方体特效
20 2
使用html+css制作一个发光立方体特效