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制作半透明边框(Facebox)类似渐变
Dec 09 HTML / CSS
CSS3过渡transition效果实例介绍
May 03 HTML / CSS
css3 矩阵的使用详解
Mar 20 HTML / CSS
详解CSS3弹性伸缩盒
Sep 21 HTML / CSS
CSS3实现的渐变幻灯片效果
Dec 07 HTML / CSS
HTML5新表单元素_动力节点Java学院整理
Jul 12 HTML / CSS
详解通过变换矩阵实现canvas的缩放功能
Jan 14 HTML / CSS
HTML5 placeholder(空白提示)属性介绍
Aug 07 HTML / CSS
基于HTML5的齿轮动画特效
Feb 29 HTML / CSS
解锁canvas导出图片跨域的N种姿势小结
Jan 24 HTML / CSS
canvas实现滑动验证的实现示例
Aug 11 HTML / CSS
AmazeUI 折叠面板的实现代码
Aug 17 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 MYSQL中插入当前时间
2008/04/06 PHP
PHP 时间日期操作实战
2011/08/26 PHP
php+mysqli数据库连接的两种方式
2015/01/28 PHP
yii gridview实现时间段筛选功能
2017/08/15 PHP
laravel 实现划分admin和home 模块分组
2019/10/15 PHP
JQuery 前台切换网站的样式实现
2009/06/22 Javascript
基于Jquery的回车成tab焦点切换效果代码(Enter To Tab )
2010/11/14 Javascript
关于锚点跳转及jQuery下相关操作与插件
2012/10/01 Javascript
用javascript将数据导入Excel示例代码
2014/09/10 Javascript
JavaScript代码应该放在HTML代码哪个位置比较好?
2014/10/16 Javascript
node.js中的console.time方法使用说明
2014/12/09 Javascript
jQuery实现鼠标经过事件的延时处理效果
2020/08/20 Javascript
JavaScript中的闭包
2016/02/24 Javascript
node.js实现端口转发
2016/04/14 Javascript
详解VUE中v-bind的基本用法
2017/07/13 Javascript
JavaScript原型对象原理与应用分析
2018/12/27 Javascript
9102年webpack4搭建vue项目的方法步骤
2019/02/20 Javascript
在vue-cli3.0 中使用预处理器 (Sass/Less/Stylus) 配置全局变量操作
2020/08/10 Javascript
Python基类函数的重载与调用实例分析
2015/01/12 Python
Python文件和目录操作详解
2015/02/08 Python
python机器学习实战之K均值聚类
2017/12/20 Python
Python数据结构与算法(几种排序)小结
2019/06/22 Python
Python音频操作工具PyAudio上手教程详解
2019/06/26 Python
pandas DataFrame 行列索引及值的获取的方法
2019/07/02 Python
python使用 __init__初始化操作简单示例
2019/09/26 Python
python如何查看网页代码
2020/06/07 Python
微信小程序之html5 canvas绘图并保存到系统相册
2019/06/20 HTML / CSS
Python面试题:Python是如何进行内存管理的
2014/08/04 面试题
事业单位竞聘上岗实施方案
2014/03/28 职场文书
租房合同协议书
2014/04/09 职场文书
四风查摆问题自查报告
2014/10/10 职场文书
医院办公室主任岗位职责
2015/04/01 职场文书
2015年环境监察工作总结
2015/07/23 职场文书
医院病假条范文
2015/08/17 职场文书
《詹天佑》教学反思
2016/02/20 职场文书
简单聊聊Golang中defer预计算参数
2022/03/25 Golang