【庫】requestAnimationFrame:raf封裝爲setInterval格式,書寫更加得心應手

說在前頭

requestAnimationFrame靠的是刷新頻率“幀”,具體的概念我就不細說了,總之就是setInterval的替代品,對於一些平滑無時間間隔的動畫來說性能更優一些。


一、方法定義

const M = ((W) => {
  let arr = [] // 閉包作用域
  // 不用變量定義,該對象本來就在全局
  W.requestAnimationFrame = W.requestAnimationFrame || W.mozRequestAnimationFrame || W.webkitRequestAnimationFrame || W.msRequestAnimationFrame
  return {
    setInterval (fn) { // 模擬函數名 --- 循環
      const len = arr.length
      arr[len] = { // 建立動畫對象
        'for' () {},
        'animate': 0
      }
      arr[len].for = () => { // 存在閉包內
        fn()
        if (!arr[len]) { // 如果該對象被刪除了,則退出遞歸
          return
        }
        arr[len].animate = W.requestAnimationFrame(arr[len].for) // 遞歸調用
      }
      arr[len].animate = W.requestAnimationFrame(arr[len].for)
      return {
        index: len, // 返回arr數組內動畫對象的下標
        obj: arr[len], // 返回當前動畫對象
        arr: arr // 返回所有生成過的對象,便於外部控制與手動釋放
      }
    },
    clearInterval (obj) { // 清空
      if (!obj || !obj.arr) {
        return
      }
      W.cancelAnimationFrame(obj.obj.animate) // 默認清除當前傳進來的對象
      obj.obj.animate = obj.obj.for = null // 斷開依賴關係,釋放內存
      delete arr[obj.index] // 刪除對象
    }
  }
})(window)

當然也可以封裝成構造函數模式


二、方法調用

let raf = M.setInterval(() => {
  // do something......
  if (/* 判斷條件 */) {
    M.clearInterval(raf)
  }
}) // raf動畫不支持定時執行,如果要加的話,內部封裝仍然是要用setTimeout的

並沒有封裝setTimeout的,如只需執行一遍,那就同步執行完再手寫清除,或修改下封裝代碼會更簡單。


關於

make:o︻そ╆OVE▅▅▅▆▇◤(清一色天空)

blog:http://blog.csdn.net/mcky_love

掘金:https://juejin.im/user/59fbe6c66fb9a045186a159a/posts


結束語

性能是個大坑,大家一起向前匍匐摸索。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章