vue css数字滚动效果

数字滚动


<template>
  <div class="chartNum" ref="chartNum">
    <div
      class="box-item"
      v-show="show"
      :style="{
        'font-size': normalNumSize,
        height: normalNumSize,
        top: normalTop,
        'font-family': fontFamily
      }"
    >
      <li
        :class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }"
        :style="{
          height: normalNumSize,
          width: !isNaN(item) ? normalWidth : '',
          
        }"
        v-for="(item, index) in orderNum"
        :key="index"
      >
        <span v-if="!isNaN(item)" :style="{ width: normalWidth }">
          <i ref="numberItem">0123456789</i>
        </span>
        <span class="symbol" v-else :style="{ 'font-size': normalNumSize,position:'absolute',top: item == '-' ? '-15px' : '' }">{{
          item
        }}</span>
      </li>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      orderNum: [0],
      show: false
    };
  },
  props: [
    "num",
    "normalNumSize",
    "normalWidth",
    "symbolPosition",
    "normalTop",
    "fontFamily",
    "fixedLength"
  ],
  mounted() {
    requestAnimationFrame(() => {
      this.show = true;
      this.setNumberTransform();
    }, 100);
  },
  computed: {
    num2: function() {
      return this.num;
    }
  },
  watch: {
    num: {
      immediate: true,
      handler: function(v) {
        // this.orderNum = v.spliif(v){}t(/^[,.]$/);
        if (v !== null && typeof v !== "undefined") {
          if (typeof v === "number") {
            v = v.toString();
          }
          if (v.length > 0) {
            this.orderNum = v.split("");
          } else {
            this.orderNum = [0];
          }
          if (this.fixedLength) {
            this.show = true;
            setTimeout(() => {
              this.setNumberTransform();
            });
          } else {
            this.show = false;
            // requestAnimationFrame(() => {
            //   this.show = true;
            //   // this.toOrderNum(v);
            //   this.setNumberTransform();
            // });
            setTimeout(() => {
              this.show = true;
              // this.toOrderNum(v);
              this.setNumberTransform();
            }, 100);
          }
        }
      }
    }
  },
  methods: {
    // 设置文字滚动
    setNumberTransform() {
      const numberItems = this.$refs.numberItem; // 拿到数字的ref,计算元素数量
      const numberArr = this.orderNum.filter(item => !isNaN(item));
      // 结合CSS 对数字字符进行滚动,显示订单数量
      for (let index = 0; index < numberItems.length; index++) {
        const elem = numberItems[index];
        // elem.display("none");
        // elem.style.display = "none";
        // elem.style.display = "block";
        setTimeout(() => {
          elem.style.transform = `translate(-50%, -${numberArr[index] * 10}%)`;
        }, 500);
        // elem.style.transform = `translate(0, -${numberArr[index] * 10}%)`;
      }
      this.$refs.chartNum.style.marginRight = "10px";
    },
    toOrderNum(num) {
      num = num.toString();
      if (num.length < 4) {
        num = "0" + num;
        this.toOrderNum(num); // 递归添加"0"补位
      } else if (num.length === 4) {
        // num = num.slice(0, 2) + "," + num.slice(2, 5) + "," + num.slice(5, 8);
        this.orderNum = num.split(""); // 将其便变成数据,渲染至滚动数组
        this.setNumberTransform();
      } else {
        this.$message.warning("数字过大");
      }
    }
  }
};
</script>
<style scoped lang="less">
@font-face {
  font-family: LEDFont;
  font-size: 36px;
  src: url("/font/UnidreamLED.ttf");
}
.chartNum {
  margin-right: 10px;
  display: flex;
  align-items: center;
  justify-content: center;
}
/*订单总量滚动数字设置*/
.box-item {
  position: relative;
  height: 100px;
  // font-size: 54px;
  font-size: 80px;
  line-height: 1;
  text-align: center;
  list-style: none;
  // font-family: LEDFont;
  color: #0eede7;
  writing-mode: vertical-lr;
  text-orientation: upright;
  /*文字禁止编辑*/
  -moz-user-select: none; /*火狐*/
  -webkit-user-select: none; /*webkit浏览器*/
  -ms-user-select: none; /*IE10*/
  -khtml-user-select: none; /*早期浏览器*/
  user-select: none;
  /* overflow: hidden; */
}
/* 默认逗号设置 */
.mark-item {
  width: 10px;
  height: 100px;
  // margin-right: 5px;
  line-height: 10px;
  font-size: 48px;
  left: 3px;
  position: relative;
  & > span {
    // position: absolute;
    font-size: 60px;
    width: 100%;
    bottom: 0;
    writing-mode: vertical-rl;
    text-orientation: upright;
  }
}
/*滚动数字设置*/
.number-item {
  // width: 41px;
  // height: 75px;
  height: 80px;
  // background: #ccc;
  list-style: none;
  margin-right: 5px;
  // background: rgba(250, 250, 250, 1);
  border-radius: 4px;
  // border: 1px solid rgba(221, 221, 221, 1);
  // &:last-child::after {
  //   content: "台";
  // }
  & > 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: 0px;
      left: 50%;
      transform: translate(-50%, 0);
      transition: transform 1s ease-in-out;
      letter-spacing: 10px;
    }
  }
}
.number-item:last-child {
  margin-right: 0;
}
.symbol{
  font-weight: bolder;
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值