This is the 22nd day of my participation in the Novembermore Challenge.The final text challenge in 2021

introduce

I don’t know how to write a circular progress bar vue component in SVG before, this is a continuation of the following, we will simply use CSS without using SVG to see how to make a progress bar with a sense of technology. Here’s a sneak peek

Ok, next, will implement it, because this is a VUE component, as to how to create a project and how to use too basic, we will not do here, we are focused on the implementation of the component.

The body of the

1. Introduction to parameter transfer

export default {
  name: "ProgressBar".props: {
    value: {
      type: [String.Number].defalut: 0
    },
    text: {
      type: String.defalut: "speed"
    },
    color: {
      type: String.defalut: "#63cdda"}},mounted() {},
  methods: {}}Copy the code

We receive three parameters here:

  • Value: indicates the progress value
  • Text: Introduces the text
  • Color: main color

2. Infrastructure

<template>
  <div class="progress-bar" ref="bar">
    <div class="hoop" ref="hoop"></div>
    <h5>
      <span ref="speed">0</span>%
    </h5>
    <p>{{text}}</p>
  </div>
</template>
Copy the code

We’re just going to put text in here, we’re going to change the color with JS, and we’re going to animate the progress and we’re just going to pass 0.

3. All styles

@import "https://fonts.googleapis.com/css?family=Share+Tech+Mono";
.progress-bar {
  --skin-color: #63cdda;
  position: relative;
  width: 200px;
  height: 100px;
  border-radius: 200px 200px 0 0;
  overflow: hidden;
  background: rgba(48.47.47.5);
  &::before {
    content: "";
    display: block;
    position: absolute;
    top: 5px;
    left: 5px;
    right: 5px;
    height: 100px;
    border-radius: 200px 200px 0 0;
    background-color: # 000;
    z-index: 8;
  }
  &::after {
    content: "";
    display: block;
    position: absolute;
    top: 10px;
    left: 10px;
    right: 10px;
    height: 100px;
    border: 5px double var(--skin-color);
    opacity: 0.25;
    border-radius: 200px 200px 0 0;
    z-index: 8;
  }
  .hoop {
    position: absolute;
    width: 220px;
    height: 420px;
    left: -10px;
    background-color: var(--skin-color);
    bottom: -5px;
    transform: rotate(180deg);
    transform-origin: 50% bottom;
  }
  h5 {
    font-family: "Share Tech Mono", monospace;
    font-size: 2em;
    color: white;
    font-weight: normal;
    text-shadow: 0 0 0.2 em var(--skin-color), 0 0 0.3 em white;
    text-align: center;
    position: relative;
    margin-top: 40px;
    z-index: 9;
  }
  p {
    position: relative;
    text-transform: uppercase;
    font-weight: normal;
    font-family: "Share Tech Mono", monospace;
    font-size: 1.2 em;
    margin: 0.3 em 0;
    color: white;
    text-align: center;
    text-shadow: 0 0 0.3 em var(--skin-color), 0 0 0.6 em white;
    z-index: 9; }}Copy the code

These are all the styles we will use. Here are the main things that have been done:

  1. Here I will create a 200-by-100 rectangle using border-radius: 200px 200px 00; So you have a semicircle.

  2. Next we use the before pseudo-class to draw a small semicircle inside, remember that the color value of the small circle must be consistent with the background color, this is actually using a disguise, cover the inside of the ring so that the outside will be left, so that the empty progress bar is finished. For embellishing, draw two circular arc lines with double using the after pseudo-border style.

  3. Now we want to draw the filled arc, which is the same thing, and draw a rectangle with the center of the semicircle as the base. When it has value, we rotate it, which will cover the background color of the box. This is the way to achieve a progress bar loading. If you don’t understand, please see the schematic diagram:

4. Change the main color

We used CSS to define the main color –skin-color before, and then we will modify it according to the entered value through JS

export default {
  	name: "ProgressBar".mounted() {
        this.initSkin();
    },
    methods: {
        initSkin() { 
            this.$refs.bar.style.setProperty('--skin-color'.this.color)
        },
    }
}
Copy the code

/ / Mounted to initialize the color. / / Mounted to initialize the color. / / Mounted to initialize the color.

5. Load the animation

At the moment, it can’t move, because we need to animate it to complete its numerical and style changes. In order to expand and experience it better, we use Animo.js to help us complete the animation.

import anime from "animejs";
export default {
  	name: "ProgressBar".methods: {
        render() {
              anime({
                targets: this.$refs.speed,
                textContent: [0.this.value],
                round: 1.easing: "easeOutCirc".duration: 1000
              });

              anime({
                targets: this.$refs.hoop,
                rotate: {
                  value: [180, (this.value * 180) / 100 + 180]},easing: "easeOutCirc".duration: 1000}); }}}Copy the code

The first anime is a typeface animation, so make sure the round is set to 1, or you’ll end up with decimals if you don’t.

The second anime is the color block rotation animation, because at the beginning we set the color block rotation to 180deg so that it was horizontal at the bottom, and its variation was between 180 and 360, so we had to convert its degree in hexadecimal.


We are now done without SVG, following the half-ring progress bar component.

conclusion

Finally, consider the pros and cons of implementing this with SVG versus CSS.

SVG has some learning costs, after all many of the front ends are weak spots, but its scalability and adaptability is a better solution.

CSS is undoubtedly the most easy to achieve, even small white can understand the use and transformation, compatibility will be better. However, the disadvantages are also obvious. This time, it is realized by using a blinding overlay. If the background color is changed, it also needs to be changed, which is quite troublesome, and zoom in and out will not be as perfect as SVG. Of course, there are other schemes that do not consider the conversion of background color, either by drawing a gradient background or by cutting, but their disadvantages are compatibility problems and expansion problems are troublesome. Finally, the application scope of stacking is wider because of the camouflage method, so I choose it as the case of this issue.

You have time to practice these ways, CSS learning is very helpful.