js实现弹幕效果

更新日期: 2019-08-02阅读: 2.8k标签: 弹幕

弹幕是一个很常见的功能,下面是本人封装的一个小小的实现方案,存在不足之处可以提出来或自由改进。

直接上代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
        <meta content="yes" name="apple-mobile-web-app-capable">
        <meta content="black" name="apple-mobile-web-app-status-bar-style">
        <meta content="telephone=no" name="format-detection">
        <meta content="email=no" name="format-detection">
        <meta name="full-screen" content="yes">
        <meta name="browsermode" content="application">
        <meta name="full-screen" content="yes">
        <meta name="browsermode" content="application">
        <meta name="x5-orientation" content="portrait">
        <title>js实现弹幕</title>
        <style>
            html,body{
                position: relative;
                width: 100%;
                max-width: 750px;
                margin: auto;
                height: 100%;
                background: #fff;
                overflow: hidden;
                font-family: SimSun,arial;
            }
            .tmBox{
                width: 100%;
                height: 16rem;
                background: #5e907b;
                position: relative;
            }
            .btn{
                display: block;
                margin: auto;
                margin-top: 20px;
                width: 100px;
                height: 40px;
                outline: none;
            }
            .tmItem{
                position: absolute;
                width: auto;
                height: auto;
                padding:4px;
            }
            
            .tmItem.runTm{
                animation: runTmEfe 4s linear 0s 1 alternate;
                animation-fill-mode: backwards;
            }
            @keyframes runTmEfe{
                from{transform: translateX(18.75rem);}
                to{transform: translateX(-100%);}
            }
        </style>
    </head>
    <body>
        <div class="tmBox">
        </div>
        <button class="btn start">开启弹幕</button>
        <button class="btn stop">停止弹幕</button>
        <button class="btn pause">暂停画面</button>
        <button class="btn resume">恢复弹幕</button>
        <button class="btn send">发射弹幕</button>
        <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.js" ></script>
        <script>
            //根字体设置
            function setHtmlFontSize(){
                var w = document.documentElement.clientWidth;
                if(w > 750){
                    w = 750;
                }
                var fz = w * 20 / 375;
                document.getElementsByTagName(‘html‘)[0].style.fontSize = fz + ‘px‘;
            }
            //实时根据屏宽来适应字体
            setHtmlFontSize();
            window.onresize = function(){
                setHtmlFontSize();
            }
            //获取不重复随机数列
            function getOrder(start, end){
                var len = end - start + 1;
                var myorder = new Array();
                var index = 0;
                while (index < len) {
                  var flag = true;
                  var num = parseInt(Math.floor(Math.random() * len) + start);
                  for (var i = 0; i < myorder.length; i++) {
                    if (myorder[i] == num) {
                      flag = false;
                      break;
                    }
                  }
                  if (flag) {
                    myorder[index] = num;
                    index++;
                  }
                }
                return myorder;
            }
            
            //弹幕的设置
            var tmEntity={
                //弹幕内容
                tmList:[
                    ‘测试弹幕01‘,
                    ‘测试弹幕02‘,
                    ‘测试弹幕03‘,
                    ‘测试弹幕04‘,
                    ‘测试弹幕05‘,
                    ‘测试弹幕06‘,
                    ‘测试弹幕07‘,
                    ‘测试弹幕08‘,
                    ‘测试弹幕09‘,
                    ‘测试弹幕10‘
                ],
                //弹幕列表上限
                tmMaxLines:10,
                //弹幕行数
                tmRows:10,
                //初始弹幕索引
                initIndex:0,
                //弹幕过度时间 s
                tmTranstionTime:0.4,
                //屏幕宽度
                swidth:document.documentElement.clientWidth,
                //弹幕循环
                isRunTm:true,
                //弹幕父容器class
                tmFatherClass:".tmBox",
                //弹幕class
                tmClass:".tmItem",
                //弹幕高度
                tmHeight:$(".tmBox").height() / 10,
                //屏中最低弹幕数
                screenTmNum:7
            }
            console.log(tmEntity);
            var rowsOrder=getOrder(0,tmEntity.tmRows-1);
            var timeOrder=getOrder(0,tmEntity.tmRows-1);
            //添加弹幕
            function addTm(item,i,max){
                var obj="<div class=‘"+tmEntity.tmClass.replace(‘.‘,‘‘)+" runTm‘ style=‘transform: translateX("+tmEntity.swidth+"px);animation-delay:"+(timeOrder[timeOrder.length-1]*tmEntity.tmTranstionTime)+"s;top:"+(rowsOrder[rowsOrder.length-1] * tmEntity.tmHeight)+"px‘>"+item+"</div>";
                $(tmEntity.tmFatherClass).append(obj);
                //addListenerStart($(tmEntity.tmClass).eq(tmEntity.initIndex));
                addListenerEnd($(tmEntity.tmClass).eq(tmEntity.initIndex));
                tmEntity.initIndex++;
                //校验行
                rowsOrder.pop();
                if(rowsOrder.length==0){
                    rowsOrder=getOrder(0,tmEntity.tmRows-1);
                }
                timeOrder.pop();
                if(timeOrder.length==0){
                    timeOrder=getOrder(0,tmEntity.tmRows-1);
                }
            }
            function addListenerEnd(el){
                el.on("animationend webkitAnimationEnd", function(){
                    el.remove();
                    tmEntity.initIndex--;
                    if(tmEntity.isRunTm && $(tmEntity.tmFatherClass+" "+tmEntity.tmClass).length <= tmEntity.screenTmNum){
                        initTm(tmEntity.tmList);
                    }
                });
            }
            function addListenerStart(el){
                el.on("animationstart webkitAnimationStart", function(){

                });
            }
            function initTm(list){
                for(var i=0;i<list.length;i++){
                    addTm(list[i],i,list.length);
                }
            }
            //开始弹幕
            function startTmRun(){
                initTm(tmEntity.tmList);
                tmEntity.isRunTm = true;
            }
            //停止产生弹幕
            function stopTmRun(){
                tmEntity.isRunTm = false;
            }
            //暂停弹幕
            function pauseTmScreen(){
                $(tmEntity.tmClass).css({"WebkitAnimationPlayState":"paused","AnimationPlayState":"paused"});
            }
            //继续弹幕
            function resumeTmScreen(){
                $(tmEntity.tmClass).css({"WebkitAnimationPlayState":"running","AnimationPlayState":"running"});
            }
            //发射单条弹幕
            function sendTm(str){
                var str=str+(Math.floor(Math.random()*(tmEntity.tmMaxLines-1+1)+1));
                tmEntity.tmList.push(str);
                if(tmEntity.tmList.length > tmEntity.tmMaxLines){
                    tmEntity.tmList.splice(0,tmEntity.tmList.length-tmEntity.tmMaxLines);
                    console.log(tmEntity.tmList);
                    console.log(tmEntity.tmList.length);
                } 
            }
            $(".btn.start").click(function(){
                startTmRun();
            })
            $(".btn.pause").click(function(){
                pauseTmScreen();
            })
            $(".btn.resume").click(function(){
                resumeTmScreen();
            })
            $(".btn.stop").click(function(){
                stopTmRun();
            })
            $(".btn.send").click(function(){
                sendTm("最帅的南哥");
            })
        </script>
    </body>
