闲言絮语
:这不刚入职新公司,接了一个项目,大体是要实现一个周年记念的app、m活动页,统计你的线上数据blablblabl...css
需求:页面中有一个功能,大体是获取db中的50条数据用于弹幕展现,用户也能够自行发送弹幕,弹幕展现完循环展现
首先,弹幕功能存在如下问题:
1.弹幕速度 位移距离
2.弹幕通道(需求中是要有3条弹幕通道)
3.当前页面弹幕数量(渲染数量)vue
我这边是经过vue的 过分组件 来实现弹幕功能的,由于以前在官网看到过实例,本身也用vue这么久了,一直没用过,此次就用来练手。数组
过分组件 顾名思义,渲染内容进行变化的时候触发的组件,官网实例以下:浏览器
个人思路简单说来: v-for 循环数组arr,内容item.msg渲染在li内部,每次维护更新这个数组arr,触发过分组件的回调函数
回调函数很简单,这里不过多提起,进入前beforeEnter,进入enter,离开leaveapp
有了思路,先从一个弹幕的实现开始,弹幕初始位置应该在 left:100% 的位置,结束位置应该是 -el.offsetwidth 的位置。函数
这里有个问题,咱们的弹幕内容是头像+msg,若是是绝对定位的弹幕元素 在beforeEach或者初始值设定left为100%,这里是没法获取正确元素宽度 的(能够自行查找why,这里很少说明),因此咱们只有在弹幕进入到当前窗口 时,单独的设置他的宽度 el.style.width = el.offsetWidth + 20 + 'px' 这里的20px 就是咱们的头像部分啦
弹幕进入enter阶段,就开始运动了,运动到哪里是个头?
咱们在enter回调函数中,加入velocity动画,(为何用velocity?由于我看中了他的complete钩子,能够直接remove掉元素,这也太爽了!我能够保证运行完的弹幕直接消失,当前页的效率就会获得保障!)
有了以上操做,一条弹幕就能够完美执行了!优化
有了一条弹幕,就要考虑把弹幕一条条加入可视窗口了,定时器走起!
setInterval 每隔几秒push一条数据到数组中,刷新浏览器,来看结果!动画
结果是悲剧的... 过分组件默认是一块儿执行的,我10秒内数组加了10条数据,结果数据一块儿运动!这天然不是咱们想要的,要咋办呢?我给数组的每一项绑定了一个自定义属性spa
而后在enter的钩子函数中获取到,没一个index,定时器设置delay秒后执行动画。
全部的弹幕就能够完美跑起来啦!3d
最后是通道问题,需求有三条通道,我并无设置弹幕的top值,这里大概思路就是随机获取一下呗,或者为了保证间距写一些固定值给弹幕设置top值,管道匹配上top值就ok了。
基本功能就这么实现了。
ps:如下是这个小功能的我的思考
1.前文提到的,绝对定位元素没法获取正确宽度,若是不在弹幕进入的钩子里设置宽度,弹幕宽度会出现奇怪的现象(只根据你的msg或者头像内容宽度展开),这是css定位的问题,有空会去了解一下
2.有关velocity的complete钩子函数怎么实现的?
我猜大概是监听动画执行完毕的事件(有兼容问题),而后封装了一下。若是这里要用原生,感受仍是在定时器内去监听弹幕是否在可视窗口内。
3.自定义属性的巧妙实用,这一步真的很nice,给每一个弹幕绑定了下标,移动的时候就可让弹幕有序的加载。
4.弹幕速度、高度、时间等具体参数,能够本身想象一下每条弹幕的运行轨迹,在move函数中得以实现。
5.基于问题3,考虑到是否能够优化弹幕页?
目前的弹幕情况是,弹幕有序加载到屏幕外侧最右边,而后每隔固定延迟开始移动,能够保证的是每条弹幕的间隔一致,也能够经过获取每隔弹幕的移动距离,实现弹幕速度一致,那会不会存在弹幕层叠的状况?理论上是会的,(3条轨道的状况下)假如第一条弹幕是长度很是长,第二条第三条通常长度,每条之间的间隔同样,第四条就可能会在第一条弹幕还没消失的时候出现,致使层叠...这里我是想把delay根据每条弹幕的宽度额外设置一下,让每条弹幕的间隔变得不同,从而使弹幕不会层叠展现。
6.有没有更好的方案?
设想:当前只有一个动画,全部的弹幕都在一个容器container内,上来就根据弹幕宽度设置好每一个弹幕的间距和位置,而后整个画布一块儿划过可视窗口,相似轮播图。可是难点就是初始设置位置,以及结束的判断,由于需求是无限重复加载弹幕...
pps:开始想到一个小小的弹幕,SO EZ,结果运行过程当中,CSS,JS,逻辑,动画 什么都出来了。很麻烦哟!