css 关键帧实现弹幕、错落弹幕

103 阅读1分钟

从左到右弹幕: 效果如图:

image.png

<view class="barrage" v-if="info.barrages && 0 !== info.barrages.length">
    // 动态计算动画时长
    <view class="item" :style="{'animation-duration':info.barrages.length*1.5+'s'}">
        <view class="tag" v-for="(item, index) in info.barrages" :key="index">{{ item }}</view>
    </view>
</view>

.barrage {
    width: 100%;
    height: 80rpx;
    white-space: nowrap;
    position: relative;

    .item {
        position: absolute;
        animation: barrage linear infinite;

        .tag {
            display: inline-block;
            color: #aa6258;
            background-color: #fef9eb;
            font-size: 20rpx;
            padding: 0 20rpx;
            border-radius: 23rpx;
            margin-left: 20rpx;
        }

        @keyframes barrage {
            0% {
                transform: translateX(0);
            }
            100% {
                transform: translateX(-100%);
            }
        }
    }
}

从左到右错落弹幕:

<view class="blindbox-barrage">
    <view class="item" :style="{ 'animation-duration': barrages.length * 3 + 's'}">
        <view>
            <view :style="{'margin-left':item.left+'rpx'}" class="tag" v-for="(item,index) in topBarrages"
                :key="index">
                <image class="headimg"
                    src="headimg"
                    mode="widthFix"></image>
                <text class="text-default font-size-left-10">
                    {{item.content}}
                </text>
            </view><strong></strong>
        </view>
        // 错开
        <view style="margin-top:35rpx"> 
            <view :style="{'margin-left':item.left+'rpx'}" class="tag" v-for="(item,index) in bottomBarrages"
                :key="index">
                <image class="headimg"
                    :src="item.headimg ? $util.img(item.headimg) : $util.getDefaultImage().head"
                    mode="widthFix"></image>
                <text class="text-default font-size-left-10">
                    {{item.content}}
                </text>
            </view>
        </view>
    </view>
</view>
        
// js        
barrages: [{
    name: 'TY12628382673876',
    text: 'iPhone13'
    },
    {
        name: '你好1266111',
        text: 'iPhone13'
    },
    {
        name: '你好66',
        text: 'iPhone13'
    },
    {
        name: '你好',
        text: 'iPhone13'
    },
    {
        name: '三七1111',
        text: 'iPhone13'
    },
    {
        name: '哈',
        text: 'iPhone13'
    }
],
topBarrages: [],
bottomBarrages: []


barragesFormat() {
    this.barrages.map((item, index) => {
        // content:弹幕内容
        item.content = this.nameEllipsis(item.name) + '获得了' + item.text; // 处理名字
        // left:距上个内容的左边距离
        item.left = 0 == index ? 0 : this.barrages[index - 1].content.length * 18
        return item
    })
    this.topBarrages = this.barrages.filter((item, index) => index % 2 === 0); // 偶数内容
    this.bottomBarrages = this.barrages.filter((item, index) => index % 2 !== 0); // 奇数内容
}

// css
.blindbox-barrage {
    width: 100%;
    height: 180rpx;
    white-space: nowrap;
    position: relative;
    overflow: hidden;

    .item {
        position: absolute;
        animation: barrage linear infinite;

        .tag {
            position: relative;
            display: inline-block;
            background: rgba(0, 0, 0, 0.5);
            padding: 5rpx 20rpx;
            border-radius: 20rpx;

            .headimg {
                width: 28rpx;
                border-radius: 14rpx;
                vertical-align: middle;
                margin-right: 10rpx;
            }
        }

        @keyframes barrage {
            0% {
                transform: translateX(0);
            }

            100% {
                transform: translateX(-100%);
            }
        }
    }
}

效果图:

image.png

从下往上弹幕:

<view class="barrages flex-end-align">
    <view class="item">
        <view class="text-right" v-for="(item,index) in barrages" :key="index">
            <view class="tag font-size-center-11">
               {{item.content}}
            </view>
        </view>
    </view>
</view>
.barrages {
    width: 100%;
    height: 50rpx;
    position: relative;
    right: 20rpx;
    bottom: 0;
    white-space: nowrap;
    overflow: hidden;

    .item {
        animation: barrage 10s linear 0s infinite;

        .tag {
            display: inline-block;
            color: #fff;
            background: rgba(0, 0, 0, 0.5);
            border-radius: 30rpx;
            line-height: 1;
            padding: 15rpx 30rpx;
            margin-top: 20rpx;

            .headimg {
                width: 28rpx;
                border-radius: 14rpx;
                vertical-align: middle;
                margin-right: 10rpx;
            }
        }

        @keyframes barrage {
            0%{
                 transform: translateY(50%);
            }

            100% {
                transform: translateY(-60%);
            }
        }
    }
}

效果图:

image.png

参考链接:blog.csdn.net/songhongchu…

处理名字:juejin.cn/spost/72622…