Web动画优化之requestAnimationFrame的使用(翻译)

本文翻译自:https://css-tricks.com/using-requestanimationframe/ ,如有侵权,请联系我!

引入

以前JavaScript只有一种时间间隔循环的方式:setInterval()。如果你需要以特别快的速度(不是像for循环那样极致快)重复一些内容,你可以使用setInterval()。如果用在动画上,让动画和屏幕刷新速度一致(大多数认为60Hz,也就是一秒钟60次),动画就会显得非常流畅,我们以前是这样解决的:

setInterval(function() {
  // animiate something
}, 1000/60);

然而,现在有了更好的替代方案。Paul Irish 两年前推荐使用requestAnimationFrame,我以前不重视这个方法,现在我用完以后觉得很舒服,还推荐给我的成家班用。

好用在哪?

Paul 是这样解释的:
1、浏览器会优化它,所以动画会显得更顺滑;
2、动画在 不活动的浏览器标签 会自动暂停,节省CPU;
3、对电池更加友好;

尽量简单的例子:

function repeatOften() {
  // Do whatever
  requestAnimationFrame(repeatOften);
}
requestAnimationFrame(repeatOften);

调用一次(最后一行语句就是),这个方法就会自己开始递归了。

动画的开始和暂停:

和我们的setTimeoutsetInterval一样,requestAnimationFrame也会返回一个定时器ID,下面用jQuery小小地演示一下(博主注:这里和传统定时器一样,也会有多次点击多次添加定时器的毛病)

var globalID;    //requestAnimationFrame定时器的ID

function repeatOften() {
  $("<div />").appendTo("body");    //动画变换本体,你也可以变换width、transform、scrollTop等等,这里是每次添加一个div盒子
  globalID = requestAnimationFrame(repeatOften);    //递归循环调用,
}

$("#start").on("click", function() {
  globalID = requestAnimationFrame(repeatOften);
});

$("#stop").on("click", function() {
  cancelAnimationFrame(globalID);
});

这个例子的实现是这样的(实际上很流畅,录制有点不好):
在这里插入图片描述

浏览器支持情况:

Can I use 可以找到。

使用之前建议加上兼容Polyfill(包括不同浏览器的不同表达方式以及不支持此方法的替代方法):

(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 - (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);
        };
}());

 

PS:收帝都工作机会 ,感谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值