`

基于脚本的动画的计时控制(“requestAnimationFrame”)(转载)

阅读更多

Internet Explorer 10 和使用 JavaScript 的 Windows 应用商店应用引入了对requestAnimationFrame 方法的支持,该方法通过在系统准备好绘制动画帧时调用该帧,从而为创建动画网页提供了一种更平滑更高效的方法。在此 API 之前,使用 setTimeout 和 setInterval 绘制的动画并没有为 Web 开发人员提供有效的方法来规划动画的图形计时器。这导致了动画过度绘制,浪费 CPU 周期以及消耗额外的电能等问题。而且,即使看不到网站,特别是当网站使用背景选项卡中的页面或浏览器已最小化时,动画都会频繁出现。

当动画使用分辨率为 10ms 的 JavaScript 计时器绘制动画时,计时可能不匹配,如下所示。

图例显示了显示器频率和 JavaScript 计时器分辨率之间的频率差异

上面一行表示大多数监视器上显示的 16.7ms 显示频率,而下面一行表示通常的 10ms setTimeout。每个第三个图形都无法绘制(由红色箭头指示),因为在显示器刷新间隔之前发生了其他绘制请求。这种过度绘制的情况会导致动画断续显示,因为所有第三帧都会丢失。这种计时器分辨率的降低也会对电池使用寿命造成负面影响,并会降低其他应用的性能。

requestAnimationFrame 方法(在万维网联合会 (W3C) 的针对基于脚本的动画的计时控制规范中定义)可以解决丢失帧的问题,因为它使应用能够在浏览器需要更新页面显示时(而且仅在这种情况下)获得通知。 因此,应用可与浏览器的绘制时间间隔保持完全一致,并且仅使用适量的资源。从 setTimeout 切换到 requestAnimationFrame 非常容易,因为它们都规划单个回调。要实现持续的动画,请在调用动画函数后再次调用 requestAnimationFrame

 

使用 requestAnimationFrame

要使用这个新的 API,只需使用回调函数调用 requestAnimationFrame 即可。计时由系统处理。 如果当前使用setTimeout 来驱动动画计时,如下所示:

 
var handle = setTimeout(renderLoop, PERIOD);

你可以将 setTimeout 替换为 requestAnimationFrame,如下所示:

 
var handle = requestAnimationFrame(renderLoop);

这会影响你的第一个重画。若要保持动画继续运行,则需要从回调函数(如此处的 renderLoop)中再次调用requestAnimationFrame

 
<!DOCTYPE html>
<html>
  <head>
    <title>Script-based animation using requestAnimationFrame</title>
    <style type="text/css">
     #animated { 
       position: absolute; top:100px; 
       padding: 50px; background: crimson; color: white; 
       }
    </style>

 
  </head>
  <body>
    <div>Click the box to stop it</div>
    <div id="animated">Hello there.</div>
   
    <script type="text/javascript">
      // global variables 
      var elm = document.getElementById("animated");
      var handle = 0;
      var lPos = 0;

      renderLoop(Date.now);  // call animation frame to start

      function renderLoop(time) {
          elm.style.left = ((lPos += 3) % 600) + "px";
          handle = window.requestAnimationFrame(renderLoop);
      }

      // click the box to stop the animation 
      document.getElementById("animated").addEventListener("click", function () {
        if (handle) {
          window.cancelAnimationFrame(handle);
          }
        }, false);
      </script>

  </body>
</html>


本示例使用 getElementById 将 <div> 元素保存到一个全局变量。调用 renderLoop() 函数以开始动画。在重新定位 <div> 元素后,再次调用 requestAnimationFrame 以设置下一次移动。此操作将继续执行,直至你关闭浏览器或单击 <div> 元素为止。

addEventListener 方法处理 <div> 元素上的单击事件。当你单击该元素时,将使用当前句柄调用cancelAnimationFrame

回调函数中的时间

你可以使用回调函数对几乎所有内容(如 SVG、Canvas 或此处所示的 CSS 属性)设置动画。回调函数具有一个传入time 参数,该参数表示调用回调函数的时间。它是一个 DOMHighResTimeStamp,是从页面导航开始时测量的高精确度时间。DOMHighResTimeStamp 以毫秒为单位,精确到千分之一毫秒。此时间值不直接与 Date.now() 进行比较,后者测量自 1970 年 1 月 1 日至今以毫秒为单位的时间。如果你希望将 time 参数与当前时间进行比较,请使用当前时间的window.performance.now。将时间值从 DOMTimeStamp 更改为 DOMHighResTimeStamp 是 W3C 针对基于脚本动画计时控制规范的最新编辑草案中的最新更改,并且某些供应商仍将其作为 DOMTimeStamp 实现。较早版本的 W3C 规范使用 DOMTimeStamp,允许你将 Date.now 用于当前时间。

浏览器支持

如上所述,某些浏览器供应商可能仍实现 DOMTimeStamp 参数,或者尚未实现 window.performance.now 计时函数。由于 W3C 规范尚未最后定稿,因此其他浏览器制造商已创建其自己的 requestAnimationFrame 和cancelAnimationFrame 前缀实现。本例提供了一个我们的动画程序版本,该程序使用 Time 移动 <div> 元素并在多个浏览器上使用。

 
<!DOCTYPE html>
<html>
<head>
<title>Script-based animation using requestAnimationFrame</title>
<style type="text/css">
div { position: absolute; left: 10px; top:100px; padding: 50px;
  background: crimson; color: white }
</style>
<script type="text/javascript">
    var requestId = 0;
    var startime = 0;
    var elm;

    function init() {
        elm = document.getElementById("animated");
    }
    
    function render(time) {
        elm.style.left = ((time - startime) / 4 % 600) + "px";
        requestId = window.requestAFrame(render);
    }

    function start() {
        if (window.performance.now) {
            startime = window.performance.now();
        } else {
            startime = Date.now();
        }
        requestId = window.requestAFrame(render);s
    }
    function stop() {
        if (requestId)
            window.cancelAFrame(requestId);        
    }


    // handle multiple browsers for requestAnimationFrame()
    window.requestAFrame = (function () {
        return window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame ||
                // if all else fails, use setTimeout
                function (callback) {
                    return window.setTimeout(callback, 1000 / 60); // shoot for 60 fps
                };
    })();

    // handle multiple browsers for cancelAnimationFrame()
    window.cancelAFrame = (function () {
        return window.cancelAnimationFrame ||
                window.webkitCancelAnimationFrame ||
                window.mozCancelAnimationFrame ||
                window.oCancelAnimationFrame ||
                function (id) {
                    window.clearTimeout(id);
                };
    })();

   
</script>
</head>
<body onload="init();">

<div id="animated">Hello there.</div>
<button onclick="start()">Start</button>
<button onclick="stop()">Stop</button>
</body>
</html>


本例是 W3C 规范的一个扩展示例,添加了供应商前缀元素。此外,本例还对 window.performance.now 进行测试,如果不支持此函数,则使用 Date.now 获取当前时间。

API 参考

requestAnimationFrame

示例和教程

使用 requestAnimationFrame 示例的高效动画

有关 Internet Explorer 的 Test Drive 演示

气泡
requestAnimationFrame API

规范

基于脚本的动画的计时控制
原文地址:

http://msdn.microsoft.com/zh-cn/library/ie/hh920765(v=vs.85).aspx#multiplebrowsers

 

相关链接:http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/

分享到:
评论

相关推荐

    时间倒计时显示页面特效脚本.zip

    本资源“时间倒计时显示页面特效脚本.zip”提供了一种实现此类功能的方法,适用于网页开发者。下面我们将详细探讨这个脚本涉及的技术和知识点。 1. **HTML**: HTML(HyperText Markup Language)是网页内容的基础...

    jQuery+css3制作精美的2020圣诞节倒计时页面动画特效代码.zip

    在这个名为"jQuery+css3制作精美的2020圣诞节倒计时页面动画特效代码.zip"的压缩包中,我们找到了一个利用jQuery和CSS3技术实现的2020年圣诞节倒计时页面动画特效。这个项目展示了如何将这两种强大的前端技术结合,...

    基于HTML5和CSS3二进制计时器.zip

    CSS3则提供了更高级的样式控制和动画效果。在这个二进制计时器中,CSS3可能被用来定义每个二进制数字的样式,如颜色、大小、位置等,以及实现计时器数字切换时的平滑过渡效果,这可能涉及到`transition`或`animation...

    36个javascript脚本

    这些脚本可能使用requestAnimationFrame或setTimeout/clearTimeout来实现帧级别的动画控制。 5. **AJAX**:异步JavaScript和XML技术使得脚本可以在不刷新整个页面的情况下与服务器交换数据并更新部分网页内容。这些...

    javascript制作js逐帧动画.zip

    在JavaScript中,我们可以利用时间戳(timestamp)和requestAnimationFrame函数来控制每一帧的显示,以实现平滑的动画效果。 1. **requestAnimationFrame**: 这是HTML5引入的一个高性能、节能的动画方法。相比于...

    1小时小球倒计时

    对于彩球的运动,可能使用`requestAnimationFrame`来创建流畅的动画效果,每次调用都更新每个彩球的位置,并在Canvas上重绘。 此外,JavaScript的Math库可能被用来生成随机颜色、位置和速度。例如,`Math.random()`...

    HTML5_JavaScript动画基础(高清带目录)

    可以使用`requestAnimationFrame`来创建一个流畅且节省资源的动画循环。 2. 时间和帧率:控制动画的速度通常涉及到时间和帧率(每秒帧数FPS)。为了使动画表现平滑,你需要计算每一帧动画应该执行的时间点。 3. ...

    html5 canvas圆形计时器特效.zip

    此外,为了实现动画效果,通常会使用`requestAnimationFrame()`函数。这是一个浏览器提供的API,用于在下一次重绘之前执行指定的函数,这使得我们可以连续地更新计时器的视觉状态,创造出平滑的动画效果。 在压缩包...

    网站维护倒计时页面Html5代码.7z

    在`js`目录中的脚本文件可能包含了一个计时器函数,用于实时更新倒计时显示,以及一个模拟弹球掉落的动画效果。这可能涉及到DOM操作(Document Object Model),例如通过`document.getElementById`获取元素并修改其...

    js写的倒计时功能,简单漂亮交互好

    8. **性能优化**:为了提高用户体验,可能会采用一些性能优化技巧,比如减少DOM操作的频率,使用requestAnimationFrame()进行平滑动画,以及利用缓存减少不必要的计算。 9. **状态管理**:如果倒计时功能涉及到多个...

    收集很久的炫酷JS +CSS 特效代码(登陆 注册 按钮 导航 抽奖 动画相册 等)

    1. **JS与CSS基础**:JS是负责网页动态行为的脚本语言,而CSS则用于控制网页布局和样式。在这些特效中,JS处理用户交互、数据处理和动画逻辑,而CSS负责静态样式和部分动画效果。 2. **登录与注册界面**:这些特效...

    JS个性Hello文字动画特效.rar

    为了实现这样的动画效果,开发者通常会使用JavaScript的时间轴或者计时器函数,如`setInterval`或`requestAnimationFrame`。这些函数可以按照设定的时间间隔重复执行某段代码,从而实现连续的动作。此外,还可能结合...

    情人节表白放烟花动画特效.zip

    可能使用了setTimeout或requestAnimationFrame来实现定时执行动画帧,以达到流畅的动画效果。此外,JavaScript还可以用来生成随机烟花的颜色、大小、发射角度,使动画看起来更加自然和多变。 为了实现烟花的动态...

    JS 系列计时器资料.rar

    JavaScript(简称JS)是网页开发中的重要脚本语言,它为开发者提供了丰富的功能,其中之一就是计时器。计时器在网页动态效果、用户交互以及数据定时更新等方面扮演着关键角色。"JS系列计时器资料.rar"这个压缩包包含...

    Canvas粒子十秒倒计时特效.zip

    开发者可能会使用定时器(setTimeout或requestAnimationFrame)来实现每秒更新粒子状态和倒计时数值,确保计时的准确性和流畅性。 4. **jQuery库**: 虽然标签中提到了jQuery特效,但在Canvas特效中,jQuery通常用于...

    JS+CSS3日历本挂历点击掉落动画特效.zip

    可能使用了DOM操作来改变元素的状态,以及计时器(setTimeout或requestAnimationFrame)来控制动画的帧率和流畅度。 总结来说,"JS+CSS3日历本挂历点击掉落动画特效.zip"是一个利用HTML5、CSS3和JavaScript技术创建...

    新年倒计时和准点烟花特效

    开发者可能使用了requestAnimationFrame来实现平滑的动画效果,并结合canvas元素进行图形绘制,以实现自定义的烟花效果。 为了将Vue3应用转化为HTML,开发者需要将项目打包,这通常通过Webpack或Vite等构建工具完成...

    leftTime.js倒计时插件

    8. **性能优化**:频繁的DOM操作可能导致页面渲染卡顿,因此插件可能采用更高效的方式更新倒计时,比如使用`requestAnimationFrame`来同步动画与浏览器的渲染周期。 9. **可定制性**:一个好的倒计时插件应允许...

    26、Jqueryhtml5悬浮圆圈背景动画特效

    5. **优化性能**:考虑到性能,可以考虑使用requestAnimationFrame API,代替setTimeout和setInterval,这样可以更高效地控制动画帧率,提高用户体验。 6. **更多资源**:提供的“更多资源.txt”文件中可能会包含...

    JS实现的超逼真闹钟动画效果源码.zip

    在这个项目中,JavaScript被用来控制闹钟的计时、动画和用户交互。 2. **DOM操作**:Document Object Model (DOM) 是HTML和XML文档的结构表示。JavaScript通过DOM可以查找、访问和修改网页元素。此项目可能涉及到...

Global site tag (gtag.js) - Google Analytics