svg圆环进度条应通过stroke-dasharray与stroke-dashoffset控制填充比例,动态计算周长(如r=45时取283),设stroke-dasharray="283,283",60%进度对应stroke-dashoffset=113.2;动画须直接驱动stroke-dashoffset,起始值为283、终点为0,并注意ie兼容性需改用path+gettotallength()。

用 stroke-dasharray 和 stroke-dashoffset 控制圆环填充比例
SVG 圆环进度条的核心不是靠 background 或 clip-path,而是利用描边的虚线机制。一个完整的圆环,其周长是 2 * π * r,我们把它设为 stroke-dasharray 的总长度,再用 stroke-dashoffset 从起点“往后推”,就能露出对应比例的实线段。
常见错误是直接写死数值,比如把 stroke-dasharray 设成 100,100 —— 这会导致不同半径的圆环表现不一致。正确做法是动态计算周长:
- 假设
r = 45,则周长 ≈282.74(2 * Math.PI * 45),取整为283更稳妥 -
stroke-dasharray设为"283,283":第一个值是实线长度,第二个是空白长度,合起来覆盖整圈 - 要显示 60%,就让
stroke-dashoffset = 283 * (1 - 0.6) = 113.2;值越小,露出越多
用 CSS @keyframes 实现平滑动画,但注意 transform 不影响描边渲染
不能对 <circle></circle> 元素用 rotate() 或 scale() 来模拟进度——这些变换不会改变 stroke-dashoffset 的计算基准,反而会让动画错位或卡顿。动画必须直接驱动 stroke-dashoffset。
示例关键帧:
@keyframes circle-progress {
from { stroke-dashoffset: 283; }
to { stroke-dashoffset: 0; }
}
注意两点:
- 动画起始值是最大偏移(空环),终点是 0(满环),和直觉相反,容易写反
- 若需“从上顶点开始顺时针填充”,需额外加
transform="rotate(-90)"到<circle></circle>,否则默认从右侧开始
JavaScript 动态更新时,避免重复设置 style 导致重排
每次更新百分比都直接写 elem.style.strokeDashoffset = ...,会触发强制同步布局,尤其在高频更新(如实时数据)下明显掉帧。
更稳的做法:
- 把
<circle></circle>包进<svg></svg>并设固定尺寸,避免父容器缩放干扰计算 - 用
requestAnimationFrame批量更新,而非setInterval - 优先用 CSS 自定义属性驱动动画:给
<svg></svg>设style="--pct: 60;",CSS 中写stroke-dashoffset: calc(283 - var(--pct) * 2.83);
IE 不支持 stroke-dasharray 动画,降级方案只能用 <path></path> + getTotalLength()
IE11 及更早版本对 SVG 描边动画支持极差,stroke-dashoffset 动画会卡顿或无效。此时不能硬扛,得换路径法:
- 不用
<circle></circle>,改用<path d="M...A..."></path>画弧线 - 用
path.getTotalLength()获取真实长度(比手动算 π 更准) - 用
path.style.strokeDasharray和strokeDashoffset配合,逻辑同前,但兼容性更好
真正麻烦的不是写法,而是 IE 下 getTotalLength() 在元素未渲染完成时返回 0 —— 必须确保 path 已挂载且 display 不为 none 后再调用。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











