使用SVG制作进度条之二

在上一节中,学习了怎么利用SVG的stroke-dasharraystroke-dashoffset来制作进度条。记得在文章末尾留了一个悬念,说这一节中,要聊聊怎么用Vue来把这个SVG的进度封装成组件。

咱们先不聊Vue怎么把这个封装成组件(我搜索了一下,有现在所这方面组件,而且做得蛮好的,接下来先学习一下)。今天接着聊上一节中的进度条怎么来实现。不过略有不同。不同点来自于网上一位朋友向我提的一个问题。问题是这样的:

用SVG做一个环形的进度条一样的东西,这个很好做(用的 stroke-dasharray),但是,我需要再做一个小圆,随着环形慢慢变成一个圆时一直和头部在一起移动(这个不懂)。这个能稍微指点一下我吗?

说实话,我也很好奇!但我想在以前的基础上添加一个<circle>,让这个新添加的circle跟着内圈做位移(旋转),应该是可以的。也正因为出于好奇,给他找了两个Demo(Demo1Demo2) 。原本应该能满足其需求。但并不是这样,他希望不借用第三方的库。后来回来自己写了一个 Demo。简单的记录一下这个过程。

简单的分析一下

不管是水平的还是圆形的,其都具有三层,比如下图所示:

  • 灰色表示进度条的底层(总共的长度)
  • 红色表示进度条的进度 (已完成长度)
  • 绿色表示起点 (跟随圆点)

在SVG中的话,对应的就是:

  • 水平进度条,灰色和红色是由<line>元素构建,绿色的由<circle>构建
  • 圆形进度条由三个<circle>构建

知道其中的原委,那就好办的得多了。咱们可以先绘制一个静态的图出来:

<svg width="200" height="200" viewBox="0 0 200 200">
    <!-- 水平进度条 -->
    <line x1="10" y1="10" x2="180" y2="10" fill="none" stroke-width="12" stroke="#666" stroke-linecap="round" />
    <line x1="10" y1="10" x2="180" y2="10" fill="none" stroke-width="12" stroke="#FC4D04" stroke-dasharray="170" stroke-dashoffset="90" stroke-linecap="round" id="lineInner" />
    <circle cx="10" cy="10" r="3" fill="none" stroke="green" stroke-width="6" />

    <!-- 圆形进度条 -->
    <circle cx="100" cy="120" r="74" fill="none" stroke="#666" stroke-width="12" />
    <circle cx="100" cy="120" r="74" fill="none" stroke="#FC4D04" stroke-width="12" stroke-dasharray="465" stroke-dashoffset="400" stroke-linecap="round" />
    <circle cx="100" cy="120" r="74" fill="none" stroke="green" stroke-width="12" stroke-dashoffset="464.5" stroke-dasharray="465" stroke-linecap="round" />
</svg>

这个时候看到的效果如下:

从效果中,可以看出来,现在绿色的圆点都在默认的起点。并没有跟随进度条红色的部分。在SVG中并没有直接的方法或者API来让绿色点保持在红色点的终点。这个时候咱们需要借助CSS的特性来完成。这也离不开一些数学的计算。具体怎么来计算呢?先来看水平进度条。

通过前面的学习,知道使用.getTotalLength()可以知道其长度。在这个示例中,通过:

document.querySelectorAll('line')[0].getTotalLength() // => 170

可以知道整个水平进度条的总长度是170,而红色的进度是通过stroke-dashoffset值来控制的,在这个示例中是90。有了这两个值,就很好的控制绿色的值了。使用CSS的translateX()来做对应的位移,其位移的值是170 - 90,即80

<circle cx="10" cy="10" r="3" fill="none" stroke="green" stroke-width="6" id="circle" style="transform: translateX(80px);"/>

在行内添加了transform:translateX(80px),当然你也可以在CSS样式中写。这个时候你看到的效果如下:

剩余70%内容付费后可查看
* 请输入阅读码(忘记阅读码?

如需转载,烦请注明出处:https://www.w3cplus.com/svg/create-progress-bar-with-svg-and-css.html

如果文章中有不对之处,烦请各位大神拍正。如果你觉得这篇文章对你有所帮助,打个赏,让我有更大的动力去创作。(^_^)。看完了?还不过瘾?点击向作者提问!

赏杯咖啡,鼓励他创作更多优质内容!
返回顶部