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>
相关推荐
木斯佳27 分钟前
前端八股文面经大全:bilibili生态技术方向二面 (2026-03-25)·面经深度解析
前端·ai·ssd·sse·rag
不会写DN38 分钟前
Gin 日志体系详解
前端·javascript·gin
冬夜戏雪1 小时前
实习面经记录(十)
java·前端·javascript
爱学习的程序媛2 小时前
【Web前端】JavaScript设计模式全解析
前端·javascript·设计模式·web
小码哥_常2 小时前
从SharedPreferences到DataStore:Android存储进化之路
前端
老黑3 小时前
开源工具 AIDA:给 AI 辅助开发加一个数据采集层,让 AI 从错误中自动学习(Glama 3A 认证)
前端·react.js·ai·nodejs·cursor·vibe coding·claude code
薛先生_0993 小时前
js学习语法第一天
开发语言·javascript·学习
jessecyj3 小时前
Spring boot整合quartz方法
java·前端·spring boot
苦瓜小生3 小时前
【前端】|【js手撕】经典高频面试题:手写实现function.call、apply、bind
java·前端·javascript
天若有情6733 小时前
前端HTML精讲03:页面性能优化+懒加载,搞定首屏加速
前端·性能优化·html