没啥用系列 之 《多色渐变环形进度条》之 CSS var( ) 函数 / background: conic-gradient( )

前言

很多开源的 UI 组件库,都有 进度条 ,直接使用就行,学习成本很低。往细了扣,他们能达到的效果和实现方式也各有不同,

比如:Echarts 用 <canvas/> ,ice-Design 用 <svg/>,Ant Design 用 <div/>。

看这篇文章可以干什么:

一. 可以学习,css 的几个不常用的函数。(为什么不常用我还要学ヾ(≧O≦)〃,因为好玩。( *︾▽︾))

二. 可以实现,多色渐变环形进度条。据本人有限的认识中,还没有那个库实现了“多色环形渐变”,这个较真的需求(我就遇到过 = = !)。

  (注意:是环形渐变,而不是左右的线性渐变,请仔细看)

正式开始

一. 环形进度条

先复习一下,background 的三种渐变:

linear-gradient : 线性渐变

radial-gradient : 径向渐变

conic-gradient : 圆锥渐变

圆锥渐变有个很好的用处,它可以模拟绘制 饼图 。

由此延伸:

css 部分

:root {
  --primary-color: hsl(196, 78%, 61%);
  --secondary-color: hsl(217, 15%, 83%);
  --success-color: hsl(165, 58%, 55%);
  --info-color: hsl(214, 79%, 65%);
  --warning-color: hsl(43, 100%, 66%);
  --danger-color: hsl(354, 81%, 63%);
  --primary-color-darker: hsl(196, 68%, 54%);
  --secondary-color-darker: hsl(215, 13%, 70%);
  --success-color-darker: hsl(165, 55%, 48%);
  --info-color-darker: hsl(214, 68%, 58%);
  --warning-color-darker: hsl(39, 97%, 62%);
  --danger-color-darker: hsl(354, 67%, 56%);
  --primary-color-lighter: hsl(196, 78%, 81%);
  --secondary-color-lighter: hsl(214, 16%, 92%);
  --success-color-lighter: hsl(165, 58%, 75%);
  --info-color-lighter: hsl(214, 79%, 85%);
  --warning-color-lighter: hsl(43, 100%, 86%);
  --danger-color-lighter: hsl(354, 81%, 83%);
  --secondary-color-darkest: hsl(215, 11%, 30%);
  --secondary-color-lightest: hsl(220, 1%, 98%);
  --gauge-color: #000;
  --gauge-bg: white;
  --gauge-width: 90px;
}

.box{
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 300px;
}

.progressBar{
  // 在行间设置
  // --gauge-value: 900;
  // --gauge-max-value: 1000;
  --gauge-percentage: calc(var(--gauge-value) / var(--gauge-max-value) * 100%);
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: var(--gauge-width);
  height: var(--gauge-width);
  color: var(--gauge-color);
  --gauge-circle-color: var(--info-color);
  --gauge-circle-color-lighter: var(--info-color-lighter);
  background: conic-gradient(var(--gauge-circle-color) var(--gauge-percentage), var(--gauge-circle-color-lighter) 0);
  border-radius: 50%;
  counter-reset: value var(--gauge-value); // counter-reset 对部分和子部分进行编号的方法
}

.progressBar::before {
  content: counter(value);
  position: absolute;
  font-family: auto;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 90%;
  height: 90%;
  background: var(--gauge-bg);
  border-radius: inherit;
}

html 部分:

<div className="box">
  <span className="progressBar" style={{"--gauge-value": "900", "--gauge-max-value": "1000"}}></span>
</div>

 

二. 渐变色环形进度条:

css 部分:

