如何实现多个终值不同的自增计数器同时结束计数动画
多计数器同步结束动画实现方案
核心逻辑:先全局统一指定所有计数器的总动画时长(可自定义,示例中为2000ms),所有计数器均以该时长为基准计算更新参数,即可保证同时启动、同时结束。
核心疑问解答
你原有写法中每次固定+1的场景下,单个计数器的总耗时为 animationSpeed * number 毫秒。要实现同步结束,只需让所有计数器的该总耗时等于预设的全局总时长即可,因此单个计数器的间隔时间计算公式为:animationSpeed = 全局总时长 / 当前计数器终值number
推荐实现方案(性能最优、动画丝滑)
使用requestAnimationFrame实现,跟随系统刷新率执行,无定时器累积误差,适配任意大小的终值:
// 全局统一总动画时长,单位:毫秒 const TOTAL_ANIMATION_DURATION = 2000; let animateNumberInItem = (number, item) => { // 终值为0的边界处理 if (number <= 0) { item.innerHTML = 0; return; } const startTime = performance.now(); function updateCount() { // 计算已运行时长 const elapsed = performance.now() - startTime; // 计算当前进度,最大为1 const progress = Math.min(elapsed / TOTAL_ANIMATION_DURATION, 1); // 计算当前应显示的数值,取整 const currentVal = Math.round(progress * number); item.innerHTML = currentVal; // 未完成则继续执行 if (progress < 1) { requestAnimationFrame(updateCount); } } requestAnimationFrame(updateCount); };
兼容setInterval的实现方案
如果需要沿用setInterval写法,可参考以下代码,适合终值较小的场景:
const TOTAL_ANIMATION_DURATION = 2000; let animateNumberInItem = (number, item) => { if (number <= 0) { item.innerHTML = 0; return; } let current = 0; // 计算间隔时间,设置最小4ms避免低于浏览器定时器最小阈值 const interval = Math.max(TOTAL_ANIMATION_DURATION / number, 4); const timer = setInterval(() => { current++; item.innerHTML = current; if (current >= number) { clearInterval(timer); // 兜底赋值避免误差 item.innerHTML = number; } }, interval); };
如果终值较大,建议固定间隔为16ms(约60帧),改为动态调整步长:
每次步长 = number / (TOTAL_ANIMATION_DURATION / 16),每帧累加对应步长后取整显示即可。
内容的提问来源于stack exchange,提问作者Gabri
相关产品推荐
相关产品推荐

