WTF小程序之animation

目錄

小程序的 animation 有一套怪異的 API,既不符合 css 的 keyframes,又不符合 DOM 的 API,能夠說是一個四不像,因此好久以來,我是對這個 API 是有點排斥的,可是,在對 cover-view 中進行動畫的時候,還非得用這個 API 不可。由於對 cover-view 進行變換存在着一些 BUG
css

animation 的幾個關鍵方法

animation 實例由 wx.createAnimation 建立獲得,支持的變換方法有:html

Object.getOwnPropertyNames(wx.createAnimation().__proto__)

["constructor", "export", "step", "matrix", "matrix3d", "rotate", "rotate3d", "rotateX", "rotateY", "rotateZ", "scale", "scale3d", "scaleX", "scaleY", "scaleZ", "skew", "skewX", "skewY", "translate", "translate3d", "translateX", "translateY", "translateZ", "opacity", "backgroundColor", "width", "height", "left", "right", "top", "bottom"]

拋開這些控制變換的方法不談,咱們要認識下面這兩個對傳統 DOM 來講相對陌生的方法:export 方法和 step 方法。
vue

step 方法

step 方法在一系列變換以後調用,而且接受 4 個可選參數:duration, timingFunction, delay,transformOrigin,其餘三個參數跟 css 沒啥區別,值得一提的是 duration 這個參數,它能夠取值爲 0,這有什麼用呢?能夠用來重置動畫到最初的狀態:小程序

this.animation.rotate(0, 0)
                  .scale(1)
                  .translate(0, 0)
                  .skew(0, 0)
                  .step({duration: 0}) // 設置 duration: 0 來使動畫回到初始狀態

那麼這個 step 方法是作什麼用的呢?它就比如是武術中的一 "招",在這一招以內,全部的動做都是同步進行的。當 step 被調用時,以前調用的全部變換是同時進行的,step 調用後再變換就會被放到下一 "招" 中。試比較下面的兩段代碼的不一樣:api

// 在一招以內,移動 100 的同時後空翻 180

this.animation.rotate(180).translateX(100).step({duration: 800})

// 第一招先移動 100,第二招後空翻 180

this.animation.rotate(180).step({duration:400}).translateX(100).step({duration: 400})

儘管上面兩個動畫都用時 800ms,可是它們表現是不一致的,見下圖:數組

兩個 step
一個 step

export 方法

export 方法返回一個具備 actions 屬性的對象,其中 actions 是一個對象數組。這個對象描述了一個 step 裏全部的變換以及所用的時間等信息。仍是拿上面的例子來講,下圖分別爲一個 step 和兩個 step 的 actions 對象:能夠看出,調用 step 的次數和 actions 數組的長度是相等的。
工具

在調用 export 方法以後,經過將這個具備 action 屬性的對象 setData 到 animationData 上面,最終的內部實現多是,小程序經過改變元素的 style 的 transition 值,最終實現一步一步的動畫。(在開發者工具能夠看出對應元素的 style 發生了變化)flex

uploading-image-272905.png

到這裏,咱們能夠發現,其實所謂的 animation,是由一系列的 transition 依次觸發,組合而成,而一個 step 是一個 transition。也就不難理解,在沒有重置動畫的狀況下,爲何再去 export 不會觸發動畫,由於此時元素在上一次動畫的做用下,元素的 style 已經被設置爲最終狀態,也就不會有過渡動畫產生。若是想再次觸發動畫,必須使用 step({duration:0}) 對動畫進行重置。動畫

如何實現 infinate 動畫

在小程序的 api 下,如何實現 infinate 動畫呢,這就要用到 transitionend 事件了。⚠️ 這個事件會在一個step結束後觸發一次,也就是說,若是你export了5個step,那麼在整個動畫進行過程當中會觸發5次this

官方文檔告訴咱們,這個事件會在 WXSS transition 或 wx.createAnimation 動畫結束後觸發,因此咱們能夠在一個 step 結束以後重置動畫,而後再次 export,實現 infinate 動畫,直接看代碼 (mpvue):

// wxml

    <cover-image src="../img/line.png" :animation="animationData" @transitionend="reAnimation" ></cover-image>


// js

    onReady () {
      this.animation = wx.createAnimation({
        duration: 8000,
        timingFunction: 'linear',
        delay: 0,
        transformOrigin: '50% 50% 0'
      })
      this.animation.rotate(360).step()
      this.animationData = this.animation.export()

    },

      reAnimation () {
        this.animation.rotate(0).step({duration: 0}) // 重置動畫
        this.animationData = this.animation.export()
        setTimeout(() => {
          this.animation.rotate(360).step()
          this.animationData = this.animation.export()
        }, 60)// 播放下一次動畫
      },

(本文完,不對之處還望指出)

相關文章
相關標籤/搜索