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相关推荐