css3

数字滚动计数器效果

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>数字滚动计数器效果</title>
    <style>
      body {
        font-family: Arial, sans-serif;
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        margin: 0;
        background-color: #f5f5f5;
      }

      .counter-container {
        display: flex;
        background-color: #fff;
        border-radius: 8px;
        padding: 20px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
      }

      .digit-container {
        width: 40px;
        height: 60px;
        overflow: hidden;
        position: relative;
        margin: 0 2px;
      }

      .digit-list {
        position: absolute;
        transition: transform 2s ease-in-out;
        transform: translateY(0);
      }

      .digit {
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 36px;
        height: 60px;
        font-weight: bold;
      }

      .prefix,
      .suffix {
        font-size: 24px;
        margin: 0 10px;
        align-self: center;
      }

      #counter {
        display: flex;
      }
    </style>
  </head>
  <body>
    <div class="counter-container">
      <div class="prefix">今日已解决</div>
      <div id="counter"></div>
      <div class="suffix">个问题</div>
    </div>

    <script>
      // 配置参数
      const CONFIG = {
        DURATION: 2000, // 动画持续时间(毫秒)
        ROLL_COUNT: 2, // 数字滚动的额外循环次数
        DELAY_BETWEEN_DIGITS: 40, // 数字之间的延迟时间(毫秒)
        DIGIT_HEIGHT: 60, // 数字高度(像素)
        TARGET_NUMBER: 7140909 // 目标数字
      };

      function createCounter(targetNumber) {
        const counterEl = document.getElementById('counter');
        const digits = targetNumber.toString().split('');

        // 为每个数字创建容器和滚动效果
        digits.forEach((digit, index) => {
          const digitContainer = document.createElement('div');
          digitContainer.className = 'digit-container';

          const digitList = document.createElement('div');
          digitList.className = 'digit-list';

          // 设置动画延迟,从左到右依次延迟
          const delay =
            (digits.length - index - 1) * CONFIG.DELAY_BETWEEN_DIGITS;
          digitList.style.transition = `transform ${
            CONFIG.DURATION - delay
          }ms ease-in-out`;

          // 创建滚动序列(0-9 重复多次)
          for (let i = 0; i <= CONFIG.ROLL_COUNT; i++) {
            for (let j = 0; j < 10; j++) {
              const digitEl = document.createElement('div');
              digitEl.className = 'digit';
              digitEl.textContent = j;
              digitList.appendChild(digitEl);
            }
          }

          digitContainer.appendChild(digitList);
          counterEl.appendChild(digitContainer);
        });

        // 开始动画
        setTimeout(() => {
          animateToTarget(targetNumber);
        }, 100);
      }
      // 启动动画
      function animateToTarget(targetNumber) {
        const digits = targetNumber.toString().split('');
        const digitLists = document.querySelectorAll('.digit-list');

        digitLists.forEach((list, i) => {
          const targetDigit = parseInt(digits[i], 10);
          //关键计算公式!(总滚动距离 = 惯性圈数*10 + 目标数字)
          const extraRolls = CONFIG.ROLL_COUNT * 10;
          const targetY = -(extraRolls + targetDigit) * CONFIG.DIGIT_HEIGHT;

          list.style.transform = `translateY(${targetY}px)`;
        });
      }

      // 初始化计数器
      window.onload = function () {
        createCounter(CONFIG.TARGET_NUMBER);
      };
    </script>
  </body>
</html>
上次更新: