這兩天又看到有人問 Vue 如何作彈幕效果。css
正好我過年的時候作了個活動,其中用戶能夠搖籤,而後 C 位飄屏展現。html
Vue 版本效果地址:https://www.lilnong.top/static/html/vue-bullet-biubiubiu.html
網上原生版本:https://www.lilnong.top/stati...前端
動畫效果其實很簡單,從右到左。vue
通常來講咱們認知的動畫流暢度順序是 css(transform) > css(left) > js
。微信
實現起來有兩種方案動畫
咱們先來看看 css 的 transform 如何實現動畫效果。this
@keyframes right2left { 0% {transform: translate(100vw)} 100% {transform: translate(-100%);} }
由於 translate
的 % 是基於當前元素的,因此咱們能夠設置開始位置在 100vw(正好在右邊屏幕外),結束位置在 -100%(正好把本身都挪到左邊屏幕外)spa
@keyframes right2left { 0% {left: 100%} 100% {left: -100%} }
left 的 % 是基於父級的 width,因此這裏開始位置能夠設置 100%,結束位置不太好控制 -100%設計
由於個人需求是當前登陸用戶發出的會在 C 位顯示,因此我把他設計成了三個隊列code
// 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 也有對應的結束事件 transtionend
。
可是開始比較坑,他須要的是兩幀。這裏咱們要依賴 $nextTick
來實現
設置五條航道,每 1000ms 渲染一個彈幕,這樣的話就能夠錯開行。
並且由於動畫是固定時長,因此能夠人爲控制一行只有一個。
歡迎你們關注個人公衆號。有疑問也能夠加個人微信前端交流羣。