SVG圆环进度条通过stroke-dasharray设为周长、stroke-dashoffset计算为circumference×(1−ratio)实现;需预设CSS变量、旋转起点、设置linecap为round,用transition配合自定义属性动态更新,IE需setAttribute兜底并校验百分比范围。

用 stroke-dasharray 和 stroke-dashoffset 控制 SVG 圆环路径长度
圆环进度条本质是 SVG 的 <circle></circle> 元素,靠控制描边的“虚线长度”和“起始偏移”来模拟填充。关键不是动画本身,而是怎么把百分比映射成两个属性值。
假设圆环半径为 r = 45,那么周长 circumference = 2 * Math.PI * r ≈ 282.74。这个值就是 stroke-dasharray 的基准:设它等于周长,再用 stroke-dashoffset 从起点往后推,就能“露出”对应比例的实线段。
例如 60% 进度:要显示 60% 的路径,即实线段长 0.6 * circumference,所以 stroke-dashoffset = circumference - 0.6 * circumference = 0.4 * circumference。
实际操作时建议:
立即学习“前端免费学习笔记(深入)”;
- 在 CSS 中预定义
--circumference: 282.74,避免 JS 重复计算 - 用
transform: rotate(-90deg)把起点调到顶部(默认在 3 点钟方向) - 务必设置
stroke-linecap: round,否则两端是直角,不圆润
用 CSS @keyframes 实现平滑过渡,但注意初始值陷阱
直接对 stroke-dashoffset 做 animation 是可行的,但容易卡顿或跳变——因为浏览器不会自动插值非数值单位(比如带单位的 px 或未声明初始值的属性)。
必须确保:
-
stroke-dasharray在元素上显式声明(哪怕只是继承),不能靠父级或默认值 - 动画起始帧的
stroke-dashoffset必须是具体数字(如282.74),不能是inherit或unset - 推荐用
transition替代@keyframes:JS 改变自定义属性后,CSS 自动过渡更可控
示例片段:
circle {
stroke-dasharray: var(--circumference);
stroke-dashoffset: var(--offset, 282.74);
transition: stroke-dashoffset 0.6s ease-out;
}然后 JS 动态设置 style.setProperty('--offset', offsetValue) 即可触发动画。
IE 不支持 CSS 自定义属性?用内联 style + setAttribute 兜底
如果需兼容 IE11,var(--xxx) 无效,得退回到直接操作 SVG 属性。这时别用 style.strokeDashoffset(IE 不认驼峰),必须用 setAttribute('stroke-dashoffset', value)。
同时注意:
- IE 对
stroke-dasharray的解析有 bug,建议始终写成两个相同数字,如"282.74 282.74",而非单个值"282.74" - IE 不支持
transition在 SVG 属性上生效,只能用 JS +requestAnimationFrame模拟逐帧更新 - 所有数值必须是字符串,且不能带单位(SVG 属性值无单位,默认是 px)
百分比传入 JS 时,记得校验并 clamp 到 0–100 范围
用户输入、API 返回或表单提交的百分比可能越界(如 -5、120),直接算 offset 会导致圆环反向转或全空/全满。
安全做法是先归一化:
- 用
Math.min(Math.max(percent, 0), 100)截断 - 再转成小数:
ratio = clampedPercent / 100 - 最后算偏移:
offset = circumference * (1 - ratio)
漏掉这步,动画在边界值(0% 或 100%)附近容易抖动或停不住——尤其当数据源频繁更新时,微小浮点误差会累积成视觉跳跃。
真正麻烦的不是怎么动起来,而是怎么让动得稳、停得准、边界不出错。


















