环形进度条
动画效果一直都喜欢用setInterval,看到了文档提供了requestAnimationFrame,所以尝试了一下,下面是代码(组件)。
wxml
<view class="progress-container">
<canvas class="canvas" type="2d" id="posterCanvas"></canvas>
<view wx:if="{{showText}}" class="num-text">
<view class="num">{{number}}</view>
<view class="text">{{text}}</view>
</view>
</view>
js
Component({
properties: {
showText: {
type: Boolean,
value: true,
},
percent: {
type: Number,
value: 0,
},
number: {
type: Number,
value: 0,
},
text: {
type: String,
value: '打卡天数',
},
},
data: {},
attached() {
this.value = 0;
this.init();
},
methods: {
init() {
const query = this.createSelectorQuery();
query
.select('#posterCanvas')
.fields({ node: true, size: true })
.exec((res) => {
const canvas = res[0].node;
const ctx = canvas.getContext('2d');
const system = wx.getSystemInfoSync();
const dpr = system.pixelRatio;
const ratio = system.windowWidth / 750;
canvas.width = res[0].width * dpr;
canvas.height = res[0].height * dpr;
ctx.scale(dpr, dpr);
// 设置圆环的宽度
ctx.lineWidth = parseInt(10 * ratio);
// 设置圆环端点的形状
ctx.lineCap = 'round';
this.drawBottomColor(ctx, ratio);
if (this.data.percent !== 0) {
const renderLoop = () => {
if (this.value <= this.data.percent) {
this.render(ctx, ratio);
canvas.requestAnimationFrame(renderLoop);
}
};
canvas.requestAnimationFrame(renderLoop);
}
});
},
render(ctx, ratio) {
ctx.clearRect(0, 0, parseInt(750 * ratio), parseInt(240 * ratio));
this.draw(ctx, ratio);
},
draw(ctx, ratio) {
// 画底色
this.drawBottomColor(ctx, ratio);
// 画高亮色
this.drawActiveColor(ctx, ratio, this.value++);
ctx.stroke();
},
// 底色条
drawBottomColor(ctx, ratio) {
ctx.beginPath();
ctx.strokeStyle = '#F8F8F8';
ctx.arc(
parseInt(90 * ratio),
parseInt(90 * ratio),
parseInt(85 * ratio),
-0.5 * Math.PI,
1.5 * Math.PI,
false
);
ctx.stroke();
},
// 高亮进度条
drawActiveColor(ctx, ratio, percent) {
ctx.beginPath();
ctx.strokeStyle = '#00CBA3'; // 设置圆环的颜色
ctx.arc(
parseInt(90 * ratio),
parseInt(90 * ratio),
parseInt(85 * ratio),
-0.5 * Math.PI,
-0.5 * Math.PI + Number(percent / 100) * 2 * Math.PI,
false
);
},
},
});