你是否曾经在某个网站上看到过那些酷炫的数字滚动效果,心里默默感叹:“这玩意儿是怎么做出来的?” 今天,我们就来揭开这个神秘面纱,手把手教你如何实现一个6位数字的滚动效果。放心,代码不会咬人,跟着我一步步来,你也能轻松搞定!


一、目标:让数字“滚”起来

我们的目标是实现一个6位数字的滚动效果,具体要求如下:

  1. 固定6位数:不足6位时用0补全,超过6位时显示99999
  2. 动态滚动:数字变化时要有滚动动画,像老虎机一样炫酷。
  3. 多数据支持:可以同时展示多个数据项,比如订单总数、访问量等。

听起来是不是很有趣?接下来,我们就从代码的角度一步步实现它!


二、HTML结构:搭建数字的“舞台”

首先,我们需要一个容器来展示数字。每个数字都是一个独立的“角色”,用<li>标签来表示。如果是数字,就让它滚动;如果是逗号,就老老实实显示。

<div class="box-item">
  <li :class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }" 
       v-for="(item, index) in orderNum" :key="index">
    <span v-if="!isNaN(item)">
      <i ref="gateTotal">0123456789</i> <!-- 这里是数字滚动的“秘密武器” -->
    </span>
    <span class="comma" v-else>{{ totalData.gateTotal[index] }}</span>
  </li>
</div>

小提示ref="gateTotal"是用来获取每个数字元素的引用,方便后面操作它的样式。


三、数据处理:让数字“听话”

接下来是数据处理部分。我们需要把传入的数字转换成6位字符串,不足6位时补零,超过6位时直接显示99999。这里用递归来实现补零操作,简单又高效。

toOrderNum(item, num) {
  num = num.toString();
  if (num.length < 6) {
    num = '0' + num; // 补零
    this.toOrderNum(item, num); // 递归调用,直到补满6位
  } else if (num.length == 6) {
    this.totalData[item] = num.split(''); // 将字符串拆分成数组
  } else {
    this.totalData[item] = 99999; // 超过6位,直接显示99999
  }
}

小技巧split('')可以把字符串拆分成单个字符的数组,方便后面逐个操作。


四、动画效果:让数字“滚”起来

现在到了最有趣的部分——让数字滚动起来!我们通过transform属性来实现垂直滚动效果。每个数字的滚动距离根据它在数组中的值来决定。

setNumberTransform() {
  Object.keys(this.totalData).forEach((item) => {
    if (item.includes('Total') || item.includes('visitCount') || item.includes('businessAmountSum')) {
      let numberItems = this.$refs[item]; // 获取所有数字元素
      let numberArr = this.totalData[item].filter((value) => !isNaN(value)); // 过滤出纯数字
      for (let index = 0; index < numberItems.length; index++) {
        let elem = numberItems[index];
        elem.style.transform = `translate(-50%, -${numberArr[index] * 10}%)`; // 设置滚动距离
      }
    }
  });
}

小提示translate(-50%, -${numberArr[index] * 10}%)中的10%是根据数字高度计算的,你可以根据实际需求调整。


五、多数据展示:让效果更“丰富”

在实际项目中,我们可能需要同时展示多个数据项,比如订单总数、访问量等。我们可以通过遍历totalData对象来实现多数据的展示和更新。

Object.keys(this.totalData).forEach((item) => {
  if (item.includes('Total') || item.includes('visitCount') || item.includes('businessAmountSum')) {
    // 模拟数据变化
    this.timer ? this.toOrderNum(item, this.totalData[item] + parseInt(Math.random() * this.timer, 10) + 1) 
               : this.toOrderNum(item, this.totalData[item]);
    this.$nextTick(() => {
      this.setNumberTransform(); // 更新动画
    });
  }
});

小技巧this.$nextTick可以确保DOM更新后再执行动画,避免出现样式错乱的问题。


六、样式设置:让效果更“炫酷”

最后,我们通过CSS来美化数字滚动效果。使用writing-mode实现文字的垂直排列,并通过transition让滚动效果更加平滑。

.box-item {
  margin-top: 3px;
  position: relative;
  width: 100%;
  height: calc(100% - 20px);
  font-size: 24px;
  font-weight: bold;
  writing-mode: vertical-lr; /* 文字垂直排列 */
  text-orientation: upright;
  user-select: none; /* 禁止用户选中文字 */
}

.number-item {
  width: calc((100% - 25px) / 6);
  background: url(../image/numbg.png) no-repeat center center;
  background-size: 100% 100%;
  list-style: none;
  margin-right: 5px;
  border-radius: 3px;
  & > span {
    position: relative;
    display: inline-block;
    margin-right: 10px;
    width: 100%;
    height: 100%;
    writing-mode: vertical-rl;
    text-orientation: upright;
    overflow: hidden;
    & > i {
      font-style: normal;
      position: absolute;
      top: 8px;
      left: 50%;
      transform: translate(-50%, 0);
      transition: transform 1s ease-in-out; /* 平滑滚动效果 */
      letter-spacing: 10px;
    }
  }
}
.number-item:last-child {
  margin-right: 0;
}

七、总结

通过以上步骤,我们成功实现了一个6位数字的滚动效果。这个效果不仅能让你的网页看起来更加动态,还能让用户感受到数据的实时变化。希望这篇文章能帮助你轻松掌握这个技巧!

这里是飞鱼爱吃米,只授渔,不授鱼!
最后,祝大家少写 Bug,多拿奖金!

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