在視頻網站看視頻的時候,經常能看到彈幕,某個時間段彈幕數超級多,某個時間段幾乎沒有,我們可以實時新增彈幕並且能實時出現在彈幕羣中。
再次進入該視頻後,會發現之前添加的彈幕還是在之前添加的時間點出現,當然還是可以再次添加彈幕。
那這樣的彈幕效果是怎麼實現的呢?
也是因爲業務方向的原因,竟然從來沒有做過彈幕功能,最近兩天在複習,順帶就試着實現下彈幕功能。時間充裕的話會逐步完善優化彈幕效果
一、最最基礎版
1、實現的效果:
- 總共4個彈幕軌道,在這4個彈幕軌道中展示所有的彈幕信息。
- 每條彈幕隨機添加字體大小、 顏色等。
- 從右向左,只顯示一遍。
- 可以新增彈幕並實時展示出來,用黑框包裹新增的彈幕。
2、思路:
- 在視頻網站看視頻時可以注意到,每條彈幕是在指定的時間出現的。由此,可以給彈幕添加一個時間字段,用於表示該彈幕是在什麼時候發送的。
- 寫一個從右向左滾動的動畫,動畫的延遲時間就是彈幕出現的時間。
- 新增彈幕,因爲要立即展示出來,則,延遲時間爲0
3、效果圖
4、 整體代碼如下:
<html>
<head>
</head>
<body>
<style type="text/css">
#danmu-wrap {
width: 1200px;
height: 520px;
border: 1px solid #3c3c33;
position: relative;
overflow: hidden;
}
.danmu-area {
width: 100%;
height: 50%;
border: 1px solid cadetblue;
position: absolute;
}
.danmu-area .line {
height: 40px;
padding: 10px 0;
line-height: 40px;
position: absolute;
}
.danmu-area .line0 {
top: 0;
}
.danmu-area .line1 {
top: 60px;
}
.danmu-area .line2 {
top: 120px;
}
.danmu-area .line3 {
top: 180px;
}
.danmu-area .line .span {
margin: 0 15px;
padding: 0 10px;
display: inline-block;
position: absolute;
left: 1200px;
width: max-content;
}
.add-area{
position: absolute;
top:280px;
}
@keyframes scrollRL {
0% {
left: 1200px;
}
25% {
left: 600px;
}
50% {
left: 0;
}
75% {
left: -600px;
}
100% {
left: -1200px;
}
}
</style>
</head>
<body>
<div id="danmu-wrap">
<div class="danmu-area" id="danmu-area">
</div>
<div class="add-area">
<input id="input" placeholder="在此輸入彈幕"> <button id="send">點擊發送</button>
</div>
</div>
<script>
var data = [{
value: "今天天氣不錯",
time: 2
}, {
value: "男主演技好差勁,是機器人嗎,只有嘴巴在動",
time: 4
},
{
value: "於媽媽,想你o(╥﹏╥)oo(╥﹏╥)oo(╥﹏╥)o",
time: 5
},
{
value: "男主演技好差勁,是機器人嗎,只有嘴巴在動",
time: 4
},
{
value: "於媽媽,想你o(╥﹏╥)oo(╥﹏╥)oo(╥﹏╥)o",
time: 7
},
{
value: "男主演技好差勁,是機器人嗎,只有嘴巴在動",
time: 11
},
{
value: "於媽媽,想你o(╥﹏╥)oo(╥﹏╥)oo(╥﹏╥)o",
time: 10
},
{
value: "哈哈哈,笑死",
time: 13
}, {
value: "辣眼睛啊,這演技",
time: 23
}, {
value: "哇撒,男兒好帥,我愛了",
time: 24
}, {
value: "啊啊啊啊啊啊,天哪,怎麼會這樣",
time: 40
},
{
value: "剛纔煮玉米,結果水燒乾了,鍋底都燒紅了,o(╥﹏╥)o",
time: 30
},
{
value: "啊啊啊啊啊啊,天哪,怎麼會這樣",
time: 44
}
, {
value: "啊啊啊啊啊啊,天哪,怎麼會這樣",
time: 49
}]
var area = document.getElementById("danmu-area");
var fontColor = ['red', 'blue', 'orange', 'dark', 'pink'];// 字體顏色
var fontSize = [14, 16, 22, 14, 20, 18];
var fontWeight = ['bold', 'bolder', 'normal', "900", '500', "400"]
// 4個彈幕軌道,所有的數據按順序隨機出現在某一個軌道上
for (var i = 0; i < 4; i++) {
var div = document.createElement("div");
div.setAttribute("class", "line" + i + " line");
area.appendChild(div);
}
for (var i = 0; i < data.length; i++) {
// 將彈幕信息按順序隨機放在彈幕軌道上
createNewInfo(data[i].value,data[i].time)
}
function createNewInfo(val,time,add){
var infoSpan = document.createElement("span");
infoSpan.setAttribute("class", "span");
infoSpan.innerText = val;
infoSpan.style.color = fontColor[Math.floor(Math.random() * 10) % 5];
infoSpan.style.fontSize = fontSize[Math.floor(Math.random() * 10) % 6];
infoSpan.style.fontWeight = fontWeight[Math.floor(Math.random() * 10) % 6];
infoSpan.style.webkitAnimationName = "scrollRL";
infoSpan.style.webkitAnimationDelay =time + "s";
infoSpan.style.webkitAnimationDuration = "12s";
infoSpan.style.webkitAnimationTimingFunction = "linear";
if(add){
infoSpan.style.border="2px solid black";
}
document.getElementsByClassName("line" + Math.floor(Math.random() * 10) % 4)[0].appendChild(infoSpan);
}
document.getElementById("send").onclick=function(){
var value=document.getElementById("input").value;
if(!value){
alert("不能爲空!");
}else{
createNewInfo(value,0,'add');
}
}
</script>
</body>
</html>
5、存在的問題
- 因爲是提前將所有彈幕信息添加到span標籤內,放入對應的彈幕軌道,若是彈幕是很多(上千,上萬),那就會添加對應個數的span標籤,過於冗餘了