JavaScript动画-2

101 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

前言

吃饱饭才有力气写代码~

昨天写到早期的定时动画通过setInterval()实现,但是它存在不能保证时间精度的问题,于是有人针对此问题思考着解决方案,如requestAnimationFrame()。

requestAnimationFrame()

这个方法接收一个参数,这个参数是要在重新绘制屏幕前调用的一个函数:

function updateProgress(){
    var div = document.getElementById("status");
    div.style.width = (parseInt(div.style.width,10) + 5) + "%";
    if(div.style.left != "100%"){
        requestAnimationFrame(updateProgress);
    }
}
requestAnimationFrame(updateProgress);

这个函数就是修改DOM样式以反映下一次重绘有什么变化的地方,为了实现动画循环,可以把多个requestAnimationFrame()方法调用串联起来,就像以前使用setTimeout()一样。因为这个方法只会调用一次传入的函数,所以每次更新用户界面时需要再手动调用它一次,同样,也需要控制动画何时停止,结果就会得到非常平滑的动画。
这个方法以经解决了浏览器不知道JavaScript动画什么时候开始的问题,以及最佳间隔是多少的问题。对于不知道代码什么时间执行这个问题,此方法也有解决方法:传给方法的参数是个函数,这个函数实际上也可以接收一个参数,这个参数是一个DOMHighResTimeStamp的实例(比如performance.now()返回的值),表示下次重绘的时间,这一点非常重要:requestAnimationFrame()方法实际上把重绘任务安排在了未来的一个已知的时间点上,而且通过这个参数告诉了开发者,基于这个参数就可以更好地决定如何调优动画了。

cancelAnimationFrame()

和setTimeout()类似,requestAnimationFrame()方法也会返回一个请求ID,可以用于通过另一个方法cancelAnimationFrame()来取消重绘任务,下面举例说明刚把一个任务加入队列又立即将其取消:

let requestID = window.requestAnimationFrame(() => {
    console.log('Repaint!');
})
window.cancelAnimationFrame(requestID);