requestAnimationFrame
是浏览器提供的一个用于创建高性能动画的 API,它会在浏览器下次重绘之前调用指定的回调函数。以下为你详细介绍其用法:
基本语法
const requestID = requestAnimationFrame(callback);
-
参数:
-
callback
:一个回调函数,该函数会在浏览器下次重绘之前被调用。这个回调函数接收一个参数timestamp
,它是一个高精度时间戳,表示从页面加载开始到当前时刻所经过的毫秒数。
-
-
返回值:
-
requestID
:一个唯一的整数 ID,用于标识这个动画帧请求。可以使用这个 ID 来取消动画帧请求,通过cancelAnimationFrame(requestID)
方法。
-
基本使用示例
下面是一个简单的示例,使用 requestAnimationFrame
实现一个元素的简单移动动画:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#box {
width: 50px;
height: 50px;
background-color: blue;
position: absolute;
left: 0;
}
</style>
</head>
<body>
<div id="box"></div>
<script>
const box = document.getElementById('box');
let position = 0;
function moveBox(timestamp) {
position += 1;
box.style.left = position + 'px';
if (position < 200) {
requestAnimationFrame(moveBox);
}
}
requestAnimationFrame(moveBox);
</script>
</body>
</html>
代码解释
-
获取元素:通过
document.getElementById
获取要进行动画的元素。 -
定义动画函数:
moveBox
函数是动画的核心逻辑,在每次调用时,将元素的left
位置增加 1 像素。 -
递归调用:在
moveBox
函数内部,使用requestAnimationFrame(moveBox)
来请求下一帧动画,形成递归调用,直到元素移动到指定位置(这里是 200 像素)。 -
启动动画:通过第一次调用
requestAnimationFrame(moveBox)
来启动动画。
实现倒计时示例
function countdown(duration) {
let startTime = null;
function step(timestamp) {
if (!startTime) startTime = timestamp;
const elapsed = timestamp - startTime;
const remaining = duration - elapsed;
if (remaining <= 0) {
console.log('倒计时结束');
} else {
console.log(`剩余时间: ${Math.ceil(remaining / 1000)} 秒`);
requestAnimationFrame(step);
}
}
requestAnimationFrame(step);
}
// 使用示例,倒计时 10 秒
countdown(10000);
代码解释
-
记录起始时间:在
step
函数中,使用startTime
记录倒计时的起始时间。 -
计算剩余时间:通过
timestamp
计算从起始时间到当前时间所经过的时间,然后用总时长减去已过去的时间,得到剩余的倒计时时间。 -
递归调用:如果剩余时间大于 0,则继续调用
requestAnimationFrame(step)
来请求下一帧动画,更新倒计时信息。
取消动画帧请求
如果需要在动画过程中停止动画,可以使用 cancelAnimationFrame
方法取消动画帧请求。
const box = document.getElementById('box');
let position = 0;
let requestID;
function moveBox(timestamp) {
position += 1;
box.style.left = position + 'px';
if (position < 200) {
requestID = requestAnimationFrame(moveBox);
} else {
// 停止动画
cancelAnimationFrame(requestID);
}
}
requestID = requestAnimationFrame(moveBox);
在这个示例中,当元素移动到 200 像素的位置时,使用 cancelAnimationFrame(requestID)
取消动画帧请求,停止动画。
综上所述,requestAnimationFrame
通过递归调用和利用 timestamp
来跟踪时间,可以实现流畅的动画效果,并且可以方便地控制动画的启动和停止。