大屏组件-数字滚动

2024-04-24  本文已影响0人  偶头像超凶
_640_1714014493.gif

父组件

<template>
  <div class="app-container rolling-wrap">
    <div style="display: flex">
      <el-button @click="handleChange">变</el-button>
      <el-alert
        type="success"
        :closable="false">
        <template slot="title">
          1、数字变化时会上下滚动数据;2、千分号,可改变
        </template>
      </el-alert>
    </div>
    <hr />
    <Index5 :num="num" :symbol="'.'"></Index5>
  </div>
</template>

<script>
import Index5 from './component/index5'
export default {
  components: { Index5 },
  data() {
    return {
      num: 0
    }
  },
  methods: {
    handleChange() {
      const aa = Math.floor((Math.random() * 1000))
      this.num = this.num + aa
      console.log('this.num>>', this.num)
    }
  },
  mounted() {
    setTimeout(() => {
      this.num = 176
    }, 1000)
  }
}
</script>

子组件

<template>
  <div class="rolling-wrap">
    <div class="rolling-item-wrap">
      <div v-for="(item, index) in list" :key="'w-'+index" :class="{ 'glow-animation': isAnimating && item !== symbol, 'rolling-item-w2': item !== symbol}">
        <div v-show="item !== symbol" class="rolling-item width-animation" :style="{transform: `translateY(-${item * 60}px)`}">
          <div class="item">0</div>
          <div class="item">1</div>
          <div class="item">2</div>
          <div class="item">3</div>
          <div class="item">4</div>
          <div class="item">5</div>
          <div class="item">6</div>
          <div class="item">7</div>
          <div class="item">8</div>
          <div class="item">9</div>
        </div>
        <div v-show="item === symbol" class="rolling-item-fh">
          <div class="item-fh">{{ symbol }}</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'Rolling',
  props: {
    // 数字
    num: {
      type: Number,
      default: 0
    },
    // 符号
    symbol: {
      type: String,
      default: ','
    }
  },
  data() {
    return {
      list: ['0'],
      isAnimating: true
    }
  },
  watch: {
    num: {
      handler(n) {
        this.isAnimating = false // 标记为正在动画中
        const nv = n.toLocaleString().replace(/,/g, this.symbol)
        const length = nv.split('').length
        const aa = JSON.parse(JSON.stringify(this.list))
        for (let i = 0; i < length; i++) {
          if (!aa[i]) {
            aa[i] = '0'
          }
        }
        this.list = aa
        this.$nextTick(() => {
          setTimeout(() => {
            this.isAnimating = true // 动画结束后重置标记
            this.list = nv.split('')
          }, 50)
        })
      },
      immediate: true
    }
  },
  methods: {
    insertPeriodsEveryThreeCharactersFromEnd(inputString) {
      let result = ''
      for (let i = inputString.length - 3; i >= 0; i -= 3) {
        result = '.' + inputString.slice(i, i + 3) + result
      }
      // 处理剩余不足3个字符的部分(如果存在)
      if (inputString.length % 3 !== 0) {
        result = inputString.slice(0, inputString.length % 3) + result
      }
      return result
    }
  }
}
</script>

<style lang="scss" scoped>
.rolling-wrap {

}
.rolling-item-wrap {
  display: flex;
  overflow: hidden;
}
.rolling-item-w2 {
  border: 1px solid #1587f1;
  border-radius: 3px;
  margin: 10px;
  position: relative;
  z-index: 1;
  overflow: hidden;
}

.rolling-item-w2:first-child {
  border: 1px solid #1587f1;
  border-radius: 3px;
  margin: 10px 10px 10px 5px;
  position: relative;
  z-index: 1;
  overflow: hidden;
}

.rolling-item-w2:last-child {
  border: 1px solid #1587f1;
  border-radius: 3px;
  margin: 10px 5px 10px 10px;
  position: relative;
  z-index: 1;
  overflow: hidden;
}

.rolling-item {
  height: 60px;
  font-weight: bold;
  font-size: 24px;
  color: red;
}

.rolling-item-fh {
  width: 10px;
  height: 60px;
  transition-duration: 1s;
  transition-delay: 0s;
  transition-timing-function: linear;
  font-weight: bold;
  font-size: 24px;
  color: red;
}

.item {
  width: 40px;
  height: 60px;
  display: flex;
  justify-content: center;
  align-items: center;
}

.item-fh {
  width: 10px;
  height: 60px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 10px 0;
}

.glow-animation {
  animation: glow 1000ms ease-in infinite alternate;
}

@keyframes glow {
  0% {
    border-color: #1587f1;
    box-shadow: 0 0 1px #1587f1, inset 0 0 1px #1587f1, 0 0 1px #1587f1;
  }

  100% {
    border-color: #1587f1;
    box-shadow: 0 0 5px #1587f1, inset 0 0 3px #1587f1, 0 0 3px #1587f1;
  }
}

.width-animation {
  transition-duration: 1s;
  transition-delay: 0s;
  transition-timing-function: linear;
}
</style>

上一篇下一篇

猜你喜欢

热点阅读