hand
_1_11_157
4
返回栏目
0k
2k
1k
2k
1k
1k
1k
2k
2k
2k
1k
2k
1k
2k
1k
1k
1k
1k
1k
2k
1k
1k
1k
1k
1k
1k
1k
1k
1k
2k
1k
1k
1k
1k
1k
1k
1k
1k
1k
2k
1k
1k
1k
1k
1k
1k
1k
2k
1k
2k
1k
1k
1k
1k
1k
1k
1k
2k
2k
1k
1k
1k
2k
1k
1k
2k
2k
1k
1k
1k
2k
1k
1k
2k
2k
1k
2k
1k
1k
2k
2k
2k
3k
3k
2k
3k
2k
3k
3k
3k
1k
2k
3k
2k
2k
3k
3k
2k
2k
6k
3k
2k
2k
5k
3k
4k
3k
3k
2k
4k
3k
3k
2k
3k
3k
1k
4k
4k
4k
2k
5k
3k
2k
3k
4k
3k
3k
4k
2k
3k
3k
4k
2k
2k
3k
4k
3k
3k
2k
5k
2k
3k
3k
3k
3k
2k
3k
3k
3k
2k
2k
2k
2k
3k
2k
2k
2k
3k
2k
2k
2k
2k
2k
2k
0.1k
0.2k
3k
2k
3k
2k
0.1k
2k
2k
4k
2k
2k
1k
2k
2k
3k
3k
3k
3k
2k
2k
3k
3k
3k
4k
3k
3k
4k
3k
2k
2k
3k
3k
3k
3k
3k
3k
2k
3k
3k
4k
4k
3k
3k
2k
2k
3k
2k
2k
1k
2k
3k
1k
2k
2k
2k
2k
2k
2k
2k
2k
2k
4k
2k
3k
2k
1k
2k
2k
2k
2k
2k
3k
2k
3k
1k
2k
2k
2k
0k
2k
2k
2k
2k
2k
2k
2k
3k
2k
2k
1k
1k
3k
2k
3k
1k
2k
1k
2k
2k
2k
2k
3k
1k
3k
2k
2k
2k
2k
2k
2k
1k
2k
2k
4k
3k
3k
2k
2k
2k
2k
2k
2k
4k
3k
3k
3k
2k
2k
2k
2k
2k
2k
3k
4k
返回前端 - Javascript栏目
作者:
贺及楼
成为作者
更新日期:2025-02-21 20:11:59
在前端开发中,实现动画效果是一项常见的需求。为了实现流畅的动画,我们常常需要借助定时器。JavaScript 中传统的定时器有 setTimeout
和 setInterval
,而 HTML5 引入了一个新的定时器函数 requestAnimationFrame
。本文将深入探讨 requestAnimationFrame
作为动画帧定时器的优势。
在介绍 requestAnimationFrame
之前,我们先来看看传统定时器 setTimeout
和 setInterval
在实现动画时存在的问题。
setTimeout
和 setInterval
是基于时间来触发回调函数的。然而,JavaScript 是单线程执行的,当主线程有其他耗时任务时,定时器的回调函数可能会被延迟执行。例如:
function expensiveTask() {
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
console.log('Expensive task finished');
}
setTimeout(() => {
console.log('Timer callback executed');
}, 100);
expensiveTask();
在这个例子中,由于 expensiveTask
是一个耗时任务,setTimeout
的回调函数可能会在 100ms 之后很久才执行,这就会导致动画的帧率不稳定。
当使用 setInterval
来实现动画时,即使页面处于不可见状态(如切换到其他标签页),定时器依然会按照设定的时间间隔不断执行回调函数,这会导致不必要的 CPU 资源浪费。
requestAnimationFrame
是专门为实现动画效果而设计的定时器,它具有以下显著优势:
浏览器的刷新频率通常是 60Hz,即每秒刷新 60 次,每次刷新的间隔约为 16.7ms。requestAnimationFrame
会根据浏览器的刷新频率来执行回调函数,确保动画的帧率稳定在 60fps(帧每秒)左右,从而实现流畅的动画效果。例如:
const element = document.getElementById('myElement');
let position = 0;
function animate() {
position++;
element.style.left = position + 'px';
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
在这个例子中,animate
函数会在每次浏览器刷新时被调用,不断更新元素的位置,实现平滑的移动动画。
当页面处于不可见状态时,requestAnimationFrame
会自动暂停执行,从而节省 CPU 资源。例如,当用户切换到其他标签页时,动画会自动停止,直到用户切换回当前页面。这使得页面在不同的使用场景下都能保持良好的性能。
requestAnimationFrame
的回调函数会传入一个时间戳参数,该时间戳表示当前帧开始的时间。通过这个时间戳,我们可以实现更加精准的动画控制。例如:
const element = document.getElementById('myElement');
let startTime;
function animate(timestamp) {
if (!startTime) {
startTime = timestamp;
}
const elapsedTime = timestamp - startTime;
const position = Math.sin(elapsedTime / 1000) * 100;
element.style.left = position + 'px';
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
在这个例子中,我们根据动画开始以来的 elapsedTime 来计算元素的位置,实现了一个正弦曲线的动画效果。
特性 | setTimeout/setInterval | requestAnimationFrame |
---|---|---|
执行时机 | 不稳定,受主线程任务影响 | 与浏览器刷新频率同步,稳定 |
CPU 占用 | 页面不可见时仍继续执行,浪费资源 | 页面不可见时自动暂停,节省资源 |
时间控制 | 基于固定时间间隔,不够精准 | 提供时间戳参数,可实现精准控制 |
综上所述,requestAnimationFrame
在实现动画效果方面具有明显的优势。在开发前端动画时,我们应该优先考虑使用 requestAnimationFrame
来替代传统的定时器,以获得更加流畅、高效的动画体验。
前端 - Javascript
整章节共299节
快分享给你的小伙伴吧 ~