html requestAnimationFrame动画
用 requestAnimationFrame 给网页动画“装上节拍器”
网页动画的节奏,往往决定着观感的轻重与流畅度。用浏览器原生的 requestAnimationFrame 来驱动动画,就像是给页面装上一个节拍器,让每一帧的切换都踩在正确的节拍上,既省力又稳定。
为什么选它
想象你在做粒子效果或平滑的滚动过渡,如果每一帧都由定时器驱动,会遇到浏览器重排、抖动和功耗飙升的问题。requestAnimationFrame 会把动画与浏览器的重绘刷新率对齐,自动在每帧的合适时机触发回调,既减少不必要的重渲染,也让动画更顺滑自然。
基本用法与关键点
function animate(time) {
// 动画逻辑,time 是上一帧的时间戳
// 更新位置或状态
// 渲染
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
- 时间参数:time 是浏览器上一帧的时间戳(毫秒),用于实现平滑的时间增量计算,不必自己维护时间变量。
- 性能控制:在动画结束或暂停时,主动取消递归调用,以减少不必要的渲染压力。
- 同步渲染:将渲染逻辑放在回调内,确保每帧只更新一次,避免累积抖动。
场景化应用:平滑滚动与交互
在做页面的平滑滚动时,使用 rAF 可以让滚动动画与屏幕刷新同步,避免浏览器的“冲帧”感:
let scrollStart = 0;
let scrollEnd = 0;
let startTime = 0;
function animateScroll(timestamp) {
if (!startTime) startTime = timestamp;
const progress = (timestamp - startTime) / (duration * 1000);
const currentScroll = scrollStart + (scrollEnd - scrollStart) * progress;
window.scrollTo(0, currentScroll);
if (progress < 1) {
requestAnimationFrame(animateScroll);
}
}
requestAnimationFrame(animateScroll);
这段代码通过时间戳与目标滚动位置计算出每帧的进度,让滚动过程在每一帧都只更新一次,既自然又省力。
场景化应用:粒子系统与渐进式渲染
构建粒子系统时,逐帧更新位置并重渲染,是 rAF 的天然适配场景:
const particles = Array(100)
.fill(0)
.map(() => ({ x: Math.random() * window.innerWidth, y: Math.random() * window.innerHeight, dx: (Math.random() - 0.5) * 2, dy: (Math.random() - 0.5) * 2 }));
function animateParticles(time) {
// 更新位置
particles.forEach(p => {
p.x += p.dx;
p.y += p.dy;
if (p.x < 0 || p.x > window.innerWidth) p.dx *= -1;
if (p.y < 0 || p.y > window.innerHeight) p.dy *= -1;
});
// 渲染
ctx.clearRect(0, 0, canvas.width, canvas.height);
particles.forEach(p => {
ctx.beginPath();
ctx.arc(p.x, p.y, 3, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(255, 255, 255, 0.7)';
ctx.fill();
});
requestAnimationFrame(animateParticles);
}
requestAnimationFrame(animateParticles);
在每一帧只更新粒子位置并一次性重绘,既保证了性能,也让粒子运动自然不卡顿。
结尾
用 requestAnimationFrame 给动画“踩上节拍”,不仅能让页面更顺滑,还能让开发者更专注在创意本身。从滚动到粒子,从交互到过渡,rAF 都能提供与设备刷新对齐的节奏,减少不必要的渲染与重排,让每一帧都更轻盈。
在实际项目中,灵活地在需要时启动与在不需要时取消递归调用,是控制性能的关键。掌握好这些节奏点,就能在代码里弹奏出更自然、更高效的动画旋律。
文章版权声明:除非注明,否则均为Dark零点博客原创文章,转载或复制请以超链接形式并注明出处。


还没有评论,来说两句吧...