話不多說,老規矩,先上Demo 點此預覽
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcuITOzUjMwIjM0AzMwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
實作思路:
- 從輸入框擷取輸入資訊
- 生成彈幕節點
- 彈幕從螢幕一側逐幀移動到另一側
- 移動完畢,删除彈幕節點
- 首先是界面布局的實作CSS
*{
padding: 0;
margin: 0;
}
html,body{
height: 100%;
user-select: none;
}
.screen{
overflow: hidden;
position: relative;
height: 100%;
background-color: rgba(249, 249, 249, 0.78);
}
.top{
position: absolute;
top:0;
height: 80px;
width: 100%;
line-height: 80px;
background-color: #ffffff;
text-align: center;
font-size: 35px;
font-weight: bold;
color: rgba(2, 2, 5, 0.87);
box-shadow: 17px -5px 40px #6d6a6a8f
}
.top span{
position: absolute;
left: 55px;
color: #7c22d6;
font-size: 25px;
}
.send{
position:absolute;
bottom: 0;
width:100%;
height:240px;
line-height:240px;
background-color: #ffffff;
text-align: center;
box-shadow: 17px 11px 40px #6d6a6a8f;
}
.input{
position: absolute;
left:50%;
top:50%;
margin: -65px -446px;
font-size: 25px;
}
.text{
float: left;
width: 584px;
height: 74px;
border: none;
border-radius:109px;
font-size: 35px;
background-color: rgba(17, 22, 45, 0.04);
}
.btn{
float:left;
margin-left: 30px;
height: 74px;
width: 74px;
background-color: rgba(135, 17, 208, 0.88);
line-height: 74px;
font-size: 35px;
color: #eeeeee;
cursor: pointer;
border-radius:22px;
box-shadow:6px 7px 12px -1px #968f96db;
}
.say{
float: right;
margin-left: 30px;
width: 160px;
height: 91px;
font-size: 38px;
font-weight: bold;
line-height: 91px;
color: #9f2dee;
cursor: pointer;
border-radius:62px;
}
.s_show div{
position: absolute;
font-size: 40px;
font-weight: bold;
color: rgba(3, 5, 2, 0.5);
}
.btn:hover{
float: left;
margin-left: 32px;
width: 65px;
background-color: rgba(31, 208, 185, 0.88);
line-height: 65px;
font-size: 35px;
color: #eeeeee;
cursor: pointer;
border-radius:15px;
}
html界面的實作
<div class="screen">
<div class="top">
Live Show
</div>
<div class="send">
<div class="input">
<input type="text" class="text" placeholder=" Say Something ...">
<div class="btn" id="btn">
</div>
<div class="say">SEND</div>
</div>
</div>
<div class="s_show">
<div>讓開!擋到我用無限屏了</div>
<div>主播求微信</div>
<div>來了老弟</div>
<div>7777777777777777777777777</div>
<div>求求你,不要秀了</div>
<div>這也太真實了吧</div>
</div>
</div>
js的實作
(function () {
//擷取所有需要的節點
let sShowList = document.querySelectorAll('.s_show div'),
oSend = document.querySelector('.send'),
oShow = document.querySelector('.s_show'),
oText = document.querySelector('.text'),
otop = document.querySelector('.top'),
oBtn = document.querySelector('.btn'),
oTime = 0,//初始化點選時間,用來限制點選頻率
waitTime = 3;
oBtn.onclick = function () {
if (new Date() - oTime > 3000 && oText.value) {//點選間隔大于3秒
let Div = document.createElement('div');
Div.innerHTML = oText.value;
oShow.appendChild(Div);//添加彈幕節點
init(Div);//初始化彈幕效果
oTime = new Date();
}
};
for (i = 0; i < sShowList.length; i++) {//周遊所有已有彈幕節點,初始化
init(sShowList[i])
}
function init(obj) {
var screenHeight = document.documentElement.clientHeight,
screenWidth = document.documentElement.clientWidth,//螢幕寬高
sendHeight = oSend.clientHeight,//輸入界面高度
topHeight = otop.clientHeight,//标題欄高度
height = screenHeight - sendHeight - obj.clientHeight - topHeight,//彈幕顯示區域高度
width = screenWidth - obj.clientWidth;
obj.style.top = Math.random() * height + topHeight + 'px';//+topHeight 是為了讓彈幕不被标題欄遮住
obj.style.left = width + 'px';
move(obj, width);
}
//動畫效果
function move(obj, width) {
if (width > -obj.clientWidth) {
width -= 2;
obj.style.left = width + 'px';
requestAnimationFrame(function () {
move(obj, width);
});//生成動畫,2px移動
} else {
oShow.removeChild(obj);//如果彈幕顯示寬度小于0—obj.width ,移除該節點。
}
}
})();
為了防止頻繁發送,可以給發送時間添加定時器。通過與上次點選的時間差, 判斷是否進行彈幕的擷取。
具體注釋都已經在上面代碼中進行标注講解