Vue 实现弹幕效果

这两天又看到有人问 Vue 如何作弹幕效果css

正好我过年的时候作了个活动,其中用户能够摇签,而后 C 位飘屏展现。html

Vue 版本效果地址:https://www.lilnong.top/static/html/vue-bullet-biubiubiu.html
网上原生版本:https://www.lilnong.top/stati...前端

image.png

实现原理

弹幕动画效果

动画效果其实很简单,从右到左vue

通常来讲咱们认知的动画流畅度顺序是 css(transform) > css(left) > js微信

实现 css 的动画效果的方式

实现起来有两种方案动画

  1. transtion 状态 A 到状态 B 使用过渡效果
    这个重点是须要触发状态变化,因此咱们能够考虑 push 以后 $nextTick 中再改变状态。
  2. animation 元素作动画。
    这个就比较简单了,他是单指元素动画

transform + animation

咱们先来看看 css 的 transform 如何实现动画效果。this

@keyframes right2left {
    0% {transform: translate(100vw)}
    100% {transform: translate(-100%);}
}

由于 translate 的 % 是基于当前元素的,因此咱们能够设置开始位置在 100vw(正好在右边屏幕外),结束位置在 -100%(正好把本身都挪到左边屏幕外)spa

left + animation

@keyframes right2left {
    0% {left: 100%}
    100% {left: -100%}
}

left 的 % 是基于父级的 width,因此这里开始位置能够设置 100%,结束位置不太好控制 -100%设计

弹幕队列设计

由于个人需求是当前登陆用户发出的会在 C 位显示,因此我把他设计成了三个队列code

  1. 普通的弹幕队列,里面用来存放其余用户发的
  2. c 位弹幕队列,用来存放当前用户发的
  3. 页面中显示的弹幕队列
// item 是当前要显示的弹幕
var item = null;
// 判断一下是不是 c 位,c 位的话要先排查 c 位弹幕队列
if(this.idx == 3){
    // c 位
    item = this.clist.shift();
}
// 若是说没有要显示的弹幕,那么取普通弹幕队列的弹幕
if(!item){
    item = this.list.shift();
}

if(item){
    // 若是有弹幕,那么放到显示队列中
    item.line = this.idx;
    this.idx = (this.idx % 5 + 1);
    this.bulletlist.push(item)
}else{
    // 若是没有弹幕,那么排查一下有没有 c位 弹幕队列
    // 由于个人弹幕作了循环,因此不太可能出现这种状况
    if(this.clist.length){
        item = this.clist.shift();
        item.line = 3;
        this.idx = 3;
        this.bulletlist.push(item)
    }
}

动画开始与结束逻辑

动画开始由于我使用的是 animation,那么当 DOM 显示在页面中他就会执行动画。
动画结束是监视 animationend 的回调,由于个人动画时长是固定,因此每次都移除第一个 DOM 便可。

若是是 transtion 应该怎么作?

transtion 也有对应的结束事件 transtionend

可是开始比较坑,他须要的是两帧。这里咱们要依赖 $nextTick 来实现

弹幕碰撞等问题

设置五条航道,每 1000ms 渲染一个弹幕,这样的话就能够错开行。

并且由于动画是固定时长,因此能够人为控制一行只有一个。

微信公众号:前端linong

欢迎你们关注个人公众号。有疑问也能够加个人微信前端交流群。
clipboard.png

相关文章
相关标签/搜索