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

Understanding Nginx Current Limitation in One Article (Simple Implementation)

Nginx is now one of the most popular load balance...

Nodejs combined with Socket.IO to realize websocket instant communication

Table of contents Why use websocket Socket.io Ope...

How to automatically execute SQL statements when MySQL in Docker starts

When creating a MySQL container with Docker, some...

JS implements array filtering from simple to multi-condition filtering

Table of contents Single condition single data fi...

JavaScript web page entry-level development detailed explanation

Part 3: ❤Three ways to overlook backend data rece...

Tips on setting HTML table borders

For many people who are new to HTML, table <ta...

How to use the dig/nslookup command to view DNS resolution steps

dig - DNS lookup utility When a domain name acces...

Vue mobile terminal determines the direction of finger sliding on the screen

The vue mobile terminal determines the direction ...

Example analysis to fix problems in historical Linux images

Fix for issues with historical Linux images The E...

Detailed tutorial of pycharm and ssh remote access server docker

Background: Some experiments need to be completed...

Some tips on deep optimization to improve website access speed

Some tips for deep optimization to improve websit...

Node.js+postman to simulate HTTP server and client interaction

Table of contents 1. Node builds HTTP server 2. H...

Two simple ways to remove text watermarks from web pages

<br /> When we browse certain websites and s...