You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现多个终值不同的自增计数器同时结束计数动画

多计数器同步结束动画实现方案

核心逻辑:先全局统一指定所有计数器的总动画时长(可自定义,示例中为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 22:57:00