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>