Vue canvas繪製圓形進度條動畫載入

&蝶儿&發表於2024-07-03

父元件程式碼:

<template>
<!-- 建立 -->
<div class="resource-warp-box">
<div class="center-box">
<div class="used-source">
<pageTitle title="已用資源" />
<div class="progress-box">
<div
v-for="(item, index) in quotaList"
:key="index"
class="progress-content"
>
<circle-progress :percent="item.proportionNum" :strokeStyle="item.color" :id="index" />
<div class="title">{{ item.title }}</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import CircleProgress from './components/circleProgress.vue';
export default {
components: {
CircleProgress
},
data() {
return {
quotaList: [
{
title: "CPU",
color: "#1161E4",
proportionNum: 33
},
{
title: "GPU",
color: "#5860F0",
proportionNum: 50
},
{
title: "記憶體",
color: "#09D99F",
proportionNum: 80
}
],
};
},
mounted() {
},
methods: {
}
};
</script>
<style lang="scss" scoped>
.center-box {
display: flex;
margin-top: 12px;
.used-source {
background-color: #ffffff;
width: 50%;
height: 294px;
border-radius: 6px;
.progress-box {
display: flex;
margin-top: 45px;
.progress-content {
width: 33.3333%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.title {
margin-top: 28px;
font-weight: 400;
font-size: 16px;
color: #333333;
}
}
}
}
}
</style>
子元件CircleProgress 程式碼:
<template>
<div class="canvas">
<canvas :id="id" width="220" height="220" style="width:110px;height:110px;"></canvas>
</div>
</template>

<script>
export default {
data () {
return {
num:0,
canvas: '',
context: '',
cirX: '',
cirY: '',
rad: '',
n: 0,
speed: 450,
r: 49
}
},
props:[
'percent', // 進度條值
'strokeStyle', // 進度條值背景顏色
'id'
],
mounted () {
this.canvas = document.getElementById(this.id)
this.context = this.canvas.getContext("2d")
this.context.scale(2,2);
this.cirX = 55,//this.canvas.width/ 2
this.cirY = 55,//this.canvas.height/ 2
this.rad = Math.PI * 2 / 100
this.DreamLoading()
},
created () {
},
methods:{
//繪製最外層細圈
writeCircle(){
this.context.save(); //save和restore可以保證樣式屬性只運用於該段canvas元素
this.context.beginPath(); //開始路徑
this.context.strokeStyle = '#f5f8fc'; //設定邊線的顏色
this.context.lineWidth = 12;
this.context.arc(this.cirX, this.cirY, this.r, 0, Math.PI * 2, false); //畫一個圓的路徑
this.context.stroke(); //繪製邊線
this.context.closePath();
},
//繪製文字
writeText(n){
this.context.save();
this.context.font = "14px MicrosoftYaHei";
this.context.fillStyle="#333333"; //字型顏色
this.context.fillText(n.toFixed(0) + "%", this.cirX - 13 , this.cirY + 6); //繪製實心
//context.strokeStyle = "#49f";
// context.strokeText(n.toFixed(0)+"%",cirX - 30 ,cirY +10); //繪製空心
this.context.stroke();
this.context.restore();
},
//繪製藍色外圈
writeBlue(n){
this.context.save();
this.context.strokeStyle = this.strokeStyle;
this.context.lineWidth = 12;
this.context.lineCap = 'round';
this.context.beginPath();
this.context.arc(this.cirX, this.cirY, this.r, -Math.PI/2,-Math.PI/2+ this.rad * n, false);
this.context.stroke();
this.context.restore();
},
DreamLoading(){
//清除所有,重新繪製
this.context.clearRect(0,0,this.canvas.width,this.canvas.height)
this.writeCircle();
this.writeText(this.n);
this.writeBlue(this.n)
if(this.n <= this.percent){
this.n = this.n + 0.4;
}else {
return this.n = 0;
}
requestAnimationFrame(this.DreamLoading);
}
}
}
</script>
<style scoped>
.canvas {
width: 110px;
height: 110px;
}
</style>

相關文章