How to realize the digital flop effect in Vue3?

1. Demand

Monitor data changes to achieve digital flop effects

My OS: I wanted to cut a gif, but I haven't found a suitable tool for cutting gif... There is a useful tool for cutting gif, please poke me~

Two, ideas

1. Set the initial array: [0]

2. Separate the entire numbers of the new data obtained with commas to form a new array

3. Each number in the array is displayed moving between 0 and 9, the general formula for digital displacement:

transform: translate(-50%,-${number * 10}%)

4. Monitor the change of data. When the data changes, get the ref corresponding to each number and add the displacement style. The moving time can be adjusted by yourself

3. Complete code

<template>

  <div class="digitalFlopBox">

    <div class="title">Digital flop</div>

    <div class="btn">

      <button @click="changeNum">点我</button>

    </div>

    <div class="boxContainer">

      <div class="box-item" v-for="(item, index) in state.numList" :key="index">

        <span class="itemNum" :class="{ isChange: state.flag }" ref="spanRefs">0123456789</span>

      </div>

    </div>

  </div>

</template>

<script setup lang='ts' name="funDigitalFlop">

import { reactive, ref, watch } from 'vue'

const spanRefs = ref()

const state = reactive({

  numList: [0],

  flag: false

})

const changeNum = () => {

  state.numList = [1, 5, 3, 2]

}

watch(() => state.numList, (newVal, oldVal) => {

  console.log(newVal, oldVal, 'data change');

  if (newVal !== oldVal) {

    console.log(spanRefs.value);

    spanRefs.value.map((item: any, index: number) => {

      const span = spanRefs.value[index];

      if (span) {

        span.style.transform = `translate(-50%, -${newVal[index] * 10}%)`

      }

    })

  }

},

  { deep: true }

)

</script>

<style lang="scss" scoped>

.digitalFlopBox {

  .title {

    width: 100%;

    text-align: center;

    font-size: 30px;

    padding: 10px;

  }

  .btn {

    text-align: center;

    margin-bottom: 10px;

  }

  .boxContainer {

    display: flex;

    justify-content: center;

    align-items: center;

    width: 300px;

    height: 200px;

    background-color: #ccc;

    margin: 0 auto;

    .box-item {

      width: 30px;

      height: 50px;

      box-shadow: 0px 6px 9px 0px rgba(28, 119, 255, 0.25);

      border-radius: 2px 2px 2px 2px;

      background: rgba(10, 35, 126, 0.5);

      border: 1px solid #3978dd;

      color: #fff;

      text-align: center;

      line-height: 50px;

      font-size: 30px;

      margin-left: 10px;

      position: relative;

      writing-mode: vertical-lr; // typesetting vertically from left to right

      text-orientation: upright;

      overflow: hidden; // overflow hidden

      .itemNum {

        position: absolute;

        top: 10px;

        left: 50%;

        transform: translateX(-50%);

        letter-spacing: 10px;

        transition: transform 1s ease-in-out;

      }

      // .isChange {

      //   transform: translate(-50%, -50%);

      // }

    }

  }

}

</style>

Guess you like

Origin blog.csdn.net/weixin_48082900/article/details/130493812