洪洞網(wǎng)站建設(shè)易觀數(shù)據(jù)
上班逛B站時(shí)摸魚(yú)時(shí),看到了滿屏的彈幕,而且還不擋臉,突然心血來(lái)潮來(lái)看看它是怎么實(shí)現(xiàn)的?
不難發(fā)現(xiàn)彈幕其實(shí)它就是有一個(gè)蒙版層div,遮擋在視頻組件的上方,z-index層級(jí)設(shè)置的比較高(這里是11),video標(biāo)簽層級(jí)為默認(rèn)值0,所以這個(gè)視頻播放的頁(yè)面是由多個(gè)層組成的(當(dāng)然該頁(yè)面還有很多其他的layout層,這里不細(xì)講),這一點(diǎn)我們也可以從頁(yè)面layout分層中也可以直觀地看出來(lái):
此時(shí)又有同學(xué)跳出來(lái)問(wèn)。。。。。。
同學(xué)A: ”那它這個(gè)不擋臉的彈幕又是如何實(shí)現(xiàn)的呢?“
me:這位同學(xué)這個(gè)問(wèn)題很好,我們接著看:
me:高端的食材往往需要最崴的廚子 不對(duì)… 高端的效果,往往底層原理很簡(jiǎn)單
廢話不多說(shuō),我模擬了一個(gè)Demo,直接上代碼。。。
// index.html文件
<head><meta charset="utf-8" /><link rel="icon" href="%PUBLIC_URL%/favicon.ico" /><meta name="viewport" content="width=device-width, initial-scale=1" /><meta name="theme-color" content="#000000" /><metaname="description"content="Web site created using create-react-app"/><title>React App</title><style>.back{position: relative;width: 751px;height: 420px;-webkit-mask-image: url('data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKIHdpZHRoPSI3NTAuMjIyMjIyMjIyMjIyMnB4IiBzdHlsZT0idHJhbnNmb3JtOnNjYWxlKDEuMDAxLDEpOyIgaGVpZ2h0PSI0MjJweCIgdmlld0JveD0iMCAwIDMyMC4wMDAwMDAgMTgwLjAwMDAwMCIKIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIG1lZXQiPgo8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLjAwMDAwMCwxODAuMDAwMDAwKSBzY2FsZSgwLjEwMDAwMCwtMC4xMDAwMDApIgpmaWxsPSIjMDAwMDAwIiBzdHJva2U9Im5vbmUiPgo8cGF0aCBkPSJNMCA5MDUgbDAgLTg5NSAyMzggMCAyMzggMCAyIDYzIGM1IDEzNiA0NiAzNTcgNzggNDE3IDIyIDQzIDU2IDc1IDE0NCAxMzUgOTYKNjUgMTI1IDg3IDE3OCAxMzEgMjAgMTcgNjUgNTAgOTggNzMgbDYxIDQxIDcgNzIgYzMgNDAgOSA5MSAxMiAxMTQgNSAzNyAxIDQ4Ci00MCAxMDggLTI1IDM3IC00NiA3NCAtNDYgODIgMCA4IC0xMSAxOSAtMjQgMjMgLTI4IDExIC0zNiAyOSAtMzYgODAgMCAyMCAtNgo0NSAtMTMgNTYgLTcgMTEgLTIwIDQ2IC0yNyA3OCAtMjQgMTA0IDIwIDIwMSAxMTMgMjQ4IDI4IDE1IDM3IDI2IDM3IDQ0IGwwCjI1IC01MTAgMCAtNTEwIDAgMCAtODk1eiIvPgo8cGF0aCBkPSJNMTU5MCAxNzc5IGMwIC0xMiA3IC0yNyAxNyAtMzQgOSAtNyAxOSAtMzQgMjMgLTYxIDQgLTI3IDE0IC02MyAyMSAtODEgMTAKLTI0IDEwIC00MCAyIC03MCAtMTkgLTY2IC00MyAtMTg3IC00MyAtMjE4IC0xIC0yNyAtNDcgLTIwNiAtNjQgLTI0NiAtNiAtMTMKOSAtMjMgNzMgLTQ5IDEwMSAtNDAgMTA4IC00OCA5MSAtMTAxIC0xNiAtNDYgLTEyIC01MiA1MSAtNjkgMzcgLTEwIDEyMyAtNTMKMTQ4IC03MyAyNiAtMjEgODYgLTExMSAxMTkgLTE3NSAyNiAtNTIgMzIgLTc2IDMyIC0xMjcgMCAtNTkgMyAtNjYgNDEgLTExMQoyMiAtMjcgNDcgLTYyIDU2IC03OSA5IC0xNiAzNSAtNTkgNTggLTk1IDQ5IC03NiA4MyAtMTUwIDc3IC0xNjggLTMgLTkgOTIKLTEyIDQ1MiAtMTIgbDQ1NiAwIDAgODk1IDAgODk1IC04MDUgMCAtODA1IDAgMCAtMjF6Ii8+CjwvZz4KPC9zdmc+Cg==');-webkit-mask-size: 751px 420px;background-color: brown;}.bullet{position: absolute;font-size: 20px;color: #FFFFFF;}</style></head><body><div id="root">23456789</div></body>
</html>
// App.js文件
import Img from './components/video';function App() {return <Img />;
}export default App;
// Img組件
const texts=[{left:140,top:10,text:'UP主好帥'},{left:200,top:430,text:'你難道就是傳說(shuō)中的奶靈'},{left:231,top:70,text:'你好,我是ronychen'},{left:20,top:35,text:'喜歡唱跳rap籃球'},{left:821,top:53,text:'HELLO WORLD'},{left:30,top:121,text:'我是練習(xí)時(shí)長(zhǎng)2年半的練習(xí)生'},{left:398,top:321,text:'哈哈哈哈'},{left:190,top:90,text:'我就蹭蹭,不進(jìn)去'},{left:170,top:200,text:'hahahahahahahahah'},{left:240,top:490,text:'這是什么XXXX'},{left:420,top:340,text:'元芳,你則么看?'},
]
const Img =()=>{return (<div className='back'>{texts.map((item,index)=>(<div key={index} className="bullet" style={{left:`${item.left}px`, top:`${item.top}px`}}>{item.text}</div>))}</div>)
}export default Img;
基本看到這,大部分同學(xué)應(yīng)該都能理解了,其實(shí)原理很簡(jiǎn)單,一張蒙版圖 + 一個(gè)屬性(-webkit-mask-image)就搞定了,實(shí)際效果就是這樣:
是不是有種那感覺(jué)了
總結(jié):
彈幕原理:就如我上面所說(shuō),有一個(gè)單獨(dú)的蒙版層div,它會(huì)設(shè)置一個(gè)比視頻組件更高的層級(jí)值,這樣就能顯示在視頻上方,這里插一句話,在移動(dòng)端,大多數(shù)瀏覽器貌似都不支持在video標(biāo)簽上放其他內(nèi)容,在移動(dòng)端,video標(biāo)簽貌似已經(jīng)脫離標(biāo)準(zhǔn)文檔流,即使你設(shè)置再高的z-index值也是不行的,回歸主題,至于彈幕不遮擋人物這種效果的實(shí)現(xiàn),我的理解應(yīng)該是AI算法會(huì)實(shí)時(shí)導(dǎo)出視頻中識(shí)別到的人物,然后導(dǎo)出這些人物的圖片,這點(diǎn)我們可以在network中看到會(huì)有實(shí)時(shí)的圖片加載,這些圖片就是我們上面要用到的蒙版圖,然后再結(jié)合css中的-webkit-mask-image屬性,就可以實(shí)現(xiàn)上述效果,該屬性具體的用法可以點(diǎn)擊這里查看
至于這一張張的蒙版圖片是怎么來(lái)的,這塊我也不是很清楚,應(yīng)該是AI算法實(shí)時(shí)導(dǎo)出的吧! 有興趣的同學(xué)自行了解吧 hahaha。。。