Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money

preface

Blessed by Buddha, there is no bug. Hello everyone! I am across the sea!

Sometimes in a project we have to take a prototype from the UI and turn it into a concrete page that uses components that are not readily available. At this point, you need to implement these specific components yourself.

These are components that you can use, that are generic to you, that you can reuse.

This time to summarize is a small module to show the data, the effects are general, look at the general, just to show the data, and there is a circle constantly turning, looks easy, let’s record

Introduction to implementation process

The effect is as follows:

Look under bright theme

With a dark theme

Let’s start with the implementation

  1. Functionally display specificLevel of numericalValue indicates the Chinese label
  2. There is a constantly rotating loop on the exterior, which is fromcssStarting with
  3. There are background color more theme switch, pass a variable to control the theme, first write the correspondingThe CSS background

So let’s go to the code

<template>
  <div :class="['container', {'bg_light': !isDarkTheme, 'bg_dark': isDarkTheme}]">
    <div class="bg3 Clockwise1" style=""></div>
    <div class="bg2 Clockwise1" style=""></div>
    <div :class="[{'bg1': !isDarkTheme, 'bg12': isDarkTheme}] " style="">
      <el-progress :width="112" :height="112" :stroke-width="9" :show-text="false"
       style="position:relative; Left: 18.5 px; Top: 18.5 px;"
       type="dashboard" :percentage="percentage" :color="colors"></el-progress>
      <div class="chartTxt">
        <div :class="{'apiValue': true, 'aqiTxtColorNull': aqiLvl === '", 'aqiTxtColorI': aqiLvl === '', 'aqiTxtColorI': AqiLvl === 'good ', 'aqiTxtColorIII': aqiLvl ===' mild ', 'aqiTxtColorIV': aqiTxtColorIV': aqiTxtColorVI': AqiLvl === 'seriously polluted ', 'aqiTxtColorV': aqiLvl ===' seriously polluted '}">{{apiValue? ApiValue: 'no'}}</div>
        <div :class="{'aqiLvl': true, 'lvlColorNull': aqiLvl === '", 'lvlColorI': aqiLvl ===' good ', 'lvlColorII': AqiLvl === 'good ', 'lvlColorIII': aqiLvl ===' mild ', 'lvlColorIV': aqiLvl === 'moderate ', 'lvlColorVI': AqiLvl = = = 'polluted', 'lvlColorV: aqiLvl = = =' severe pollution '}">
          <span class="aqiTxt">{{aqiLvl? AqiLvl: 'none '}}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  / / value
  props: ['apiValue'.'aqiLvl'.'isDarkTheme'].computed: {
    percentage() {
      // We express progress in percentage terms, because sometimes the value passed may not be exactly 100. So we usually deal with that
      if (typeof this.apiValue === 'string' || typeof this.apiValue === 'number') {
        // The actual value of the processing percentage is divided by the upper limit and multiplied by 100
        // 300 is the AQI rating. 300-500 is the severe pollution range
        if (this.apiValue * 1 < 300) {
          const dealValue = (this.apiValue * 1 / 300) * 100;
          return dealValue;
        } else {
          return 100; }}return 100; }},data() {
    return {
      // percentage: 10,
      colors: [{color: '#00e400'.percentage: 10 },
        { color: '#ffff00'.percentage: 20 },
        { color: '#ff7e00'.percentage: 30 },
        { color: '#ff0000'.percentage: 40 },
        { color: '#99004c'.percentage: 60 },
        { color: '#7e0023'.percentage: 100},]}; },methods: {}};</script>

