仅供参考,可以自己封组件使用
<template>
<view class="list3">
<view style="width: 750rpx; height: 350rpx;background-size: cover;background-image: url('https://bpic.588ku.com/ad_diversion/22/09/01/ee5f14ee42db43bed2211537b48a5efd.png!/fw/320/unsharp/true/compress/true') ; " id="scream"></view>
<canvas style="width: 750rpx; height: 350rpx;" canvas-id="circle" id="circle"></canvas>
</view>
</template>
<script>
export default {
data(){
return {
canvas:{
},
data:[//界面所显示的等级
'V1','V2','V3','V4','V5','V6','V7','V8','V9',
],
progress: 54.45,//进度条
progressValue: 'V6',//进度所属等级,该字段为空时progress有效
progressNum:25, // 二级进度:若为100,则表示进入{{progressValue}} 的下一等级,若为50则代表{{progressValue}}和下一等级之间
tips1:'我的成长值', //界面展示的文字
tips2:'9800',//界面展示的文字
tips3:'还差50积分升级v2'//界面展示的文字
}
},
mounted() {
uni.createSelectorQuery().in(this).select("#circle").boundingClientRect(data => {
this.canvas.height = data.height;
this.canvas.width = data.width;
}).exec();
this.toCanvas();
},
methods:{
toCanvas(id) {
if(this.progressValue){
let index = this.data.indexOf(this.progressValue);
this.progress = index/(this.data.length-1)*100;
if(this.progressNum){
this.progress+= this.progressNum/(this.data.length-1)
}
console.log(index,this.progress)
}
if(this.progress>100){
this.progress =100;
}
var ctx = uni.createCanvasContext("circle")
var percent = this.progress; //最终百分比
var circleX = this.canvas.width/ 2; //中心x坐标
var circleY = 170;//this.canvas.height*1.9 / 2; //中心y坐标
var radius = 130; //圆环半径
var lineWidth = 7; //圆形线条的宽度
//中间的字
var fontSize = 25;
ctx.font = fontSize + "px April";
ctx.textAlign = "center";
ctx.fillStyle = "#000";
ctx.fillText(this.tips2, circleX, circleY*0.7);
fontSize = 12;
ctx.font = fontSize + "px April";
ctx.fillStyle = "#999";
ctx.fillText(this.tips1, circleX, circleY*0.7 - 30);
ctx.fillStyle = "#999";
ctx.fillText(this.tips3, circleX, circleY*0.7 + 20);
//画圆
function circle(cx, cy, r) {
ctx.beginPath();
ctx.lineCap = "round";
// ctx.moveTo(cx + r, cy);
ctx.lineWidth = lineWidth;
ctx.strokeStyle = "#848b8c";
ctx.arc(cx, cy, r, (Math.PI * 3.3) / 3, (Math.PI * 5.7) / 3);
ctx.stroke();
}
// 画弧线
function sector(cx, cy, r, startAngle, endAngle) {
ctx.beginPath();
//ctx.moveTo(cx, cy + r); // 从圆形底部开始画
ctx.lineWidth = lineWidth;
// // 渐变色 - 可自定义
var linGrad = ctx.createLinearGradient(
circleX - radius - lineWidth,
circleY,
circleX + radius + lineWidth,
circleY
);
linGrad.addColorStop(0.0, "#06a8f3");
linGrad.addColorStop(0.1, '#9bc4eb');
linGrad.addColorStop(1.0, "#00f8bb");
ctx.strokeStyle = linGrad;
//圆弧两端的样式
ctx.lineCap = "round";
//圆弧
ctx.arc(
cx,
cy,
r,
(Math.PI * 3.3) / 3,
(Math.PI * 3.3) / 3 + (endAngle / 100) * ((Math.PI * 0.8) ),
false
);
ctx.stroke();
}
//画等级
function dengji(cx,cy,data){
ctx.beginPath();
var my_gradient=ctx.createLinearGradient(0,0,170,0);
my_gradient.addColorStop(0,"#00d8f9");
my_gradient.addColorStop(1,"#ffd764");
ctx.fillStyle=my_gradient;
console.log(cx,cy)
for(let i=0;i<data.length;i++){
var itemAngle = 250-(157/data.length)*i;
var x = cx + radius*1.1 * Math.sin(itemAngle * 3.14 / 180);
var y =cy + radius*1.1 * Math.cos(itemAngle * 3.14 / 180);
ctx.fillText(data[i],x,y);
}
ctx.stroke();
}
dengji(circleX, circleY, this.data)
// 圆形
circle(circleX, circleY, radius);
//圆弧
sector(circleX, circleY, radius,(Math.PI * 3.3) / 3, percent);
ctx.draw()
}
}
}
</script>
<style>
#canvas{ position: absolute;z-index: 1; }
#scream{ position: absolute; }
.list3{float: right; position:relative; }
</style>
部分内容参考了网上的,自己按自己的需求做了修改和优化