requestAnimationFrame创建高性能动画(个人笔记)

requestAnimationFrame 是浏览器提供的一个用于创建高性能动画的 API,它会在浏览器下次重绘之前调用指定的回调函数。以下为你详细介绍其用法:

基本语法

const requestID = requestAnimationFrame(callback);
  • 参数
    • callback:一个回调函数,该函数会在浏览器下次重绘之前被调用。这个回调函数接收一个参数 timestamp,它是一个高精度时间戳,表示从页面加载开始到当前时刻所经过的毫秒数。
  • 返回值
    • requestID:一个唯一的整数 ID,用于标识这个动画帧请求。可以使用这个 ID 来取消动画帧请求,通过 cancelAnimationFrame(requestID) 方法。

基本使用示例

下面是一个简单的示例,使用 requestAnimationFrame 实现一个元素的简单移动动画:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <style>
        #box {
            width: 50px;
            height: 50px;
            background-color: blue;
            position: absolute;
            left: 0;
        }
    </style>
</head>

<body>
    <div id="box"></div>
    <script>
        const box = document.getElementById('box');
        let position = 0;

        function moveBox(timestamp) {
            position += 1;
            box.style.left = position + 'px';

            if (position < 200) {
                requestAnimationFrame(moveBox);
            }
        }

        requestAnimationFrame(moveBox);
    </script>
</body>

</html>

代码解释

  1. 获取元素:通过 document.getElementById 获取要进行动画的元素。
  2. 定义动画函数moveBox 函数是动画的核心逻辑,在每次调用时,将元素的 left 位置增加 1 像素。
  3. 递归调用:在 moveBox 函数内部,使用 requestAnimationFrame(moveBox) 来请求下一帧动画,形成递归调用,直到元素移动到指定位置(这里是 200 像素)。
  4. 启动动画:通过第一次调用 requestAnimationFrame(moveBox) 来启动动画。

实现倒计时示例

function countdown(duration) {
    let startTime = null;

    function step(timestamp) {
        if (!startTime) startTime = timestamp;
        const elapsed = timestamp - startTime;
        const remaining = duration - elapsed;

        if (remaining <= 0) {
            console.log('倒计时结束');
        } else {
            console.log(`剩余时间: ${Math.ceil(remaining / 1000)} 秒`);
            requestAnimationFrame(step);
        }
    }

    requestAnimationFrame(step);
}

// 使用示例,倒计时 10 秒
countdown(10000);

代码解释

  1. 记录起始时间:在 step 函数中,使用 startTime 记录倒计时的起始时间。
  2. 计算剩余时间:通过 timestamp 计算从起始时间到当前时间所经过的时间,然后用总时长减去已过去的时间,得到剩余的倒计时时间。
  3. 递归调用:如果剩余时间大于 0,则继续调用 requestAnimationFrame(step) 来请求下一帧动画,更新倒计时信息。

取消动画帧请求

如果需要在动画过程中停止动画,可以使用 cancelAnimationFrame 方法取消动画帧请求。

const box = document.getElementById('box');
let position = 0;
let requestID;

function moveBox(timestamp) {
    position += 1;
    box.style.left = position + 'px';

    if (position < 200) {
        requestID = requestAnimationFrame(moveBox);
    } else {
        // 停止动画
        cancelAnimationFrame(requestID);
    }
}

requestID = requestAnimationFrame(moveBox);

在这个示例中,当元素移动到 200 像素的位置时,使用 cancelAnimationFrame(requestID) 取消动画帧请求,停止动画。

综上所述,requestAnimationFrame 通过递归调用和利用 timestamp 来跟踪时间,可以实现流畅的动画效果,并且可以方便地控制动画的启动和停止。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容