工作中遇到需要实现圆环式渐变颜色的进度条倒计时,这篇文章记录一下,方便日后查看。
本文内容只是实现了简单的5S 10S 20S等(符合100的因数) 倒计时。
1.效果图:
2.代码
<template>
<view class="progress-box">
<!-- 旧的 -->
<canvas style="width: 370px; height: 370px; border: 2px solid red;" canvas-id="firstCanvas">
</canvas>
<button bindtap="timeDown(5)">5s倒计时</button>
<button bindtap="timeDown(25)">25s倒计时</button>
<button bindtap="timeDown(100)">100s倒计时</button>
</view>
</template>
<script>
import wepy from 'wepy';
export default class circleProgress extends wepy.page {
config = {
navigationBarTitleText: 'canvas环形渐变进度条',
navigationBarBackgroundColor: '#F9F9F9',
};
data = {
colorArr: [],
precent: 100,
startColor: '#FFA309',
endColor: '#FF5E0B',
num: 0, // 当前进度
context: null,
id: null,
allTime: 5,
nums: []
};
methods = {
timeDown(e) {
this.allTime = Number(e)
this.num = 0
this.nums = []
this.calNums()
this.calInterTime()
this.draw()
}
}
calNums() {
let singleNum = this.precent / this.allTime
for(let i = 0; i <= this.allTime; i++) {
this.nums.push(singleNum * i)
}
// console.log('this.nums', this.nums)
}
calInterTime() {
this.inter = this.allTime * 1000 / this.precent
// console.log('this.inter', this.inter)
}
getColorArr() {
let startRgb = this.hexToRgb(this.startColor)
let endRgb = this.hexToRgb(this.endColor)
let stepR = (endRgb[0] - startRgb[0]) / this.precent
let stepG = (endRgb[1] - startRgb[1]) / this.precent
let stepB = (endRgb[2] - startRgb[2]) / this.precent
for (let i = 0; i <= this.precent; i++) {
let hex = this.rgbToHex(startRgb[0] + stepR * i, startRgb[1] + stepG * i, startRgb[2] + stepB * i)
hex = hex.length == 4 ? ('00' + hex) : hex.length == 5 ? ('0' + hex) : hex
this.colorArr.push('#' + hex)
}
// console.log('this.colorArr', this.colorArr)
}
hexToRgb(hex) {
if (hex.length == 4)
return [parseInt('0x' + hex.slice(1, 2).repeat(2)), parseInt('0x' + hex.slice(2, 3).repeat(2)), parseInt('0x' + hex.slice(3, 4).repeat(2))]
else if (hex.length == 7)
return [parseInt('0x' + hex.slice(1, 3)), parseInt('0x' + hex.slice(3, 5)), parseInt('0x' + hex.slice(5, 7))]
else
alert('颜色错误')
}
rgbToHex(r, g, b) {
return ((r << 16) | (g << 8) | b).toString(16)
}
onLoad(options) {
this.init()
}
onShow() {}
init() {
this.context = wx.createCanvasContext('firstCanvas')
this.getColorArr()
}
draw() {
this.context.clearRect(0, 0, 370, 370)
this.drawCircle()
let index = -1
this.id = setInterval(() => {
if(this.num <= this.precent) {
index = this.nums.indexOf(this.num)
if(index > -1) {
this.context.clearRect(105, 105, 90, 90)
this.drawText(this.nums.length - index - 1)
}
this.drawProgress(this.num, this.precent)
this.num++
console.log('this.num', this.num)
} else {
clearInterval(this.id)
}
}, this.inter);
}
// 画字
drawText(currentTime) {
this.context.save();
this.context.fillStyle = '#3396c7'
this.context.font = '40px Helvetica'
this.context.textAlign = 'center';
this.context.fillText(currentTime + 'S', 150, 160)
this.context.restore()
}
// 画进度条
drawProgress(num, precent) {
this.context.setLineWidth(50)
this.context.setStrokeStyle(this.colorArr[num])
this.context.setLineCap('round')
this.context.arc(150, 150, 100, - Math.PI / 2 + (num - 1) * 2 * Math.PI / precent, - Math.PI / 2 + num * 2 * Math.PI / precent)
this.context.stroke()
this.context.draw(true)
}
// 画轨道
drawCircle() {
this.context.arc(150, 150, 100, 0, 2 * Math.PI)
this.context.setLineWidth(50)
this.context.setStrokeStyle('yellow')
this.context.setLineCap('round')
this.context.stroke()
this.context.draw()
}
watch = {
}
}
</script>
<style lang="less">
</style>