:root {
  --primary-color: hsl(196, 78%, 61%);
  --secondary-color: hsl(217, 15%, 83%);
  --success-color: hsl(165, 58%, 55%);
  --info-color: hsl(214, 79%, 65%);
  --warning-color: hsl(43, 100%, 66%);
  --serious-color: #FF904D;
  --danger-color: hsl(354, 81%, 63%);
  --primary-color-darker: hsl(196, 68%, 54%);
  --secondary-color-darker: hsl(215, 13%, 70%);
  --success-color-darker: hsl(165, 55%, 48%);
  --info-color-darker: hsl(214, 68%, 58%);
  --warning-color-darker: hsl(39, 97%, 62%);
  --danger-color-darker: hsl(354, 67%, 56%);
  --primary-color-lighter: hsl(196, 78%, 81%);
  --secondary-color-lighter: hsl(214, 16%, 92%);
  --success-color-lighter: hsl(165, 58%, 75%);
  --info-color-lighter: hsl(214, 79%, 85%);
  --warning-color-lighter: hsl(43, 100%, 86%);
  --danger-color-lighter: hsl(354, 81%, 83%);
  --secondary-color-darkest: hsl(215, 11%, 30%);
  --secondary-color-lightest: hsl(220, 1%, 98%);
  --gauge-color: #000;
  --gauge-bg: white;
  --gauge-width: 90px;
}

.box{
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 300px;
}

.progressBar{
  // 在行间设置,在样式表计算,的方式。也可以在 js 文件中直接计算好。
  // --gauge-value: 900;
  // --gauge-max-value: 1000;
  --gauge-percentage: calc(var(--gauge-value) / var(--gauge-max-value) * 100%);
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  width: var(--gauge-width);
  height: var(--gauge-width);
  color: var(--gauge-color);
  background: conic-gradient(
    var(--success-color-darker) 0%,
    var(--success-color) var(--Quarter), 
    var(--warning-color) var(--half), 
    var(--serious-color) var(--threeQuarters), 
    var(--danger-color) var(--gauge-percentage), 
    var(--info-color-lighter) 0);
  border-radius: 50%;
  counter-reset: value var(--gauge-value); // counter-reset 对部分和子部分进行编号的方法
}

.progressBar::before {
  content: counter(value); // 在CSS2.1中counter()只能被使用在content属性上。用来获取值。
  position: absolute;
  font-family: auto;
  display: flex;
  justify-content: center;
  align-items: center;
  width: 90%;
  height: 90%;
  background: var(--gauge-bg);
  border-radius: inherit;
}

react, js + html 部分:

import React, { Component } from "react";
import styles from './index.less';

class firstPage extends Component {
  constructor(props) {
    super(props);
    this.state = {
      num: 0,
      gaugeValue: 900,
      gaugeMaxValue: 1000,
      Quarter: 25,
      half: 50,
      threeQuarters: 75
    }
  }

  componentDidMount() {
    const { gaugeValue, gaugeMaxValue } = this.state;
    const num = gaugeValue / gaugeMaxValue * 100;
    this.setState({
      Quarter: num < 25 ? num : 25,
      half: num < 50 ? num : 50,
      threeQuarters: num < 75 ? num : 75,
    })
  }

  numAdd = () => {
    this.setState({
      num: ++this.state.num
    })
  }

  handClick = () => {
    const { gaugeValue, gaugeMaxValue } = this.state;
    const newGaugeValue = gaugeValue - 10;
    const num = newGaugeValue / gaugeMaxValue * 100;
    this.setState({
      gaugeValue: gaugeValue - 10,
      Quarter: num < 25 ? num : 25,
      half: num < 50 ? num : 50,
      threeQuarters: num < 75 ? num : 75,
    })
  }

  render() {
    const { num, gaugeValue, gaugeMaxValue, Quarter, half, threeQuarters } = this.state;
    return (
      <div>
        <div className={styles.box}>
          <span
            onClick={() => this.handClick()}
            className={styles.progressBar}
            style={{
              "--gauge-value": `${gaugeValue}`,
              "--gauge-max-value": `${gaugeMaxValue}`,
              "--Quarter": `${Quarter}%`,
              "--half": `${half}%`,
              "--threeQuarters": `${threeQuarters}%`
            }}>
          </span>
        </div>
      </div>
    )
  }
}

export default firstPage

 

posted @ 2020-08-03 18:24  真的想不出来  阅读(561)  评论(0编辑  收藏  举报