pin_drop当前位置:知识文库 ❯ 图文

HTML5 API:HTML5 requestAnimationFra - 完整教程与代码示例

一、教程简介

requestAnimationFrame(rAF)是 HTML5 提供的用于在浏览器下一次重绘之前执行回调函数的 API,专门为流畅动画设计。相比 setTimeout/setInterval,rAF 与浏览器刷新率同步(通常 60fps),在页面不可见时自动暂停,性能更优、动画更流畅,是制作 Web 动画的首选方案。

二、核心概念

rAF vs setTimeout

特性 rAF setTimeout(fn, 16)
帧率同步 与刷新率同步 不保证
页面隐藏时 自动暂停 继续执行
精度 高(亚毫秒) 低(4ms 最小)
回调参数 DOMHighResTimeStamp
帧丢失 避免丢帧 可能丢帧

工作原理

代码示例

浏览器渲染循环:
  ┌─── 样式计算 ─── 布局 ─── 绘制 ─── 合成 ───┐
  │                                              │
  └── rAF 回调在此执行 ←────────────────────────┘

语法

代码示例

const id = requestAnimationFrame(callback);  // 请求下一帧
cancelAnimationFrame(id);                     // 取消请求

回调函数接收一个高精度时间戳参数:

代码示例

function animate(timestamp) {
    // timestamp: 从页面加载开始的毫秒数(高精度)
    requestAnimationFrame(animate);
}
requestAnimationFrame(animate);

三、语法与用法

基本语法

代码示例

// 请求动画帧
const id = requestAnimationFrame(callback);

// 取消动画帧
cancelAnimationFrame(id);

四、代码示例

示例一:多种动画效果

使用 rAF 实现流畅的 Canvas 动画效果,包含粒子系统、连线效果、FPS 计算等功能。

五、浏览器兼容性

浏览器 支持版本
Chrome 24+
Firefox 23+
Safari 6.1+
Edge 12+
Opera 15+
IE 10+
iOS Safari 7+

六、注意事项与最佳实践

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创作,请仔细甄别

list快速访问

上一篇: HTML5 API:HTML5 URL API - 完整教程与代码示例 下一篇: HTML5 API:Web Audio API - 完整教程与代码示例

poll相关推荐