效果如下:
代码如下:
<template>
<div>
<!-- 圆环背景 -->
<canvas id="canvas" style="width: 100%;height: 100%">
</canvas>
</div>
![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/71c0bcaa7a9d4df0b93840d5765d26a0~tplv-k3u1fbpfcp-watermark.image?)
</template>
![image.png](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5fe8e07943d144b096767fa5fdc853fe~tplv-k3u1fbpfcp-watermark.image?)
<script>
export default {
// 电量环形图
name:'electricQuantity',
props:{
num:{
type:Number,
default:()=>0
}
},
data(){
return{
defaultValue:0,
timer:null
}
},
created(){
this.$nextTick(()=>{
this.drawCanvas()
})
},
watch:{
num:function(){
this.drawCanvas()
}
},
methods:{
drawCanvas(){
var canvas=document.getElementById('canvas');
canvas.width = 300
canvas.height = 300
var ctx=canvas.getContext("2d")
this.timer = setInterval(()=>{
this.drawMove(ctx)
},5)
},
drawMove(ctx){
ctx.clearRect(0, 0, 300, 300);
const {defaultValue,num} = this
// 外部圆环
ctx.lineWidth = 2
ctx.beginPath();
ctx.arc(150,150,150,0,Math.PI * 2,false);
var canvasGradient = ctx.createLinearGradient(150, 150, 40, 150);
// ctx.strokeStyle='#fff';
canvasGradient.addColorStop(0, "#289EFF");
canvasGradient.addColorStop(0.12, "#00EBCE");
//将fillStyle的属性值设为该CanvasGradient对象
ctx.strokeStyle = canvasGradient;
ctx.closePath()
ctx.stroke();
// 内部空槽
ctx.lineWidth = 23
ctx.beginPath();
ctx.arc(150,150,120,0,Math.PI * 2,false);
ctx.strokeStyle='rgb(29,39,53)';
ctx.closePath()
ctx.stroke();
if(defaultValue>=num){
this.defaultValue = num
clearInterval(this.timer)
}else{
this.defaultValue = this.defaultValue + 1
}
ctx.lineWidth = 23
ctx.beginPath();
ctx.arc(150,150,120,Math.PI*1.5,this.defaultValue?Math.PI * ((this.defaultValue/100 -0.25)*2-0.0001):Math.PI*1.5,false);
var canvasGradient = ctx.createLinearGradient(150, 0, 150, 300);
canvasGradient.addColorStop(0, "#289EFF");
canvasGradient.addColorStop(1, "#00EBCE");
ctx.strokeStyle = canvasGradient;
// ctx.closePath()
ctx.stroke();
// 文字部分
if(this.defaultValue >= 100){
ctx.font = "bold 50px arial";
}else{
ctx.font = "bold 70px arial";
}
ctx.fillStyle='#02D3FD';
ctx.fillText(this.defaultValue,105,160);
let numWidth = ctx.measureText(this.defaultValue).width
ctx.font = "bold 20px arial";
ctx.fillStyle='#02D3FD';
ctx.fillText("%",110+numWidth,160);
ctx.font = "23px arial";
ctx.fillStyle='#02D3FD';
ctx.fillText("电量剩余",105,190);
// 起点小圆
ctx.beginPath();
ctx.arc(150, 10, 5, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = '#27A0FE';
ctx.fill();
// 终点小圆
let x = 150 + Math.cos(this.defaultValue?Math.PI * ((this.defaultValue/100 -0.25)*2-0.0001):Math.PI*1.5) * 140
let y = 150 + Math.sin(this.defaultValue?Math.PI * ((this.defaultValue/100 -0.25)*2-0.0001):Math.PI*1.5) * 140
ctx.beginPath();
ctx.arc(x, y, 5, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fillStyle = '#27A0FE';
ctx.fill();
}
},
}
</script>
感觉有很多不妥,欢迎大佬指正
记录萌新第一步