图片要当数字—实现数字滚动效果

0 阅读1分钟

原生js版本

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>图片数字滚动效果</title>
  <style>
    .number-scroll {
      display: flex;
      gap: 5px;
      height: 80px;
    }
    .digit {
      width: 50px;
      height: 80px;
      object-fit: contain;
      transition: transform 0.3s ease;
    }
  </style>
</head>
<body>
  <div class="number-scroll" id="numberContainer"></div>

  <script>
    // 初始化数字容器
    const container = document.getElementById('numberContainer');
    const digitCount = 5; // 显示5位数
    const targetNumber = 20000; // 目标数值
    const duration = 3000; // 动画时长(ms)
    
    // 预加载数字图片(假设图片路径为数字0-9.png)
    const digitImages = Array(10).fill().map((_, i) => {
      const img = new Image();
      img.src = `./${i}.png`; // 替换为实际图片路径
      return img;
    });

    // 初始化显示位
    function initDigits() {
      container.innerHTML = '';
      for (let i = 0; i < digitCount; i++) {
        const img = document.createElement('img');
        img.className = 'digit';
        img.src = digitImages[0].src; // 初始显示0
        container.appendChild(img);
      }
    }

    // 数字滚动动画
    function animateNumber() {
      const startTime = Date.now();
      const digits = container.querySelectorAll('.digit');
      
      const update = () => {
        const elapsed = Date.now() - startTime;
        const progress = Math.min(elapsed / duration, 1);
        const currentVal = Math.floor(progress * targetNumber);
        const paddedVal = String(currentVal).padStart(digitCount, '0');
        
        // 更新每位数字图片
        paddedVal.split('').forEach((digit, index) => {
          digits[index].src = digitImages[digit].src;
          digits[index].style.transform = `translateY(${10 * (1 - progress)}px)`;
        });

        if (progress < 1) {
          requestAnimationFrame(update);
        } else {
          // 动画结束后的回调
          console.log('Animation completed');
        }
      };
      
      requestAnimationFrame(update);
    }

    // 初始化并开始动画
    initDigits();
    setTimeout(animateNumber, 500); // 延迟启动避免图片未加载
  </script>
</body>
</html>

Vue版本

 <template>
  <div>
    <div class="priceBox">
        <img 
            v-for="(digit, index) in digitCount" 
            :key="index" 
            class="digit" 
            :src="currentDigits[index]" 
            :style="{ transform: `translateY(${offsetY}px)` }"
            />
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      digitCount: 5,      // 显示位数
      targetNumber: 20000, // 目标数值
      duration: 3000,     // 动画时长(ms)
      currentDigits: [],   // 当前显示的图片路径
      offsetY: 0,         // Y轴偏移量
      digitImages: Array(10).fill().map((_, i) => require(`../../../static/imgs/${i}.png`)) // 预加载图片
    };
  },
  mounted() {
    this.initDigits();
    this.$nextTick(() => {
      setTimeout(this.animateNumber, 500); // 延迟启动确保DOM渲染完成
    });
  },
  methods: {
    initDigits() {
      this.currentDigits = Array(this.digitCount).fill(this.digitImages[0]);
    },
    animateNumber() {
      const startTime = Date.now();
      
      const animate = () => {
        const elapsed = Date.now() - startTime;
        const progress = Math.min(elapsed / this.duration, 1);
        const currentVal = Math.floor(progress * this.targetNumber);
        const paddedVal = String(currentVal).padStart(this.digitCount, '0');
        
        // 更新数字图片和动画偏移
        this.currentDigits = paddedVal.split('').map(d => this.digitImages[d]);
        this.offsetY = 10 * (1 - progress);
        
        if (progress < 1) {
          requestAnimationFrame(animate);
        } else {
          console.log('Animation completed');
        }
      };
      
      requestAnimationFrame(animate);
    }
  },
};
</script>
<style>
.number-scroll {
  display: flex;
  gap: 5px;
  height: 80px;
}
.digit {
  width: 50px;
  height: 80px;
  object-fit: contain;
  transition: transform 0.3s ease;
}
</style>

        

效果图

微信视频2025-04-22_110634_967.-迅捷PDF转换器.gif