前言
在实际开发中,环形进度条是很常用的一个组件,特别是在管理后台数据统计的页面上或是一些需要用户等待的任务。但很多时候我们都是使用现成的组件来实现,但从未自己手写实现过。
其实环形进度条实现起来也不是很难,接下来我将带你一步一步实现它!
如果你对SVG
不是很理解,可以先看下我专栏中的SVG
系列教程:点击跳转SVG系列教程
实现效果
原理
利用stroke-dasharray
和stroke-dashoffset
属性,将描边的显示进行一个偏移错位。将stroke-dasharrary
设定为圆的周长。也即是每段实线距离为圆的一圈。之后再利用stroke-dashoffset
属性进行线条的偏移来实现进度条效果。
如果你对以上这两个属性不是很明白,可以阅读前端必知必会 | 学SVG看这篇就够了(十三),这对你后续编写SVG
动画很有帮助!
用码实现
码出基本样式
先一个创建SVG
画布,绘制一个简单的圆形。作为环形进度条的基础。
<svg>
<circle cx="80" cy="80" r="50" fill="none" stroke-width="8" stroke="#7C83FD"></circle>
</svg>
我们给circle
绑定一个类,设置stroke-dasharray
、stroke-dashoffset
为圆的总长度,同时我们也把circle
标签内的一些属性放在类中。让circle
标签看起来不会很复杂。
<circle class="circle" cx="80" cy="80" r="50" fill="none" stroke-width="8"></circle>
.circle {
fill: none;
stroke: #7C83FD;
stroke-width: 8;
stroke-dasharray: 314;
stroke-dashoffset:314;
}
添加动画效果
创建一个帧动画函数circle,将stroke-dashoffset
设置为0
,并在circle
类绑定它。
.circle {
fill: none;
stroke: #7C83FD;
stroke-width: 8;
stroke-dasharray: 314;
stroke-dashoffset:314;
animation: circle 3s infinite;
}
@keyframes circle {
100%{
stroke-dashoffset:0;
}
}
到了这里,我们环型进度条效果可以说是完成了一半啦!
我们再优化下,添加stroke-linecap: round;
让切口的变为圆形状,这样子让切口看起来更舒服一些。
把圆的开口调整到12点钟方向(正上方),在circle
标签中加入transform="rotate(-90 80 80)“
。
如果你将这行代码添加到CSS
中是无效的。如果你想在CSS
中调整,你需要使用transform-origin
、transform-box
来调整图形的旋转中心点。
transform:rotate(-90deg);
transform-origin: center;
transform-box:fill-box;
加入text
标签,在圆的中心显示环形进度条的百分比效果。给数字标签绑定一个text
类,用于后续控制显示环形进度条数值。
<svg>
<circle class="circle" cx="80" cy="80" r="50" transform="rotate(-90 80 80)"></circle>
<text x="80" y="85" fill="#6b778c" text-anchor="middle">
<tspan class="text">0</tspan><tspan class="percent">%</tspan>
</text>
</svg>
.text{
font-size: 20px;
}
.percent{
font-size: 10px;
}
码出交互
移除circle
帧动画函数,在这里我们不需要使用CSS
来控制它了,加入JavaScript
代码,让我们可以自主的控制环形进度条里边的进度。
首先,定义一个圆周长的变量并将它赋值为314
,这用于我们后续进度的计算,获取SVG
画布中的circle
图形和text
中的数字标签。
let progressLen=314;
const textDom=document.getElementsByClassName('text')[0];
const circleDom=document.getElementsByClassName('circle')[0];
定义一个setPercent
函数,用于设定这个环形进度条的百分比。
setPercent=(num)=>{
if(num>100) return;
circleDom.style['stroke-dashoffset']=progressLen-(progressLen/100)*num;
textDom.innerHTML=num;
}
实现加载页面后,让环形从0
加载到100%
,在script
标签内代码末行加入以下代码即可,意思是每150毫秒更新环形进度条的进度,进度百分比=当前进度数值+随机数值。
let i=0;
setInterval(()=>{
i+=Math.floor(Math.random()*5);
if(i>=100)i=100;
setPercent(i);
},250)
在circle
类中加入transition: all 1s;
,让stroke-dashoffset
属性在更新数值时有个过渡效果,让整个过程不会很生硬。
最后
本文带着大家从零实现到一个环形进度条,使用SVG进行开发实现。我们还可以将这个环形动画引入到按钮中,或是悬浮球中作为显示,结合其他组件获得更好获得交互体验。希望大家能从中有所收获,写出更好更炫酷的动画效果。
😉 如果你觉得本文对你有所帮助 请留个赞 😉