本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1.我们先来写css html模板
写下来大概就是用svg path先画一个圆环轨道,在用另一层带颜色的 path去覆盖颜色。圆环中的倒计时先用一个变量占位,这里还初始化了一个ps的css样式变量'stroke-dasharray': '0, 0'记住后面让圆环进度条动起来全靠它了
2.让我们再来写一个倒计时先让倒计时先动起来
//这里在state里初始化了 countDownSeconds 属性 用来记录倒计时的总秒数
//在Mounted阶段调用 timingstart方法开始计时
//使用computed计算方法 每次倒计时动态更新换算成对应时间
const state = reactive({
ps: {
'stroke-width': '40px',
'stroke-dasharray': '0, 0',
},
countdowntext:'倒计时',
countDownSeconds: 900, //900秒相当于 15分钟
t:null
})
onMounted(() => {
timingstart()
})
const countdownValue = computed(() => {
return countdownTime(state.countDownSeconds)
})
const countdownTime = (Seconds = 60) => {
var d = parseInt(Seconds / 60 / 60 / 24); //获取天数
var h = parseInt(Seconds / 60 / 60 % 24); //获取小时数
var m = parseInt(Seconds / 60 % 60); //获取分钟数
var s = parseInt(Seconds % 60); //获取秒数
m = m < 10 ? '0' + m : m;
s = s < 10 ? '0' + s : s;
return `${m}:${s}`
}
function timingstart() {
state.countDownSeconds--;
if (state.countDownSeconds <= 0) {
console.log('倒计时结束')
clearTimeout(state.t)
} else {
state.t = setTimeout(() => {
timingstart()
}, 1000)
}
}
return {
...toRefs(state),
countdownValue
}
3.圆环内的倒计时已经动起来了,接下来我们需要做些修改来让时间和圆环的进度条保持同步
这里开始没想到可以用
stroke-dasharray属性来控制进度条的加载 之前看过vant的圆环组件是使用stroke-dasharray这个属性来控制进度条的加载(心血来潮想照着模仿一个)代码趴下来 发现stroke-dasharray: 2198px, 3140px;这个有意思的css属性,经过调试大概猜出来两个属性值的意思2198px代表了当前的圆环进度,而3140px代表着总进度
想到这里感觉那这就好办了呀 但是仔细一想我当前的进度可以计算得来也就是
stroke-dasharray的第一个属性值但是,我第二个总进度条的长度(我不能写死呀,这样就不灵活了)是从何而来呢?然后好巧不巧当天晚上在B站上刷到了一条关于svg动画的教学,好家伙正好发现了可以获取svgpath路径总长度的方法getTotalLength(真是天助我也哈哈哈哈哈,下面代码有注释。)可以开心写js代码了。
const state = reactive({
ps: {
'stroke-width': '41px',
'stroke-dasharray': '0, 0',
},
countDownSeconds: 900, //900秒相当于 15分钟
activeprogress: 0, //当前进度
stepSeconds:0,
t: null,
})
onMounted(() => {
let cir = document.getElementById('cir')
let circleTotalLength = parseInt(cir.getTotalLength()) //获取path路径总长度的方法
//每秒走的进度
state.stepSeconds = Number((circleTotalLength/state.countDownSeconds).toFixed(2))
timingstart(state.stepSeconds,circleTotalLength)
})
function timingstart(step_,circleTotalLength) {
state.countDownSeconds--;
state.activeprogress += step_
state.ps = {
'stroke-width': '41px',
'stroke-dasharray': `${state.activeprogress.toFixed(2)}px,${circleTotalLength}px`,
}
if (state.countDownSeconds <= 0) {
console.log('倒计时结束')
clearTimeout(state.t)
} else {
state.t = setTimeout(() => {
timingstart(state.stepSeconds,circleTotalLength)
}, 1000)
}
}
好了到这里代码也写完了代码,其他地方还有优化的空间,这次只是写个例子提供大家参考。
如果这篇文章有帮助到你,❤️点赞❤️鼓励一下作者,谢谢大家