实现原理和之前写的《vue仿app聊天室》一样的

vue仿app聊天室

分析

  • 接收到新的弹幕消息时
    1、从右边进入显示区
    2、随机弹幕距离顶部的位置
    3、随机弹幕的字体颜色
  • 弹幕在显示区的移动动画
    1、随机移动速度
  • 弹幕离开显示区后移出其dom结构

技术点

html 结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  <template>
<transition-group tag="ul" name="slide" class="barrage-container"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"

v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
>

<li v-for="(item, index) in barrageList" :key="index" class="barrage-item">
{{ item}}
</li>
</transition-group>
</template>

js 实现

1、初始化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
export default{
data () {
color:[ // 随机字体颜色
'yellow',
'blue',
'pink',
'red'
],
speed:{ // 弹幕随机移动速度范围,(每秒移动的px)
min: 50,
max: 100
}
}
}

1
2
3
4
5
6
__init () {
this.container = $('.barrage-container')
this.containerW = this.container.width()
this.containerParentH = this.container.parent().height()
this.colorL = this.color.length
}

2、获取随机定位

1
2
3
4
5
// 随机获取定位
positionRandom (insertH) {
const top = Math.floor(Math.random() * (this.containerParentH - insertH)) // 随机的范围是弹幕显示区的高度-当前插入的弹幕高度
return top
}

3、获取随机字体颜色

1
2
3
4
5
// 获取随机字体颜色
colorRandom () {
const index = Math.floor(Math.random() * this.colorL)
return this.color[index]
}

4、获取随机移动速度

1
2
3
4
5
// 获取随机移动速度
speedRandom () {
const speed = this.containerW / (Math.floor(Math.random() * (this.speed.max - this.speed.min + 1) + this.speed.min))
return parseInt(speed * 1000) // 转换成毫秒
},

5、钩子函数的实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  beforeEnter (el) {
el.style.cssText = `left: 100%;color:${this.colorRandom()}`
},
// 此回调函数是可选项的设置
// 与 CSS 结合时使用
enter: function (el, done) {
const insertH = el.offsetHeight
el.style.top = `${this.positionRandom(insertH)}px` // 这块代码本想放在beforenter函数里,但获取不到当前元素的高度。
velocity(el, {left: 0}, {duration: this.speedRandom(), complete: done})
},
afterEnter: function (el) {
// 此处代码是定义了弹幕离开显示区的动画,动画执行完,就把当前的dom结构移除
// 当然这块的逻辑代码也可以在 元素离开的钩子函数里实现
velocity(el, {left: '-100%'}, {duration: 2000,
complete: () => {
el.parentNode.removeChild(el)
}})
},
beforeLeave: function (el) {
},
// 此回调函数是可选项的设置
// 与 CSS 结合时使用
leave: function (el, done) {
done()
},
afterLeave: function (el) {
},

源码地址