近接到公司小程序項目首頁迭代改版的工作,涉及到文章圖文布局改版。主要是精選文章,在首頁推廣入口增加評論彈幕效果,后端彈幕數據是隨文章列表接口一次性返回給前端,由前端來處理彈幕數據及相關彈幕交互效果。
隨后,簡單分析了一下后端接口的數據結構,以及查詢了一些傳統web端彈幕的js實現方式。
鑒于我們當前業務的后端彈幕數據非動態持續發送,而是固定的評論條目,前端處理也僅僅是把文章評論渲染成彈幕并循環滾動,于是我采用的解決方案是通過css3的Animation動畫屬性來實現。
下面是拆分出來的部分代碼demo實現效果的動畫演示效果。
左邊的視頻演示:有序彈幕(固定軌道式,彈幕數據劃分為三條固定軌道進行滾動顯示)
右邊的視頻演示:無序彈幕(每條彈幕的出現位置隨機性);
如果視頻無法播放的話,可以查看下方對比圖:
當前代碼邏輯比較適合一些展示型的前端交互效果,比如:資訊類欄目、社交屬性圖文欄目、推廣類廣告位等。
# 無序彈幕 wxml #
<view class='dmGroup' wx:for="{{ dmData }}" wx:key="{{ item.id }}" style="top:{{ item.top }}%; animation: dmAnimation {{item.time}}s linear {{ index*3 }}s infinite; "> <view class='dmItem'> <view class='dm'> <view class='avatarBox'> <image src='{{ item.sex == 0 ? avatarBoy : avatarGirl }}' class='avatar' mode='aspectFit'></image> <image src='{{ item.sex == 0 ? iconBoy : iconGirl }}' class='sex' mode='aspectFit'></image> </view> <text class='content'>{{ item.content }}</text> <image src='{{ iconGood }}' class='icon good' mode='aspectFill'></image> <text>{{ item.zanNumber }}</text> </view> </view> </view>
# 無序彈幕 wxss #
@keyframes dmAnimation{ from{ left: 100%; } to{ left: -100%; } }
# 有序彈幕(軌道式) wxml #
<!-- top --> <view class='dmGroup top' style="animation: dmAnimation2 35s linear infinite; "> <view class='dmItem' wx:for="{{ dmData }}" wx:if="{{ index < 6 }}" wx:key="{{ item.id }}"> <view class='dm'> <view class='avatarBox'> <image src='{{ item.sex == 0 ? avatarBoy : avatarGirl }}' class='avatar' mode='aspectFit'></image> <image src='{{ item.sex == 0 ? iconBoy : iconGirl }}' class='sex' mode='aspectFit'></image> </view> <text class='content'>{{ item.content }}</text> <image src='{{ iconGood }}' class='icon good' mode='aspectFill'></image> <text>{{ item.zanNumber }}</text> </view> </view> </view> <!-- mid --> <view class='dmGroup mid' style="animation: dmAnimation2 30s linear 1s infinite; "> <view class='dmItem' wx:for="{{ dmData }}" wx:if="{{ index > 5 && index < 10 }}" wx:key="{{ item.id }}"> <view class='dm'> <view class='avatarBox'> <image src='{{ item.sex == 0 ? avatarBoy : avatarGirl }}' class='avatar' mode='aspectFit'></image> <image src='{{ item.sex == 0 ? iconBoy : iconGirl }}' class='sex' mode='aspectFit'></image> </view> <text class='content'>{{ item.content }}</text> <image src='{{ iconGood }}' class='icon good' mode='aspectFill'></image> <text>{{ item.zanNumber }}</text> </view> </view> </view> <!-- btm --> <view class='dmGroup btm' style="animation: dmAnimation2 45s linear infinite; "> <view class='dmItem' wx:for="{{ dmData }}" wx:if="{{ index > 9 }}" wx:key="{{ item.id }}"> <view class='dm'> <view class='avatarBox'> <image src='{{ item.sex == 0 ? avatarBoy : avatarGirl }}' class='avatar' mode='aspectFit'></image> <image src='{{ item.sex == 0 ? iconBoy : iconGirl }}' class='sex' mode='aspectFit'></image> </view> <text class='content'>{{ item.content }}</text> <image src='{{ iconGood }}' class='icon good' mode='aspectFill'></image> <text>{{ item.zanNumber }}</text> </view> </view> </view>
# 有序彈幕 wxss #
@keyframes dmAnimation2{ 0% { transform: translateX(0); } 100% { transform: translateX(-130%); } }
# 查看線上項目彈幕效果 #
# 詳細代碼片段及詳解,請私信喲#
者:Panda Shen
轉發鏈接:https://www.overtaking.top/2018/06/21/20180621113025/
聊時看了下斗魚直播,突然靈感乍現,想做出這個彈幕效果,于是有了下文
這里還是要說一下我的前端學習群:594959296,從我一個到現在的都是看我每一篇文章來的,可以說都是我們大前端的學霸啊,不定期分享干貨。想學到東西的都可以來,歡迎初學和進階中的小伙伴
1、像優酷、愛奇藝等,記錄用戶發送彈幕時該視頻播放的位置,其他人播放這個視頻時到了這個點就顯示彈幕。
2、像斗魚、熊貓這樣的直播網站,用戶發送彈幕直接顯示在屏幕上,以后不需要再顯示了。
我們就來做第二種!!!
實現效果
項目分析
1、獲取用戶輸入信息;
2、在頁面中創建一個 <span></span>來放獲取到的文本,并添加一些樣式(字體大小、顏色等);
3、給這個 span添加一個從右向左移動的動畫;
4、動畫結束后,移除這個 <span>。
思路很清楚了,就來動手實現一下。。
布局
頁面中要有一個輸入框讓用戶輸入信息,還要一個盒子用來顯示彈幕。為了美觀,我多加了一些東西。
1、#dm 是顯示彈幕的區域,input供用戶輸入信息(其中 placeholder 屬性規定輸入框中默認顯示內容)。
2、其它元素都是為了美觀和布局。
樣式
跟以前一樣,先給出代碼然后再講解。
1、首先還是格式化瀏覽器默認的 margin和 padding。overflow屬性設置超出屏幕的部分隱藏,這樣就不會出現下拉和水平的滾動條了。
2、#dm用來顯示彈幕,我們把它的高度設置為 90vh。vh 是 CSS3 中新增的長度單位,表示相對于視口的高度。視口高度被均分為100單位的vh,90vh 就表示當前瀏覽器可視區域高度的 90%。(vw 就是視口寬度)
3、#dm span是每條彈幕的樣式。你可以修改為你喜歡的樣子,不過一定要設置 position
定位屬性。
4、然后就是下面的輸入部分了。使用了 flex布局 (也是CSS3 中新增的內容,太方便了)。只需要 align-items:center;justify-content:center; 這兩句就可以使其中的子元素在水平和垂直方向居中。所以 #idDom 和 #content都使用了。
5、然后就是 輸入框、按鈕的樣式了,沒什么好說的,應該都能看懂。
JS部分
先看看代碼吧。。
1、說明:向頁面添加彈幕使用 addBarrage() 函數,添加動畫用 move()函數。(把一種功能封裝為一個函數是一個好習慣)
2、首先思考一下彈幕的觸發事件。應該有兩個:點擊“發射”按鈕、按下 Enter按鍵。所以分別監聽點擊 和 鍵盤事件。
3、然后就要思考怎么向頁面添加彈幕了?
先得到用戶輸入的信息
然后在頁面中創建一個
<span></span>
把得到的文本放進去添加到 #dm這個盒子中:
這樣就可以了嗎?? 當然不是的。。
4、每條彈幕應該有不同的顏色,這樣才炫酷。思路就是把預先的顏色放進一個數組,使用的時候用隨機的下標,這樣就獲得了隨機顏色。(借鑒斗魚的 7 中顏色)
這樣每條彈幕就有不同的顏色了。
5、每條彈幕在頁面上還要有不同的位置(高度),也就是不同的 top 值。我的想法是,雖然要有不同的 top ,但也不能太隨意。就像下面這樣:(一行是一行的)
我的思路是:先判斷頁面可以放多少行?
然后計算可以有的 top 值:(加 10 是為了不至于緊挨著屏幕頂部,最后的 -1 是為了不至于太靠下 )
你可以自己理解一下我的這種計算方式。。
然后應用給
<span>
即可:
6、對了,彈幕應該添加到頁面的什么位置呢?因為彈幕要從右往左移動,所以應該添加到屏幕的右側,left 值為瀏覽器頁面的寬度。這時候就知道為什么前面要設置 body 的 overflow: hidden;了吧?。?br>
動畫
彈幕(也就是<span>)被添加到頁面中了,我們要讓他動起來。思路就是寫一個函數,減少 <span>
的 left 值。每隔幾毫秒執行一次這個函數,我們看起來這個 <span>元素就動起來了。
7、但是有幾個問題:
頁面中有多少個彈幕(<span>)?因為頁面中只有 彈幕 使用的是 <span> 標簽,所以這樣就可以獲取所有 <span>的 nodeList(類似數組但不是數組,可以使用下標索引訪問):
怎樣記錄每條彈幕的 left 值?獲取到所有的 <span>后,用一個 for 循環將每一個 <span> 的 left 值放進一個數組:
這樣 arr[] 就保存了所有彈幕的 left 值。
8、接下來我們就逐個減少每條彈幕的 left 值:
9、最后判斷如果彈幕已經移出了頁面的左邊,就把這條彈幕刪除了吧。
我們可以在開發工具中看一下這個過程:
彈幕的 left 一直減小,移出頁面后 #dm中就沒有這個 <span>了。
10、最后處理一個小細節吧!當我們點擊按鈕或按回車后,輸入框中的文字會保留,影響我們下次輸入,所以只要獲取到了用戶輸入的內容,就把輸入框清空吧!
到此,彈幕就實現了。。。
學習javascript也是有門檻的,就是你的html和css至少還比較熟練,您不能連html這東東是干啥的都不知道就開始學javascript了,學乘除前,學好加減法總是有益無害的。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。