純js 實現彈幕效果
阿新 • • 發佈:2019-01-26
彈幕時近幾年新興的一種技術,接下來我要展示的就是怎麼實現類似彈幕的效果。
先貼下效果圖:
說是效果,要拿出去用肯定是不行的。
先說一下是怎麼樣的實現方法。彈幕肯定是出現在螢幕上,所以我們暫時把出現彈幕的視窗稱為背景。
彈幕肯定儘量不能重疊在一起,所以我把整個彈幕出現的背景劃分為幾塊,如下圖:
1 |
2 |
3 |
4 |
5 |
什麼意思呢?就是這裡有5條彈道,彈幕就是出現在這5條彈道之間的一條。具體劃多少條彈道,每條彈道的寬度要看你的背景和你自己的設計了。
好了,彈道有了,怎麼建立彈幕呢?這裡我們用到了appendChild方法,每個彈幕的內容都是隨機的。然後我固定了彈幕的數量,並且加了定時器,
當彈幕到達左邊時,彈幕內容再次隨機,輸入框傳送的彈幕出現一次後,將內容加入到預備詞庫中,並將此彈幕刪除。防止彈幕過多報錯。
同時每個彈幕出現的時機肯定不能相同,所以我在每個彈幕最開始出現時加了延遲。
大概的設計就是這樣了,這裡還是總結一下存在的問題:
1.彈幕有時會出現同時出現在同一個彈道上,甚至重疊,暫時還沒找到原因。
2.當輸入框連續多次傳送彈幕時,可能會因為彈道不夠出現意外的情況。
3.與真正的彈幕相比,只是簡易版的,功能單一。
程式碼貼上:
<!--作者:natural_live 時間:2017-7-30 --> <!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="Generator" content="EditPlus®"> <meta name="Author" content="natural_live"> <meta name="Keywords" content="barrage"> <meta name="Description" content=""> <title>彈幕</title> <style> *{margin:0;padding:0;} #barrage{ margin:auto; margin-top:50px; position:relative; width:800px; height:400px; background:#fff; border:2px solid #ffcc00; } #barrage div{ width:100%; height:20px; line-height:20px; position:absolute; } #btn{ margin:auto; margin-top:30px; height:50px; width:300px; } #text{ font-size:20px; height:30px; border-radius:4px; border:1px solid #c8cccf; color:#6a6f77; } #submit{ padding:7px; font-size:14px; height:30px; border-radius:4px; border:1px solid #c8cccf; } </style> </head> <body> <div id="barrage"></div> <div id="btn"> <input type="text" id="text"></input> <input type="button" id="submit" value="傳送"></input> </div> <script> var timer=null; var current=[];//儲存當前輸入框的內容 var newarr=[];//儲存每個彈幕距左邊框的距離 var flag=0;//標誌量 var num=new Array();//陣列,用來儲存劃分每個塊的序號 //var t=12; var words = ["富強","民主","文明","和諧","自由","平等","公正","法治","愛國","敬業","誠信","友善"]; function $(id){ return document.getElementById(id); } for(var i=0;i<$("barrage").offsetHeight/20 - 1;i++){ num.splice(i,0,i);//將整個顯示框劃分成多個塊,並對每個塊進行標號 //console.log(num) } //console.log(num) //console.log(num.length) window.onload = function(){//載入頁面發生的事件 clearInterval(timer);//清除定時器 for(var i = 0;i<10;i++){ setTimeout(function(){ var word=words[random(0,words.length-1)];//隨機產生一個彈幕的內容 create(word);//建立一個彈幕 },100*random(10,100))//給彈幕隨機加一個延遲 } timer=setInterval(move,20);//開啟定時器 } function create(w){//建立一個彈幕 var node=document.createElement("div");//建立一個div元素,用來儲存彈幕的資訊 //console.log(words.length) node.innerHTML=w; //console.log($("barrage").offsetHeight) var t= random(0,num.length-1); //console.log(num) node.style.top=num[t]*20+"px";//從劃分的塊中隨機選中一塊。 Delete(num[t]);//刪除已被選中的塊 //console.log(t) //console.log(node.style.top); node.style.left="800px"; node.style.color="#"+randomColor();//隨機顏色 $("barrage").appendChild(node);//插入子節點 flag++;//建立了一個新彈幕時,更新為0 //console.log(node.offsetLeft) } function move(){ var arr=$("barrage").getElementsByTagName("div");//獲取所有的彈幕 for(var i=0;i<arr.length;i++){ newarr.push(arr[i].offsetLeft);//將每個彈幕距左邊邊框的距離分別儲存在newarr陣列中 arr[i].style.left=newarr[i]+"px";//更新距離 newarr[i] = newarr[i] - 2;//每次減少2px if(newarr[i]<0){ //console.log(arr[i].innerHTML) if(currentTest(arr[i].innerHTML) && flag != 0){//當是從輸入框傳送的彈幕時而且是第一次時,將內容新增到預備的詞庫中,並刪除這個div元素。這麼做是為了將彈幕數量維持在一定數量,防止在輸入框傳送大量彈幕,導致出現錯誤。 //console.log(current) words.push(arr[i].innerHTML); $("barrage").removeChild(arr[i]); newarr.splice(i,1);//在newarr中刪除這個div flag--; }else{//當彈幕到達最左邊時,彈幕內容再次隨機,同時,將這個塊加入到預選塊中,並在預選塊中隨機再選一個,顏色也再次隨機,這樣就保持塊的數量不變。 newarr[i]=800; //console.log(parseInt(arr[i].style.top)) //console.log(arr[i].style.top/20) arr[i].innerHTML=words[random(0,words.length-1)]; num.splice(num.length,0,parseInt(arr[i].style.top)/20); var t= random(0,num.length); arr[i].style.top=num[t]*20+"px"; Delete(num[t]); //console.log(num) //console.log(node.style.top); arr[i].style.left="800px"; arr[i].style.color="#"+randomColor(); } } } } $("submit").onclick=function(){//輸入款傳送彈幕 create($("text").value); current[current.length]=$("text").value; //console.log(current) $("text").value=""; } //console.log(num) function Delete(m){//從預選塊中刪除已被選擇的塊 for(var i = 0;i < num.length;i++){ if(num[i] == m){ //console.log(m) num.splice(i,1); } } } function currentTest(m){ var fl=false; for(var i = 0;i < current.length;i++){ if(current[i] == m){ //console.log(m) current.splice(i,1); fl=true; } } return fl; } function randomColor(){//隨機顏色 var color=Math.ceil(Math.random()*16777215).toString(16); while(color.length < 6){ color = "0" + color; } return color; } function random(m,n){//隨機在m、n之間的整數 return Math.round(Math.random()*(n - m)) + m; } </script> </body> </html>