美文网首页
弹幕插件编写

弹幕插件编写

作者: LuoDada | 来源:发表于2019-10-16 17:22 被阅读0次
    • 注意:该插件依赖于jQuery

    HTML和CSS代码

    <!DOCTYPE html>
    <html lang="zh">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>简单实用文字弹幕</title>
        <style type="text/css">
            html {
              color: #fff;
              -webkit-text-size-adjust: 100%;
              -ms-text-size-adjust: 100%;
              background: #cf6a6d;
              background: linear-gradient(to right, #f6ad32, #cf6a6d);
            }
            body {
                margin: 0;
                min-width: 960px;
            }
            html, body {
                height: 100%;
                overflow: hidden;
            }
            input, button {
                border: none;
                outline: none;
            }
            .clearfix::after {
                content: '';
                height: 0;
                display: table;
                visibility: hidden;
                clear: both;
            }
            .container {
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
            }
            .input-box {
                position: absolute;
                left: 0;
                right: 0;
                bottom: 0;
                z-index: 1;
                height: 40px;
                padding: 30px 0;
                text-align: center;
                background: rgba(0,0,0,.6);
            }
            .input-box input {
                width: 320px;
                height: 40px;
                padding: 0 10px;
                font-size: 16px;
                border-radius: 10px;
                color: #333;
                transition: box-shadow .5s;
            }
            .input-box .btn {
                width: 100px;
                height: 40px;
                line-height: 40px;
                margin-left: 10px;
                border-radius: 10px;
                font-weight: bold;
                color: #fff;
                font-size: 16px;
                background: #cf6a6d;
                background: linear-gradient(to right, #f6ad32, #cf6a6d);
                cursor: pointer;
                transition: box-shadow .5s;
            }
            .list {
                position: absolute;
                left: 100%;
                white-space: nowrap;
                line-height: 32px;
                font-size: 18px;
                color: #fff;
                text-shadow: 0 0 3px #000;
                transition: transform 25s linear;
            }
            .list.animate {
                transform: translateX(-3420px);
            }
            .container .list img {
              width: 24px;
              height: 24px;
              margin-right: 5px;
              border-radius: 50%;
              vertical-align: text-top;
            }
        </style>
    </head>
    <body>
        <div class="container" id="container"></div>
        
        <div class="input-box">
            <input type="text" maxlength="20" placeholder="说点什么吧~"/>
            <button class="btn" id="btn">发送</button>
        </div>
        
        <script src="js/jquery-1.10.2.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/barrageWall.js" type="text/javascript" charset="utf-8"></script>
        
        <script type="text/javascript">
            // 实例化弹幕墙
            var send = new BarrageWall({
                container: '#container',
                barrageLen: 10
            });
            // 发送弹幕
            send.upWall('图片路径.png', '小菜基', '发表想法');
            
            // 发送弹幕
            $('#btn').click(function () {
                var $oIpt = $(this).prev(), // 获取input元素
                    val = $oIpt.val().trim(); // 获取input值
                send.upWall('images/aq.png', '小菜基', val);
                $oIpt.val(''); // 清空输入内容
            })
            
            // 通过定时器模拟用户输入
            var i = 0,
                t = null;
            t = setInterval(function () {
                if (i > 10) {
                    clearInterval(t);
                }
                send.upWall('图片路径.png', '小菜基'+ i +'号', '发表个'+ i +'感想.');
                i++;
            }, 300);
        </script>
    </body>
    </html>
    
    

    barrageWall.js 代码

    ;(function () {
        var BarrageWall = function (opt) {
            this.init(opt);
        }
        
        BarrageWall.prototype = {
            init: function (opt) {
                if (!opt.container) {
                    throw new Error('必须指定 container 属性,container为弹幕容器的选择器');
                }
                if (opt.barrageLen < 1) {
                    throw new Error('必须指定barrageLen属性,barrageLen为弹幕的轨道数');
                }
                this.container = opt.container; // 弹幕容器
                this.barrageLen = opt.barrageLen; // 轨道数
                this.lastElem = 0; // 弹幕出现的位置
                this.barrage = []; //弹幕墙
                this.barrageOffset = []; // 弹幕墙上最后一条弹幕的偏移量
                
                for (var i = 0; i < opt.barrageLen; i++) {
                    this.barrage.push([])
                }
            },
            upWall: function (img, user, txt) {
                this.positionWall(); // 从上至下找出每条弹幕轨道上最后一条弹幕移动位置
                
                var elem = $('<div></div>') // 创建元素
                        .addClass('list')               // 添加样式
                        .css('top', this.lastElem * 38 + 'px'); // 定位
                elem.html('<img src='+ img +' alt="" />'+ user + ':' + txt) // 添加内容
                        .appendTo(this.container); // 追加在父元素后面
                        
                this.barrage[this.lastElem].push(elem); // elem追加在数组中
                
                // 延迟200ms添加动画,防止元素动画不执行
                setTimeout(function () {
                    elem.addClass('animate')
                }, 200)
                
                // 25s后动画执行完毕,从数组和页面中移除
                setTimeout(function () {
                    var item,
                        flag = false;
                    for (var i = 0; i < this.barrageLen; i++) {
                        item = this.barrage[i];
                        if (flag) {
                            break; // true 跳出循环
                        }
                        for (var j = 0; j < item.length; j++) {
                            if (item[j] === elem) {
                                this.barrage[i].splice(j, 1);
                                flag = true;
                                break; // 满足条件跳出当前循环
                            }
                        }
                    }
                    elem.remove(); // 移除自己
                }, 25000)
            },
            positionWall: function () {
                // 从上至下找出每条弹幕轨道上最后一条弹幕移动位置
                var len = this.barrageLen;
                for (var i = 0; i <= len; i++) {
                    if (i === len) { // 弹幕队列超过弹道数进入
                        this.minOffset()// 弹幕墙上所有的位置都有弹幕且都未出现完毕时,找出他们当中完全最先的那个
                    } else {
                        // 找到弹幕出现的位置,找到退出循环
                        if (this.afterOffset(i)) {
                            break;
                        }
                    }
                }
            },
            afterOffset: function (i) { // 找到弹幕出现的位置
                if (this.barrage[i].length === 0) {
                    this.lastElem = i;
                    return true;
                } else { // 轨道有数据
                    var elem = this.barrage[i][this.barrage[i].length - 1], // 获取当前弹幕轨道上最后一条弹幕
                            aboveWidth = elem.width(), // 获取它的宽度
                            matrix = elem.css('transform'); // 获取它的矩阵值
                    if (matrix !== 'none') {
                        var aboveTransform = parseInt(matrix.split(',')[4]); // 取出最后一条弹幕的矩阵值中X轴的偏移量,即translateX
                        // 50为间隔,为true则表示当前弹幕轨道上最后一条弹幕已经全部出现,则当前弹幕放在该轨道上
                        if (-aboveTransform - aboveWidth > 50) {
                            this.lastElem = i;
                            return true;
                        }
                    }
                }
                return false;
            },
            minOffset: function () { // 弹幕墙上所有的位置都有弹幕且都未出现完毕时,找出他们当中完全最先的那个
                var minOffset = 0,
                        item;
                for (var i = 0; i < this.barrageLen; i++) { // 遍历比较弹幕墙,找出队列最远的那个元素
                    item = this.barrage[i];
                    
                    var elem = item[item.length - 1], // 获取当前弹幕轨道上最后一条弹幕
                            aboveWidth = elem.width(), // 获取它的宽度
                            matrix = elem.css('transform'); // 获取它的矩阵值
                    this.barrageOffset[i] = matrix === 'none' ? -aboveWidth : -parseInt(matrix.split(',')[4]) - aboveWidth;
                    minOffset = this.barrageOffset[i] > this.barrageOffset[minOffset] ? i : minOffset;
                }
                this.lastElem = minOffset;
            }
        }
        
        window.BarrageWall = BarrageWall;
    })();
    

    如有不足或更好的方式实现,欢迎大家留言探讨

    相关文章

      网友评论

          本文标题:弹幕插件编写

          本文链接:https://www.haomeiwen.com/subject/cngqjqtx.html