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>
相关推荐
Patrick_Wilson24 分钟前
修好 bug 只是开始:一次由监控需求反向重构日志结构的复盘
前端·监控·数据可视化
kyriewen40 分钟前
面试官让我优化一个卡死的表格,我打开 Claude 五秒重写,他放下咖啡问我要不要来当组长
前端·javascript·面试
小粉粉hhh1 小时前
React(二)——dom、组件间通信、useEffect
前端·javascript·react.js
Csvn1 小时前
🤖 AI 生成前端代码的 5 个典型翻车现场及修复指南
前端
IT_陈寒2 小时前
SpringBoot自动装配坑了我一天,原来问题出在这
前端·人工智能·后端
索西引擎3 小时前
【React】key 属性:协调算法中的元素标识机制与最佳实践
前端·javascript·react.js
只会cv的前端攻城狮4 小时前
动态组件架构设计:从配置到事件驱动全链路解析
前端·vue.js
飞天狗4 小时前
Next.js 16 App Router 实战:服务端组件与流式渲染
前端·next.js
万敏4 小时前
Vue3 全栈实战第二周:Pinia + Vite + Router + axios 完整记录
vue.js·node.js·全栈
OpenTiny社区4 小时前
TinyEngine 2.11版本发布:AI 进一步融入画布,Vue 工程可一键转DSL
前端·vue.js·github