前端要怎么做B站那樣的彈幕效果?非常有趣?。?!
前言
大家好,我是林三心,用最通俗易懂的話講最難的知識點是我的座右銘,基礎是進階的前提是我的初心~
最近發(fā)現(xiàn)一個超級好玩的彈幕工具庫,他就是:danmu
圖片
- 文檔: https://imtaotao.github.io/danmu/document/zh/
- github: https://github.com/imtaotao/danmu?tab=readme-ov-file
- 在線demo地址: https://imtaotao.github.io/danmu/
1、安裝依賴
npm install danmu
2、創(chuàng)建 manager
danmu
核心包只暴露了一個 create
方法,用來創(chuàng)建一個 manager
實例
import { create } from'danmu';
// 在此處創(chuàng)建一個 manager 實例,如果不傳遞則會使用默認的配置
const manager = create({
trackHeight: '20%',
plugin: {
$createNode(danmaku) {
danmaku.node.textContent = danmaku.data;
},
willRender(ref) {
console.log(ref.type); // 即將要渲染的彈幕類型
console.log(ref.danmaku); // 即將要渲染的彈幕實例
ref.prevent = true; // 設置為 true 將阻止渲染,可以在這里做彈幕過濾工作
return ref;
},
},
// .
});
配置:
interface CreateOption {
rate?: number; // 用來設置設置彈幕的運動速率
interval?: number; // 內核輪詢渲染的頻率
gap?: number | string; // 同一條軌道在碰撞檢測的啥情況下,后一條彈幕與前一條彈幕最小相隔的距離
durationRange?: [number, number]; // 普通彈幕的運動時間,這是一個范圍值,普通彈幕會在這個范圍內隨機選擇一個時間作為運動時間,如果你希望所有的彈幕運動時間都一致,你可以將兩個數設置為同樣的數
trackHeight?: number | string; // 軌道高度
plugin?: ManagerPlugin;
limits?: { // 這個參數會限制彈幕渲染的數量
view?: number;
stash?: number;
};
direction?: 'right' | 'left'; // 彈幕的運動方向
mode?: 'none' | 'strict' | 'adaptive'; // 用來確定內核的碰撞檢測算法
}
exportdeclarefunction create(options?: CreateOption): Manager;
3、掛載并渲染
當我們創(chuàng)建好了一個manager
的時候就可以掛載到某個具體的節(jié)點上并渲染,實際上manager
內部會啟動一個定時器來輪詢將內存區(qū)的彈幕來渲染出來,而輪詢的時間是交由你來控制的
const container = document.getElementById('container');
// 掛載,然后開始渲染
manager.mount(container);
manager.startPlaying();
4、發(fā)送普通彈幕
// 發(fā)送彈幕的內容類型可以在創(chuàng)建 manager 的時候通過范型來約定,可以看后面的章節(jié)
manager.push('彈幕內容');
但是通過manager.push
方法來發(fā)送的彈幕可能會受到彈幕算法的影響,不會立即渲染,想象一些往一個數組里面 push 一個數據,但是消費是從數組最前端拿出數據消費的。我們可以換一個manager.unshift
方法來發(fā)送彈幕
// 這會在下一次渲染輪詢中,立即渲染
manager.unshift('彈幕內容');
5、發(fā)送高級彈幕
普通彈幕會受到碰撞渲染算法的限制,對于那些需要特殊處理的彈幕,例如頂部彈幕,特殊位置的彈幕,則需要通過manager.pushFlexibleDanmaku
這個 API 發(fā)送高級彈幕來渲染,高級彈幕不會受到碰撞算法的限制
manager.pushFlexibleDanmaku('彈幕內容', {
id: 1, // 可選參數
duration: 1000, // 默認從 manager.options.durationRange 中隨機取一個值
direction: 'none', // 默認取 manager.options.direction 的值
position: (danmaku, container) => {
// 這會讓彈幕在容器居中的位置出現(xiàn),因為 direction 為 none,所以會靜止播放 1s
return {
x: `50% - ${danmaku.getWidth() / 2}`,
y: `50% - ${danmaku.getHeight() / 2}`,
};
},
plugin: {
// plugin 參數是可選的,具體可以參考普通彈幕的鉤子,這里是一樣的
},
});