Newer
Older
CloudBrainNew / src / components / text / digitalFlop / DigitalFlop.vue
StephanieGitHub on 4 Feb 2021 4 KB first commit
<template>
  <div class="chartNum">
    <slot name="title"></slot>
    <div class="box-item" :style="{'color': mergedOptions.color}">
      <li :class="{'number-item': !isNaN(item), 'mark-item': isNaN(item) }"
          v-for="(item,index) in orderNum"
          :key="index"
          :style="{'background':!isNaN(item)?mergedOptions.bgColor:'transparent',
          'border-color':!isNaN(item)?mergedOptions.borderColor:'transparent'
          }"
      >
       <span v-if="!isNaN(item)">
        <i ref="numberItem">0123456789</i>
       </span>
        <span class="comma" v-else>{{item}}</span>
      </li>
      <li>{{mergedOptions.unit}}</li>
    </div>
  </div>
</template>
<script>
export default {
  name: 'DigitalFlop',
  props: {
    data: {
      type: Number,
      default: 0
    }, // 显示数据
    length: {
      type: Number,
      default: 8
    }, // 显示长度
    options: {
      type: Object,
      default: () => { return {} }
    } // 配置
  },
  data () {
    return {
      orderNum: ['0', '0', '0', '0', '0', '0', '0', '0'], // 要显示数字数组
      defaultOptions: {
        unit: '',
        color: '#2D7CFF',
        bgColor: '#ffffff',
        borderColor: 'rgba(221,221,221,1)',
        formatter: true
      },
      mergedOptions: {}
    }
  },
  mounted () {
    this.mergeOptions()
    this.toOrderNum(this.data) // 这里输入数字即可调用
    this.setNumberTransform()
  },
  watch: {
    data (val) {
      this.toOrderNum(val)
      this.setNumberTransform()
    }
  },
  methods: {
    formatter (number) {
      const numbers = number.toString().split('').reverse()
      const segs = []
      while (numbers.length) segs.push(numbers.splice(0, 3).join(''))
      return segs.join(',').split('').reverse().join('')
    },
    // 合并配置
    mergeOptions () {
      this.mergedOptions = Object.assign(this.defaultOptions, this.options)
    },
    // 设置文字滚动
    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.style.transform = `translate(-50%, -${numberArr[index] * 10}%)`
      }
    },
    // 处理数字转字符串数组
    toOrderNum (num) {
      num = num.toString()
      // 把数字变成字符串
      if (num.length < this.length) {
        num = '0000000000' + num // 如未满八位数,添加"0"补位
        num = num.substr((0 - this.length), this.length)
      }
      if (this.mergedOptions.formatter) {
        num = this.formatter(num)
      }
      this.orderNum = num.split('')
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
  /*订单总量滚动数字设置*/
  .box-item {
    position: relative;
    box-sizing: border-box;
    height: 75px;
    margin: 10px 0px;
    font-size: 54px;
    line-height: 41px;
    text-align: center;
    list-style: none;
    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;
    margin-right: 5px;
    line-height: 10px;
    font-size: 48px;
    position: relative;
    & > span {
      position: absolute;
      width: 100%;
      bottom: 0;
      writing-mode: vertical-rl;
      text-orientation: upright;
    }
  }
  /*滚动数字设置*/
  .number-item {
    width: 41px;
    height: 70px;
    list-style: none;
    margin-right: 5px;
    /*background:rgba(250,250,250,0.8);*/
    border-radius:4px;
    border-width: 1px;
    border-style: solid;
    & > 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;
  }
</style>