浏览器动画之requestAnimationFrame()


前言

在相当长的一段时间里,定时器工具是JavaScript中最常使用的动画工具,但是该方式作为动画的实现手段存在其原理上的弊端,直到requestAnimationFrame()这个API的出现,可以使浏览器以最优的时机进行重绘,自此后,requestAnimationFrame已经成为前端动画实现的最佳选择。


浏览器动画原理

要真正理解requestAnimationFrame的优势首先要清楚浏览器动画的基本实现思路。实际上就是在前端运行一个频繁触发的函数,这个函数每次运行时都是更新物体的位置属性,比如每次都沿X方向每次都会加1,当这个函数的触发频率足够高,人眼就不会有任何察觉,因此显示在屏幕上的效果就是流畅的动画了。在requestAnimationFrame之前,最常用的是setInterval定时器,结合canvas,实现每15毫秒移动一次,效果是这样的:

setInterval(() => {
      translate += 0.005;
      if (translate > 1) {
        translate = 0
      }
      gl.vertexAttrib1f(aTranslate, translate)
      gl.drawArrays(gl.POINTS, 0, 1)
    }, 15);

在这里插入图片描述

setInterval实现的动画效果如上,但是明显看到它并不流畅,这是它的设计缺陷决定的:虽然我们在代码中每隔15ms更改一次图形的位置,但是浏览器执行频率是存在极限的,一般来说浏览器的刷新频率是每秒60次,也就是每隔大约16ms执行一次,在这个频率之上即便高再多人眼也没有感知,但是为了满足尽可能使每次浏览器刷新时都能执行到我们的函数,要把时间间隔设置的尽量小,因为setInterval函数无法保证和浏览器刷新同时执行,间隔过大时在容易把浏览器“套圈”,造成丢帧现象,而间隔设置的过小又会提高运行负担,影响效率。

requestAnimationFrame()——更丝滑的动画实现

与setInterval的缺点相对应,requestAnimationFrame动画完全避免了setInterval的缺点,首先,它的执行时机完全和浏览器的刷新时机完全一致,其次,由于requestAnimationFrame是动画API,在页面销毁或隐藏时它会自动停止执行,节约了浏览器的开销。该API的使用方法是回调:

 function animate() {
      console.log('setInterval')
      translate += 0.005;
      if (translate > 1) {
        translate = 0
      }
      gl.vertexAttrib1f(aTranslate, translate)

      // 开始绘制
      gl.drawArrays(gl.POINTS, 0, 1)
      requestAnimationFrame(() => animate())
    }

    animate()

在这里插入图片描述

若需要销毁定时器,使用cancelAnimationFrame即可:

   let timer
    function animate() {
      console.log('setInterval')
      translate += 0.005;
      if (translate > 1) {
        translate = 0
      }
      gl.vertexAttrib1f(aTranslate, translate)

      // 开始绘制
      gl.drawArrays(gl.POINTS, 0, 1)
      timer = requestAnimationFrame(() => animate())
    }
    
    // 销毁定时器
    function removeAnimate(){
      cancelAnimationFrame(timer)
    }

总结

浏览器动画原理

  • 浏览器动画原理
  • setInterval不足

requestAnimationFrame()——更丝滑的动画实现

  • requestAnimationFrame优势
  • requestAnimationFrame使用
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值