You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SVG环形进度条无法按设定值完成进度的技术求助

SVG环形进度条无法根据指定数值显示进度的修复方案

问题根源

当前代码存在几个核心问题导致进度无法按指定数值显示:

  • 混淆了目标数值和进度百分比的映射:把data-degree当成了计数终点,而非要显示的进度百分比(比如75应该对应75%进度,而非计数到75就满格)。
  • 全局DOM选择器冲突:用document.querySelector选文本元素,多进度条时会出错。
  • SVG元素属性误用:给<circle>设置background,但SVG矢量元素不支持这个CSS属性,得用原生的stroke-dashoffset控制进度。
  • 进度计算逻辑错误:直接用目标数值计算偏移量,而非当前进度的百分比。

修改后的完整代码

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Circular Progress Bar</title>
</head>
<body>
  <div class="center">
    <div class="progress">
      <svg class="progress-bar" data-degree="75" data-color="#0b60e9" width="300" height="300">
        <circle class="progress-circle" cx="150" cy="150" r="135"></circle>
        <circle class="progress-circle progress-fill" cx="150" cy="150" r="135"></circle>
      </svg>
      <div class="text">
        0
        <span>Completed</span>
      </div>
      <div class="totalfilling">
        <h5>75</h5>
      </div>
    </div>
  </div>
</body>
</html>

CSS

body {
  width: 100%;
  height: 100vh;
  margin: 0;
  padding: 0;
}
.center {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgb(25, 25, 50);
}
.progress {
  width: 400px;
  height: 400px;
  background: rgb(255, 255, 255);
  border-radius: 5mm;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
circle {
  fill: none;
}
svg {
  transform: rotate(90deg);
}
.progress-circle:nth-child(1) {
  stroke: rgb(240, 248, 255);
  stroke-width: 12px;
}
.progress-fill {
  stroke-width: 16px;
  stroke-linecap: round;
  stroke-dasharray: 848;
  stroke-dashoffset: 848;
}
.text {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-family: poppins;
  font-size: 60px;
  color: rgb(78, 91, 205);
  font-weight: 500;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
.text span {
  font-size: 14px;
  color: rgb(78, 91, 205);
}
.totalfilling {
  position: absolute;
  bottom: 20px;
  right: 20px;
}

JavaScript

window.addEventListener("load", function(event){
  let progressbars = document.querySelectorAll('.progress-bar');
  progressbars.forEach(function(svg){
    let currentProgress = 0;
    const targetPercent = parseInt(svg.getAttribute('data-degree'));
    const color = svg.getAttribute('data-color');
    const progressFill = svg.querySelector('.progress-fill');
    // 从当前进度条的父容器找文本元素
    const progressContainer = svg.closest('.progress');
    const numberElem = progressContainer.querySelector('.text');
    const totalElem = progressContainer.querySelector('.totalfilling h5');

    // 设置初始样式
    progressFill.style.stroke = color;
    numberElem.style.color = color;
    totalElem.textContent = targetPercent;

    const interval = setInterval(function(){ 
      currentProgress += 1;
      // 当达到目标百分比时停止
      if(currentProgress > targetPercent){
        clearInterval(interval);
        return;
      }
      // 计算当前进度的百分比(0-1)
      const progressRatio = currentProgress / 100;
      // 计算stroke-dashoffset:总长度 - 已填充长度
      const dashOffset = 848 - (848 * progressRatio);
      progressFill.style.strokeDashoffset = dashOffset;
      // 更新文本显示
      numberElem.firstChild.textContent = currentProgress;
    },50);
  });
});

关键修改点

  1. DOM结构规范:把文本元素从SVG内部移到外部容器,符合SVG标准,同时方便精准查找元素。
  2. 进度逻辑修正:明确data-degree代表进度百分比,比如75就对应75%的环形填充,而非计数到75就满格。
  3. 精准元素选择:通过closest('.progress')限定查找范围,避免多进度条时的元素冲突。
  4. SVG原生属性控制:改用stroke-dashoffset控制环形进度,这是SVG环形进度条的标准实现方式,避免无效的CSS属性设置。
  5. 初始样式设置:提前设置进度条颜色和文本颜色,确保样式统一。

内容的提问来源于stack exchange,提问作者Vicky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:10:53