mpvue小程序循環動畫開啓暫停

用小程序的animation屬性實現循環動畫的開啓與暫停,並封裝到組件。vue

  • 實現一個字體圖標組件的循環旋轉動畫開啓/暫停小程序

    • 用於點擊圖標,字體顏色變換,開始循環旋轉動畫,並刷新內容
    • 刷新結束,中止動畫,並設置字體顏色爲原來的
    • 主要利用setInterval定時器循環執行動畫

首先,組件寫出來

添加點擊事件,動畫屬性,style屬性(用來動態修改樣式)api

  • 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) {
        // 防止網速過快,動畫隊列還沒生成就刷新完成,這裏判斷動畫隊列是否爲空
        // 爲空,就重置一下樣式
        if (!this.refreshA) 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) {
        if (!this.refreshA) 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>

效果

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

圖片描述

  • 網速太快

圖片描述

相關文章
相關標籤/搜索