requestAnimationFrame() API 实现动画效果

为什么要使用 requestAnimationFrame:

    • 我们知道,浏览器实现动画绘制无非就是 CSS3 的动画属性transitionaniamtion和 JavaScript 的setTImeOutsetInterval方法(进行 DOM 的样式循环改变达到动画效果)。说到这可能很多同学都有疑问了,既然有 CSS 的动画属性这么方便的东西了,为何还要用setTimeOut等 js 方法这么麻烦呢?我们首先来解决这个疑问。
    1. CSS3 的动画属性与 JavaScript 的动画方法:

        1. 一个事物的存在必有其存在的道理,api 也不例外,不然早被淘汰了。首先 CSS3 的动画属性是存在兼容问题的,最明显的就是 IE10 之后才兼容。而目前主流的向下兼容的标准还是要达到 IE9 的,所以setTImeOut等 js 方法还是主流的动画解决方案。
      1. 有些动画效果 CSS3 无法实现,如改变元素scrollTop的值进行滚动,这样就只能使用 js 的相关方法了。
      2. CSS3 的动画无法实现过于复杂的动画效果,如 CSS3 支持控制动画速度赛贝尔曲线的数值有限,更复杂的动画效果得使用 js 结合相关算法才能完成
    • 接着回到正题哈, 那requestAnimationFramesetTimeOutsetInterval又有和区别呢,嗯,接下来就是正题了。
    • setTimeOutsetInterval出现的问题:

        1. 首先,我们得知道动画的渲染是一帧一帧的进行的,每一帧就是动画的一个静止状态,每一帧连起来就成为了一个动画。因此每一帧的时间间隔要足够短动画才显得平滑流畅,但每一帧又不能间隔得太短,因为浏览器每一秒的渲染能是有限的,而且屏幕的刷新能力也是有限的,大多数的显示器刷新频率是 60H 也就是每秒 60 帧,因此浏览器的重绘频率不会超过显示器的刷新频率。
      1. 所以每一帧大约 17 秒就是最佳的重绘间隔。那使用就直接使用setTimeOut或者setInterval,间隔设置为 17 不就得了?但这样还是不行的。

        1. 因浏览器的毫秒不精确:浏览器的计时器精度并非精确到毫秒级的,IE8 的精确度是 15ms 多一点,而 IE9 等大多数的浏览器精确度都在 4ms 差不多。所以难以保证动画最佳的时间间隔。
        2. 不同的浏览器渲染能力不同,因此并非每一帧 17ms 就是最佳渲染间隔。
        3. 在不需要动画的地方,如后台标签页,动画任然在运行,消耗 CPU 的性能。
    • 因此,h5 的requestAnimationFrame就是解决以上问题的。
    1. requestAnimationFrame 的特点:

        1. requestAnimationFrame会把每一帧中所有的 DOM 操作集中起来,在一次重绘或者重排中就完成。
      1. requestAnimationFrame重绘或者重排的时间间隔是系统的时间间隔,因为不同的浏览器的系统时间间隔不同,requestAnimationFrame将会保持最佳的绘制间隔,即不会因为绘制间隔时间过短而造成浏览器渲染能力跟不上,也不会因为绘制间隔时间过长,而造成动画卡顿。这样就能在不同的浏览器中实现最佳的绘制效果。
      2. 在隐藏或者不可见的元素中,requestAnimationFrame将不会进行重排或者重绘,而运行在页面没有激活的情况下,如requestAnimationFrame运行在后台标签页中,动画将会暂停,有效的节省了 CPU 的开销。
    • 那么,该如何使用requestAnimationFrame呢?

requestAnimationFrame 的具体使用:

    • requestAnimationFrame使用非常简单,只需传入改变 DOM 的函数,然后反复调用requestAnimationFrame即可达到动画效果了。requestAnimationFrame 返回一个整数型请求 id 的,可以用cancelAnimationFrame函数去取消传入requestAnimationFrame的回调函数。具体使用可以看MDN 的教程
上次更新: 8/13/2020, 6:23:50 PM