vue3数字上下滚动显示动效

实现动效如下:

2023-07-19 11.10.26.gif

2023-07-19 11.10.53.gif

代码具体如下:

  • vue3+ts+setup 封装组件

第一步封装组件 NumberAnimation.vue

  <template>
    <div class="number-digital">
        <div class="box-item">
            <li :class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }"
                :style="{ marginRight: needDivideMgright(index) }" v-for="(item, index) in orderNum" :key="index">
                <span v-if="!isNaN(item)">
                    <i :id="`numberItem${index}`">0123456789</i>
                </span>
                <div v-if="needDivideDot(index)" class="num-dot">,</div>
            </li>
        </div>
    </div>
</template>
   
<script lang="ts" setup>
const props = defineProps<{
    numm: number | string
    numLen: number
    noneDivide?: boolean // 默认需要超过7位数字以上以,分隔
}>()
function needDivideDot(index: number): boolean {
    if (props.noneDivide) { //不需要分隔符
        return false
    }
    if (props.numLen <= 7) {
        return false
    }
    return index === props.numLen - 8 || index === props.numLen - 5
}
function needDivideMgright(index: number): string {
    if (props.noneDivide) { //不需要分隔符
        return '2px'
    }
    if (props.numLen <= 7) {
        return '2px'
    }
    return (index === props.numLen - 7 || index === props.numLen - 4) ? '14px' : '2px'
}

const orderNum = ref<Array<number>>([]);
// 处理数字
// numm: 传入的数字  numLen: 默认显示几位数
const toOrderNum = (num: string | number) => {
    num = num.toString();
    if (num.length < props.numLen) {
        num = '0' + num // 如未满定义的位数,添加"0"补位
        toOrderNum(num) // 递归添加"0"补位
    } else if (num.length === props.numLen) {
        orderNum.value = num.split('') as unknown as number[] // 将其便变成数据,渲染至滚动数组
    }

}
watch(() => props.numm, (newVal: any) => {
    toOrderNum(newVal)
    setNumberTransform()
})
function setNumberTransform() {
    for (let index = 0; index < orderNum.value.length; index++) {
        const ele: HTMLDivElement = document.getElementById(`numberItem${index}`) as HTMLDivElement
        if (ele) {
            ele.style.transform = `translate(-50%, -${orderNum.value[index] as number * 10}%)`
        }
    }
}
toOrderNum(props.numm)
onMounted(() => {
    setTimeout(() => {
        setNumberTransform()
    }, 200)
})

</script>
<style lang='scss' scoped>
.number-digital {
    margin-right: 8px;

    .box-item {
        position: relative;
        font-size: 54px;
        line-height: 41px;
        text-align: center;
        list-style: none;
        color: #2D7CFF;
        writing-mode: vertical-lr;
        text-orientation: upright;
        /*文字禁止编辑*/
        -moz-user-select: none;
        -webkit-user-select: none;
        -ms-user-select: none;
        -khtml-user-select: none;
        user-select: none;
    }

    /*滚动数字设置*/
    .number-item {
        width: 50px;
        height: 56px;
        color: #fff;
        font-size: 40px;
        font-family: MiSans, MiSans-Demibold;
        font-weight: 800;
        list-style: none;
        margin-right: 3px;
        background: rgba(3, 21, 42, 0.50);
        border: 1px solid #4d9ef8;
        box-shadow: 0px 0px 3px 0px #01072E;

        &>span {
            position: relative;
            display: inline-block;
            margin-right: 10px;
            width: 100%;
            height: 100%;
            writing-mode: vertical-rl;
            text-orientation: upright;
            overflow: hidden;

            &>i {
                font-style: normal;
                position: absolute;
                top: 8px;
                left: 50%;
                transform: translate(-50%, 0);
                transition: transform 1s ease-in-out;
                letter-spacing: 10px;
            }
        }
    }

    .number-item:last-child {
        margin-right: 0;
    }

    .num-dot {
        display: inline-block;
        margin-left: 8px;
        height: 53px;
        font-size: 47px;
        font-family: MiSans, MiSans-Demibold;
        font-weight: normal;
        text-align: CENTER;
        color: #ffffff;
        line-height: 47px;
    }

}
</style>
  

第二步 使用 NumberAnimation.vue组件

 <!-- 逗号分隔 (需要import引入组件) -->
            <NumberAnimation :numm="rand" :numLen="9"></NumberAnimation>
 <!-- 不进行逗号分隔 (需要import引入组件) -->
            <NumberAnimation :numm="rand" :numLen="9" :noneDivide="true"></NumberAnimation>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值