阅读 50

requestAnimationFrame 再理解

概述

有很长一段时间没有开发动画相关的代码了,最近看React源码,又看到了requestAnimationFrame这个API,突然忘记这个API的用法。看来还是得及时总结,做下笔记才能帮助后续理解。

官方的解释是:window.requestAnimationFrame() 告诉浏览器——你希望执行一个动画,并且要求浏览器在下次重绘之前调用指定的回调函数更新动画。该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行。

OK,还是得用自己的话总结才能更方便理解和记忆。

显示器有固定的刷新频率(60Hz或75Hz),也就是说,每秒最多只能重绘60次或75次,requestAnimationFrame 的基本思想就是与这个刷新频率保持同步,利用这个刷新频率进行页面重绘,浏览器每次刷新前都会执行 requestAnimationFrame 中的回调函数。

特点

  • requestAnimationFrame会把每一帧中的所有DOM操作集中起来,在一次重绘或回流中就完成,并且重绘或回流的时间间隔紧紧跟随浏览器的刷新频率
  • 在隐藏或不可见的元素中,requestAnimationFrame将不会进行重绘或回流,这当然就意味着更少的CPU、GPU和内存
  • requestAnimationFrame是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用

为什么不使用setTimeout、setInterval

setTimeout 和 setInterval 需要设置时间间隔,他们的内在运行机制决定了事件间隔参数实际上只是指定了把动画代码添加到浏览器UI线程队列中以等待执行的时间。如果队列前面已经加入了其他任务,那动画代码就要等前面的任务完成后再执行。

cancelAnimationFrame方法

cancelAnimationFrame方法用于取消重绘。 它的参数是requestAnimationFrame返回的一个代表任务ID的整数值。

实例

<html>
<body>
    <div id="container" style="width: 100px;height: 100px;background-color: aquamarine;"></div>
    <script type="text/babel">
        var start = null;
        var element = document.getElementById('container');
        element.style.position = 'absolute';

        function step(timestamp) {
            if (!start) start = timestamp;
            var progress = timestamp - start;
            element.style.left = Math.min(progress / 10, 200) + 'px';
            if (progress < 2000) {
                window.requestAnimationFrame(step);
            }
        }

        window.requestAnimationFrame(step);
    </script>
</body>
</html>
复制代码

container元属会随着浏览器的刷新频率,改变自己的left值,达到动画的效果。

关注下面的标签,发现更多相似文章
评论