使用svg实现一个半圆圆角进度条

前言

在使用echarts环形图实现半圆进度条的过程中,遇到一个究极蛋疼的问题,这个进度条需要是一个圆角的,但是目前echarts对圆角的支持并不完善(只支持平角和尖角,尖角的实现请看:使用echarts实现多重环形图
所幸的是,UI对于进度条的的要求并不严格,既然这样的话,我们可以使用svg自己画出一个理想中的圆角进度条
先来看看效果:
processBar.png
效果还是能看的,下面讲讲如何去实现它

一个圆

无论如何,我们首先需要一个圆,使用svg画一个圆出来

<svg>
   <circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="grey" />
</svg> 

画出来的效果是这样的:
a circle
其中,cxcy 属性定义圆点的 xy 坐标。如果省略 cxcy,圆的中心会被设置为 (0, 0),放到图中就是圆心会跑到图片的左上角。
r 属性定义圆的半径。
stroke指的是这个圆形的描边(就是圆周围黑色的线),stroke-width指它的描边宽度
fill指的是圆中填充的颜色

我们后面调整的最多的就是stroke相关的属性

调整

有了一个圆之后,我们需要将它一步步调整为我们理想中的样子。
首先,作为半圆进度条,我们不需要这个圆中有填充的部分,所以我们设置fillnone
为了让线条更加显眼一些,暂时先把stroke描边的颜色设置为grey, 将stroke-width设置为12, 设置完成之后如下所示
circle
接下来,我们将会调整circle的stroke-dasharray 属性以及stroke-dashoffset属性

stroke-dasharray属性可以将图形的描边进行点状化,这个点的大小并不是固定的,可以变长或者变短。这一点请读者自行尝试设置一下,就可以有非常直观的感受。
下面是我调整过stroke-dasharray 的代码以及效果:

<svg>
	<circle
	  cx="150"
	  cy="73"
	  r="60"
	  stroke="grey"
	  stroke-width="12"
	  fill="none"
	  stroke-dasharray="213"
	/>
</svg> 

half circle
一个半圆的进度条已经有了,虽然它的姿势有点问题~:)

接下来,我们调整它的stroke-dashoffset属性

stroke-dashoffset可以使上一步中使用 stroke-dasharray 生成的沿着path移动, 我个人的理解就是点的偏移量,通过不断的调整,可以使图形的描边不断产生偏移,最终达到需要的效果;

调整后的代码和效果如下:

<svg>
	<circle
	  cx="150"
	  cy="73"
	  r="60"
	  stroke="grey"
	  stroke-width="12"
	  fill="none"
	  stroke-dasharray="213"
	  stroke-dashoffset="238"
	/>
</svg> 

在这里插入图片描述
好了,一个基础的半圆进度条已经绘制完成了。接下来,我们要将它设置为圆角,值得一提的,stroke属性对于设置圆角是非常友好的,我们只需要设置stroke-linecap属性就可以了,我们来看一下关于stroke-linecap属性的解释

The stroke-linecap property defines different types of endings to an open path

stroke-linecap可以设置描边末端的样式,目前我所了解支持的样式一共有3种,我们只需要关心圆角的那一种就Ok了。
在上述代码circle标签中添加stroke-linecap="round",再来看一下效果:
在这里插入图片描述
非常完美的圆角。

添加进度效果

进度条当然得有进度,我们需要为上述图形在添加一个显示进度的图形,在之前我们已经画出了一个像模像样的半圆,我们现在可以直接复制半圆的代码。仅将stroke的颜色做一个替换。效果如下:
在这里插入图片描述
这里黄色的半圆环覆盖了原来的圆环,我们接下来就会调整这个黄色半圆环的stroke array属性

通过stroke array属性, 我们可以方便的调整描边“点”之间的间距,从视觉上营造出一种进度条的感觉,给stroke array多添加一个参数,这样我们可以分开控制实线和虚线。参数可以是一个数组,这意味着我们可以精确的控制每一根实线和虚线长短,关于stroke array

The first value and every second value in the list after it specifies the length of a dash, and every other value specifies the length of a gap between the dashes

当只有一个数值时,会复制该值以对虚线进行控制

If the list has an odd number of values, then it is repeated to yield an even number of values.

想要深入理解stroke array以及stroke-dashoffset属性的话,可以参考这篇文章 : SVG理解stroke-dasharray和stroke-dashoffset属性。 或者多尝试一下自己调整参数,看看出现什么样的效果,加深理解。

以下调试的过程的略去(a few moment later…)
最终调试好的代码和效果如下:

<svg>
     <circle
       cx="150"
       cy="73"
       r="60"
       stroke="grey"
       stroke-width="12"
       fill="none"
       stroke-dasharray="190"
       stroke-dashoffset="-190"
       stroke-linecap="round"
     />

     <circle
       cx="150"
       cy="73"
       r="60"
       stroke="gold"
       stroke-width="12"
       fill="none"
       stroke-dasharray="95 190" # 注意,这里数字的比例即为进度条比例
       stroke-dashoffset="-190"
       stroke-linecap="round"
     />
</svg>

在这里插入图片描述
最后,我们只要数据驱动,当数据改变时,重新渲染该图形,就能实现进度条的自由控制啦~

在此基础上,我们可以给描边加上渐变效果数据变化时添加动画效果等等其他方式来对进度条进行美化,后续这些就不详细讲了。

参考

笔记:SVG 环形动画(进度条)原理
SVG:理解stroke-dasharray和stroke-dashoffset属性

最后照例放上一张美图~_(:з」∠)_
一张美图

发布了19 篇原创文章 · 获赞 17 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/breavo_raw/article/details/96159252