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动画和opacity透明度实现呼吸灯效果
Aug 09 HTML / CSS
CSS3教程(1):什么是CSS3
Apr 02 HTML / CSS
10 套华丽的CSS3 按钮小结
Oct 03 HTML / CSS
基于HTML5的WebSocket的实例代码
Aug 15 HTML / CSS
利用HTML5+css3+jquery+weui实现仿微信聊天界面功能
Jan 08 HTML / CSS
HTML5实践-图片设置成灰度图
Nov 12 HTML / CSS
HTML5 Web存储方式的localStorage和sessionStorage进行数据本地存储案例应用
Dec 09 HTML / CSS
基于HTML5的齿轮动画特效
Feb 29 HTML / CSS
HTML5中的强制下载属性download使用实例解析
May 12 HTML / CSS
HTML5 weui使用笔记
Nov 21 HTML / CSS
微信小程序canvas实现水平、垂直居中效果
Feb 05 HTML / CSS
从QQtabBar看css命名规范BEM的详细介绍
Aug 07 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 mkdir()定义和用法
2009/01/14 PHP
基于PHP对XML的操作详解
2013/06/07 PHP
php调用nginx的mod_zip模块打包ZIP文件
2014/06/11 PHP
PHP实现的一致性哈希算法完整实例
2015/11/14 PHP
php异步:在php中使用fsockopen curl实现类似异步处理的功能方法
2016/12/10 PHP
PHP实现上传多图即时显示与即时删除的方法
2017/05/09 PHP
PHP框架Laravel中使用UUID实现数据分表操作示例
2018/05/30 PHP
yii2 上传图片的示例代码
2018/11/02 PHP
详解PHP多个进程配合redis的有序集合实现大文件去重
2019/03/06 PHP
JS解密入门之凭直觉解
2008/06/25 Javascript
js读取json的两种常用方法示例介绍
2014/10/19 Javascript
轻松实现javascript数据双向绑定
2015/11/11 Javascript
jquery实现横向图片轮播特效代码分享
2015/11/19 Javascript
JavaScript使用DeviceOne开发实战(三)仿微信应用
2015/12/02 Javascript
详解JavaScript中localStorage使用要点
2016/01/13 Javascript
让nodeJS支持ES6的词法----babel的安装和使用方法
2017/07/31 NodeJs
JS遍历DOM文档树的方法实例详解
2018/04/03 Javascript
jQuery+Datatables实现表格批量删除功能【推荐】
2018/10/24 jQuery
解析vue、angular深度作用选择器
2019/09/11 Javascript
vue使用swiper.js重叠轮播组建样式
2019/11/14 Javascript
vue如何使用async、await实现同步请求
2019/12/09 Javascript
优化Vue中date format的性能详解
2020/01/13 Javascript
[02:17]2016完美“圣”典风云人物:Sccc专访
2016/12/03 DOTA
Python分析彩票记录并预测中奖号码过程详解
2019/07/09 Python
Python3 pywin32模块安装的详细步骤
2020/05/26 Python
基于Python词云分析政府工作报告关键词
2020/06/02 Python
HTML5地理定位与第三方工具百度地图的应用
2016/11/17 HTML / CSS
高清屏下canvas重置尺寸引发的问题的解决
2019/10/14 HTML / CSS
adidas马来西亚官网:adidas MY
2020/09/12 全球购物
主键(Primary Key)约束和唯一性(UNIQUE)约束的区别
2013/05/29 面试题
人力资源部门的主要职能
2014/02/22 职场文书
群众路线个人对照检查材料2014
2014/09/26 职场文书
2016党员党章学习心得体会
2016/01/14 职场文书
Python实战之实现康威生命游戏
2021/04/26 Python
python字典的元素访问实例详解
2021/07/21 Python
十大最强电系宝可梦,阿尔宙斯电系之一,第七被称为雷神
2022/03/18 日漫