svg实现3环进度图,可动态调节进度数值,(vue)

html 复制代码
<template>
  <div id="app">
    <svg width="400" height="400" viewBox="0 0 400 400">
      <defs>
        <filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
          <feDropShadow dx="0" dy="0" stdDeviation="5" flood-color="rgba(0, 0, 0, 0.5)" />
        </filter>
      </defs>
      <!-- 外层圆环 -->
      <circle cx="200" cy="200" r="180" stroke="lightgray" stroke-width="20" fill="none" />
      <circle
        class="progress-circle"
        cx="200"
        cy="200"
        r="180"
        stroke="red"
        stroke-width="20"
        fill="none"
        :stroke-dasharray="outerCircumference"
        :stroke-dashoffset="outerOffset"
        stroke-linecap="round"
        transform="rotate(-90 200 200)"
        filter="url(#shadow)"
      />
      <!-- 中层圆环 -->
      <circle cx="200" cy="200" r="140" stroke="lightgray" stroke-width="20" fill="none" />
      <circle
        class="progress-circle"
        cx="200"
        cy="200"
        r="140"
        stroke="green"
        stroke-width="20"
        fill="none"
        :stroke-dasharray="middleCircumference"
        :stroke-dashoffset="middleOffset"
        stroke-linecap="round"
        transform="rotate(-90 200 200)"
        filter="url(#shadow)"
      />
      <!-- 内层圆环 -->
      <circle cx="200" cy="200" r="100" stroke="lightgray" stroke-width="20" fill="none" />
      <circle
        class="progress-circle"
        cx="200"
        cy="200"
        r="100"
        stroke="blue"
        stroke-width="20"
        fill="none"
        :stroke-dasharray="innerCircumference"
        :stroke-dashoffset="innerOffset"
        stroke-linecap="round"
        transform="rotate(-90 200 200)"
        filter="url(#shadow)"
      />
    </svg>
    <div>
      <label>外层进度: </label>
      <input
        type="number"
        v-model="outerProgress"
        @input="updateProgress('outer')"
        min="0"
        max="100"
      />
    </div>
    <div>
      <label>中层进度: </label>
      <input
        type="number"
        v-model="middleProgress"
        @input="updateProgress('middle')"
        min="0"
        max="100"
      />
    </div>
    <div>
      <label>内层进度: </label>
      <input
        type="number"
        v-model="innerProgress"
        @input="updateProgress('inner')"
        min="0"
        max="100"
      />
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      outerProgress: 0,
      middleProgress: 0,
      innerProgress: 0,
      outerCircumference: 2 * Math.PI * 180,
      middleCircumference: 2 * Math.PI * 140,
      innerCircumference: 2 * Math.PI * 100
    }
  },
  computed: {
    outerOffset() {
      return this.outerCircumference - (this.outerProgress / 100) * this.outerCircumference
    },
    middleOffset() {
      return this.middleCircumference - (this.middleProgress / 100) * this.middleCircumference
    },
    innerOffset() {
      return this.innerCircumference - (this.innerProgress / 100) * this.innerCircumference
    }
  },
  methods: {
    updateProgress(type) {
      if (type === "outer" && this.outerProgress >= 0 && this.outerProgress <= 100) {
        this.outerProgress = this.outerProgress
      } else if (type === "middle" && this.middleProgress >= 0 && this.middleProgress <= 100) {
        this.middleProgress = this.middleProgress
      } else if (type === "inner" && this.innerProgress >= 0 && this.innerProgress <= 100) {
        this.innerProgress = this.innerProgress
      }
    }
  }
}
</script>

<style scoped>
#app {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
}
input {
  margin-top: 10px;
  width: 60px;
  text-align: center;
}
.progress-circle {
  transition: stroke-dashoffset 0.5s ease;
}
</style>
相关推荐
柳杉2 分钟前
Codex + 可视化大屏工作流实践:15 个行业场景的设计产出合集
前端·openai·数据可视化
@#¥&~是乱码鱼啦4 分钟前
ArkWeb开发手记05|SPA单页H5适配、自定义历史栈与全局状态同步
前端·harmonyos
peter67686 分钟前
vue学习小结
前端·vue.js·学习
七仔啊11 分钟前
数字孪生大屏设计器
前端
知野小兔12 分钟前
JavaScript 数组方法大全(超详细整理)
开发语言·前端·javascript
火眼金睛记单词17 分钟前
零基础成人重拾英语:第一个月的30天行动地图
前端·经验分享·学习·小程序
ljt272496066132 分钟前
Vue笔记(十二)--mitt
前端·笔记
传人once12 小时前
页面中心圆圈放大效果如何写
开发语言·javascript·ecmascript
用户0333074139513 小时前
TypeScript using 与 AsyncDisposableStack:在真实服务端代码中协调多资源清理
前端
web3d52013 小时前
Vue3 地图白屏排查清单:容器、弹窗与 ol-viewport 重复创建
vue.js·gis