需求
最近遇到的需求,写一个弹幕功能
大致就是实现这样的效果
弹幕轮播,上下两排,一共30个弹幕,30个轮播完毕之后获取新的弹幕数据
实现方法
目前我想到的实现方法是用css的动画来实现这个功能
<view class="barrage">
<view class="barrageBox">
<view class="barrageList" v-for="(item,index) in barrage1" :key="index">
</view>
</view>
<view class="barrageBottom barrageBox">
<view class="barrageList" v-for="(item,index) in barrage2" :key="index">
</view>
</view>
</view>
布局层级
给barrageBox盒子一个相对定位
给barrageList绝对定位 先将list盒子定位到box盒子的右边外面
然后是动画 最开始百分之0的时候在最右边
时间最后结束的时候移动到最左边left给0,然后再移动自身的百分之百到最左边,就可以实现整个盒子都移动到最左边并且隐藏
因为时间是固定的 所以从最右边移动到最左边的时间是一致的,但是盒子给了max-content的属性。盒子宽度根据内容的最大宽带撑开,不同大小的盒子要在同样的时间之内走完,所以会有走得快走得慢的区别,刚刚好也实现了我们现在的需求,盒子的运动速度不同
.barrageList {
background: rgba(0, 0, 0, 0.2);
border-radius: 60rpx 60rpx 60rpx 60rpx;
height: 52rpx;
width: max-content;
display: flex;
align-items: center;
padding: 0 16rpx 0 6rpx;
font-size: 24rpx;
color: #FFFFFF;
position: absolute;
left: 750rpx;
top: 0;
animation: barrageMove 6s linear 1;
@keyframes barrageMove {
0% {
left: 750rpx;
}
100% {
left: 0;
transform: translateX(-100%);
}
}
}
到了这个时候其实已经可以看到盒子的运动了,但是目前只有一条数据
如果一次性把所有的数据渲染,那么就会出现所有数据堆叠在一起的情况
这个时候我想到的是,动态数据,因为每次渲染一个新的数据的时候,都会重新给这个数据css,也就是都会从最右边隐藏的地方开始渲染
然后就是写算法了
先在data里面给两个数据列表
data() {
return {
// 弹幕数据
barrage1: [],
barrage2: [],
};
},
接下来就是获取后台的数据,没有数据的时候可以自己进行模拟数据
async getbarrageList() {
// 每次调用方法的时候都把两个列表数据清空,避免出现数据堆叠
this.barrage1 = []
this.barrage2 = []
// 获取到数据之后
if (res) {
// 首先对用户name做处理,我比较懒,就除了名字第一个保留,剩下的用xxx来代替了
res.forEach(i => {
i.nickName = i.nickName[0] + 'xxx'
})
let n = 0
// 重点在这里,设置一个定时器,每过1.2秒判断一次数据,单还是双,分别给第一个列表和第二个列表加入数据
this.barrageTimer = setInterval(() => {
if ((this.barrage1.length + this.barrage2.length) < res.length - 1) {
if ((n + 1) % 2 != 0) {
this.barrage1.push(res[n])
n++
} else {
this.barrage2.push(res[n])
n++
}
} else {
clearInterval(this.barrageTimer)
}
// console.log(this.barrage1, '1', this.barrage2, '2');
}, 1200)
}
},
我懒得写for循环了,假设获取到数据之后 先对需要处理的数据进行处理,我这里因为需要隐藏用户name,所以先对用户name做了处理
然后定义一个n,作为起始的下标
这个时候需要定义一个定时器 因为后续需要对定时器清除 所以data里面要定义定时器
data() {
return {
// 弹幕数据
barrage1: [],
barrage2: [],
barrageTimerOut: null,
barrageTimer: null
};
},
除了现在用的这个计时器,后续还有一个,所以我两个一起定义了,具体第二个用来干嘛的,等下我会说
然后就是判断数据是否完全分别加入两个列表里面了,如果没有的话,单数的数据加入第一个列表里面,双数的数据加入到第二个数据里面,我们需求是1.2秒加一条数据,刚好这样能形成数据的错开,n的下标是从0开始的 我们一共是30条数据 所以算是单双的时候需要+1,算数据是否完毕的时候,因为第一条数据判断是两个列表都为0的时候,所以总数的res.length需要-1。
这个时候再回头去看弹幕,已经开始滚动起来了
实现原理
实现的原理就是动态数据,每次间隔一段时间渲染一条数据,每次渲染数据的时候会重新赋一个class,css属性会给初始值也就是在最右边,同时也会开始动画,6秒的时间,从最右边到最左边,而新数据渲染的时候,之前渲染的数据已经在往左边走了,所以两条数据会错开,就会有滚动的效果,如果要实现无限滚动,只需要用第二个动画,把循环次数改为infinite无限就行
animation: barrageMove 6s linear 1;
animation: barrageMove 6s linear infinite;
实现过一段时间刷新新的弹幕数据
先上代码
onShow() {
this.barrage1 = []
this.barrage2 = []
if (this.barrageTimerOut) {
clearInterval(this.barrageTimerOut)
}
this.getbarrageList()
this.barrageTimerOut = setInterval(() => {
this.getbarrageList()
}, 42000)
},
onHide() {
console.log('hide');
clearInterval(this.barrageTimerOut)
clearInterval(this.barrageTimer)
},
在获取数据之前,记得一定要在onshow里面先把两个列表数据进行一次清空,不清空的话,可能会出现数据堆叠的情况,我写代码喜欢多写一次判断,判断是否有定时器存在,没有被清除,有的话先把定时器清除
然后说一下算法为什么是需求是30条数据后获取新数据,我要写42秒
算法是1.2秒*30条数据+最后一条数据完全走完所需的时间6秒
1.2*30+6 就是所有数据完全走完所需要的时间,如果没有完全走完的话就获取新的数据的话,会出现数据还没走完,然后就被完全清空的情况,我们觉得不美观,数据突然消失,所以还是在数据走完后获取
在onshow里写定时器,每过42秒获取新数据,就可以实现弹幕的实时更新,最后记得,离开页面的时候,把所有的定时器清除,如果觉得onHide不保险,可以在onUnload里面也写一次
补充
今天测试发现的一个bug,数据如果后端忘记做限制最大30条的时候会出现bug,所以在获取到数据的时候要做一个判断
let newArr=[]
if(res.length>30){
newArr=res.slice(0,30)
}else{
newArr=res
}
截取数据到只有30条,后续的res替换成resArr就行
作为保险
onShow里面的定时器里面记得清除调用方法时候的计时器文章来源:https://www.toymoban.com/news/detail-807281.html
onShow() {
this.barrage1 = []
this.barrage2 = []
if (this.barrageTimerOut) {
clearInterval(this.barrageTimerOut)
}
this.getbarrageList()
this.barrageTimerOut = setInterval(() => {
clearInterval(this.barrageTimer)
this.getbarrageList()
}, 42000)
},
this.barrageTimerOut = setInterval(() => {
clearInterval(this.barrageTimer)
this.getbarrageList()
}, 42000)文章来源地址https://www.toymoban.com/news/detail-807281.html
到了这里,关于小程序弹幕自动滚动实时更新数据功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!