首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

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

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() polyfill
1
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:定义单词 polyfillpolymorphism(多态)和 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 的实现很有趣,但不必理解它;相反,您只需要了解如何使用它即可,我会在下一节说明这一点。
返回列表