效果图
1.html 引入代码
<!-- top -->
<view class='dmGroup top' :animation="animationData" @transitionend="endAnimation">
<view class='dmItem' v-for="(item,index) in giftList " v-if=" index < 6" :key="item.id">
<view :class="['barrage',' row-b',item.from_user.is_vip==1?'vip8':'']">
<view class="row-s">
<image :src="item.from_user.avatar" class="active-hare" mode="aspectFill">
</image>
<view>
<view :class="['name',item.from_user.is_vip==1?'vip9':'']">
{{item.from_user.nickname}}
</view>
<view class="tip">送出{{item.gift.name}}</view>
</view>
</view>
<image :src="item.gift.img" class="giftImg" mode="aspectFill"></image>
</view>
</view>
</view>
<!-- mid -->
<view class='dmGroup mid' :animation="animationData3" @transitionend="endAnimation2">
<view class='dmItem' v-for="(item,index) in giftList" v-if=" index > 5 && index < 10 "
:key="item.id">
<view :class="['barrage',' row-b',item.from_user.is_vip==1?'vip8':'']">
<view class="row-s">
<image :src="item.from_user.avatar" class="active-hare" mode="aspectFill">
</image>
<view>
<view :class="['name',item.from_user.is_vip==1?'vip9':'']">
{{item.from_user.nickname}}
</view>
<view class="tip">送出{{item.gift.name}}</view>
</view>
</view>
<image :src="item.gift.img" class="giftImg" mode="aspectFill"></image>
</view>
</view>
</view>
2.引入css
这里为什么要用fixed 因为ios系统,用absolute 可以左右滑动,我们的弹幕是整体滑动,不是一个一个滑动动画出来
.dmGroup {
position: fixed;
top: 25rpx;
left: 100%;
z-index: 10;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-fill-mode: none;
transform: translateZ(0);
white-space: nowrap;
height: 60rpx;
}
.dmGroup.top {
height: 64rpx;
}
.dmGroup.mid {
height: 64rpx;
top: 125rpx;
}
.dmGroup.btm {
height: 60rpx;
top: 260rpx;
}
.dmItem {
display: inline-flex;
margin-right: 60rpx;
white-space: nowrap;
}
3.为什么要用 createAnimation js来创建动画,因为ios 用 css动画不兼容,不会滚动
因为createAnimation 里面没有循环参数,只能在动画结束后重新在调用,因为用的是fixed定位,所以要在onPageScroll中判断滑动的位置,滑动到固定位置后自动隐藏
js
data() {
return {
giftList: [],
animationData: {},
animationData2: {},
animationData3: {},
act:true
}
},
onShow() {
this.getGiftList() //获取送礼列表的方法
if(this.act) return
this.act=true
this.$forceUpdate()
setTimeout(()=>{
this.endAnimation(1)
this.endAnimation2(1)
},1000)
},
methods: {
// 弹幕动画 第一行
getAnimation(type) {
let self = this
var animation = uni.createAnimation({
duration: type == 1 ? 100 : 15000,
timingFunction: 'linear',
})
let info2 = uni.createSelectorQuery().select(".top");
info2.boundingClientRect(function(data) { //data - 各种参数
self.animation = animation
var width = data.width ? -data.width - 375 : 0
animation.translateX(0).translateX(width).step()
setTimeout(function() {
self.animationData = animation.export()
}.bind(self), 1000)
}).exec()
},
// 弹幕动画 第一行结束后 重置
getAnimation2() {
var animation = uni.createAnimation({
duration: 0,
timingFunction: 'linear',
})
this.animation = animation
animation.translateX(0).step()
// this.animationData = animation.export()
setTimeout(function() {
this.animationData = animation.export()
}.bind(this), 1000)
},
// 弹幕动画 第二行
getAnimation3(type) {
let self = this
var animation = uni.createAnimation({
duration: type == 1 ? 100 : 20000,
timingFunction: 'linear',
})
let info2 = uni.createSelectorQuery().select(".mid");
info2.boundingClientRect(function(data) { //data - 各种参数
self.animation = animation
var width = data.width ? -data.width - 375 : 0
animation.translateX(0).translateX(width).step()
setTimeout(function() {
self.animationData3 = animation.export()
}.bind(self), 1000)
}).exec()
},
// 弹幕动画 第二行结束后 重置
getAnimation4() {
var animation = uni.createAnimation({
duration: 0,
timingFunction: 'linear',
})
this.animation = animation
animation.translateX(0).step()
// this.animationData = animation.export()
setTimeout(function() {
this.animationData3 = animation.export()
}.bind(this), 1000)
},
// 实现第一行循环动画弹幕
endAnimation() {
this.getGiftList(1)
this.animationData = {}
this.getAnimation2()
setTimeout(function() {
this.getAnimation()
}.bind(this), 1000)
},
// 实现第二行循环动画弹幕
endAnimation2() {
this.animationData = {}
this.getAnimation4()
setTimeout(function() {
this.getAnimation3()
}.bind(this), 1000)
},
async getGiftList(type) {
if(this.from==1){
return
}
let res = await this.$api.giftBarrage({
to_user_id:this.id
})
if (res) {
let {
data
} = res
if (data) {
this.giftList = data
this.$forceUpdate()
if(type==1) {
return
}else{
this.getAnimation(1)
this.getAnimation3(1)
}
}
}
}
},
//因为页面需要跳转,跳转后在返回到这个页面,不隐藏会错乱,所以得隐藏
onHide() {
this.act=false
},
onUnload() {
this.act=false
},
onPageScroll(opt) {
if(opt.scrollTop>64){
this.act=false
}else{
if(this.act) return
this.act=true
this.$forceUpdate()
setTimeout(()=>{
this.endAnimation(1)
this.endAnimation2(1)
},1000)
}
}