前言
6000+門店使用的大屏,主機(jī)配置竟然是Android5.5 + Chrome 78,不支持es6。。。
隨隨便便一個css動畫都可以把頁面卡成ppt。
開發(fā)只給兩天。。。
buff疊滿,還想在頁面中做websocket,實(shí)現(xiàn)彈幕滿屏播放功能。。。
調(diào)研嘗試了一下,考慮了repaint等因素,用了css的transform:tanslate屬性,頁面只有兩個div在移動頁面都卡,無語了,甚至還開啟了gpu加速transform:tanslateZ,一樣卡成ppt,真的是delay no more了
無奈之下,嘗試了自己最不熟悉的Canvas,沒想到竟然如此絲滑,把元素調(diào)成100個也絲毫不影響性能。
大家逛街時估計都見過吧哈哈哈
核心優(yōu)勢
Canvas繪圖
批量渲染:可以在一次繪制循環(huán)中處理所有彈幕,減少瀏覽器重繪次數(shù)。
內(nèi)存效率:不需要為每個彈幕創(chuàng)建DOM元素,降低內(nèi)存使用。
靈活性:可以輕松實(shí)現(xiàn)復(fù)雜的視覺效果和碰撞檢測。
requestAnimationFrame
function animate() {
// 更新彈幕位置
updateBarrages();
// 渲染彈幕
renderBarrages();
// 循環(huán)調(diào)用
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
與setTimeout或setInterval相比,requestAnimationFrame有以下優(yōu)勢:
與顯示器刷新率同步,通常是60fps,減少丟幀。
在標(biāo)簽頁不可見時自動暫停,節(jié)省資源。
允許瀏覽器優(yōu)化并合并多個動畫操作,提高性能。
隊列虛擬列表:突破性能瓶頸
為了處理大量彈幕,實(shí)現(xiàn)了一個隊列虛擬列表:
class CanvasBarrage {
// ...其他代碼
handleBarrageRenderList() {
// 移除已經(jīng)離開屏幕的彈幕
this.barrageList = this.barrageList.filter(item => !item.isExit);
// 添加新的彈幕到渲染列表
let addList = this.handleBarrageOriginList(this.barrageOriginList);
addList = this.handleBarragePosition(addList);
this.barrageList = this.barrageList.concat(addList);
this.barrageCleanCount = 0;
}
}
自適應(yīng)
支持px到vw的轉(zhuǎn)換,使彈幕在不同屏幕尺寸下都能正常顯示。
使用介紹
配置參數(shù)
以下是CanvasBarrage
類的主要配置參數(shù):
參數(shù)名 | 類型 | 默認(rèn)值 | 描述 |
---|
id | string | null | 容器元素的選擇器 |
barrageList | IBarrageItem[] | [] | 初始彈幕列表 |
barrageRow | number | 5 | 彈幕行數(shù) |
barrageSpace | number | 50 | 彈幕間隔 |
toVw | boolean | false | 是否轉(zhuǎn)換為vw單位 |
basePx | number | clientWidth | 基準(zhǔn)像素值 |
renderSize | number | 50 | 渲染size |
fontSize | number | 20 | 字體大小 |
fontFamily | string | 'Arial' | 字體族 |
isRandomFontColor | boolean | false | 是否使用隨機(jī)字體顏色 |
fontColor | string | 'black' | 字體顏色 |
barrageSpeed | number | 1 | 彈幕速度 |
renderOverLimit | number | 20 | 渲染超出限制數(shù)量 |
maxLimit | number | 200 | 最大渲染數(shù)量 |
使用方法
const barrageSystem = new CanvasBarrage({
id: '#video-container',
barrageList: initialBarrages,
barrageRow: 10,
fontSize: 24,
isRandomFontColor: true
});
barrageSystem.drawBarrage();
// 添加新彈幕
barrageSystem.addBarrage([{ value: '新彈幕內(nèi)容' }]);
?
效果
因為移除了UI,給大家自定義化,所以效果是最原始樣式

源碼
記得點(diǎn)一個star
哦
Github鏈接
轉(zhuǎn)自https://juejin.cn/post/7428247498861396022
該文章在 2024/10/25 10:52:25 編輯過