使用SVG制作进度条
进度条是我们在Web中经常看到的一种效果,常见的进度条有水平横条和径向圆形的进度条。今天我们来看看怎么使用SVG来实现进度条的效果。使用SVG可以很容易的实现,也易于理解,最主要是使用SVG实现的进度条具有良好的跨浏览器,并且能根据浏览器屏幕尺寸很好的显示。
基础
在具体制作之前,有一些简单的概念要了解一下,这是制作进度条的一些基础。
- 水平进度条,是一条直线,使用SVG的
<line>
元素可以绘制 - 圆形进度条,是一个环形,使用SVG的
<circle>
元素可以绘制 - 通过
fill:none
设置线条无填充色,使用stroke-width
来设置进度条的粗细
使用stroke-width
设置进度条粗细,水平进度条相对而言较主简单,直接设置就能指定进度条的高度,对于其长度通过(x1,y1)
和(x2,y2)
来确定。对于圆形进度条,同样需要使用fill:none
让圆形不填充任何颜色,stroke-width
设置圆形的粗细,只是其值是圆周长的十分之一。
通过stroke-width
和圆的周长,我们可以计算出圆形的半径。比如我们圆形的外周长是120
,同时stroke-width
的值是12
。这样我们就可以计算出圆形半径:
(120 / 2) - (12 / 2) = 54
SVG代码很简单:
<svg width="200" height="200" viewBox="0 0 200 200">
<line x1="10" y1="10" x2="110" y2="10" fill="none" stroke-width="12" stroke="#666" />
<circle cx="60" cy="80" r="54" fill="none" stroke="#666" stroke-width="12" />
</svg>
这个时候你看到的效果如下:
制作进度条
事实上,我们所看到的进度条都是有另一个颜色来表示进度的,而上面我们看到的只是进度条的背景色。也就是说,我们需要再绘制一个<line>
和<circle>
元素,其坐标参数,进度条粗细等参数都一样,唯一不同的是,线条的颜色要不一样。
通过《SVG的图层和渲染顺序》和《优雅的轮廓与 SVG paint-order
》学习,了解了SVG中绘制过程有自己的基本原则:
解析顺序和绘制顺序一致,都要遵守XML中元素的位置排列。SVG中元素在XML中有固定的排列顺序,浏览器渲染时会遵守这个顺序,绘制时也同样会遵守这个顺序。也就是说先出现的元素会出现在绘制的底层,而后出现的元素会绘制在顶层,如果元素间的位置有重叠,则会后绘制的元素会盖住先绘制的元素。
了解了这一种,那就好办了。依次在<line>
后面再绘制一个<line>
,并把它的stroke
设置为其他颜色,比如orange
。同样的在<circle>
之后再绘制一个<circle>
,同样把stroke
设置为orange
:
<svg width="200" height="200" viewBox="0 0 200 200">
<line x1="10" y1="10" x2="110" y2="10" fill="none" stroke-width="12" stroke="#666" />
<line x1="10" y1="10" x2="110" y2="10" fill="none" stroke-width="12" stroke="#FC4D04" />
<circle cx="60" cy="80" r="54" fill="none" stroke="#666" stroke-width="12" />
<circle cx="60" cy="80" r="54" fill="none" stroke="#FC4D04" stroke-width="12" />
</svg>
你将看到的效果现在变成这样了,橙色的覆盖了灰色的:
改变进度条位置
上面看到的效果就是进度条100%
的位置,但我们很多时候不是100%
,而是其他的位置,那么上面的效果就不是我们所需要的了。我们需要一些方法来处理不同进度时,橙色的进度位置。那怎么做呢?
如果你阅读了前面整理的:
我想你肯定会想到SVG的stroke-dasharray
和stroke-dashoffset
。是的,就是这两个属性能轻易的帮助我们要达到我们想要的效果。其技术关键点:
- 如果
stroke-dasharray
和stroke-dashoffset
设置的值都是路径(line
的长度,circle
的周长),那么橙色的line
和circle
将看不到,这个时候就是进度条0%
的状态,当stroke-dashoffset
加到0
的位置时,这个时候就是进度条100%
的状态。言外之意,改变stroke-dashoffset
的值,就能得到进度条0%~100%
之间的状态。 - 通过
.getTotalLength()
获取对应图形的长度。
比如:
document.querySelectorAll('line')[1].getTotalLength() // => 100
document.querySelectorAll('circle')[1].getTotalLength() // => 338.7438659667969
这就好办了,在橙色的line
和circle
上设置stroke-dasharray
和stroke-dashoffset
值:
<svg width="200" height="200" viewBox="0 0 200 200">
<line x1="10" y1="10" x2="110" y2="10" fill="none" stroke-width="12" stroke="#666" />
<line x1="10" y1="10" x2="110" y2="10" fill="none" stroke-width="12" stroke="#FC4D04" stroke-dasharray="100" stroke-dashoffset="100" />
<circle cx="60" cy="80" r="54" fill="none" stroke="#666" stroke-width="12" />
<circle cx="60" cy="80" r="54" fill="none" stroke="#FC4D04" stroke-width="12" stroke-dasharray="339" stroke-dashoffset="339" />
</svg>
这样一来,橙色的就看不到了:
为了更易于理解,在上面的基础上做一下简单的修改:
上面的效果相对而言较为简单。如果你使用SVG的其他一些特性,比如渐变,甚至是将line
和circle
换成path
。这样一来,要整成什么样形状的进度条都OK,也简单。比如下面这个示例:
总结
今天主要介绍了怎么使用SVG来制作水平和圆形的进度条,甚至怎么制作任意思形状的进度条。制作原理并不复杂,我想你要是阅读到这里,以及阅读前面的内容,你应该非常的清楚。但话说回来,现在的进度条效果还很粗陋,但并不要紧,如果你感兴趣的话,请关注后续的更新,下一次咱们来看看怎么用Vue来把今天这两个进度条封装成对应的组件,并且将这个进度条打磨的更精美。
如需转载,烦请注明出处:https://www.fedev.cn/svg/create-progress-bar-with-svg.html2019 Air Vapormax Flair