前端之簡易彈幕實作
- 實作效果:
- 實作思路:
- 實作代碼
實作效果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cs0TPB5kejpXT0smeNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL1czMwEzMxEjMyEDOwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
打開網頁,直接顯示一遍本地存儲的彈幕(本地存儲的主要用于效果檢視,可删);
編輯新的彈幕,點選發送,首先顯示最新彈幕,再依次顯示一遍所有彈幕;
點選清屏,目前顯示框div下的所有子元素全部,但已進入發送隊列的會繼續顯示(可認為是bug,但也可以認為不是,畢竟隻是清理目前螢幕而已,又不是關閉彈幕 > v <)
實作思路:
- html布局:中間一個div顯示框,用于裝填彈幕消息;下面兩個button,一個用于發送新消息,一個用于清屏。
-
js邏輯:
a. 發送按鈕事件:擷取input輸入框中的值val,将其傳入senddanmu()方法中,同時将val加入消息list隊列。
b. 清屏按鈕事件:擷取顯示框div,用empty()方法清空其下的所有子元素。
c. senddanmu(val)方法:
首先,建立一個新的div标簽,将傳入的彈幕消息val加入進去,主要設定好标簽的position(由于要給div标簽添加動畫,故隻能為absolute或fixed或relative),top、right或者left(即确定好div的初始位置)。
然後,将新建立的div标簽加入顯示框div中。然後通過通路顯示框div新加入的子元素獲得新建立的div标簽,接着對其添加動畫效果。
d. danmu()方法:每間隔一定時間,依次發送消息隊列中的消息。可以用setTimeout()或者setInterval()實作時間間隔,由于它們均是異步操作,并且原理各有不同,有坑,仔細~
e. randomColor()方法:随機生成六位十六進制rgb顔色,用于給彈幕消息設定不同的顔色。
實作代碼
html:
<div class="container-fluid" style="display:flex;flex-direction:column;align-items:center;">
<div class="screen" style="position:relative;width:80%;height:400px;border:1px solid #999999;margin-top:30px;">
//插入彈幕消息
</div>
<div style="margin-top:20px;">
<input type="text" style="width:400px;height:30px;" placeholder='說點什麼...'id="something" autocomplete="off">
</div>
<div style="margin-top:10px;">
<button style="color:orange;font-size:20px;margin-right:20px;" onClick="saySomething()">發射</button>
<button style="color:purple;font-size:20px;margin-left:20px" onClick="doClear()">清屏</button>
</div>
</div>
js:
var t=0;
var list=['1','2','3','4','5','6','7','8'];
var diff=40; //相鄰彈幕高度差
var _height=10; //彈幕初始高度
function saySomething(){ //發送button的綁定事件
var something = document.getElementById("something").value;
document.getElementById("something").value = "";
list.push("'"+something+"'");
senddanmu(something);
setTimeout("danmu()",1000);
}
function doClear(){ //清屏button的綁定事件
console.log("clear");
$(".screen").empty();
}
$(document).ready(function(){
danmu();//發預設彈幕
});
function senddanmu(val){ //發送單條彈幕
var item_t = "<div style='position:absolute;color:"+randomColor()+";right:0px;top:"+_height+"px;'>"+val+"</div>";
$(".screen").append($(item_t));
var item = $(".screen").children()[$(".screen").children().length - 1];
$(item).animate({left:'10px'},10000,function(){
$(this).remove();
});
//console.log(item);
_height = _height + diff;
// console.log($(".screen").height());
// console.log(_height);
if(_height > $(".screen").height()){
_height = 20;
}
}
function danmu(){ //發送彈幕清單list
//使用setTimeout實作時間間隔
if(list){
for(var i = 0; i<list.length;i++){
console.log(list.length);
t = setTimeout("senddanmu("+list[i]+")",i*1000);
}
}
//使用setInterval實作時間間隔
// var i = 0;
// t = setInterval(function(){
// senddanmu(list[i]);
// i++;
// if(i > list.length - 1){
// clearInterval(t);
// }
// },2000);
}
function randomColor(){ //随機生産字型顔色
var color='#';
for(var i = 0;i<6;i++){
var temp = Math.floor(Math.random()*15)+1;
color = color+ temp.toString(16);
}
// console.log(color);
return color;
}