JS——弹幕发送(这个不是我完全原创的文章底部有原作者的地址)

barrage.js

     /**
     * 设置 弹幕DOM池 每一个通道最多六条弹幕
     **/

    const MAX_DM_COUNT = 6;
    const CHANNEL_COUNT = 10;
    var domPool = [];
    var danmuPool = [];
    var hasPosition = [];
    var barrageflag = true


    function barrageinit(id) {
        let wrapper = document.querySelectorAll(id)[0]
        console.log(wrapper)
        // 先new一些span 重复利用这些DOM
        for (let j = 0; j < CHANNEL_COUNT; j++) {
            let doms = [];
            for (let i = 0; i < MAX_DM_COUNT; i++) {
                // 要全部放进wrapper
                let dom = document.createElement('span');
                wrapper.appendChild(dom);
                // 初始化dom的位置 通过设置className
                dom.className = 'barrageright';
                // DOM的通道是固定的 所以设置好top就不需要再改变了
                dom.style.top = j * 20 + 'px';
                // 放入改通道的DOM池
                doms.push(dom);
                // 每次到transition结束的时候 就是弹幕划出屏幕了 将DOM位置重置 再放回DOM池
                dom.addEventListener('transitionend', () => {
                    dom.className = 'barrageright';
                    // dom.style.transition = null;
                    // dom.style.left = null;
                    dom.style.transform = null;

                    domPool[j].push(dom);
                });
            }
            domPool.push(doms);
        }
        // hasPosition 标记每个通道目前是否有位置
        for (let i = 0; i < CHANNEL_COUNT; i++) {
            hasPosition[i] = true;
        }
    }
    /**
     * 获取一个可以发射弹幕的通道 没有则返回-1
     */
    function getChannel() {
        for (let i = 0; i < CHANNEL_COUNT; i++) {
            if (hasPosition[i] && domPool[i].length) return i;
        }
        return -1;
    }

    /**
     * 根据DOM和弹幕信息 发射弹幕
     */
    function shootDanmu(dom, text, channel) {
        console.log('biu~ [' + text + ']');
        dom.innerText = text;
        // 如果为每个弹幕设置 transition 可以保证每个弹幕的速度相同 这里没有保证速度相同
        // dom.style.transition = `transform ${7 + dom.clientWidth / 100}s linear`;

        // dom.style.left = '-' + dom.clientWidth + 'px';
        // 设置弹幕的位置信息 性能优化 left -> transform
        dom.style.transform = `translateX(${-dom.clientWidth}px)`;
        dom.className = 'barrageleft';

        hasPosition[channel] = false;
        // 弹幕全部显示之后 才能开始下一条弹幕
        // 大概 dom.clientWidth * 10 的时间 该条弹幕就从右边全部划出到可见区域 再加1秒保证弹幕之间距离
        setTimeout(() => {
            hasPosition[channel] = true;
        }, dom.clientWidth * 10 + 1000);
    }

需要发射的页面调用

    <link rel="stylesheet" href="../css/barrage.css">
        <script src="../js/barrage.js"></script>
<script>
    window.onload = function () {

        barrageinit(".player");

        // 为input和button添加事件监听
        let btn = document.getElementsByTagName('button')[0];
        let input = document.getElementsByTagName('input')[0];
        // 每隔1ms从弹幕池里获取弹幕(如果有的话)并发射
        setInterval(() => {
            let channel;
            if (danmuPool.length && (channel = getChannel()) != -1) {
                let dom = domPool[channel].shift();
                let danmu = danmuPool.shift();
                shootDanmu(dom, danmu, channel);
            }
        }, 1);

    }
</script>

barrage.css部分

.barrageright {
    position: absolute;
    visibility: hidden;
    white-space: nowrap;
    /*left: 700px;*/
    transform: translateX(4.245rem);
    z-index: 100;
    color: #fff;
    font-size: 0.1rem;
}

.barrageleft {
    z-index: 100;
    position: absolute;
    white-space: nowrap;
    user-select: none;
    transition: transform 7s linear;
    color: #fff;
    font-size: 0.1rem;
    /* 时间相同 越长的弹幕滑动距离越长 所以越快~ */
}

聊天同时调用弹幕文件chat.js

//先声明一个方法
        function getbarrage(msg) {
            let qq = msg
            let barrageflag = parent.barrageflag
            if(barrageflag){
                parent.danmuPool.push(qq)
                console.log(parent.danmuPool, qq)
            }
        }
//在websocket发送时 调用
        function sendmsg() {
            if (!!token) {
                let msgdata = {
                    'status': 3,
                    'data': {//这里我先省略了
                      ...
                    }
                }
                socket.send(JSON.stringify(msgdata));
                $(".chat_send_div").append(`
                	//这里只是设计到聊天的样式
                `)
                gotobottom()//发送消息聊天回到底部 保证看到最新的消息
                getbarrage($(".send_input").val())//发送聊天弹幕
                $(".send_input").val('')//重置为空
            }
        }
https://www.cnblogs.com/wenruo/p/9566612.html

原作者大神文章地址

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值