vue圓環百分比進度條組件功能的實現

  有需要的人可以參考一下,如果試用過,發現問題,歡迎留言告知,不勝感激。

功能介紹:

1、若頁面無刷新,且第一次傳值小於第二次傳值或者圓環初始化時執行的是遞增動畫

2、若頁面無刷新,且第一次傳值大於第二次傳值則為執行遞減動畫

3、中間展示的百分比數字有緩動動畫(速度同圓環進度動畫一直)

4、動畫完成時會觸發動畫完成回調

5、外部傳值為圓環進度百分比(整數),圓環動畫速度(整數)

效果如圖所示:

<template>
  <div class="percentloop">
    <div class="circle-left">
      <div ref="leftcontent"></div>
    </div>
    <div class="circle-right">
      <div ref="rightcontent"></div>
    </div>
    <div class="number">
      {{ percent }} %
    </div>
  </div>
</template>

<script>
export default {
  props: {
    percentNum: {
      type: [String, Number],
      default: 0
    },
    speed: { // 建議取值為0-3
      type: [String, Number],
      default: 1
    }
  },
  data () {
    return {
      percent: 0,
      initDeg: 0,
      timeId: null,
      animationing: false
    }
  },
  methods: {
    transformToDeg (percent) {
      let deg = 0
      if (percent >= 100) {
        deg = 360
      } else {
        deg = parseInt(360 * percent / 100)
      }
      return deg
    },
    transformToPercent (deg) {
      let percent = 0
      if (deg >= 360) {
        percent = 100
      } else {
        percent = parseInt(100 * deg / 360)
      }
      return percent
    },
    rotateLeft (deg) { // 大於180時,執行的動畫
      this.$refs.leftcontent.style.transform = 'rotate(' + (deg - 180) + 'deg)'
    },
    rotateRight (deg) { // 小於180時,執行的動畫
      this.$refs.rightcontent.style.transform = 'rotate(' + deg + 'deg)'
    },
    goRotate (deg) {
      this.animationing = true
      this.timeId = setInterval(() => {
        if (deg > this.initDeg) { // 遞增動畫
          this.initDeg += Number(this.speed)
          if (this.initDeg >= 180) {
            this.rotateLeft(this.initDeg)
            this.rotateRight(180) // 為避免前後兩次傳入的百分比轉換為度數後的值不為步距的整數,可能出現的左右轉動不到位的情況。
          } else {
            this.rotateRight(this.initDeg)
          }
        } else { // 遞減動畫
          this.initDeg -= Number(this.speed)
          if (this.initDeg >= 180) {
            this.rotateLeft(this.initDeg)
          } else {
            this.rotateLeft(180) // 為避免前後兩次傳入的百分比轉換為度數後的值不為步距的整數,可能出現的左右轉動不到位的情況。
            this.rotateRight(this.initDeg)
          }
        }
        this.percent = this.transformToPercent(this.initDeg) // 百分比數據滾動動畫
        const remainer = Number(deg) - this.initDeg
        if (Math.abs(remainer) < this.speed) {
          this.initDeg += remainer
          if (this.initDeg > 180) {
            this.rotateLeft(deg)
          } else {
            this.rotateRight(deg)
          }
          this.animationFinished()
        }
      }, 10)
    },
    animationFinished () {
      this.percent = this.percentNum // 百分比數據滾動動畫
      this.animationing = false
      clearInterval(this.timeId)
      this.$emit('animationFinished') // 動畫完成的回調
    }
  },
  created () {
    this.goRotate(this.transformToDeg(this.percentNum))
  },
  watch: {
    'percentNum': function (val) {
      if (this.animationing) return
      this.goRotate(this.transformToDeg(val))
    }
  }
}
</script>

<style scoped lang="scss">
.percentloop {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  overflow: hidden;
  .circle-left, .circle-right {
    position: absolute;
    top: 0;
    left: 0;
    width: 50%;
    height: 100%;
    background-color: red;
    overflow: hidden;
    &>div {
      width: 100%;
      height: 100%;
      background-color: #8a8a8a;
      transform-origin: right center;
      /*transition: all .5s linear;*/
    }
  }
  .circle-right {
    left: 50%;
    &>div {
      transform-origin: left center;
    }
  }
  .number {
    position: absolute;
    top: 9%;
    bottom: 9%;
    left: 9%;
    right: 9%;
    background-color: #fff;
    border-radius: 50%;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #000;
  }
}
</style>

以上就是vue圓環百分比進度條組件功能的實現的詳細內容,更多關於vue進度條的資料請關註WalkonNet其它相關文章!

推薦閱讀: