You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

77 lines
1.6 KiB

<template>
<div class="circle-progress">
<svg :width="size" :height="size" viewBox="0 0 100 100">
<!-- 背景圆环 -->
<circle
cx="50"
cy="50"
:r="radius"
fill="none"
:stroke="backgroundColor"
:stroke-width="strokeWidth"
/>
<!-- 进度圆环 -->
<circle
cx="50"
cy="50"
:r="radius"
fill="none"
:stroke="color"
:stroke-width="strokeWidth"
:stroke-dasharray="circumference"
:stroke-dashoffset="dashOffset"
class="progress"
/>
<!-- 中心文本 -->
<slot>
<text x="50" y="50" text-anchor="middle" dominant-baseline="middle" class="progress-text">
{{ text }}
{{ percentage }}%
</text>
</slot>
</svg>
</div>
</template>
<script setup lang="ts">
import { computed } from 'vue';
interface Props {
percentage: number;
size?: number;
strokeWidth?: number;
color?: string;
backgroundColor?: string;
text?: string;
}
const props = withDefaults(defineProps<Props>(), {
size: 100,
strokeWidth: 6,
color: '#409eff',
backgroundColor: '#e5e9f2',
text: ''
});
const radius = computed(() => 50 - props.strokeWidth / 2);
const circumference = computed(() => 2 * Math.PI * radius.value);
const dashOffset = computed(() =>
circumference.value * (1 - props.percentage / 100)
);
</script>
<style lang="scss" scoped>
.circle-progress {
display: inline-block;
.progress {
transform: rotate(-90deg);
transform-origin: center;
}
.progress-text {
font-size: 14px;
fill: #606266;
}
}
</style>