JavaScript 簡單的彈幕功能的實現

在視頻網站看視頻的時候,經常能看到彈幕,某個時間段彈幕數超級多,某個時間段幾乎沒有,我們可以實時新增彈幕並且能實時出現在彈幕羣中。
再次進入該視頻後,會發現之前添加的彈幕還是在之前添加的時間點出現,當然還是可以再次添加彈幕。
那這樣的彈幕效果是怎麼實現的呢?

也是因爲業務方向的原因,竟然從來沒有做過彈幕功能,最近兩天在複習,順帶就試着實現下彈幕功能。時間充裕的話會逐步完善優化彈幕效果

一、最最基礎版

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、存在的問題
  1. 因爲是提前將所有彈幕信息添加到span標籤內,放入對應的彈幕軌道,若是彈幕是很多(上千,上萬),那就會添加對應個數的span標籤,過於冗餘了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章