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 16 HTML / CSS
css3个性化字体_动力节点Java学院整理
Jul 12 HTML / CSS
CSS3正方体旋转示例代码
Aug 08 HTML / CSS
CSS3实现点击放大的动画实例代码
Feb 27 HTML / CSS
使用phonegap检测网络状态的方法
Mar 30 HTML / CSS
x-ua-compatible content=”IE=7, IE=9″意思理解
Jul 22 HTML / CSS
html5 css3网站菜单实现代码
Dec 23 HTML / CSS
使用HTML5 Canvas API控制字体的显示与渲染的方法
Mar 24 HTML / CSS
amazeui页面分析之登录页面的示例代码
Aug 25 HTML / CSS
完美实现CSS垂直居中的11种方法
Mar 27 HTML / CSS
CSS中float高度塌陷问题的四种解决方案
Apr 18 HTML / CSS
HTML5中的DOCUMENT.VISIBILITYSTATE属性详解
May 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 团购折扣计算公式
2011/11/24 PHP
zend framework文件上传功能实例代码
2013/12/25 PHP
浅谈本地WAMP环境的搭建
2015/05/13 PHP
深入浅析PHP的session反序列化漏洞问题
2017/06/15 PHP
用函数式编程技术编写优美的 JavaScript_ibm
2008/05/16 Javascript
面向对象继承实例(a如何继承b问题)(自写)
2013/07/01 Javascript
js局部刷新页面时间具体实现
2013/07/04 Javascript
javascript实现的DES加密示例
2013/10/30 Javascript
JavaScript中对象property的删除方法介绍
2014/12/30 Javascript
Jquery使用val方法读写value值
2015/05/18 Javascript
jquery插件bootstrapValidator数据验证详解
2016/11/09 Javascript
原生JS实现图片左右轮播
2016/12/30 Javascript
深入理解Angular4中的依赖注入
2017/06/07 Javascript
js实现图片懒加载效果
2017/07/17 Javascript
页面缩放兼容性处理方法(zoom,Firefox火狐浏览器)
2017/08/29 Javascript
基于Vue2.0+ElementUI实现表格翻页功能
2017/10/23 Javascript
基于JS开发微信网页录音功能的实例代码
2019/04/30 Javascript
vue elementUI使用tabs与导航栏联动
2019/06/21 Javascript
Vue el-autocomplete远程搜索下拉框并实现自动填充功能(推荐)
2019/10/25 Javascript
[41:08]2014 DOTA2国际邀请赛中国区预选赛 HGT VS NE
2014/05/22 DOTA
python实现全盘扫描搜索功能的方法
2019/02/14 Python
python threading和multiprocessing模块基本用法实例分析
2019/07/25 Python
python--shutil移动文件到另一个路径的操作
2020/07/13 Python
一款纯css3制作的2015年元旦雪人动画特效教程
2014/12/29 HTML / CSS
美国医生配方营养补充剂供应商:Healthy Directions
2019/07/10 全球购物
社区矫正工作方案
2014/06/04 职场文书
电子商务求职信
2014/06/15 职场文书
保安2014年终工作总结
2014/12/06 职场文书
2015年个人自我剖析材料
2014/12/29 职场文书
幼儿园开学家长寄语(2016秋季)
2015/12/03 职场文书
2016教师六五普法学习心得体会
2016/01/21 职场文书
win11如何查看端口是否被占用? Win11查看端口是否占用的技巧
2022/04/05 数码科技
vue中使用mockjs配置和使用方式
2022/04/06 Vue.js
Alexa停服!网站排名将何去何从?目前还没有替代品。
2022/04/15 杂记
Redis 异步机制
2022/05/15 Redis
pytest实现多进程与多线程运行超好用的插件
2022/07/15 Python