1、效果
2、代码
<template>
<div>
<canvas ref="progressCanvas" ></canvas>
</div>
</template>
<script setup>
import { reactive, onMounted, watch ,getCurrentInstance} from "vue";
const props = defineProps({
size:{
type: Number,
default: 100
},
progress: {
type: Number||String,
default: 0,
validator: value => value >= 0 && value <= 100
},
})
onMounted(() => {
drawProgressCircle1(props.progress);
})
const { proxy } = getCurrentInstance()
function drawProgressCircle1(progress) {
const rootFontSize = 1;
// 设备像素比
const dpr = window.devicePixelRatio || 1;
const canvas = proxy.$refs.progressCanvas
// 设置canvas的样式大小
canvas.style.width = `${props.size}px`;
canvas.style.height = `${props.size}px`;
// 设置canvas的属性大小
canvas.width = props.size * rootFontSize * dpr;
canvas.height = props.size * rootFontSize * dpr;
const ctx = canvas.getContext('2d');
const radius = ( props.size * rootFontSize * dpr - 20) / 2;
const x = props.size * rootFontSize * dpr / 2;
const y = props.size * rootFontSize * dpr / 2;
// 灰色背景圈
ctx.beginPath();
ctx.arc(x, y, radius-8* dpr, 0, 2 * Math.PI);
const gradient = ctx.createLinearGradient(0, 0, x, y)
gradient.addColorStop(0, 'rgb(220, 222, 247)');
gradient.addColorStop(1, 'rgb(223, 241, 254)');
ctx.fillStyle = gradient
ctx.fill();
ctx.beginPath();
ctx.arc(x, y, radius-2* dpr, -0.5 * Math.PI, (-0.5 * Math.PI) + (2 * Math.PI ));
ctx.strokeStyle = 'rgb(229, 239, 255)'
ctx.lineWidth = 5* dpr;
ctx.stroke();
// 彩色进度圈
ctx.beginPath();
ctx.arc(x, y, radius, -0.5 * Math.PI, (-0.5 * Math.PI) + (2 * Math.PI * (progress / 100)));
const gradientCircel = ctx.createLinearGradient(0, 0, x, y)
gradientCircel.addColorStop(0, '#60C1FF');
gradientCircel.addColorStop(1, 'rgb(87, 125, 229)');
ctx.strokeStyle = gradientCircel;
ctx.lineWidth = 5* dpr;
ctx.lineCap = "round";
ctx.stroke();
ctx.font = 8*dpr + "px Microsoft YaHei";
const insertContent = progress+'%';
const measureText = ctx.measureText(insertContent);
ctx.fillStyle = '#000'
ctx.fillText(insertContent, (x - ((measureText.width)/2)), y+4* dpr);
// ctx.fillText(insertContent, 300, 300);
}
const progressWatch = watch(() => props.progress,(newVal,oldVal) => {
drawProgressCircle1(newVal)
})
</script>
<style scoped>
canvas {
display: block;
}
</style>