如何基于现有滚动进度代码实现非SVG环形滚动进度条
环形滚动进度环解决方案
我们可以通过CSS锥形渐变(conic-gradient)结合JavaScript实现无SVG的环形进度环,代码简洁且效果流畅。以下是改造后的完整代码:
完整代码
HTML
<div class="content-site"></div> <footer> <div id="main_box"> <div id="progress-ring"> <div id="inner-circle"> <p id="progress"></p> </div> </div> </div> </footer>
CSS
.content-site { height: 500vh; background: #f5f5f5; /* 添加上背景色方便滚动测试 */ } #main_box { position: fixed; right: 50px; bottom: 80px; } #progress-ring { width: 120px; height: 120px; border-radius: 50%; background: conic-gradient(#050030 0deg, #e0e0e0 0deg); /* 初始渐变,JS会动态更新 */ display: flex; align-items: center; justify-content: center; box-shadow: 0 0 4px rgba(5, 0, 48, 0.3); } #inner-circle { width: 100px; height: 100px; background: #ffffff; border-radius: 50%; display: flex; align-items: center; justify-content: center; } #progress { color: #050030; font-weight: 600; margin: 0; font-size: 16px; }
JavaScript
function getScrollPercent() { const h = document.documentElement; const scrollTop = h.scrollTop; const scrollHeight = h.scrollHeight; const clientHeight = h.clientHeight; return scrollTop / (scrollHeight - clientHeight) * 100; } function update_scroll() { const scrollPercent = getScrollPercent(); const angle = scrollPercent * 3.6; // 1%对应3.6度(360/100) // 更新锥形渐变角度 document.getElementById("progress-ring").style.background = `conic-gradient(#050030 ${angle}deg, #e0e0e0 ${angle}deg)`; // 更新百分比文本 document.getElementById("progress").textContent = Math.round(scrollPercent) + '%'; } window.addEventListener('scroll', update_scroll); update_scroll(); // 初始化加载时执行一次
关键改造点说明
HTML结构调整:
- 新增
#progress-ring作为环形进度容器,内部嵌套#inner-circle展示中心文本区域。 - 移除原
#scroll-line元素,改用CSS渐变实现进度效果。
- 新增
CSS核心实现:
- 使用
conic-gradient创建环形进度,通过动态调整渐变角度控制进度填充。 - 外层
#progress-ring作为进度环载体,内层#inner-circle作为遮罩露出中心百分比文本。
- 使用
JavaScript逻辑修改:
- 保留原有滚动百分比计算函数
getScrollPercent,计算当前滚动位置占页面总高度的比例。 - 将百分比转换为角度值(1% = 3.6度),动态更新
#progress-ring的背景渐变样式。
- 保留原有滚动百分比计算函数
兼容性备选方案(无锥形渐变)
若需兼容不支持conic-gradient的旧浏览器,可采用双半圆旋转方案:
调整后的HTML
<div class="content-site"></div> <footer> <div id="main_box"> <div class="progress-container"> <div class="progress-circle progress-left"> <div class="progress-bar"></div> </div> <div class="progress-circle progress-right"> <div class="progress-bar"></div> </div> <div id="inner-circle"> <p id="progress"></p> </div> </div> </div> </footer>
调整后的CSS
.content-site { height: 500vh; background: #f5f5f5; } #main_box { position: fixed; right: 50px; bottom: 80px; } .progress-container { width: 120px; height: 120px; border-radius: 50%; position: relative; overflow: hidden; box-shadow: 0 0 4px rgba(5, 0, 48, 0.3); } .progress-circle { width: 50%; height: 100%; position: absolute; top: 0; overflow: hidden; } .progress-left { left: 0; } .progress-right { right: 0; } .progress-bar { width: 100%; height: 100%; background: #050030; border-radius: 0 100% 100% 0 / 50%; position: absolute; top: 0; transform-origin: left center; } .progress-left .progress-bar { left: 100%; border-radius: 100% 0 0 100% / 50%; transform-origin: right center; } #inner-circle { width: 100px; height: 100px; background: #ffffff; border-radius: 50%; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); display: flex; align-items: center; justify-content: center; } #progress { color: #050030; font-weight: 600; margin: 0; font-size: 16px; }
调整后的JavaScript
function getScrollPercent() { const h = document.documentElement; const scrollTop = h.scrollTop; const scrollHeight = h.scrollHeight; const clientHeight = h.clientHeight; return scrollTop / (scrollHeight - clientHeight) * 100; } function update_scroll() { const scrollPercent = getScrollPercent(); const leftBar = document.querySelector('.progress-left .progress-bar'); const rightBar = document.querySelector('.progress-right .progress-bar'); if (scrollPercent <= 50) { rightBar.style.transform = `rotate(${scrollPercent * 3.6}deg)`; leftBar.style.transform = 'rotate(0deg)'; } else { rightBar.style.transform = 'rotate(180deg)'; leftBar.style.transform = `rotate(${(scrollPercent - 50) * 3.6}deg)`; } document.getElementById("progress").textContent = Math.round(scrollPercent) + '%'; } window.addEventListener('scroll', update_scroll); update_scroll();
该方案通过两个半圆的旋转模拟环形进度,兼容性更好但代码稍复杂,可根据需求选择合适版本。
内容的提问来源于stack exchange,提问作者Wp-PHP
相关产品推荐
相关产品推荐

