环形进度条的模样
设计思路
// 将 圆分为两半, 画出两个半圆
// 超出部分 overflow: hidden, rotate(-45deg)
// 初始化时 先把 进度条 隐藏
html部分
<div id="wrap">
<div class="box-left">
<div class="circle-left" ref="left"></div>
</div>
<div class="box-right">
<div class="circle-right" ref="right"></div>
</div>
<div class="mark-box">
<!-- 显示进度条数值的元素 -->
<div class="number">{{percent}}</div>
</div>
</div>
css部分
#wrap{
width: 200px; // 总width为200px
height: 200px;
margin: 20px auto;
position: relative;
border-radius: 50%;
}
/*底部圆圈*/
#wrap::before{
content: "";
position: absolute;
width: 95%;
height: 95%;
box-sizing: border-box;
left: 4px;
top: 4px;
border: 10px solid #F0BFC4;
border-radius: 50%;
}
/*左右两个盒子里面各放着一个半圆圈,主要overflow*/
.box-left, .box-right{
width: 50%;
height: 100%;
box-sizing: border-box;
position: absolute;
top: 0;
overflow: hidden;
}
.box-left, .circle-left{
left: 0;
}
.box-right, .circle-right{
right: 0;
}
.circle-left, .circle-right{
width: 200%;
height: 100%;
box-sizing: border-box;
border: 20px #C40112 solid;
border-radius: 50%;
position: absolute;
top: 0px;
}
/*左边盒子里的圆圈初始时只显示在右半边*/
.circle-left{
border-top-color: transparent;
border-left-color: transparent;
transform: rotate(-45deg);
}
/*右边盒子里的圆圈初始时只显示在左半边*/
.circle-right{
border-bottom-color: transparent;
border-right-color: transparent;
transform: rotate(-45deg);
}
js部分
initData () {
let _this = this
function go (target, total) {
let that = _this
let avg = div(target,total) // 总的平均数
let progress = 0
let now = 0
// 用定时器模拟进度增长
let progressAvg
if(avg >= 0.5) {
progress = div(total, 2)
that.$refs.right.style.transform = 'rotate(135deg)'
}
let interVal = setInterval(() => {
progress++
progressAvg = div(progress, target) // 目标平均 (目前走动的进度 / 总的要走的target)
requestAnimationFrame(grow)
if (target <= progress) {
clearInterval(interVal)
}
}, 10)
function grow () {
if (progress > target) {
return;
}
// 如果进度数值有变化才做dom操作
if (progress !== now) {
now = progress;
// deg : 360 块
let deg = (360 * avg) * progressAvg
if (avg < 0.5) { // 小于半圆
that.$refs.right.style.transform = `rotate(${deg - 45}deg)`
// that.$refs.left.style.transform = 'rotate(-45deg)'
} else if (avg === 0.5) {
that.$refs.right.style.transform = 'rotate(135deg)'
} else if (avg >= 0.5 && avg < 1) { // 如果进度值大于50,那就左边半圆转动
that.$refs.left.style.transform = `rotate(${deg - 225}deg)`
} else if (avg >= 1) {
that.$refs.left.style.transform = 'rotate(135deg)'
that.$refs.right.style.transform = 'rotate(135deg)'
}
}
}
}
go(this.target, this.total);
}