Vue3中如何实现数字翻牌效果?

一、需求

监听数据的变化,实现数字翻牌效果

本人OS:本想截一个gif,但是一直没找到合适的截gif工具......有好用的截gif工具,跪求戳戳我~

二、思路

1.设置初始数组:[0]

2. 把获取到的新数据整个数字用逗号隔开,组成一个新的数组

3.数组中的每一个数字都是在0~9之间移动展示,数字位移的通用公式:

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

4.监听数据的变化,当数据变化时,获取每个数字对应的ref,添加位移样式即可,移动的时间可以自行调整

三、完整代码

<template>

  <div class="digitalFlopBox">

    <div class="title">数字翻牌器</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, '数据变化');

  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; // 从左到右垂直排版

      text-orientation: upright;

      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>

猜你喜欢

转载自blog.csdn.net/weixin_48082900/article/details/130493812
今日推荐