Appearance
17%
复制代码
查看源代码
vue
<template>
<div class="content">
<!-- div css 旋转实现进度条 -->
<div class="one">
<div class="circle-box">
<div class="circle a">
<div class="txt">{{ getProcess }}%</div>
</div>
<div class="circle b" :style="{ transform: `rotate(${fillProcess}deg)` }"></div>
<div class="mark"></div>
</div>
</div>
<!-- svg实现 -->
<div class="second">
<svg class="dashboard" viewBox="0 0 100 100">
<!-- 定义渐变色 -->
<defs>
<linearGradient id="gradient" gradientUnits="userSpaceOnUse" x1="50" y1="0" x2="50" y2="100%">
<stop offset="0%" style="stop-color: rgba(111, 232, 191, 1)" />
<stop offset="33%" style="stop-color: rgba(255, 175, 19, 1)" />
<stop offset="70%" style="stop-color: rgba(222, 19, 80, 1)" />
<stop offset="100%" style="stop-color: rgba(133, 14, 205, 1)" />
</linearGradient>
</defs>
<!-- 背景圆环 -->
<circle class="circle-background" cx="50" cy="50" r="40"></circle>
<!-- 进度圆环 -->
<circle class="circle-progress" cx="50" cy="50" r="40"></circle>
</svg>
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted, onUnmounted } from 'vue'
const ROTATE = 180
const fillProcess = ref(0)
const fillAction = ref(null)
const getProcess = computed(() => {
return ((fillProcess.value / ROTATE) * 100).toFixed(0)
})
const start = () => {
fillAction.value = setInterval(() => {
const str = Math.floor(Math.random() * 10) + 1
if (str + fillProcess.value >= ROTATE) {
fillProcess.value = ROTATE
} else if (fillProcess.value >= ROTATE) {
stop()
} else {
fillProcess.value += str
}
}, 200)
}
const stop = () => {
clearInterval(fillAction.value)
}
onMounted(() => {
// 第一段
start()
// 第二段
// 设置初始进度为0%
setProgress(0)
// 模拟过渡效果,从0%到50%
setTimeout(() => {
setProgress(100)
}, 1000) // 过渡时间为1秒,你可以根据需要调整这个值
})
const setProgress = function (value) {
const circleProgress = document.querySelector('.circle-progress')
const circleBackground = document.querySelector('.circle-background')
const circumference = 2 * Math.PI * 40 // 圆的周长
const circumNewLength = (value / 100) * (circumference - 52)
const dashOffset = 163 - circumNewLength
// 设置进度圆环的样式
circleBackground.style.strokeDashoffset = dashOffset
circleBackground.style.strokeDasharray = `${200 - circumNewLength}, ${52 + circumNewLength}`
circleProgress.style.strokeDasharray = `${circumNewLength}, ${circumference - circumNewLength}`
}
onUnmounted(() => {
stop()
})
</script>
<style lang="scss" scoped>
.one {
.circle-box {
position: relative;
width: 200px;
height: 200px;
}
.circle {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
border-radius: 50%;
clip-path: inset(0 0 50% 0);
box-sizing: border-box;
}
.a {
border: 10px solid #ccc;
transform: rotate(180deg);
}
.b {
border: 10px solid green;
position: relative;
&::after {
position: absolute;
transform: rotate(180deg);
left: 90%;
bottom: 50%;
content: '';
width: 10px;
height: 10px;
background: red;
}
}
.txt {
position: absolute;
top: 30%;
left: 50%;
transform: translate(-50%) rotate(180deg);
}
.mark {
position: absolute;
left: -5%;
top: 0;
width: 110%;
height: 50%;
background-color: white;
}
}
/* 第二段 */
.second {
.dashboard {
position: relative;
width: 200px;
height: 200px;
background-size: 100% 100%;
}
.circle-background {
fill: none; /* 不填充 */
stroke: #fff; /* 圆环的颜色 */
stroke-width: 10; /* 圆环的宽度 */
stroke-dasharray: 200, 52; /* 圆环断开部分的长度,总长度为周长 */
stroke-dashoffset: 163;
stroke-linecap: round;
border-radius: 10;
transition: all 1s; /* 过渡效果时间 */
}
.circle-progress {
fill: none; /* 不填充 */
stroke: url(#gradient); /* 圆环的颜色 */
stroke-width: 10; /* 圆环的宽度 */
stroke-dasharray: 252, 0; /* 圆环断开部分的长度,总长度为周长 */
stroke-dashoffset: 163;
stroke-linecap: round; /* 圆滑断点 */
transition: all 1s; /* 过渡效果时间 */
}
}
</style>
``` :::
隐藏源代码