效果

组件代码
<template>
<div
class="card-flop"
:style="{
height: typeof height === 'number' ? `${height}px` : height,
'--box-width': typeof boxWidth === 'number' ? `${boxWidth}px` : boxWidth,
'--box-height': typeof boxHeight === 'number' ? `${boxHeight}px` : boxHeight,
'--color': color
}"
>
<div
:class="{ 'card-flop__number': true, 'is-comma': isNotNumber(number) }"
v-for="(number, index) in countArray"
:key="`num-${index}`"
>
<div v-if="isNotNumber(number)" class="card-flop__number-comma">
<span>{{ number }}</span>
</div>
<div v-else class="card-flop__number-box" :style="{ transform: getTransform(number, index) }">
<div v-for="(item, index) in numbers" class="card-flop__number-item" :key="`item-${index}`">
<span>{{ item }}</span>
</div>
</div>
</div>
<div class="card-flop__unit">
<span>{{ unit }}</span>
</div>
</div>
</template>
<script >
export default {
name: 'CardFlopCom',
components: {},
props: {
count: {
type: [String, Number],
default: 0
},
height: {
type: Number,
default: 32
},
boxWidth: {
type: Number,
default: 24
},
boxHeight: {
type: Number,
default: 32
},
unit: {
type: String,
default: '条'
},
color: {
type: String,
default: '#fff'
}
},
data() {
return {
numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
}
},
computed: {
countArray() {
const formattedNumber = Number(this.count).toLocaleString()
return formattedNumber.split('')
}
},
methods: {
isNotNumber(number) {
return [',', '.'].includes(number)
},
getTransform(number) {
const offset = Number(number) * this.boxHeight
return `translateY(-${offset}px)`
}
}
}
</script>
<style lang="scss" scoped>
.card-flop {
display: flex;
align-items: baseline;
justify-content: center;
&__number {
height: var(--box-height);
color: var(--color);
background-size: 100% 100%;
background-repeat: no-repeat;
margin-right: 3px;
overflow: hidden;
&:not(.is-comma) {
width: var(--box-width);
// background-image: url('@/assets/images/screen-zhidu/card_flop_bg.png');
background-image: url('~@/assets/images/screen-zhidu/card_flop_bg.png');
}
&.is-comma {
margin-right: 2px;
}
&-box {
transition: transform 1s ease-in-out;
}
&-item {
width: var(--box-width);
height: var(--box-height);
display: flex;
align-items: center;
justify-content: center;
span {
font-weight: bold;
font-size: 26px;
}
}
}
&__unit {
font-size: 16px;
color: rgba(225, 239, 255, 0.6);
margin-left: 2px;
}
}
</style>
背景素材
