参考文档:
张鑫旭大佬的博客:https://www.zhangxinxu.com/study/201710/colorful-time-count-d...
改造后的效果:
源码:vue3 <script lang="ts" setup> 模式版本:
<template>
<div
class="config-progress"
:style="`--size:${size}px; --circle-size:${circleSize}px;`"
>
<svg :width="size" :height="size" :viewBox="`0 0 ${size} ${size}`">
<defs>
<linearGradient id="color1">
<stop
v-for="(item, index) in color1"
:key="index"
:offset="index === 0 ? 0 : 1 / (color1.length - 1) * index"
:style="`stop-color:${item}`"
/>
</linearGradient>
<linearGradient id="color2">
<stop
v-for="(item, index) in color2"
:key="index"
:offset="index === 0 ? 0 : 1 / (color2.length - 1) * index"
:style="`stop-color:${item}`"
/>
</linearGradient>
</defs>
<!-- 外层 圆点 -->
<circle
stroke="#C3C3C3"
class="out-border"
stroke-dasharray="1,5"
v-if="showBorder"
/>
<!-- 内层 圆点 -->
<circle
stroke="#C3C3C3"
class="inner-border"
stroke-dasharray="1,5"
v-if="showBorder"
/>
<!-- 背景色 -->
<circle stroke="#DBDBDB" class="group placeholder" />
<circle
stroke="url(#color1)"
class="group progress"
stroke-linecap="round"
:stroke-dasharray="`${value1}, ${perimeter}`"
:transform="`rotate(-90,${size / 2},${size / 2})`"
/>
<circle
stroke="url(#color2)"
class="group progress"
stroke-linecap="round"
:stroke-dasharray="`${value2}, ${perimeter}`"
:transform="`rotate(90,${size / 2},${size / 2})`"
v-if="percentage > 50"
/>
</svg>
<div class="shadow">
<slot />
</div>
</div>
</template>
<script setup lang="ts">
import { computed, defineProps } from 'vue';
interface IProps {
size?: number;
circleSize?: number;
colors?: string[];
percentage: number;
showBorder?: boolean;
}
const props = defineProps<IProps>({
size: 250,
color: ['#FF5353', '#FF7400 ', '#fff000', '#A4DC66', '#4BCCCC'],
circleSize: 24,
percentage: 0,
showBorder: false
});
const outerBorderSize = computed(() => props.size * 0.012);
const outerBorderSpace = computed(() => props.size * 0.016);
const color1 = computed(() => [props.colors[2], props.colors[1], props.colors[0]]);
const color2 = computed(() => [props.colors[4], props.colors[4], props.colors[3], props.colors[2]]);
const perimeter = computed(() => {
const r = props.size / 2 - outerBorderSize.value - outerBorderSpace.value - props.circleSize / 2;
return 2 * Math.PI * r;
});
const value1 = computed(() => {
const v = (props.percentage * perimeter.value) / 100;
return v > perimeter.value ? perimeter.value : v;
});
const value2 = computed(() => {
return ((props.percentage - 50) * perimeter.value) / 100;
});
</script>
<style scoped lang="scss">
.config-progress {
width: var(--size);
height: var(--size);
--outer-border-length: calc(var(--size) * 0.012);
--outer-border-space: calc(var(--size) * 0.016);
position: relative;
.shadow {
position: absolute;
top: calc(var(--outer-border-length) + var(--outer-border-space) + var(--circle-size));
left: calc(var(--outer-border-length) + var(--outer-border-space) + var(--circle-size));
width: calc(var(--size) - var(--outer-border-length) * 2 - var(--outer-border-space) * 2 - var(--circle-size) * 2);
height: calc(var(--size) - var(--outer-border-length) * 2 - var(--outer-border-space) * 2 - var(--circle-size) * 2);
border-radius: 50%;
box-shadow: 0 0 calc(var(--circle-size) / 2) rgba(0, 0, 0, 0.25);
padding: calc(var(--outer-border-length) + var(--outer-border-space));
box-sizing: border-box;
}
svg {
width: var(--size);
height: var(--size);
background-color: transparent;
}
svg {
circle {
fill: none;
cx: calc(var(--size) / 2);
cy: calc(var(--size) / 2);
}
.out-border {
stroke-width: var(--outer-border-length);
r: calc(var(--size) / 2 - var(--outer-border-length));
transform-origin: 50% 50%;
}
.shadow {
r: calc(var(--size) / 2 - var(--outer-border-length) / 2 - var(--outer-border-space) - var(--circle-size));
fill: rgba(0, 0, 0, 1);
}
.group {
r: calc(var(--size) / 2 - var(--outer-border-length) - var(--outer-border-space) - var(--circle-size) / 2);
stroke-width: var(--circle-size);
}
.inner-border {
stroke-width: var(--outer-border-length);
r: calc(var(--size) / 2 - var(--outer-border-length) - var(--outer-border-space) * 2 - var(--circle-size));
transform-origin: 50% 50%;
}
.progress {
}
}
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes rotate2 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(-360deg);
}
}
</style>
调用:
<CirclePercentage :percentage='40' :show-border='false' :size='100' :circle-size='24'/>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。