uniapp+vue3之消息自定义向左滚动(图片加文字)自定义组件,适用多端


  效果图

 <template>

    <view class="l-barrage">
        <block v-for="(item,index) in state.items" :key="index">
            <view v-if="item.display" class="aon"
                :style="{top: `${index%2!=0?item.top*27:item.top}rpx`}">
                <view class="bbg">
                    <view class="bbg-flex">
                        <view class="bbg-flex-item">
                            <view class="name">{{item.name}}</view>
                            <view>购买了</view>
                            <view class="msg">{{item.msg}}</view>
                        </view>
                    </view>
                </view>
            </view>
        </block>
    </view>
</template>

<script setup lang="ts">
    import {
        reactive,
        getCurrentInstance,
    } from 'vue'
    const {
        proxy
    } = getCurrentInstance();
    let cycle;
    interface Props {
        minTime ?: any,
        maxTime ?: any,
        minTop ?: any,
        maxTop ?: any
    }
    let props = withDefaults(defineProps<Props>(), {
        minTime: {
            type: Number,
            default: 6
        },
        maxTime: {
            type: Number,
            default: 18
        },
        minTop: {
            type: Number,
            default: 14
        },
        maxTop: {
            type: Number,
            default: 40
        }
    })
    const state : any = reactive({
        items: [],
    })
    const add = (item, time = Math.ceil(Math.floor(Math.random() * (props.maxTime - props.minTime +
        1) + props.minTime))) => {
        // let op = mathAdd(mathMul(mathAdd(Math.floor(Math.random()*5) , 1),50),100)
        let op = 3
        state.items.push({
            msg: item.msg,//奖品名称
            time,//时间
            top: op,//距离顶部高度
            // top: Math.ceil(Math.random() * (this.maxTop - this.minTop + 1) + this.minTop),
            display: true,
            name: item.name.length >= 6 ? item.name.substring(0, 5) + '...' : item.name,
        });
    }
    const emit = defineEmits(['end'])
    const start = (items = [], type : string) => {
        state.items = [];
        cycle && (clearInterval(cycle));
        let i = 0,
            len = items.length;
        cycle = setInterval(() => {
            let time = 3;
            // #ifndef H5
            time = Math.ceil(Math.floor(Math.random() * (props.maxTime - props.minTime + 1) + props.minTime));
            // #endif            
            if (type == 'onload') {
                if (i < len) {
                    add(items[i], time);
                    i++;
                } else {
                    clearInterval(cycle);
                    setTimeout(() => {
                        emit("end", {});
                    }, time * 1000)
                }
            } else {
                clearInterval(cycle);
            }
        }, 2000)
    }
    // 第二部:暴露方法
    defineExpose({
        start,
        add
    })
</script>

<style lang="scss">
    .page {
        width: 100%;
        height: 300rpx;
    }

    .aon {
        position: absolute;
        z-index: 9;
        white-space: nowrap;
        animation: mymove 10s linear forwards;
        animation-timing-function: linear;
        -webkit-animation-timing-function: linear;
        animation-fill-mode: forwards;
        height: 59rpx;
        padding: 0 1rpx;
    }


    @keyframes mymove {
        from {
            left: 100%;
        }

        to {
            left: -200%;
        }
    }

    @-moz-keyframes mymove

    /* Firefox */
        {
        from {
            left: 100%;
        }

        to {
            left: -200%;
        }
    }

    @-webkit-keyframes mymove

    /* Safari and Chrome */
        {
        from {
            left: 100%;
        }

        to {
            left: -200%;
        }
    }

    @-o-keyframes mymove

    /* Opera */
        {
        from {
            left: 100%;
        }

        to {
            left: -200%;
        }
    }

    .bbg {
        width: 432.63rpx;
        height: 59rpx;
        border-radius: 89.5rpx;
        background-color: rgba(0, 0, 0, 0.59);
        padding-right: 16rpx;
        font-size: 24rpx;
        font-weight: 500;
        color: #fff;

        .bbg-flex {
            height: 100%;
            display: flex;
            align-items: center;
            width: 100%;
            overflow: hidden;
            white-space: nowrap;
            text-overflow: ellipsis;
            -o-text-overflow: ellipsis;
        }

        .bbg-flex-item {
            display: flex;
            align-items: center;
            padding: 0 0 0 25rpx;
        }
    }
</style>
<template>
<barrage ref="lBarrage" @end="getWinActive"></barrage>
</template>
    const lBarrage = ref<any>(null)
    const getWinActive = () => {
        let webList = getWinList(state.recordLength)
        funcTimer = setTimeout(() => {
            lBarrage._value.start(webList, 'onload')
        }, 150)
        // lBarrage.value.start(webList)
    }
    //一次展示几条弹幕
    const getWinList = (len : number) => {
        let webList = []
        for (let i = 0; i < len; i++) {
            let obj = {
                name: state.orderTwentyLately[i].userNickName,
                msg: state.orderTwentyLately[i].numeration,
                top: i,
            }
            webList.push(obj)
        }
        return webList
    }

 

posted @ 2023-08-03 14:00  晨曦_yuan小海  阅读(472)  评论(0)    收藏  举报