SVG实现不规则进度条

361 阅读1分钟

原理

要用SVG绘制出图案,有两种方法:fill和stroke,即填充色和边框色。

绘制进度条时,我们将fill设为none,设置边框宽度来填充形状。

需要用到的属性:

  • getTotalLength():可以获取path元素的路径总长度
  • stroke-dasharray:控制用来描边的点划线(即虚线边框)的图案范式。将其长度设为图形总长度,则边框的虚线变实线
  • stroke-dashoffset:边框线距离开始的位移

实现

  • 将进度条形状的svg图形放两份,分为背景和进度条
  • 将背景的path放到进度条上层进行覆盖
  • 利用 stroke-dashoffset 让背景从某位置开始,前面未遮挡的部分就露出来了,也就是当前的进度。

Demo:封装一个进度条组件

<!-- svgProgress.vue -->
<template>
  <svg width='100%' height='100%' :viewBox='viewBox' :stroke-width='strokeWidth'>
    <path class="path" :d='d' :stroke='color'></path>
    <path class="path" :d='d' :stroke='bgColor' ref='bg'></path>
  </svg>
</template>

<script>
export default {
  props: {
    d: String,
    viewBox: String, // 当传入的svg图形大小和外部容器不匹配时,需要借助viewBox缩放
    percent: Number,
    color: String,
    bgColor: String,
    strokeWidth: {
      type: Number,
      default: 10,
    },
  },
  mounted() {
    this.setProgress()
  },
  watch: {
    percent() {
      this.setProgress()
    },
  },
  methods: {
    setProgress() {
      const bg = this.$refs.bg
      const len = bg.getTotalLength()
      bg.style.strokeDasharray = len
      bg.style.strokeDashoffset = len
      bg.style.strokeDashoffset = len * this.percent
    },
  },
}
</script>

<style>
.path {
  stroke-linejoin: round;
  stroke-linecap: round;
  fill: none;
  transition: all 0.7s;
}
</style>