Implementation of the function of the vue circular percentage progress bar component

Implementation of the function of the vue circular percentage progress bar component

Anyone in need can refer to it. If you have tried it and found any problems, please leave a message to let me know. I will be very grateful.

Function introduction:

1. If the page is not refreshed, and the first value is less than the second value, or the incremental animation is executed when the ring is initialized

2. If the page is not refreshed and the first value is greater than the second value, the decreasing animation is executed

3. The percentage number displayed in the middle has a slow animation (the speed is the same as the circular progress animation)

4. The animation completion callback will be triggered when the animation is completed

5. External value is the circle progress percentage (integer), circle animation speed (integer)

The effect is shown in the figure:

<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: { // The recommended value is 0-3
      type: [String, Number],
      default: 1
    }
  },
  data () {
    return {
      percent: 0,
      initDeg: 0,
      timeId: null,
      animation: 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) { // When the angle is greater than 180, the animation is executed this.$refs.leftcontent.style.transform = 'rotate(' + (deg - 180) + 'deg)'
    },
    rotateRight (deg) { // When the angle is less than 180, the animation is executed this.$refs.rightcontent.style.transform = 'rotate(' + deg + 'deg)'
    },
    goRotate(deg) {
      this.animationing = true
      this.timeId = setInterval(() => {
        if (deg > this.initDeg) { // Incremental animation this.initDeg += Number(this.speed)
          if (this.initDeg >= 180) {
            this.rotateLeft(this.initDeg)
            this.rotateRight(180) // To avoid the situation where the value converted from the percentages passed in twice is not an integer of the step length, which may cause the left and right rotation to fail.
          } else {
            this.rotateRight(this.initDeg)
          }
        } else { // Decrease animation this.initDeg -= Number(this.speed)
          if (this.initDeg >= 180) {
            this.rotateLeft(this.initDeg)
          } else {
            this.rotateLeft(180) // To avoid the situation where the value converted from the percentages passed in twice is not an integer of the step length, which may cause the left and right rotation to fail.
            this.rotateRight(this.initDeg)
          }
        }
        this.percent = this.transformToPercent(this.initDeg) // Percentage data scrolling animation 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 // Percentage data scrolling animation this.animationing = false
      clearInterval(this.timeId)
      this.$emit('animationFinished') // callback when animation is completed}
  },
  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>

The above is the detailed content of the implementation of the vue circular percentage progress bar component function. For more information about the vue progress bar, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • Vue implements dynamic circular percentage progress bar
  • Using vue+ElementUI+echarts front-end and back-end interaction to realize dynamic donut chart in Springboot project (recommended)
  • Springboot uses vue+echarts front-end and back-end interaction to realize dynamic donut chart
  • Example of implementing circular progress bar in Vue
  • Vue dynamically draws the effect of three-quarters donut chart
  • Example code of using echarts to make a donut chart in vue
  • Vue uses canvas to draw a circle

<<:  Pitfalls and solutions for upgrading MySQL 5.7.23 in CentOS 7

>>:  Solution to nginx not jumping to the upstream address

Recommend

Example code of implementing starry sky animation with CSS3 advanced LESS

This article introduces the sample code of advanc...

Web design tips on form input boxes

This article lists some tips and codes about form...

Detailed explanation of samba + OPENldap to build a file sharing server

Here I use samba (file sharing service) v4.9.1 + ...

Specific use of Linux gcc command

01. Command Overview The gcc command uses the C/C...

Semantics: Is Html/Xhtml really standards-compliant?

<br />Original text: http://jorux.com/archiv...

How to install MySQL under Linux (yum and source code compilation)

Here are two ways to install MySQL under Linux: y...

jQuery implements accordion small case

This article shares the specific code of jQuery t...

Handtrack.js library for real-time monitoring of hand movements (recommended)

【Introduction】: Handtrack.js is a prototype libra...

Vue song progress bar sample code

Note that this is not a project created by vue-cl...

How to install jupyter in docker on centos and open ports

Table of contents Install jupyter Docker port map...

Using js to implement the two-way binding function of data in Vue2.0

Object.defineProperty Understanding grammar: Obje...

PHP scheduled backup MySQL and mysqldump syntax parameters detailed

First, let's introduce several common operati...

Thirty HTML coding guidelines for beginners

1. Always close HTML tags In the source code of p...