如何为环形进度条添加平滑动画?点击进度瞬间增加问题排查
环形进度条平滑分段动画修复方案
点击页面时希望环形进度条平滑增加分段,但目前点击后进度瞬间完成,使用setInterval实现平滑动画无效,进度百分比直接跳变。
修复前代码
JavaScript
let progressBar = document.querySelector(".progressbar"); let progressBarValue = document.querySelector(".progressbar__value"); const body = document.querySelector("body"); let progressBarStartValue = 0; let progressBarEndValue = 100; let speed = 50; body.addEventListener("click", function(e) { if (progressBarStartValue === progressBarEndValue) { alert("you have completed all the tasks"); } else { let progress = setInterval(() => { if (progressBarStartValue != 100) { progressBarStartValue += 10; clearInterval(progress); } progressBarValue.textContent = `${progressBarStartValue}%`; progressBar.style.background = `conic-gradient( #FFF ${progressBarStartValue * 3.6}deg, #262623 ${progressBarStartValue * 3.6}deg )`; }, speed); } });
CSS
.progressbar { position: relative; height: 150px; width: 150px; background-color: #262623; border-radius: 50%; display: flex; align-items: center; justify-content: center; } .progressbar::before { content: ""; position: absolute; height: 80%; width: 80%; background-color: #0f0f0f; border-radius: 50%; } .progressbar__value { color: #fff; z-index: 9; font-size: 25px; font-weight: 600; }
HTML
<main class="main"> <section class="statistic"> <div class="container"> <div class="statistic__inner"> <div class="statistic__text"> <h2 class="statistic__title">You're almost there!</h2> <p class="statistic__subtitle">keep up the good work</p> </div> <div class="progressbar"><span class="progressbar__value">0%</span></div> </div> </div> </section> </main>
问题原因
原代码中setInterval的回调函数执行一次就立刻调用clearInterval(progress)终止了定时器,导致进度直接一次性增加10%,完全没有逐步动画的过程。同时没有设置每次点击的阶段性目标,直接修改最终值,自然无法实现平滑过渡。
修复后代码
仅需修改JavaScript部分,CSS和HTML保持不变:
let progressBar = document.querySelector(".progressbar"); let progressBarValue = document.querySelector(".progressbar__value"); const body = document.querySelector("body"); let currentProgress = 0; const maxProgress = 100; const step = 1; // 每次递增的步长,值越小动画越平滑 const speed = 20; // 每步间隔的毫秒数,值越小动画速度越快 body.addEventListener("click", function(e) { if (currentProgress >= maxProgress) { alert("所有任务已完成!"); return; } // 计算本次点击的目标进度(每次增加10%,不超过最大值) const targetProgress = Math.min(currentProgress + 10, maxProgress); // 启动定时器逐步更新进度 const progressTimer = setInterval(() => { currentProgress += step; // 更新进度文本和环形样式 progressBarValue.textContent = `${currentProgress}%`; progressBar.style.background = `conic-gradient( #FFF ${currentProgress * 3.6}deg, #262623 ${currentProgress * 3.6}deg )`; // 达到本次目标后停止定时器 if (currentProgress >= targetProgress) { clearInterval(progressTimer); } }, speed); });
修改说明
- 用
currentProgress替代原变量,更清晰表示当前进度状态 - 每次点击先计算阶段性目标进度,确保每次只增加10%且不超过100%
- 定时器内按小步长逐步递增进度,直到达到本次点击的目标值再停止,实现平滑动画
- 调整
step和speed参数可以自定义动画的平滑度和速度
内容的提问来源于stack exchange,提问作者Flain
相关产品推荐
相关产品推荐

