SVG环形进度条通过stroke-dasharray与stroke-dashoffset控制路径绘制长度,配合transform:rotate(-90)使进度从顶部顺时针增长;JS动态更新stroke-dashoffset实现百分比动画,CSS transition可简化平滑过渡;周长应动态计算以适配不同半径,文字用text-anchor和dominant-baseline居中,响应式推荐viewBox。

在 H5 中用 SVG 实现环形进度条的百分比动态增长动画,核心是利用 <circle> 的 stroke-dasharray 和 stroke-dashoffset 配合 CSS 或 JS 动画控制路径绘制长度,再结合 transform: rotate() 调整起始角度,让进度从顶部开始顺时针增长。
1. SVG 圆环基础结构:先画一个“空圆环”
关键点是把圆拆成“不可见的轮廓”+“可见的描边”,用 stroke-dasharray 设定虚线模式,让它刚好等于圆周长,再用 stroke-dashoffset 控制从哪开始画。
示例(半径 50,圆心 (60,60),描边宽 8):
<svg width="120" height="120">
<circle
cx="60" cy="60" r="50"
fill="none"
stroke="#e0e0e0"
stroke-width="8"
/>
<circle
cx="60" cy="60" r="50"
fill="none"
stroke="#409eff"
stroke-width="8"
stroke-dasharray="314.16" <!-- 2 * π * r ≈ 314.16 -->
stroke-dashoffset="314.16" <!-- 初始完全隐藏 -->
transform="rotate(-90 60 60)" <!-- 把起点转到顶部 -->
/>
</svg>2. 动态更新进度:JS 控制 dashoffset
设总周长为 circumference,当前完成百分比为 percent(0–100),则显示长度 = circumference * percent / 100,剩余未画部分 = circumference - 显示长度,即 stroke-dashoffset = circumference * (1 - percent/100)。
常用做法:
- 用
requestAnimationFrame或setTimeout逐帧更新dashoffset - 用 CSS transition 实现平滑过渡(更简洁)
CSS 方式示例(给第二个 <circle> 加 class progress-ring__circle):
.progress-ring__circle {
transition: stroke-dashoffset 0.5s ease-out;
}JS 更新(假设目标值是 75%):
const circle = document.querySelector('.progress-ring__circle');
const circumference = 314.16;
const targetPercent = 75;
const offset = circumference - (targetPercent / 100) * circumference;
circle.style.strokeDashoffset = offset;3. 自动适配半径:用 getBoundingClientRect + Math 计算周长
避免硬编码 314.16,更健壮的方式是在 JS 中实时获取:
const circle = document.querySelector('circle:last-of-type');
const radius = parseFloat(circle.getAttribute('r'));
const circumference = 2 * Math.PI * radius;
circle.setAttribute('stroke-dasharray', circumference);
circle.setAttribute('stroke-dashoffset', circumference); // 初始全隐藏这样换尺寸、换 SVG 也能复用。
4. 补充细节:文字居中 + 响应式处理
在 SVG 内加 <text> 显示百分比数字,用 text-anchor="middle" 和 dominant-baseline="middle" 居中:
<text x="60" y="60" text-anchor="middle" dominant-baseline="middle" font-size="16">75%</text>
如需响应式,可用 viewBox 替代固定宽高,并设置 width="100%" height="auto",让 SVG 自适应容器。


