<style scoped>* {margin: 0;
  padding: 0;
}
@-webkit-keyframes rotate{from{-webkit-transform: rotate(0deg)}
  to{-webkit-transform: rotate(360deg)}}@-moz-keyframes rotate{from{-moz-transform: rotate(0deg)}
  to{-moz-transform: rotate(359deg)}}@-o-keyframes rotate{from{-o-transform: rotate(0deg)}
  to{-o-transform: rotate(359deg)}}@keyframes rotate{from{transform: rotate(0deg)}
  to{transform: rotate(359deg)}}.Clockwise1{
  -webkit-animation: rotate 15s linear infinite;
  -moz-animation: rotate 15s linear infinite;
  -o-animation: rotate 15s linear infinite;
  animation: rotate 15s linear infinite;
}
.container{
  margin-top: 10px;
  width: 149px;
  height: 150px;
  border: 0px solid red;
  background-color: transparent;
}
.bg_light{
  background-color: rgba(239.245.254.9);
}
.bg_dark{
  background-color: rgba(3.22.37.85);
}
.bg1{
  border: 0px solid blue;
  position: relative;
  top: -300px;
  width:149px;
  height: 150px;
  background-image:  url(~ @ / assets/imgs/spin 0. PNG);
}
.bg12{
  border: 0px solid blue;
  position: relative;
  top: -300px;
  width:149px;
  height: 150px;
  background-image:  url(~@/assets/imgs/ rotate 0 backup. PNG);
}
.bg2{
  border: 0px solid green;
  position: relative;
  top: -150px;
  width:149px;
  height: 150px;
  background-image:  url(~ @ / assets/imgs/rotating 1. PNG);
  opacity: 0.6;
}
.bg3{
  position: relative;
  width:149px;
  height: 150px;
  background-image:  url(~ @ / assets/imgs/rotating (2) the PNG);
  opacity: 0.6;
}
.bg1 >>> svg path:first-child {
  stroke: #ffffff;
}
.bg12 >>> svg path:first-child {
  stroke: #ffffff;
}
.chartTxt{
  width: 65px;
  /* border: 1px solid white; * /
  text-align: center;
  position: relative;
  left: 43px;
  top: -65px;
}
.apiValue{
  font-size: 27px;
  text-shadow: # 000 0.5 px. 0.5 px. 0.5 px..# 000 0 0.5 px. 0.# 000 -0.5 px. 0 0.# 000 0 -0.5 px. 0;
}
.aqiTxtColorNull{
  color: gray;
}
.aqiTxtColorI{
  color: #00e400;
}
.aqiTxtColorII{
    color: #ffff00;
}
.aqiTxtColorIII{
    color: #ff7e00;
}
.aqiTxtColorIV{
    color: #ff0000;
}
.aqiTxtColorV{
    color: #99004c;
}
.aqiTxtColorVI{
    color: #7e0023;
}
.aqiLvl{
  width: 100%;
  height: 20px;
  border-radius: 10px;
  line-height: 20px;
  font-size: 14px;
  /* position: relative; * /
  /* left: -7px; * /
  color: white
}
.aqiTxt{
  border-radius: 5px;
  padding: 2px;
  text-shadow: # 000 0.5 px. 0.5 px. 0.5 px..# 000 0 0.5 px. 0.# 000 -0.5 px. 0 0.# 000 0 -0.5 px. 0;
}
.lvlColorNull{
  background-color: gray;
}
.lvlColorI{
    background-color: #00e400;
}
.lvlColorII{
    background-color: #ffff00;
}
.lvlColorIII{
    background-color: #ff7e00;
}
.lvlColorIV{
    background-color: #ff0000;
}
.lvlColorV{
    background-color: #99004c;
}
.lvlColorVI{
    background-color: #7e0023;
}
</style>
Copy the code

Since this is a component, let’s refer to it

<template>
  <div>
    <module :apiValue="curApiValue" :aqiLvl="curAqiLvl" :isDarkTheme="curIsDarkTheme"/>
  </div>
</template>

<script>
// Water balloon progress component
import module from '. /.. /.. /components/comRotateSgin'
export default {
  name: 'test'.components: {
    module,},data() {
    return {
      curApiValue: 30.// Specific value
      curAqiLvl: 'best'.// The label corresponding to the specific value (excellent, good, Slightly polluted, moderately polluted, severely polluted, severely polluted)
      curIsDarkTheme: true.// true: dark theme fasle: bright theme}},methods: {},mounted(){},}</script>

<style scope>

</style>
Copy the code

Picture materials used:

You can get the F12 console

  1. Spin 0. PNG

  1. Rotate 0 backup.png

  1. Rotating 1. PNG

  1. Rotate 1 backup.png

subsequent

Later, the artists gave a new prototype that looked better

Look under bright theme

With a dark theme

The main difficulty is that each color level of the circle transitions naturally, so how to draw the small circle on the picture to the corresponding color of different AQI values? Because of the natural transition, it is not easy to grasp the color level boundary.

The idea here is to set a fixed value for the AQI interval of different levels (this value is the Angle to which the small circle should turn), and then use the corresponding value of the AQI value in the actual transmitted level interval

Specific process:

Component complete code

<template>
  <div :class="['container', {'bg_light': !isDarkTheme, 'bg_dark': isDarkTheme}]">
    <div class="bg3 Clockwise1" style=""></div>
    <div class="bg2 Clockwise1" style=""></div>
    <div :class="[{'bg1': !isDarkTheme, 'bg12': isDarkTheme}] " style="">
      <div class="percentBg" style="">
        <div class="percentBgValue" :style="'transform: rotate(' + percentage + 'deg); '"></div>
      </div>
      <div class="chartTxt">
        <div :class="{'apiValue': true, 'aqiTxtColorNull': aqiLvl === '", 'aqiTxtColorI': aqiLvl === '', 'aqiTxtColorI': AqiLvl === 'good ', 'aqiTxtColorIII': aqiLvl ===' mild ', 'aqiTxtColorIV': aqiTxtColorIV': aqiTxtColorVI': AqiLvl === 'seriously polluted ', 'aqiTxtColorV': aqiLvl ===' seriously polluted '}">{{apiValue? ApiValue: 'no'}}</div>
        <div :class="{'aqiLvl': true, 'lvlColorNull': aqiLvl === '", 'lvlColorI': aqiLvl ===' good ', 'lvlColorII': AqiLvl === 'good ', 'lvlColorIII': aqiLvl ===' mild ', 'lvlColorIV': aqiLvl === 'moderate ', 'lvlColorVI': AqiLvl = = = 'polluted', 'lvlColorV: aqiLvl = = =' severe pollution '}">
          <span class="aqiTxt">{{aqiLvl? AqiLvl: 'none '}}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: ['apiValue'.'aqiLvl'.'isDarkTheme'].computed: {
    percentage() {
      if (typeof this.apiValue === 'string' || typeof this.apiValue === 'number') {
        const value = this.dealAQIValue(this.apiValue * 1);
        return value;
      } else {
        return 0; }}},data() {
    return {
      // percentage: 10,
      colors: [{color: '#00e400'.percentage: 10 },
        { color: '#ffff00'.percentage: 20 },
        { color: '#ff7e00'.percentage: 30 },
        { color: '#ff0000'.percentage: 40 },
        { color: '#99004c'.percentage: 60 },
        { color: '#7e0023'.percentage: 100},]}; },methods: {
    dealAQIValue(value) {
      let perValue = 0;
      if (value >= 0 && value <= 50) {
        perValue = 23;
      } else if (value > 50 && value <= 100) {
        perValue = 72;
      } else if (value > 100 && value <= 150) {
        perValue = 128;
      } else if (value > 150 && value <= 200) {
        perValue = 192;
      } else if (value > 200 && value <= 300) {
        perValue = 288;
      } else if (value > 300) {
        perValue = 346;
      }
      returnperValue; ,}}};</script>

<style scoped>* {margin: 0;
  padding: 0;
}
@-webkit-keyframes rotate{from{-webkit-transform: rotate(0deg)}
  to{-webkit-transform: rotate(360deg)}}@-moz-keyframes rotate{from{-moz-transform: rotate(0deg)}
  to{-moz-transform: rotate(359deg)}}@-o-keyframes rotate{from{-o-transform: rotate(0deg)}
  to{-o-transform: rotate(359deg)}}@keyframes rotate{from{transform: rotate(0deg)}
  to{transform: rotate(359deg)}}.Clockwise1{
  -webkit-animation: rotate 15s linear infinite;
  -moz-animation: rotate 15s linear infinite;
  -o-animation: rotate 15s linear infinite;
  animation: rotate 15s linear infinite;
}
.container{
  margin-top: 10px;
  width: 149px;
  height: 150px;
  border: 0px solid red;
  background-color: transparent;
}
.bg_light{
  background-color: rgba(239.245.254.9);
}
.bg_dark{
  background-color: rgba(3.22.37.85);
}
.bg1{
  border: 0px solid blue;
  position: relative;
  top: -300px;
  width:149px;
  height: 150px;
}
.bg12{
  border: 0px solid blue;
  position: relative;
  top: -300px;
  width:149px;
  height: 150px;
}
.bg2{
  border: 0px solid green;
  position: relative;
  top: -150px;
  width:149px;
  height: 150px;
  background-image:  url(~ @ / assets/imgs/group 263. PNG);
  opacity: 0.6;
}
.bg3{
  position: relative;
  width:149px;
  height: 150px;
  opacity: 0.6;
}
.bg1 >>> svg path:first-child {
  stroke: #ffffff;
}
.bg12 >>> svg path:first-child {
  stroke: #ffffff;
}
.percentBg{
  width:126px;
  height: 126px;
  background-image:  url(~@/assets/imgs/ percentage of rotation.png);
  position:relative;
  top: 13px;
  left: 12px;
}
.percentBgValue{
  width:126px;
  height: 126px;
  background-image:  url(~@/assets/ IMgs/Rotation percentage value. PNG);
  position:relative;
  top: 0px;
  left: 0px;
}
.chartTxt{
  width: 65px;
  /* border: 1px solid white; * /
  text-align: center;
  position: relative;
  left: 43px;
  top: -65px;
}
.apiValue{
  font-size: 27px;
  text-shadow: # 000 0.5 px. 0.5 px. 0.5 px..# 000 0 0.5 px. 0.# 000 -0.5 px. 0 0.# 000 0 -0.5 px. 0;
}
.aqiTxtColorNull{
  color: gray;
}
.aqiTxtColorI{
  color: #00e400;
}
.aqiTxtColorII{
    color: #ffff00;
}
.aqiTxtColorIII{
    color: #ff7e00;
}
.aqiTxtColorIV{
    color: #ff0000;
}
.aqiTxtColorV{
    color: #99004c;
}
.aqiTxtColorVI{
    color: #7e0023;
}
.aqiLvl{
  width: 100%;
  height: 20px;
  border-radius: 10px;
  line-height: 20px;
  font-size: 14px;
  /* position: relative; * /
  /* left: -7px; * /
  color: white
}
.aqiTxt{
  border-radius: 5px;
  padding: 2px;
  text-shadow: # 000 0.5 px. 0.5 px. 0.5 px..# 000 0 0.5 px. 0.# 000 -0.5 px. 0 0.# 000 0 -0.5 px. 0;
}
.lvlColorNull{
  background-color: gray;
}
.lvlColorI{
    background-color: #00e400;
}
.lvlColorII{
    background-color: #ffff00;
}
.lvlColorIII{
    background-color: #ff7e00;
}
.lvlColorIV{
    background-color: #ff0000;
}
.lvlColorV{
    background-color: #99004c;
}
.lvlColorVI{
    background-color: #7e0023;
}
</style>
Copy the code

The reference method is the same as above

Pictures used:

  1. Percentage rotation.png

  1. The rotation percentage value.png

  1. Group 263. PNG

Now that you’ve seen this, please give me a thumbs up before you go, because your thumbs up means a lot to me