单页多圆形进度条实现问题求助
多圆形进度条解决方案
以下是修改后的完整代码,解决单页多进度条的复用问题:
完整代码示例
HTML
<div class="progress-container"> <canvas class="progress-canvas" width="400" height="400"></canvas> <span class="progress-percent" data-target="6289">0</span> </div> <div class="progress-container"> <canvas class="progress-canvas" width="400" height="400"></canvas> <span class="progress-percent" data-target="3000">0</span> </div> <div class="progress-container"> <canvas class="progress-canvas" width="400" height="400"></canvas> <span class="progress-percent" data-target="1500">0</span> </div>
CSS
.progress-container { position: relative; display: inline-block; margin: 20px; } .progress-percent { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); font-size: 24px; font-weight: bold; color: #55c800; }
JavaScript
window.onload = function() { // 获取所有进度条容器 const containers = document.querySelectorAll('.progress-container'); containers.forEach(container => { const canvas = container.querySelector('.progress-canvas'); const percentSpan = container.querySelector('.progress-percent'); const targetPercent = parseInt(percentSpan.dataset.target, 10); initProgressBar(canvas, percentSpan, targetPercent); }); }; function initProgressBar(canvas, percentSpan, targetPercent) { const c = canvas.getContext('2d'); const posX = canvas.width / 2; const posY = canvas.height / 2; const fps = 2000 / 150; // 控制动画速度 let degrees = 0; // 计算每1度对应的百分比 const oneDegreePercent = targetPercent / 360; const totalDegrees = 360; c.lineCap = 'round'; function arcMove() { const interval = setInterval(() => { degrees += 1; c.clearRect(0, 0, canvas.width, canvas.height); // 计算当前进度百分比 const currentPercent = degrees * oneDegreePercent; percentSpan.textContent = Math.min(currentPercent.toFixed(), targetPercent); // 绘制背景圆环 c.beginPath(); c.arc(posX, posY, 140, (Math.PI / 180) * 270, (Math.PI / 180) * (270 + 360)); c.strokeStyle = '#55c800'; c.lineWidth = 5; c.stroke(); // 绘制进度圆环 c.beginPath(); c.strokeStyle = '#55c800'; c.lineWidth = 10; c.arc(posX, posY, 140, (Math.PI / 180) * 270, (Math.PI / 180) * (270 + degrees)); c.stroke(); // 达到目标后停止动画 if (degrees >= totalDegrees) { clearInterval(interval); percentSpan.textContent = targetPercent; } }, fps); } arcMove(); }
关键改动说明
复用化结构
- 用类名替代id(
.progress-canvas、.progress-percent),避免id唯一性限制 - 每个进度条放在独立容器
.progress-container中,通过data-target属性自定义目标百分比
- 用类名替代id(
独立初始化逻辑
- 封装
initProgressBar函数,每个进度条的canvas、文本节点、目标值都是独立传入的 - 用
forEach遍历所有容器,逐个初始化进度条,确保每个动画互不干扰
- 封装
动态百分比计算
- 去掉硬编码的目标值,改为从
data-target读取,支持不同进度条设置不同目标 - 修正百分比计算逻辑,确保动画转满一圈时,文本显示准确的目标值
- 去掉硬编码的目标值,改为从
细节优化
- 动画结束后强制设置文本为目标值,避免计算精度偏差
- 添加CSS让进度数字居中显示,优化视觉效果
内容的提问来源于stack exchange,提问作者vicartdesign
相关产品推荐
相关产品推荐

