HTML5探秘:用requestAnimationFrame优化Web动画


Posted in HTML / CSS onJune 03, 2018

requestAnimationFrame是什么?

在浏览器动画程序中,我们通常使用一个定时器来循环每隔几毫秒移动目标物体一次,来让它动起来。如今有一个好消息,浏览器开发商们决定:“嗨,为什么我们不在浏览器里提供这样一个API呢,这样一来我们可以为用户优化他们的动画。”所以,这个requestAnimationFrame()函数就是针对动画效果的API,你可以把它用在DOM上的风格变化或画布动画或WebGL中。

使用requestAnimationFrame有什么好处?

浏览器可以优化并行的动画动作,更合理的重新排列动作序列,并把能够合并的动作放在一个渲染周期内完成,从而呈现出更流畅的动画效果。比如,通过requestAnimationFrame(),JS动画能够和CSS动画/变换或SVG SMIL动画同步发生。另外,如果在一个浏览器标签页里运行一个动画,当这个标签页不可见时,浏览器会暂停它,这会减少CPU,内存的压力,节省电池电量。

requestAnimationFrame的用法

// shim layer with setTimeout fallback
window.requestAnimFrame = (function(){
  return  window.requestAnimationFrame       ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame    ||
          function( callback ){
            window.setTimeout(callback, 1000 / 60);
          };
})();


// usage:
// instead of setInterval(render, 16) ....

(function animloop(){
  requestAnimFrame(animloop);
  render();
})();
// place the rAF *before* the render() to assure as close to
// 60fps with the setTimeout fallback.

对requestAnimationFrame更牢靠的封装

Opera浏览器的技术师Erik Möller 把这个函数进行了封装,使得它能更好的兼容各种浏览器。你可以读一读这篇文章,但基本上他的代码就是判断使用4ms还是16ms的延迟,来最佳匹配60fps。下面就是这段代码,你可以使用它,但请注意,这段代码里使用的是标准函数,我给它加上了兼容各种浏览器引擎前缀。

(function() {
    var lastTime = 0;
    var vendors = ['webkit', 'moz'];
    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
        window.cancelAnimationFrame =
          window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
    }

    if (!window.requestAnimationFrame)
        window.requestAnimationFrame = function(callback, element) {
            var currTime = new Date().getTime();
            var timeToCall = Math.max(0, 16 - (currTime - lastTime));
            var id = window.setTimeout(function() { callback(currTime + timeToCall); },
              timeToCall);
            lastTime = currTime + timeToCall;
            return id;
        };

    if (!window.cancelAnimationFrame)
        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        };
}());

我来看看使用requestAnimationFrame的效果

 requestAnimationFrame API

window.requestAnimationFrame(function(/* time */ time){
  // time ~= +new Date // the unix time
});

 回调函数里的参数可以传入时间。

各种浏览器对requestAnimationFrame的支持情况
谷歌浏览器,火狐浏览器,IE10+都实现了这个函数,即使你的浏览器很古老,上面的对requestAnimationFrame封装也能让这个方法在IE8/9上不出错。

HTML / CSS 相关文章推荐
CSS3的颜色渐变效果的示例代码
Sep 29 HTML / CSS
详解CSS 3 中的 calc() 方法
Jan 12 HTML / CSS
css和css3弹性盒模型实现元素宽度(高度)自适应
May 15 HTML / CSS
HTML5 video视频字幕的使用和制作方法
May 03 HTML / CSS
HTML5之SVG 2D入门6—视窗坐标系与用户坐标系及变换概述
Jan 30 HTML / CSS
探索HTML5本地存储功能运用技巧
Mar 02 HTML / CSS
纯HTML5+CSS3制作生日蛋糕(代码易懂)
Nov 16 HTML / CSS
详解HTML5之pushstate、popstate操作history,无刷新改变当前url
Mar 15 HTML / CSS
解锁canvas导出图片跨域的N种姿势小结
Jan 24 HTML / CSS
Html5自定义字体解决方法
Oct 09 HTML / CSS
canvas绘制太极图的实现示例
Apr 29 HTML / CSS
CSS实现两列布局的N种方法
Aug 02 HTML / CSS
html5触摸事件判断滑动方向的实现
Jun 05 #HTML / CSS
使用Canvas操作像素的方法
Jun 14 #HTML / CSS
Html5移动端获奖无缝滚动动画实现示例
Jun 25 #HTML / CSS
video结合canvas实现视频在线截图功能
Jun 25 #HTML / CSS
详解Canvas事件绑定
Jun 27 #HTML / CSS
Html5剪切板功能的实现代码
Jun 29 #HTML / CSS
HTML5 使用 sessionStorage 进行页面传值的方法
Jul 02 #HTML / CSS
You might like
新手配置 PHP 调试环境(IIS+PHP+MYSQL)
2007/01/10 PHP
解析zend studio中直接导入svn中的项目的方法步骤
2013/06/21 PHP
php5.3不能连接mssql数据库的解决方法
2014/12/27 PHP
php实现对象克隆的方法
2015/06/20 PHP
php实现图片上传、剪切功能
2016/05/07 PHP
用Javascript 和 CSS 实现脚注(Footnote)效果
2009/09/09 Javascript
初窥JQuery(二)事件机制(2)
2010/12/06 Javascript
基于jquery的复制网页内容到WORD的实现代码
2011/02/16 Javascript
使用javascript获取页面名称
2014/12/23 Javascript
js实现表单Radio切换效果的方法
2015/08/17 Javascript
Bootstrap 树控件使用经验分享(图文解说)
2017/11/06 Javascript
webpack配置proxyTable时pathRewrite无效的解决方法
2018/12/13 Javascript
深入浅析vue全局环境变量和模式
2020/04/28 Javascript
JavaScript 面向对象程序设计详解【类的创建、实例对象、构造函数、原型等】
2020/05/12 Javascript
js实现九宫格布局效果
2020/05/28 Javascript
JavaScript TAB栏切换效果的示例
2020/11/05 Javascript
python查看列的唯一值方法
2018/07/17 Python
pytorch 模拟关系拟合——回归实例
2020/01/14 Python
Python 如何创建一个简单的REST接口
2020/07/30 Python
python操作链表的示例代码
2020/09/27 Python
Python中BeautifulSoup通过查找Id获取元素信息
2020/12/07 Python
美国婚礼和派对礼品网站:Kate Aspen(新娘送礼会、迎婴派对)
2018/03/28 全球购物
安德玛比利时官网:Under Armour比利时
2019/08/28 全球购物
园林施工员岗位职责
2013/12/11 职场文书
学校介绍信范文
2014/01/14 职场文书
大学国际贸易专业自荐信
2014/06/05 职场文书
品牌转让协议书
2014/08/20 职场文书
党的群众路线教育实践活动个人对照检查剖析材料
2014/09/23 职场文书
考试作弊检讨书怎么写?
2014/12/21 职场文书
本科毕业论文导师评语
2014/12/31 职场文书
幼儿园大班教师个人总结
2015/02/05 职场文书
我的1919观后感
2015/06/03 职场文书
周一早安温馨问候祝福语!
2019/07/15 职场文书
HTML5+CSS+JavaScript实现捉虫小游戏设计和实现
2021/10/16 HTML / CSS
python中的random模块和相关函数详解
2022/04/22 Python
Mysql如何查看是否使用到索引
2022/12/24 MySQL