你們都說前端寫頁面較多,幾乎用不到算法。本文願從彈幕設計這個場景來描述算法在前端中的應用,咱們先來看下實現效果:前端
圖1.1 彈幕效果
開場以前咱們先來描述彈幕開發的難度,再集中精力描述算法設計的思路。git
如何保證不一樣字號的彈幕不碰撞github
若是彈幕採用相同的字號,碰撞的問題處理起來比較簡單,只要考慮相鄰彈幕的播放速度和偏移的位置就能夠計算出來。然而使用不一樣字號的彈幕處理起來就麻煩了許多,彈幕的起始位置不能夠線性的增長,好比第一行放了字幕,接下來的字幕能夠按順序從上至下依次放置便可。算法
彈幕的位置計算緩存
只有設計好彈幕的初始位置,才能夠動態、高效的管理不一樣字號彈幕的碰撞問題。打個比方,咱們經過接口獲取了2秒以內的彈幕數據1000條,每一個字幕的長度、速度、字號都不一樣,怎麼管理這些彈幕,示意圖以下:動畫
圖2.1 彈幕管理示意圖
這是第一種狀況,按照從上到啊的順序依次擺放之後會有幾個問題:spa
一系列問題就不通通列舉出來了,基於這個背景咱們結合數學建模的思惟方式,找到了彈幕場景類似度很是高的機場運營。咱們能夠把彈幕當作飛機,每一個時間段播放多少彈幕和機場每一個時間段放飛多少飛機一個道理。設計
首都國際機場一共有3條跑道,兩條4E級跑道、一條4F級跑道,2016年的吞吐量爲9000萬人次。它的運行機制就是全部飛機經過搭臺有順序的共用3條跑道來完成運輸任務的。3d
同理,咱們也設計了幾個個角色:一個是軌道(跑道)、一個是調度(塔臺)、一個是彈幕(飛機),咱們爲每一個角色設計一個類分爲爲Track、Main、Bullet。code
軌道
軌道這個角色很重要,它能夠解決彈幕位置計算、速度控制、碰撞檢測問題。
首先,咱們要來初始化軌道。通俗的說咱們要修建幾個跑道呢,咱們不是實物,能夠動態調整軌道的 數量,計算的原則:
軌道數量 = 播放器有效高度 / 設備基準字號
設備基準字號:移動端是10px,pc端是12px;
爲啥計算公式是這樣的?由於咱們要支持不一樣字號的彈幕。試想不一樣的字號對物理空間的佔用是不一樣的,然而若是要求軌道的尺寸是動態的,那就帶來很複雜的計算。本文提出「虛擬軌道」的概念,在交通管制中最多見的就是道路合併或者改向。咱們也是採用將相鄰的物理軌道臨時合併爲一條軌道。這樣就能夠輕鬆的解決不一樣字號的軌道佔用問題。原理圖以下:
圖2.2 軌道計算示意圖
其次咱們來回憶下機場的工做流程:
機長呼叫塔臺,CZ6132請求起飛
目前跑道均被佔用,請等待
目前跑道 A1 空閒,准許進入
按照這個思路,咱們的彈幕工做流程:
軌道根據彈幕的播放速度、尺寸計算是否有合適的軌道提供
沒有
有
圖2.3 軌道可用性計算示意圖
關於軌道的基本原理咱們整理清楚了,固然還有很多細節好比如何和調度通訊、如何和彈幕通訊以及虛擬軌道檢測算法等。有興趣的同窗能夠參考代碼吧。https://github.com/bytedance/...
調度
調度就是搭臺的化身,承接着軌道、彈幕的控制,也保持着與播放器的步調一致。它的職責以下:
在彈幕啓動以後,首先要檢查本地是否已有緩存數據,沒有的話直接請求數據並緩存,而後執行數據讀取,首次過濾數據進入彈幕隊列,同時啓動定時器。彈幕隊列的數據會按期請求軌道,檢測隊列裏的彈幕是否能夠進入,一旦確認後軌道作好登記,彈幕就能夠進入播放器開啓動畫播放了。定時器每隔2秒就會再次更新數據進入到彈幕隊列(這塊不一樣的業務能夠定製不一樣的規則)。彈幕播放結束後會通知調度和軌道,調度會在彈幕隊列中移除該彈幕實例,軌道也會移除該彈幕實例的軌道佔用。