环形渐变进度条组件

背景

实习过程中,发现滴滴H5页面中,多处用到了进度条,部分是渐变色,部分是纯色

我觉得每次都去单独写一遍组件很麻烦,虽然可以copy上一份代码,但是还是需要微调

不如直接封装一个通用组件,使用上会方便很多

参数介绍

参数

说明

类型

可选值

默认值

progress

百分比(必填)

number

0-1

0

progressOption

进度条配置选项

object

--

{}

接下来是progressOption的可选属性

参数

说明

类型

可选值

默认值

strokeWidth

进度条的宽度,单位 px

number

--

10

radius

圆环的半径,单位是px

number

--

50

backColor

进度条的背景颜色

string

--

white

startColor

进度条渐变色的开始

array

--

[160,209,236]

endColor

进度条渐变色的结束

array

--

[179,160,236]

progressTextColor

进度条中文字的颜色

string

--

black

progressTextSize

进度条中文字的大小

number

--

20

progressTextWeight

进度条中文字的粗细

string

--

normal

progressTextFamily

进度条中文字的字体

string

--

--

showProgressText

是否展示进度百分比

boolean

--

true

 默认效果

在手机上没有这么粗糙,图片的问题

使用方法

使用很简单,只用给一个参数就够了(进度百分比)

// progressOption可不带,只需要携带一个参数progress,0.6含义为:60%
<circular-progress-bar :progress="0.6" :progressOption="progressOption"></circular-progress-bar>

代码

用一个for循环circle标签一小块一小块的渲染,每一小块的颜色不同,展示出来的地方也不同,产生了渐变的效果

<template>
  <svg
  :height="option.size"
  :width="option.size"
  x-mlns="http://www.w3.org/200/svg"
  class="progress"
  >
    <circle
      :r="option.radius"
      :cx="option.cx"
      :cy="option.cy"
      :stroke="option.backColor"
      :stroke-width="option.strokeWidth"
      fill="none"
    />
    <circle
      v-for="(item, index) in arcArr"
      :key="index"
      :r="option.radius"
      :cx="option.cx"
      :cy="option.cy"
      :stroke="item.color"
      :stroke-dasharray="item.arcLength"
      :stroke-width="option.strokeWidth"
      :stroke-dashoffset="item.arcLength"
      fill="none"
      stroke-linecap="round"
    />
    <text
      v-if="option.showProgressText"
      :x="option.cx"
      :y="option.cy"
      text-anchor="middle"
      dominant-baseline="middle"
      :font-size="option.progressTextSize"
      :fill="option.progressTextColor"
      :font-weight="option.progressTextWeight"
      :font-family="option.progressTextFamily"
      class="progress-text"
    >
      {
   
   { progressPercentage }}
    </text>
  </svg>
</template>
<script>
/* eslint-disable */
export default {
  name: 'circular-progress-bar',
  props: {
    progress: {
      type: Number,
      required: true,
      default: 0,
      validator (value) {
        return value >= 0 && value <= 1
      }
    },
    progressOption: {
      type: Object,
      default: () => { }
    }
  },
  computed: {
    // 进度百分比文字
    progressPercentage () {
      return parseFloat((this.progress * 100).toFixed(2)).toFixed(2) + '%'
    },
    arcArr () {
      if (this.progress === 0) return []
      const circleLength = Math.floor(2 * Math.PI * this.option.radius)
      const progressLength = this.progress * circleLength
      const step = 100 // 设置到100则已经比较难看出来颜色断层
      const gradientColor = (startRGB, endRGB, step) => {
        // 定义一个渐变颜色函数,根据给定的起始颜色、结束颜色和步数生成一个颜色数组
        // 返回一个由起始颜色到结束颜色之间渐变的颜色数组
        const startR = startRGB[0]
        const startG = startRGB[1]
        const startB = startRGB[2]
        const endR = endRGB[0]
        const endG = endRGB[1]
        const endB = endRGB[2]
        const sR = (endR - startR) / step
        const sG = (endG - startG) / step
        const sB = (endB - startB) / step
        const colorArr = []
        for (let i = 0; i < step; i++) {
          const color = `rgb(${Math.floor(sR * i + startR)},${Math.floor(sG * i + startG)},${Math.floor(sB * i + startB)})`
          colorArr.push(color)
        }
        return colorArr
      }
      const colorArr = gradientColor(this.option.startColor, this.option.endColor, step)
      // 计算每个步进中的弧长
      const arcLengthArr = colorArr.map((color, index) => ({
        arcLength: `${index * (progressLength / 100)},100000000`,
        color: color
      }))
      arcLengthArr.reverse()
      return arcLengthArr
    },
    option () {
      // 进度条的可配置项
      const baseOption = {
        radius: 50, // 半径,作用是控制圆的大小,单位是px
        strokeWidth: 10, // 圆环的宽度,即进度条的宽度,单位是px
        backColor: 'white', // 圆环的背景颜色,即进度条的背景颜色
        startColor: [160, 209, 236], // 用于渐变色的开始
        endColor: [179, 160, 236], // 用于渐变色的结束
        progressTextColor: 'black', // 进度条中文字的颜色
        progressTextSize: 20, // 进度条中文字的大小
        progressTextWeight: 'normal', // 进度条中文字的粗细
        progressTextFamily: '', // 进度条中文字的字体
        showProgressText: true // 是否显示进度条中的文字
      }
      Object.assign(baseOption, this.progressOption)
      baseOption.cy = baseOption.cx = baseOption.radius + baseOption.strokeWidth
      baseOption.size = (baseOption.radius + baseOption.strokeWidth) * 2
      return baseOption
    }
  }
}
</script>
<style scoped lang="stylus">
.progress
  transform: rotate(-90deg)
.progress-text
  transform: rotate(90deg)
  transform-origin: 50% 50%
</style>

猜你喜欢

转载自blog.csdn.net/yjxkq99/article/details/131686824