前言
在Web应用中,实现动画效果的方法比较多,Javascript 中可以通过定时器 setTimeout 来实现,css3 可以使用 transition 和 animation 来实现,html5 中的 canvas 也可以实现。除此之外,html5 还提供一个专门用于请求动画的API,那就是 requestAnimationFrame,就是请求动画帧。
1.什么是requestAnimationFrame?
MDN描述:window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。
requestAnimationFrame是一个浏览器提供的用于执行动画的JavaScript方法。它允许我们按照浏览器的刷新率来调度动画帧,从而实现更加流畅和高效的动画效果。
大多数电脑显示器的刷新频率是 60Hz,大概相当于每秒钟重绘 60 次。大多数浏览器都会对重绘操作加以限制,不超过显示器的重绘频率,因为即使超过那个频率用户体验也不会有提升。因此最平滑动画的最佳循环间隔是1000ms/60,约等于 16.6ms。
在之前,为了实现动画,常常使用setTimeout()或setInterval()方法来定时更新动画帧。然而,这种方法并不理想,因为它们受限于定时器的精度和浏览器在不同设备上的性能差异。它们的内在运行机制决定了时间间隔参数实际上只是指定了把动画代码添加到浏览器 UI 线程队列中以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务完成后再执行
requestAnimationFrame的出现解决了这个问题。它使用浏览器的刷新率作为参考,确保动画帧的更新在每一帧之间的间隔是最佳的,从而实现更加流畅和自然的动画效果。
2.如何使用requestAnimationFrame?
使用requestAnimationFrame非常简单。以下是基本的用法示例:
function animate() {
// 执行动画逻辑
timer=requestAnimationFrame(animate);
}
// 启动动画
let timer=requestAnimationFrame(animate);
//取消动画
cancelAnimationFrame(timer);
在上面的示例中,我们定义了一个名为animate
的函数,该函数包含了动画的逻辑。然后,我们使用requestAnimationFrame
方法调用animate
函数,从而开始动画的循环。在animate
函数的结尾,我们再次调用requestAnimationFrame(animate)
,以便在下一帧继续更新动画。
这样做的好处是,requestAnimationFrame
会自动根据浏览器的刷新率来调度动画帧。它会在每一帧开始之前自动调用我们提供的函数,从而创建流畅的动画效果。
案例
<html>
<head>
<title>requestAnimationFrame</title>
<style>
#box {
width: 500px;
margin-top: 20px;
background-color:pink;
}
</style>
</head>
<body>
<button id="start">开始</button>
<button id="stop">停止</button>
<div id="box"></div>
<script>
window.onload = function () {
var stratBtn = document.querySelector("#start"),
stopBtn = document.querySelector("#stop"),
box = document.querySelector("#box");
var timer;
stratBtn.addEventListener("click", () => {
timer = requestAnimationFrame(test)
});
stopBtn.addEventListener("click", () => {
cancelAnimationFrame(timer);
});
function test() {
console.log(timer)
box.style.height = `${timer}%`;
timer= requestAnimationFrame(test)
}
}
</script>
</body>
</html>
3. requestAnimationFrame与其他动画技术的比较
现在让我们将requestAnimationFrame与其他常见的动画技术进行比较。
1. setTimeout和setInterval
如前所述,setTimeout和setInterval方法在实现动画时存在一些问题,例如定时器的不准确性和性能差异。相比之下,requestAnimationFrame使用浏览器的刷新率作为参考,可以更好地保持动画的流畅性和性能。
2. CSS3过渡和动画
CSS3过渡和动画是通过CSS属性和关键帧来实现的动画效果。与requestAnimationFrame相比,CSS动画的语法更简单,而且在某些情况下性能更好。然而,CSS动画通常更适用于简单的动画效果,而对于更复杂的、需要动态计算的动画,使用JavaScript和requestAnimationFrame更为灵活和强大。
3. WebGL和Canvas
WebGL和Canvas是基于HTML5的高级绘图技术,可以创建复杂的图形和动画效果。它们通常与requestAnimationFrame结合使用,以便实现更复杂的动画和交互效果。requestAnimationFrame提供了一个精确的时间间隔,使得在每一帧之间对Canvas或WebGL上的图形进行适当的更新成为可能。
结论
requestAnimationFrame是一个强大的JavaScript方法,用于在网页上创建流畅和高效的动画效果。它利用浏览器的刷新率来调度动画帧,避免了定时器的不准确性和性能差异。与其他动画技术相比,requestAnimationFrame提供了更好的流畅性和性能,特别适用于复杂的动画效果和交互式应用程序。无论是在开发游戏、创建交互式界面还是实现视觉效果,requestAnimationFrame都是一个不可或缺的工具。