用requestAnimationFrame实现无限循环背景动画需递归调用自身以维持帧循环,通过累加偏移量并超出背景图宽时重置实现无缝滚动,推荐用transform替代backgroundPosition提升性能,并利用rAF自动暂停/恢复特性优化资源占用。

用 requestAnimationFrame 制作无限循环背景动画,核心是让动画帧持续递归调用、同时控制背景位置平滑位移,并在位移超出范围时无缝重置——不靠定时器,而是依赖浏览器刷新节奏,更流畅、更省资源。
基础循环结构:递归调用 rAF
不同于 setInterval,requestAnimationFrame 是单次调用,必须在回调函数末尾再次调用自身,才能形成持续动画循环:
- 定义一个动画函数(例如
animateBackground) - 在函数内部更新动画状态(如背景偏移量)
- 调用
requestAnimationFrame(animateBackground)触发下一帧 - 首次启动只需调用一次该函数
实现无缝滚动:位移与重置逻辑
常见需求是横向/纵向无限滚动背景(如云层、粒子流)。关键在于:当背景图完全移出视口时,立刻将其“跳回”起始位置,人眼察觉不到中断:
- 设背景容器宽度为
containerWidth,背景图宽度为bgWidth - 用一个变量(如
offsetX)记录当前水平偏移 - 每帧按固定速度(如
speed = 0.5)累加:offsetX += speed - 一旦
offsetX >= bgWidth,就重置为offsetX -= bgWidth(或直接设为 0) - 用
element.style.backgroundPosition = `${-offsetX}px 0`应用位移
优化细节:避免抖动与性能浪费
看似简单,但实际容易出现卡顿或错位。注意这几个点:
-
使用
transform: translateX()替代backgroundPosition—— 更易被 GPU 加速,尤其对大背景或高分辨率屏 - 将背景图设为
background-repeat: repeat-x或用双图拼接(两张相同图左右排列),可减少重置瞬间的空白感 - 在动画函数开头用
performance.now()计算 delta 时间,实现帧率无关的速度控制(例如:根据上一帧耗时动态调整位移量) - 离开页面标签页时,
rAF自动暂停;切回时自动恢复,无需手动管理——这是它比setInterval的天然优势
一个最小可用示例(横向滚动)
HTML 中有一个
let offsetX = 0;
const speed = 0.8;
const bg = document.getElementById('bg');
const bgWidth = 1920; // 背景图原始宽度(单位 px)
function animateBackground() {
offsetX += speed;
if (offsetX >= bgWidth) {
offsetX -= bgWidth;
}
bg.style.backgroundPosition = `${-offsetX}px 0`;
requestAnimationFrame(animateBackground);
}
// 启动
animateBackground();
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











