Barrage UI
Best and lightest barrage component for web UI.
適用於 web 端使用者介面和播放器的輕量級彈幕元件
用途
- 為你的 視訊播放器、圖片瀏覽器 等元素掛載彈幕動畫
- 用於實現 B 站(bilibili.com) 風格的 蒙版彈幕 效果
安裝
yarn add barrage-ui
複製程式碼
或
npm install --save barrage-ui
複製程式碼
快速開始
import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json'; // 元件提供的示例資料
// 載入彈幕
const barrage = new Barrage({
container: 'barrage', // 父級容器或ID
data: example, // 彈幕資料
config: {
// 全域性配置項
duration: 20000, // 彈幕迴圈週期(單位:毫秒)
fontFamily: 'Microsoft Yahei', // 彈幕預設字型
defaultColor: '#fff', // 彈幕預設顏色
},
});
// 新增一條彈幕
barrage.add({
key: 'fctc651a9pm2j20bia8j', // 彈幕的唯一標識
time: 1000, // 彈幕出現的時間(單位:毫秒)
text: '這是新增的一條彈幕', // 彈幕文字內容
fontSize: 24, // 該條彈幕的字號大小(單位:畫素),會覆蓋全域性設定
color: '#0ff', // 該條彈幕的顏色,會覆蓋全域性設定
});
// 播放彈幕
barrage.play();
複製程式碼
初始化引數
建立彈幕例項時,需要傳入的初始化引數如下:
引數 | 資料型別 | 預設值 | 說明 |
---|---|---|---|
container | string/element | 必傳,無預設值 | 彈幕的掛載點 |
data | array | [] | 彈幕資料 |
config | object | 詳見全域性配置項 | 詳見全域性配置項 |
mask | string/ImageData | string/ImageData | 蒙版影像,用於實現蒙版彈幕效果,詳見蒙版彈幕 |
beforeRender | function | (ctx, progress, animState) => {} | 幀渲染前的回撥,函式實參分別為:ctx canvas 畫布的上下文progress 動畫的播放進度(毫秒)animState 動畫狀態: 'paused' 或 'playing' |
afterRender | function | (ctx, progress, animState) => {} | 幀渲染後的回撥,函式實參分別為:ctx canvas 畫布的上下文progress 動畫的播放進度(毫秒)animState 動畫狀態: 'paused' 或 'playing' |
overlapOptimized | boolean | false | 彈幕裝填時是否啟用佈局優化,以儘可能避免使相鄰時間的彈幕重疊 |
其中,container
引數在初始化例項時必傳,其他引數為可選,資料型別及預設值如上表所示。
全域性配置項
配置項及預設值
彈幕的所有全域性配置項及預設值如下:
{
duration: -1, // 彈幕動畫的迴圈週期,-1 表示不迴圈播放
speed: 100, // 彈幕的運動速度
fontSize: 24, // 文字大小,單位:畫素
fontFamily: 'Microsoft Yahei', // 字型,預設值:微軟雅黑
textShadowBlur: 1.0, // 字型陰影擴散,有效值 >= 0
opacity: 1.0, // 透明度,有效值 0-1
defaultColor: '#fff', // 預設顏色,與 CSS 顏色屬性一致
}
複製程式碼
更新配置項
如果你的彈幕例項已建立或者正在播放,可以通過 .setConfig()
方法進行實時更新:
// 更新全域性透明度
barrage.setConfig({ opacity: 0.5 });
複製程式碼
彈幕資料
結構與內容
彈幕資料集為一個物件陣列。每個陣列元素對應一條彈幕記錄,其結構如下:
{
key: 'fctc651a9pm2j20bia8j',
createdAt: '2019-01-13T13:34:47.126Z',
time: 1200,
text: '我膨脹了',
fontFamily: 'SimSun',
fontSize: 32,
color: 'yellow',
}
複製程式碼
資料欄位
- createdAt - 彈幕的建立時間 (必須)
- time - 彈幕的動畫時間 (必須)
- text - 彈幕文字內容 (必須)
- key - 資料的唯一標示 (推薦)
- fontFamily - 彈幕文字的字型 (可選)
- fontSize - 彈幕文字字號大小,單位:畫素 (可選)
- color - 彈幕文字的顏色 (可選)
關於 key
當動畫過程中需要更新資料集時,推薦設定此欄位。
動態更新資料集時,為了動畫的連續性,更新前後的資料集可能存在部分相同的資料。Barrage 元件內部會對更新前後的資料的 key 進行比較,只增量渲染那些新增的資料,而不改變已經存在的彈幕布局。
綜上所述,欄位 key 的取值應該是穩定且唯一的。對於同一條彈幕而言,key 的值應該是不變的。
裝填彈幕
裝填彈幕有兩種方式:
方式一:初始化時傳入資料
const barrage = new Barrage({
container: 'barrage',
data: JSON_DATA, // JSON_DATA -> 你的彈幕資料
});
複製程式碼
方式二:初始化後更新資料
const barrage = new Barrage({
container: 'barrage',
});
barrage.setData(JSON_DATA); // JSON_DATA -> 你的彈幕資料
複製程式碼
新增彈幕
如果你的彈幕例項已建立或者正在播放,可以通過 .add()
方法新增一條記錄:
barrage.add({
key: 'fctc651a9pm2j20bia8j',
time: 1000,
text: '這是新增的一條彈幕',
fontSize: 26,
color: '#0ff',
});
複製程式碼
.add()
方法一般搭配 資料提交/請求 操作進行使用,以實現真實的線上應用。
適用場景: 實現多終端同步的實時彈幕
- 某使用者在客戶端提交了一條彈幕到服務端
- 服務端將資料儲存並分發給正在進行會話的客戶端
- 客戶端收到資料後,使用
.add()
方法進行資料更新
動畫控制介面
barrage.play()
描述
用於播放動畫。若當前為暫停狀態,則從當前進度繼續播放
用例
barrage.play();
複製程式碼
barrage.pause()
描述
用於暫停動畫
用例
barrage.pause();
複製程式碼
barrage.replay()
描述
用於重新開始播放動畫
用例
barrage.replay();
複製程式碼
barrage.goto(progress)
描述
用於跳轉播放進度。此方法在動畫播放和暫停的狀態下均有效
引數
progress - 待跳轉的進度。值為一個毫秒數,表示跳轉到動畫的第幾毫秒
用例
barrage.goto(15000); // 跳轉到第 15 秒
複製程式碼
動畫狀態屬性
barrage.progress
含義
當前動畫的播放進度
型別
描述播放進度的一個毫秒數
barrage.animState
含義
當前動畫的播放狀態
型別
描述播放狀態的一個字串:
- 'ready' - 已就緒。即:barrage 例項已建立,但從未播放
- 'paused' - 已暫停
- 'playing' - 播放中
其他介面&屬性
barrage.setMask(mask)
描述
用於設定蒙版影像。蒙版影像的概念見下文 蒙版彈幕
引數
mask - 蒙版影像的 url 或 ImageData
用例
barrage.setMask('mask.png'); // 通過圖片 url 設定蒙版影像
barrage.setMask(imageData); // 直接設定 ImageData 型別的資料
複製程式碼
barrage.clearMask()
描述
用於清空當前的蒙版影像。清空後若不再重新設定蒙版影像,則動畫將不再具有蒙版效果
用例
barrage.clearMask();
複製程式碼
barrage.canvas
含義
渲染彈幕的 canvas 畫布
barrage.ctx
含義
畫布的上下文,相當於 barrage.canvas.getContext('2d')
蒙版彈幕
Barrage 元件提供了實現 蒙版彈幕 效果的可能。基於本元件實現的 demo 效果如下:
什麼是“蒙版彈幕”
蒙版彈幕 是由知名彈幕視訊網站 bilibili 於 2018 年中推出的一種彈幕渲染效果,可以有效減少彈幕文字對視訊主體資訊的干擾。
詳細資料可參考 bilibili 的相關文章:
實現原理
如果你熟悉最著名的影像處理軟體——Adobe Photoshop,那麼你應該對 “蒙版” 的概念不陌生,“蒙版彈幕” 的實現原理與此類似,即:將影像的一部分 “隱藏”。
Barrage 元件的初始化引數中的 mask
一項即用於處理蒙版效果。對於上文截圖中的效果,其使用的蒙版影像效果如下:
彈幕渲染時,會將蒙版影像中 “鏤空” 的部分(影像 RGBA 通道中 Alpha 通道為 0 的畫素)去除,從而達到 “蒙版彈幕” 的效果。
簡單蒙版彈幕的實現
為 barrage 例項設定蒙版影像(mask)即可實現蒙版彈幕效果。
- 可通過初始化引數
mask
傳入蒙版影像:
import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json';
const barrage = new Barrage({
container: 'barrage',
data: example,
mask: 'mask.png', // 傳入蒙版影像的 url
});
複製程式碼
- 也可以在彈幕初始化後,通過
.setMask()
方法進行實時更新:
import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json';
const barrage = new Barrage({
container: 'barrage',
data: example,
});
// 設定蒙版影像
barrage.setMask('mask.png'); // 傳入蒙版影像的 url
複製程式碼
注意
mask
引數和.setMask()
方法的引數型別一致,可接收影像的 url 或 ImageData
實時渲染
上文的示例僅能夠實現一幀蒙版影像的渲染(只設定了一次 mask 而沒有實時更新它),要實現實時的蒙版效果(如:與視訊實時同步的蒙版效果),需要對彈幕動畫的每一幀進行處理。
使用元件提供的 beforeRender 鉤子函式,可以輕易的實現:
import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json';
const barrage = new Barrage({
container: 'barrage',
data: example,
beforeRender: (ctx, progress) => {
const imageData = getMask(progress); // 用於獲取當前進度對應蒙版的方法
barrage.setMask(imageData);
},
});
複製程式碼
當然,beforeRender 鉤子也可以在彈幕初始化之後掛載:
import Barrage from 'barrage-ui';
import example from 'barrage-ui/example.json';
const barrage = new Barrage({
container: 'barrage',
data: example,
});
barrage.beforeRender = (ctx, progress) => {
const imageData = getMask(progress); // 用於獲取當前進度對應蒙版的方法
barrage.setMask(imageData);
};
複製程式碼