pin_drop当前位置:知识文库 ❯ 图文
HTML5 API:HTML5 requestAnimationFra - 完整教程与代码示例
一、教程简介
requestAnimationFrame(rAF)是 HTML5 提供的用于在浏览器下一次重绘之前执行回调函数的 API,专门为流畅动画设计。相比 setTimeout/setInterval,rAF 与浏览器刷新率同步(通常 60fps),在页面不可见时自动暂停,性能更优、动画更流畅,是制作 Web 动画的首选方案。
二、核心概念
rAF vs setTimeout
工作原理
代码示例
浏览器渲染循环:
┌─── 样式计算 ─── 布局 ─── 绘制 ─── 合成 ───┐
│ │
└── rAF 回调在此执行 ←────────────────────────┘语法
代码示例
const id = requestAnimationFrame(callback); // 请求下一帧
cancelAnimationFrame(id); // 取消请求回调函数接收一个高精度时间戳参数:
代码示例
function animate(timestamp) {
// timestamp: 从页面加载开始的毫秒数(高精度)
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);三、语法与用法
基本语法
代码示例
// 请求动画帧
const id = requestAnimationFrame(callback);
// 取消动画帧
cancelAnimationFrame(id);四、代码示例
示例一:多种动画效果
使用 rAF 实现流畅的 Canvas 动画效果,包含粒子系统、连线效果、FPS 计算等功能。
五、浏览器兼容性
六、注意事项与最佳实践
1. 基于时间的动画
代码示例
// 不推荐:基于帧的动画(不同帧率速度不同)
element.style.left = parseInt(element.style.left) + 5 + 'px';
// 推荐:基于时间的动画
let lastTime = 0;
function animate(timestamp) {
const delta = timestamp - lastTime;
lastTime = timestamp;
const speed = 100; // 像素/秒
const distance = speed * delta / 1000;
element.style.left = parseFloat(element.style.left) + distance + 'px';
requestAnimationFrame(animate);
}2. 及时取消
代码示例
// 页面隐藏时暂停
document.addEventListener('visibilitychange', function() {
if (document.hidden) {
cancelAnimationFrame(animId);
} else {
animId = requestAnimationFrame(animate);
}
});3. 避免内存泄漏
代码示例
// 组件销毁时取消动画
class AnimationComponent {
constructor() {
this.animId = null;
}
start() {
const animate = (timestamp) => {
// 动画逻辑
this.animId = requestAnimationFrame(animate);
};
this.animId = requestAnimationFrame(animate);
}
destroy() {
if (this.animId) {
cancelAnimationFrame(this.animId);
this.animId = null;
}
}
}七、代码规范示例
代码示例
class AnimationLoop {
constructor(onUpdate) {
this.onUpdate = onUpdate;
this.animId = null;
this.lastTime = 0;
this.isRunning = false;
}
start() {
if (this.isRunning) return;
this.isRunning = true;
this.lastTime = performance.now();
this._loop(this.lastTime);
}
stop() {
this.isRunning = false;
if (this.animId) {
cancelAnimationFrame(this.animId);
this.animId = null;
}
}
_loop(timestamp) {
if (!this.isRunning) return;
const delta = timestamp - this.lastTime;
this.lastTime = timestamp;
this.onUpdate(delta, timestamp);
this.animId = requestAnimationFrame((t) => this._loop(t));
}
}
// 使用
const loop = new AnimationLoop((delta, timestamp) => {
// 基于时间的动画更新
updatePhysics(delta);
render();
});
loop.start();八、常见问题与解决方案
常见问题
Q1:动画在不同设备上速度不同?
解决方案:使用基于时间的动画,根据 delta time 计算位移。
Q2:rAF 回调频率是多少?
解答:通常为 60fps(约 16.67ms),高刷新率屏幕可达 120fps 或更高。
Q3:如何在 rAF 中使用缓动函数?
解决方案:使用缓动函数计算动画进度。
代码示例
function easeInOutCubic(t) {
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
}
function animateValue(from, to, duration) {
const start = performance.now();
function update(now) {
const elapsed = now - start;
const progress = Math.min(elapsed / duration, 1);
const value = from + (to - from) * easeInOutCubic(progress);
// 使用 value...
if (progress < 1) requestAnimationFrame(update);
}
requestAnimationFrame(update);
}九、总结
requestAnimationFrame 是制作流畅 Web 动画的首选方案,与浏览器刷新率同步、页面隐藏时自动暂停、提供高精度时间戳。使用时需注意基于时间而非帧数计算动画、及时取消不再需要的动画、页面隐藏时手动暂停,以及避免在回调中执行耗时操作影响帧率。
标签:
requestAnimationFrame
动画帧
Canvas动画
60fps
流畅动画
本文涉及AI创作
内容由AI创作,请仔细甄别