弹幕是一个很常见的功能,下面是本人封装的一个小小的实现方案,存在不足之处可以提出来或自由改进。
直接上代码:复制可运行
<!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, //屏幕宽度 sdocument.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>
效果如图:
点击开启弹幕按钮: