效果图

semicircle-progress 自定义组件
<canvas type="2d" id="ring" class="progress-canvas"></canvas>
.progress-canvas {
width: 300rpx;
height: 300rpx;
}
Component({
properties: {
percentage: Number,
activeColor: {
type: String,
value: '#56B37F',
},
GradientColor: {
type: String,
value: '#c0e674',
},
},
lifetimes: {
ready() {
const query = this.createSelectorQuery();
query
.select('#ring')
.fields({ node: true, size: true })
.exec(res => {
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
const width = res[0].width;
const height = res[0].height;
const dpr = wx.getSystemInfoSync().pixelRatio;
canvas.width = width * dpr;
canvas.height = height * dpr;
ctx.scale(dpr, dpr);
this.drawProgress(ctx, width, height);
});
},
},
methods: {
drawProgress(ctx, width, height) {
ctx.beginPath();
ctx.arc(
width / 2,
height / 2,
width / 2 - 10,
(3 / 4) * Math.PI,
(9 / 4) * Math.PI
);
ctx.lineWidth = 15;
ctx.lineCap = 'round';
ctx.strokeStyle = '#eaeff4';
ctx.stroke();
ctx.beginPath();
ctx.arc(
width / 2,
height / 2,
width / 2 - 10,
(3 / 4) * Math.PI,
this.percentageToAngle(this.data.percentage)
);
ctx.lineWidth = 15;
ctx.lineCap = 'round';
if (this.data.GradientColor) {
const grd = ctx.createLinearGradient(0, 0, 100, 90);
grd.addColorStop(0, this.data.activeColor);
grd.addColorStop(1, this.data.GradientColor);
ctx.strokeStyle = grd;
} else {
ctx.strokeStyle = this.data.activeColor;
}
ctx.stroke();
},
percentageToAngle(percentage) {
const deltaAngle = (3 / 2) * Math.PI;
const start = (3 / 4) * Math.PI;
if (percentage >= 1) {
return deltaAngle + start;
} else if (percentage <= 0) {
return start;
} else {
return deltaAngle * percentage + start;
}
},
},
});
使用
{
"usingComponents": {
"semicircle-progress": "/components/semicircle-progress/index"
}
}
<semicircle-progress percentage="{{percentage}}"/>