持续动画效果实现
使用 JavaScript 实现持续动画的几种方式
问题
使用 JavaScript 实现一个持续的动画效果。
解答
方式一:requestAnimationFrame(推荐)
// 动画元素
const box = document.getElementById('box');
let position = 0;
function animate() {
// 更新位置
position += 2;
if (position > 300) position = 0;
// 应用样式
box.style.transform = `translateX(${position}px)`;
// 递归调用,形成持续动画
requestAnimationFrame(animate);
}
// 启动动画
requestAnimationFrame(animate);
方式二:带时间控制的 requestAnimationFrame
const box = document.getElementById('box');
let startTime = null;
const duration = 2000; // 动画周期 2 秒
function animate(timestamp) {
// 记录开始时间
if (!startTime) startTime = timestamp;
// 计算进度 (0 ~ 1)
const elapsed = timestamp - startTime;
const progress = (elapsed % duration) / duration;
// 根据进度计算位置
const position = progress * 300;
box.style.transform = `translateX(${position}px)`;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
方式三:setInterval
const box = document.getElementById('box');
let position = 0;
const timer = setInterval(() => {
position += 2;
if (position > 300) position = 0;
box.style.transform = `translateX(${position}px)`;
}, 16); // 约 60fps
// 停止动画
// clearInterval(timer);
完整示例
<!DOCTYPE html>
<html>
<head>
<style>
#box {
width: 50px;
height: 50px;
background: #3498db;
}
</style>
</head>
<body>
<div id="box"></div>
<button id="start">开始</button>
<button id="stop">停止</button>
<script>
const box = document.getElementById('box');
let position = 0;
let animationId = null;
function animate() {
position += 2;
if (position > 300) position = 0;
box.style.transform = `translateX(${position}px)`;
animationId = requestAnimationFrame(animate);
}
document.getElementById('start').onclick = () => {
if (!animationId) animate();
};
document.getElementById('stop').onclick = () => {
cancelAnimationFrame(animationId);
animationId = null;
};
</script>
</body>
</html>
关键点
requestAnimationFrame会在浏览器下次重绘前执行回调,通常是 60fpsrequestAnimationFrame在页面不可见时会自动暂停,节省性能- 使用
cancelAnimationFrame停止动画 - 回调函数接收一个时间戳参数,可用于精确控制动画进度
- 避免使用
setInterval,它不会与浏览器刷新率同步,可能造成掉帧
目录