滚动圆形进度环特效(容器滚动百分比圆环,颜色实时可调)

JSCSSSVG 许可:自研原创

滚动圆形进度环:SVG 圆环实时显示容器滚动进度,中心百分比可隐藏,圆环颜色实时可调,支持整页与任意容器滚动,零依赖自研实现。

效果演示(真实可交互)

⭕ 在下方容器内滚动:右上角圆环实时显示阅读进度

《长页面动效设计指南》节选

当页面足够长时,用户会本能地想知道「我读到哪了、还剩多少」。线性进度条常见,但圆形进度环更适合放在角落或侧边,占用空间更小,形态也更精致。

圆形进度环的实现只需要一个 SVG 圆:把 `stroke-dasharray` 设为圆的周长,滚动时按进度比例缩短 `stroke-dashoffset`,笔画就像被「擦掉」一样呈现剩余量。

第一条原则:数值真实。进度必须与滚动位置严格同步,任何滞后都会让用户失去信任。每帧只更新一次 dashoffset,避免浮点抖动。

第二条原则:视觉克制。圆环细、颜色跟随品牌色,中心百分比数字字号小一号;过度装饰反而喧宾夺主。

第三条原则:性能友好。滚动回调里只做数学计算和一次属性写入,不操作 DOM 布局属性;SVG 属性动画走合成层,开销可忽略。

第四条原则:场景适配。整页滚动用 `window`,局部容器(本演示)用容器元素;还可以把圆环换成「圆形按钮」,点击回到顶部。

第五条原则:可访问性。装饰性圆环应加 `aria-hidden="true"`,百分比文字用真实文本而非图片,屏幕阅读器也能读到进度。

第六条原则:移动端。触屏滚动同样触发 scroll 事件,同一套代码覆盖桌面与移动端;注意 iOS 橡皮筋下 scrollTop 为负,要做下限保护。

演示区右上角的圆环实时反映左侧滚动容器的阅读进度。圆环颜色与中心百分比均可通过下方控件调节。正式使用时把监听对象换成 window 即可作用于整页。

完整代码

<svg class="ring" viewBox="0 0 120 120">
  <circle class="track" cx="60" cy="60" r="52" />
  <circle class="bar" id="bar" cx="60" cy="60" r="52" />
</svg>
.bar {
  fill: none;
  stroke: #6c8cff;
  stroke-width: 6;
  stroke-linecap: round;
  stroke-dasharray: 326.7;      /* 圆周长 2πr */
  stroke-dashoffset: 326.7;     /* 初始完全隐藏 */
}
const CIRC = 2 * Math.PI * 52;
function update() {
  const max = scroller.scrollHeight - scroller.clientHeight;
  const pct = max > 0 ? Math.max(0, scroller.scrollTop) / max : 0;
  bar.style.strokeDashoffset = (CIRC * (1 - pct)).toFixed(1);
}
scroller.addEventListener('scroll', update, { passive: true });

实现要点:圆的 stroke-dasharray 等于周长,滚动进度为 p 时把 stroke-dashoffset 设为 周长 × (1 - p),笔画按比例「露出」,看起来就像圆环被逐渐填满。SVG 加 transform: rotate(-90deg) 让起点位于正上方,更符合进度环习惯。

参数说明

参数位置说明
圆环颜色stroke 属性或控件品牌色即可,渐变可用 SVG 线性渐变
笔画粗细stroke-width: 64-8 之间,越细越精致
中心文字#spcNum 元素百分比或隐藏,二选一
圆环半径r="52"改半径时同步更新周长常量
监听对象window / 容器元素整页或局部容器滚动

兼容性与性能

常见问题

Q: 圆环不转、一直是空的? 大概率是 stroke-dasharray 与半径不匹配:半径 52 时周长是 326.7,改过半径记得同步更新两个值,否则进度比例会错乱。

Q: 想让它转起来而不是「被填满」? 那是另一类效果。本组件的「填满」语义更适合进度;若想要旋转装饰,请把动画放在 transform: rotate() 上而非 dashoffset。

Q: 圆环可以点击回到顶部吗? 可以。给 .spc-ringbox 加 cursor: pointer 与 click 监听,调用 scroller.scrollTo({ top: 0, behavior: 'smooth' }) 即可,视觉上还能加悬停放大。

Q: 可以商用吗? 可以。本组件为粤喵自研原创代码,免费商用无需署名,无任何协议限制。

许可与来源

  • 许可证:自研原创 —— 粤喵自研原创,可免费用于个人与商业项目,无需署名。查看来源公示与许可清单
  • 来源:粤喵团队原创自研(从效果思路到代码实现均为独立完成,未直接复制第三方代码)
  • 首次发布:2026-09-01 · 最近更新:2026-09-01
  • 修改日志:2026-09-01 首次发布;2026-09-13 补充许可证与来源标注、复制按钮说明与法务页入口
  • 纠错:联系页面 / min@cactus.asia,2 个工作日内核实处理

常见问题

这个组件可以商用吗?

可以。本组件为粤喵自研原创,可免费用于个人和商业项目,无需署名。

浏览器兼容性如何?

支持所有现代浏览器(Chrome / Firefox / Safari / Edge 最新版本)。旧版 IE 不支持 CSS 动画相关特性。

怎么修改动画参数?

直接调整 CSS 中的 animation-duration(时长)、animation-timing-function(缓动曲线)等属性即可,代码中有注释说明。

✍️ 作者与审核