HTML5 2D 游戏开发 图形和动画(3)HTML5 动画更新
 
- UID
- 1066743
|

HTML5 2D 游戏开发 图形和动画(3)HTML5 动画更新
一个 requestAnimationFrame() polyfill从许多方面来看,HTML5 是程序员的乌托邦。没有专用的 API,开发人员使用 HTML5 在无处不在的浏览器中实现跨平台运行的应用程序。规范发展迅速,不断采用新技术,同时改进现有的功能。
Polyfill:面向未来的编程过去,大多数跨平台软件都在最低的共同点实现。Polyfill 彻底颠覆了这一概念,它让您能够访问高级特性(如果它们可用),并在必要时回退到一个能力较低的实现。
然而,新技术要实行规范,往往是通过特定浏览器现有的功能来实现的。浏览器厂商通常为这样的功能添加了前缀,使它们不会干扰其他浏览器的实现;例如,requestAnimationFrame() 最初被 Mozilla 实现为 mozRequestAnimationFrame()。然后 WebKit 实现了它,将其函数命名为 webkitRequestAnimationFrame()。最后,W3C 将它标准化为 requestAnimationFrame()。
供应商提供了对前缀实现以及标准实现的不同支持,这使得新功能的使用变得非常棘手,所以 HTML5 社区发明了一种被称为 polyfill 的东西。Polyfill 针对特定功性确定浏览器的支持级别,如果浏览器已经实现了该功能,您就可以直接访问它,否则,浏览器会向您提供一个暂时尽量模仿标准功能的实现。
Polyfill 易于使用,但实现起来可能比较复杂。清单 6 演示了 requestAnimationFrame() 的一个 polyfill 的实现:
Listing 6. requestNextAnimationFrame() polyfill1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
| // Reprinted from Core HTML5 Canvas
window.requestNextAnimationFrame =
(function () {
var originalWebkitRequestAnimationFrame = undefined,
wrapper = undefined,
callback = undefined,
geckoVersion = 0,
userAgent = navigator.userAgent,
index = 0,
self = this;
// Workaround for Chrome 10 bug where Chrome
// does not pass the time to the animation function
if (window.webkitRequestAnimationFrame) {
// Define the wrapper
wrapper = function (time) {
if (time === undefined) {
time = +new Date();
}
self.callback(time);
};
// Make the switch
originalWebkitRequestAnimationFrame = window.webkitRequestAnimationFrame;
window.webkitRequestAnimationFrame = function (callback, element) {
self.callback = callback;
// Browser calls the wrapper and wrapper calls the callback
originalWebkitRequestAnimationFrame(wrapper, element);
}
}
// Workaround for Gecko 2.0, which has a bug in
// mozRequestAnimationFrame() that restricts animations
// to 30-40 fps.
if (window.mozRequestAnimationFrame) {
// Check the Gecko version. Gecko is used by browsers
// other than Firefox. Gecko 2.0 corresponds to
// Firefox 4.0.
index = userAgent.indexOf('rv:');
if (userAgent.indexOf('Gecko') != -1) {
geckoVersion = userAgent.substr(index + 3, 3);
if (geckoVersion === '2.0') {
// Forces the return statement to fall through
// to the setTimeout() function.
window.mozRequestAnimationFrame = undefined;
}
}
}
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback, element) {
var start,
finish;
window.setTimeout( function () {
start = +new Date();
callback(start);
finish = +new Date();
self.timeout = 1000 / 60 - (finish - start);
}, self.timeout);
};
}
)
();
|
Polyfill:定义单词 polyfill 是 polymorphism(多态)和 backfill(回填)的混合。类似于多态,polyfill 在运行时选择适当的代码,并且它们回填 (backfill) 了缺失的功能。
中实现的 polyfill 为 window 对象添加了一个名为 requestNextAnimationFrame() 的函数。函数名称中包含的 Next 使其能够区别于底层的 requestAnimationFrame() 函数。
该 polyfill 分配给 requestNextAnimationFrame() 的函数要么是 requestAnimationFrame()(如果浏览器支持它),要么是一个厂商前缀实现。如果浏览器对这两种方式均不支持,那么该函数会使用 setTimeout() 作为临时实现,以便尽可能地模仿 requestAnimationFrame()。
几乎所有 polyfill 复杂性都涉及解决两个错误并在 return 语句前构成代码。第一个错误涉及 Chrome 10,它为时间传递一个 undefined 值。第二个错误涉及 Firefox 4.0,它将帧速率限制为每秒 35-40 帧。
虽然 requestNextAnimationFrame() polyfill 的实现很有趣,但不必理解它;相反,您只需要了解如何使用它即可,我会在下一节说明这一点。 |
|
|
|
|
|