mpvue小程式迴圈動畫開啟暫停

tingzhong發表於2019-05-14

用小程式的animation屬性實現迴圈動畫的開啟與暫停,並封裝到元件。

  • 實現一個字型圖示元件的迴圈旋轉動畫開啟/暫停
    • 用於點選圖示,字型顏色變換,開始迴圈旋轉動畫,並重新整理內容

    • 重新整理結束,停止動畫,並設定字型顏色為原來的

    • 主要利用setInterval定時器迴圈執行動畫

首先,元件寫出來

新增點選事件,動畫屬性,style屬性(用來動態修改樣式)

  • src/components/refresh.vue
<template>
  <div>
    <div
      class="iconfont icon-shuaxin"
      :animation='refreshA'
      @click="refresh"
      :style='style'></div>
  </div>
</template>
複製程式碼

設定初始資料

使用一個 布林 資料refreshing判斷動畫的狀態為開啟true/暫停false

<script>
export default {
  data () {
    return {
      refreshA: null,
      style: 'color: #eee;',
      // 用來設定儲存旋轉的度數
      rotate: 0,
      // 儲存定時器id
      refreshI: null
    }
  },
  props: ['refreshing']
}
</script>
複製程式碼

新增點選事件函式

<script>
export default {
  methods: {
    // 重新整理按鈕點選
    refresh () {
      // 正在重新整理 則跳出,避免在迴圈動畫執行時,再次出發點選重新整理事件
      if (this.refreshing) return
      // 否則提交重新整理事件
      this.$emit('refresh')
    },
    // 重新整理動畫結束
    refreshend () {
    	// 當動畫結束,字型顏色恢復原來
      this.style = 'color: #eee;'
    }
  }
}
</script>
複製程式碼

監聽refreshing狀態

<script>
export default {
  watch: {
    refreshing (newV, oldV) {
      // 沒有正在重新整理 > 正在重新整理 設定迴圈動畫
      if (newV && !oldV) {
        this.style = 'color: #fff;'
        this.refreshI = setInterval(() => {
        // 每次 +360 實現每 300 毫秒旋轉 360 度  
          this.rotate += 360
          let animation = wx.createAnimation()
          animation.rotateZ(this.rotate).step()
          this.refreshA = animation.export()
        }, 300)
        return
      }
      // 從正在重新整理 > 重新整理完成  清空迴圈定時器動畫
      if (!newV && oldV) {
        // 防止網速過快,動畫佇列還沒生成就重新整理完成,這裡判斷動畫佇列是否為空
        // 為空,就重置一下樣式
        this.style = 'color: #eee;'
        
        clearInterval(this.refreshI)
        this.refreshA = null
      }
    }
  }
}
</script>
複製程式碼
  • 需要注意的是定時器時間必須和動畫的過渡時間設定為相同

元件呼叫

  • src/pages/index/index.vue
<template>
  <div>
    <Refresh @refresh='refresh' :refreshing='refreshing'/>
  </div>
</template>

<script>
import Refresh from '@/components/refresh'

export default {
  data: {
    // 初始狀態肯定為 false ,點選重新整理元件後,在事件函式中再設定為 true
    refreshing: false
  },
  components: {
    Refresh
  },
  methods: {
    async refresh () {
    this.refreshing = true
    // 這裡為一個非同步請求api
    let data = await api.getData()
    // 請求完成,執行想要操作的程式碼後,設定動畫為 false
    // this.data = data
    this.refreshing = false
    }
  }
}
</script>

<style lang="stylus" scoped>
</style>
複製程式碼

refresh元件完整程式碼

<template>
  <div>
    <div
      class="iconfont icon-shuaxin"
      :animation='refreshA'
      @click="refresh"
      :style='style'></div>
  </div>
</template>

<script>
export default {
  data () {
    return {
      refreshA: null,
      style: 'color: #eee;',
      rotate: 0,
      refreshI: null
    }
  },
  props: ['refreshing'],
  watch: {
    refreshing (newV, oldV) {
      if (newV && !oldV) {
        this.style = 'color: #fff;'
        this.refreshI = setInterval(() => {
          this.rotate += 360
          let animation = wx.createAnimation()
          animation.rotateZ(this.rotate).step()
          this.refreshA = animation.export()
        }, 300)
        return
      }
      if (!newV && oldV) {
        this.style = 'color: #eee;'
        clearInterval(this.refreshI)
        this.refreshA = null
      }
    }
  },
  methods: {
    refresh () {
      if (this.refreshing) return
      this.$emit('refresh')
    },
    refreshend () {
      this.style = 'color: #eee;'
    }
  }
}
</script>

<style lang="stylus" scoped>
</style>

複製程式碼

效果

  • 正常效果,看圖中右上角

mpvue小程式迴圈動畫開啟暫停

  • 網速太快

mpvue小程式迴圈動畫開啟暫停

相關文章