window.requestAnimationFrame

306 阅读1分钟

参考文章: developer.mozilla.org/zh-CN/docs/…

语法:window.requestAnimationFrame(callback);

使用场景:动画

说明:由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销。

使用方法:

例1:

<style>
div {
    width: 100px;
    height: 100px;
    background: #ccc;
}
</style>
<div id="some-element-you-want-to-animate"></div>
<script>
    const element = document.getElementById('some-element-you-want-to-animate');
    let start;

    function step(timestamp) {
        console.log('timestamp: ', timestamp) // 回调函数的参数
        if (start === undefined)
            start = timestamp;
        const elapsed = timestamp - start;

        //这里使用`Math.min()`确保元素刚好停在200px的位置。
        element.style.transform = 'translateX(' + Math.min(0.1 * elapsed, 200) + 'px)';

        if (elapsed < 2000) { // 在两秒后停止动画
            // 若你想在浏览器下次重绘之前继续更新下一帧动画,
            // 那么回调函数自身必须再次调用window.requestAnimationFrame()
            let id = window.requestAnimationFrame(step); // 返回值
            console.log('id: ', id) // 2, 3, 4 ......
        }
    }

    let id1 = window.requestAnimationFrame(step);
    console.log('id1: ', id1) // 1

例2:

<style>
#dom {
    width: 100px;
    height: 100px;
    background: red;
    position: absolute;
    left: 0;
    top: 0;
}
</style>
<div id="dom"></div>
<script>
    var ele = document.getElementById("dom");
    var flag = true;
    var left = 0;
    var rafId = null;
    function render() {
        if (flag == true) {
            if (left >= 100) {
                flag = false
            }
            ele.style.left = ` ${left++}px`
        } else {
            if (left <= 0) {
                flag = true
            }
            ele.style.left = ` ${left--}px`
        }
    }
    // 若你想在浏览器下次重绘之前继续更新下一帧动画,
    // 那么回调函数(animloop)自身必须再次调用window.requestAnimationFrame()
    (function animloop(time) {
        console.log(time, Date.now())
        render();
        rafId = requestAnimationFrame(animloop);
        // rafId = requestAnimationFrame(render);  // error
        console.log('rafId: ', rafId)
            //如果left等于50 停止动画
        if (left == 50) {
            cancelAnimationFrame(rafId) // 取消回调
        }
    })();
</script>