requestAnimationFrame实现动画循环与帧率控制
请用requestAnimationFrame(rAF)实现一个平滑动画循环,包含帧率控制、deltaTime计算、暂停/恢复和性能优化。
回答
我还是少年
class AnimationLoop {
constructor(callback) {
this.callback = callback;
this.isRunning = false;
this.rafId = null;
this.lastTime = 0;
this.elapsed = 0;
this.targetFPS = 60;
this.frameInterval = 1000 / 60;
}
start() {
if (this.isRunning) return;
this.isRunning = true;
this.lastTime = performance.now();
this.tick(this.lastTime);
}
stop() {
this.isRunning = false;
if (this.rafId) cancelAnimationFrame(this.rafId);
}
setFPS(fps) { this.targetFPS = fps; this.frameInterval = 1000 / fps; }
tick = (currentTime) => {
if (!this.isRunning) return;
const deltaTime = currentTime - this.lastTime;
this.lastTime = currentTime;
if (deltaTime < this.frameInterval - 1) {
this.rafId = requestAnimationFrame(this.tick);
return;
}
this.elapsed += deltaTime;
this.callback({ deltaTime: Math.min(deltaTime, 100), elapsed: this.elapsed, fps: 1000 / deltaTime });
this.rafId = requestAnimationFrame(this.tick);
}
}
性能优化:使用deltaTime保证不同刷新率设备速度一致;使用transform代替left/top避免layout触发;离屏Canvas减少重绘。