圆形的进度条
1.用css实现
<template>
<div class="wrap" :style="{'--finalProcess': barProcess, '--finalValue': process }">
<div class="g-progress-wrap">
<div class="circle bottom" ref="circle">
</div>
<div class="circle top" :class="{'zero': (process == 0 && readProcess === 0), 'single': process <= 25}">
<div class="dot" :class="{'zero': (process == 0 && readProcess === 0), 'single': process <= 25}"></div>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'CircularProgressBar',
props: {
barProcess: {}, // 传过来的是百分比
readProcess: {}, // 数字
},
computed: {
process() {
const num = (this.barProcess && this.barProcess.slice(0, this.barProcess.length - 1)) || 0;
return num;
},
},
};
</script>
<style lang="stylus">
.wrap
display flex
justify-content center
align-items center
width 100%
&.night
.g-progress-wrap
.circle
&.top
background: conic-gradient(#115941 0, #40806E var(--finalProcess), transparent var(--finalProcess), transparent 100%)!important;
&::before
background #115941!important
&.single
background: conic-gradient(#115941 0, #115941 var(--finalProcess), transparent var(--finalProcess), transparent 100%)!important;
.dot
&::before
background #40806E!important
&.single
&::before
background #115941!important
.g-progress-wrap
display flex
justify-content center
align-items center
width 100%
position relative
padding-top 100%
.circle
position absolute
--width: 65%
--progressGap: 17%
width: var(--width);
height: var(--width);
border-radius: 50%;
top 50%
left 50%
transform translate(-50%, -50%);
mask: radial-gradient(transparent,transparent 47%, #000 48%,#000 48%, #000 100%);
&.bottom
background-color rgba(35,179,131,0.10);
&.mask
width 50%
height 50%
background-color transparent
z-index 4
&.top
z-index 2;
background: conic-gradient(#23B383 0, #28D49B var(--finalProcess), transparent var(--finalProcess), transparent 100%);
&.zero
opacity: var(--finalValue);
&::before
content: '';
position absolute
width: var(--progressGap);
height: var(--progressGap);
left: 50%
top: 0;
transform translate(-50%, 0)
border-radius: 50%;
background: #23B383;
z-index: 1;
&.single
background: conic-gradient(#23B383 0, #23B383 var(--finalProcess), transparent var(--finalProcess), transparent 100%);
.dot
width: 100%;
height: 100%;
position absolute
top 0
left 0
z-index 6
transform translateX(-50%)
transform: rotate(calc(var(--finalValue) * 3.6deg));
&.zero
&::before
opacity: var(--finalValue);
&::before
content: '';
position absolute
width: var(--progressGap);
height: var(--progressGap);
left: 50%
top: 0;
transform translate(-50%, 0)
border-radius: 50%;
background #28D49B
z-index 10
&.single
&::before
content: '';
position absolute
width: var(--progressGap);
height: var(--progressGap);
left: 50%
top: 0;
transform translate(-50%, 0)
border-radius: 50%;
background #23B383
z-index 10
</style>
缺点:符合设计的需求,但是用的属性值不兼容低版本的chrome,chrome的版本号必须大于69,还有低版本的安卓机也不兼容。
2.用svg
<template>
<div class="wrap">
<svg viewBox="0 0 250 250" ref="svg" :style="{'--finalProcess': process}" class="circular-progress">
<defs>
<linearGradient
id="linear"
x1="0%"
y1="0%"
x2="100%"
y2="100%"
>
<stop
offset="0%"
:style="{stopColor: theme === 'night' ? '#40806E' : '#28D49B'}"
/>
<stop
offset="100%"
:style="{stopColor: theme === 'night' ? '#115941 ' : '#23B383'}"
/>
</linearGradient>
</defs>
<circle class="bg" :r="radius" :cx="cx" :cy="cy" :stroke-width="strokeWidth" ></circle>
<circle class="fg" :r="radius" :cx="cx" :cy="cy" :stroke-width="strokeWidth" :style="{strokeDasharray: `${dash} ${space}`}" stroke="url(#linear)" :class="{'zero': (process == 0 && readProcess === 0) }"></circle>
</svg>
</div>
</template>
<script>
export default {
name: 'CircularProgressBarSvg',
inheritAttrs: false,
props: {
barProcess: {},
theme: {},
readProcess: {},
},
data() {
return {
size: 220,
strokeWidth: 36,
// 圆心x轴坐标
};
},
computed: {
cx() {
return (this.size + 32) / 2;
},
// 圆心y轴坐标
cy() {
return (this.size + 30) / 2;
},
// 半径
radius() {
return (this.size - this.strokeWidth) / 2;
},
circumference() {
return 2 * Math.PI * this.radius;
},
process() {
const num = (this.barProcess && this.barProcess.slice(0, this.barProcess.length - 1)) || 0;
if (num > 62 && +num !== 100) {
return num - 6;
} else {
return num;
}
},
dash() {
return this.process * this.circumference / 100;
},
space() {
return this.circumference - this.dash;
},
},
method: {
},
};
</script>
<style lang="stylus">
.wrap
display flex
justify-content center
align-items center
margin 4px 0
width 100%
.circular-progress
width 80%
height 84%
.circular-progress circle
fill: none;
stroke-linecap: round;
.circular-progress circle.bg
stroke: rgba(35,179,131,0.1); // 描边颜色
transform: rotate(-90deg);
transform-origin: 50% 50%
background: conic-gradient(#23B383 0, #28CC95 var(--finalProcess));
.circular-progress circle.fg
transform: rotate(-90deg);
transform-origin: 50% 50%;
&.zero
opacity: var(--finalProcess);
</style>
说明:不存在兼容问题,但是不符合设计的需求。