</html>


效果如图:

点击开启弹幕按钮:


链接: https://fly63.com/article/detial/4482

前端将数据转化为弹幕效果的实现方式

这个需求如题,大体上是将文章的评论数据,在文章的首图上面以弹幕的形式出现。实现弹幕的原理,并不算太复杂,耗费一些时间,怼一怼应该都可以做出来。获取弹幕数据,将弹幕设置为四个通道...

虎牙直播弹幕转换字幕格式 基于Node.js 的 huya-danmu

首先安装nodejs运行环境, 从 http://nodejs.cn/download/ 下载对应的版本, 安装 huya-danmu 模块, https://github.com/BacooTang/huya-danmu 有详细的安装方法,参照 huya-danmu 模块中 test.js 编写 huya.js 新文件,录视频的同时运行 huyaDanmu 批处理命令, 就不用在调整时间轴;

B站自动填弹幕(附带createEvent消息机制)

经过我多次调试,发现B站的textarea需要触发一个keydown事件之后才能发送。Events 可以使用 Event 构造函数创建如下:请使用 event constructors 来替代.创建一个指定类型的事件。其返回的对象必须先初始化并可以被传递

DPlayer:H5视频播放器支持弹幕

DPlayer 是一个支持弹幕的 HTML5 视频播放器。支持 Bilibili 视频和 danmaku,支持HLS,FLV,MPEG DASH,WebTorrent以及其他视频格式,支持截屏、热键、切换清晰度以及字幕等。

B站不挡脸弹幕前端是如何实现的?

相信最近有很多B站的用户都注意到了不挡脸的弹幕,打开一则视频右下角的“智能防挡弹幕”功能后,弹幕就不会再覆盖人像,而是呈现从人体身后穿过的效果。

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!