buddhism/components/circle-progress/circle-progress.vue

137 lines
2.7 KiB
Vue

<!--@example-->
<!--<circle-progress-->
<!-- :canvas-size="120"-->
<!-- :progress="80"-->
<!-- content="学习进度"-->
<!-- progress-color="#42b983"-->
<!--&gt;</circle-progress>-->
<template>
<!-- 圆形进度条 -->
<view
:style="{ width: canvasSize + 'px', height: canvasSize + 'px' }"
class="progress-container"
>
<canvas
:style="{ width: canvasSize + 'px', height: canvasSize + 'px' }"
canvas-id="progressCanvas"
class="progress-canvas"
></canvas>
<view class="progress-text">
<text class="percent">{{ progress }}%</text>
<text class="label">{{ content }}</text>
</view>
</view>
</template>
<script>
export default {
name: "circle-progress",
props: {
progress: {
type: Number,
default: 80,
},
canvasSize: {
type: Number,
default: 80,
},
strokeWidth: {
type: Number,
default: 12,
},
bgColor: {
type: String,
default: "#f0f0f0",
},
progressColor: {
type: String,
default: "#007AFF",
},
textColor: {
type: String,
default: "#333",
},
content: {
type: String,
default: "",
},
},
mounted() {
this.drawProgress();
},
watch: {
progress() {
this.drawProgress();
},
progressColor() {
this.drawProgress();
},
},
methods: {
// 绘制进度条
drawProgress() {
const { progress, canvasSize, strokeWidth, bgColor, progressColor } =
this;
const ctx = uni.createCanvasContext("progressCanvas", this);
const center = canvasSize / 2;
const radius = center - strokeWidth / 2;
// 清除画布
ctx.clearRect(0, 0, canvasSize, canvasSize);
// 绘制背景圆
ctx.beginPath();
ctx.arc(center, center, radius, 0, 2 * Math.PI);
ctx.setStrokeStyle(bgColor);
ctx.setLineWidth(strokeWidth);
ctx.stroke();
// 绘制进度圆
const startAngle = -Math.PI / 2; // 从顶部开始
const endAngle = startAngle + (progress / 100) * 2 * Math.PI;
ctx.beginPath();
ctx.arc(center, center, radius, startAngle, endAngle);
ctx.setStrokeStyle(progressColor);
ctx.setLineWidth(strokeWidth);
ctx.setLineCap("round");
ctx.stroke();
ctx.draw();
},
},
};
</script>
<style scoped>
.progress-container {
position: relative;
}
.progress-canvas {
border-radius: 50%;
box-shadow: 0 8rpx 25rpx rgba(0, 0, 0, 0.1);
}
.progress-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
}
.percent {
font-size: 28rpx;
font-weight: bold;
color: #333;
display: block;
}
.label {
font-size: 24rpx;
color: #666;
display: block;
margin-top: 10rpx;
}
</style>