为了账号安全,请及时绑定邮箱和手机立即绑定

容易被忽视的RequestAnimationFrame

标签:
Html/CSS

传统的JS动画都是用 setTimeout 和 setInterval 实现的,后来无意中在网上看到一个新的JS函数 requestAnimationFrame 用它来替代传统的JS动画方法,说是效果更好,当时也没有仔细深究。直到昨天去魅族面试的时候,面试官问我有什么新的办法可以替代传统的JS动画,我说“我知道一个叫 requestAnimationFrame 的函数,它的执行效果更好”。但是让我仔细描述的时候,我就说不下去了,这也是我写这篇博客的初衷,我们学习的过程中一定要知其然比知其所以然,不要什么都略懂,最后落得跟半吊子一样。

定时器一直都是JS动画的核心技术。而编写动画循环的关键是要知道延迟时间多长合适。一方面,循环间隔必须足够短,这样才能让不同的动画效果显得平滑流畅;另一方面,循环间隔还要足够长,才能确保浏览器有能力渲染产生的变化。

大多数电脑显示器的刷新频率是60HZ,也就是每秒钟重绘60次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会提升。因此,最平滑动画的最佳循环间隔是 1000ms / 60 ,约为16.7ms。

传统的 setTimeout 和 setInterval 它们都不是很精确,因为它们实际上只是把动画代码添加到浏览器UI线程队尾以等待执行时间,如果它们前面有其它任务,则必须等前面的任务执行完在执行动画代码。

而 requestAnimationFrame 采用系统时间间隔,让各种动画效果能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。它有如下三个特点:

  • 会把每一帧中所有的DOM操作集中起来,在一次动画操作就完成,并且动画的时间间隔紧紧跟随浏览器的刷新频率(不需要设置时间间隔)。

  • 在隐藏或者不可见的元素中,不会进行动画操作。

  • 当浏览器不是激活状态,不会进行动画操作。

下面是一个兼容所有浏览器的使用 requestAnimationFrame 的代码(IE9-无该方法)

(function() {    var lastTime = 0;    var vendors = ['ms', 'moz', 'webkit', 'o'];    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.7 - (currTime - lastTime));            var id = setTimeout(function() {
                callback(currTime + timeToCall);
            }, timeToCall);
            lastTime = currTime + timeToCall;            return id;
        }
    }    if (!window.cancelAnimationFrame) {        window.cancelAnimationFrame = function(id) {
            clearTimeout(id);
        }
    }
}());

最后附上我利用 requestAnimationFrame 制作的一个 跳动的小球 的DEMO。



作者:蓝瘦额香菇
链接:https://www.jianshu.com/p/d6bf5faa6a66


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消