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

直接上代码:复制可运行

<!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>

效果如图:

点击开启弹幕按钮:

js实现弹幕的更多相关文章

  1. 原生JS实现弹幕效果

    纯属无聊写的,可能有很多问题,欢迎批评指教. 效果图:图一是预设的一些弹幕,图二是自己发射的弹幕,效果是一样的.   首先是弹幕的位置,是要从最右滑到最左,为了防止随机高度弹幕会覆盖的问题,设置了通道 ...

  2. js实现弹幕效果

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...

  3. JS 发送弹幕

    JS实现弹幕的发送 <div class="box1"> <div class="box2" style="width: 600px ...

  4. JS原生实现视频弹幕Demo(仿)

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  5. 弹幕文化与HTML5

    分享人:herry 弹幕篇:弹幕文化与HTML5 说说弹幕 弹幕文化 1什么是弹幕? 弹(dàn)幕(mù)在国内兴起已经有个把年了,相信很多朋友都差不多知道弹幕这个东西. 弹幕系统最初的起源是一家日 ...

  6. JavaScript简单的弹幕

    弹幕 首先是弹幕的位置,是要从最右滑到最左,为了防止随机高度弹幕会覆盖的问题,设置了通道. 每一个通道是从左到右的一条,高度固定,这样不同通道的弹幕不会相互覆盖. 弹幕滑动就是简单设置CSS属性  t ...

  7. 基于jquery的弹幕实现

    前几天,需要做一个弹幕展示效果,看了网上很多资料,但是很不凑巧,都不能满足自己的需求和功能点,但是总不能放弃吧,那么就自己写一个,今天把成果分享给大家,首先说一下市面上比较流行的弹幕插件吧: 1.有关 ...

  8. 让弹幕给 PPD 生个孩子

    怎样才能跑起来我写的弹幕程序 资源下载 申请野狗后端云账号注册 创建应用: 复制appId到index.html的 var ref = new Wilddog("https://<ap ...

  9. 【Java EE】从零开始写项目【总结】

    从零开发项目概述 最近这一直在复习数据结构和算法,也就是前面发出去的排序算法八大基础排序总结,Java实现单向链表,栈和队列就是这么简单,十道简单算法题等等... 被虐得不要不要的,即使是非常简单有时 ...

随机推荐

  1. 关于vm.min_free_kbytes的合理设置推测

    前言 之前系统出现过几次hung住的情况,没有oom,也没有其它内存相关的信息,而linux设计就是去尽量吃满内存,然后再回收清理的机制 探讨 目前这个参数还没有找到合适的处理这个预留的参数,一般也没 ...

  2. Java 实例化接口或抽象类

    1. 实例化接口: 某一天,我们想通过反射调用一个类的方法,但发现方法参数中有一个接口,我们都知道接口不能被实例化,这该怎么办呢? 举例: public class TestLib { public ...

  3. 汇编语言CPU状态控制指令

    CPU状态控制指令 1.空操作指令NOP /该指令不执行任何操作,只是使IP加1,其机器码占有一个字节的存储单元,常用于程序调试./ 2.总线封锁前缀指令LOCK /该指令与其他指令联合使用,作为指令 ...

  4. Nginx下关于缓存控制字段cache-control的配置说明

    HTTP协议的Cache -Control指定请求和响应遵循的缓存机制.在请求消息或响应消息中设置 Cache-Control并不会影响另一个消息处理过程中的缓存处理过程.请求时的缓存指令包括: no ...

  5. linux qt 5.12.6 编译mysql驱动

    环境:ubuntu 18.4 x64.qt 5.12.6 问题:安装后是没有mysql的驱动的 解决过程: 各种搜索,先后安装了mysql mysql-client,mysql-server,和各种l ...

  6. ASP.NET Core管道详解[3]: Pipeline = IServer + IHttpApplication

    ASP.NET Core的请求处理管道由一个服务器和一组中间件构成,但对于面向传输层的服务器来说,它其实没有中间件的概念.当服务器接收到请求之后,会将该请求分发给一个处理器进行处理,对服务器而言,这个 ...

  7. python自动化测试pytest框架

    pytest和unittest都是python中的测试框架,pytest相比unittest 更加的灵活,具体体现在 以下几点 1.写测试方法时不用继承类 2.前置后置放在一起 2.1如果是全局共享的 ...

  8. Java中对象在内存中的大小、分配等问题

    Java创建一个对象的过程 是否对象指向的类已经加载到内存了 如果没有加载,就要经过load.linking(verification.preparation.resolution).initiali ...

  9. NOIP2012 解题报告

    TG Day1 T3 开车旅行 1. 预处理出从每座城市两人分别会到达的两座城市. 用 set 可以轻松实现. 2. 用倍增优化 DP 令 \(f_{i,j,k}\) 表示从城市 \(j\) 出发,行 ...

  10. 记一次Ddos遭遇

    万年不用的vps最近借朋友用了几天,今天突然跟我说连不上了 上服务器先暴力重启一波 还是不行,netstat一看 端口的连接状态是这个样子: 估计连接被打满了,遂换了个端口 重启之 问题解决