没啥用系列 之 《多色渐变环形进度条》之 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