弹幕是一个很常见的功能,下面是本人封装的一个小小的实现方案,存在不足之处可以提出来或自由改进。
直接上代码:
<!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>
效果如图:
点击开启弹幕按钮:
这个需求如题,大体上是将文章的评论数据,在文章的首图上面以弹幕的形式出现。实现弹幕的原理,并不算太复杂,耗费一些时间,怼一怼应该都可以做出来。获取弹幕数据,将弹幕设置为四个通道...
首先安装nodejs运行环境, 从 http://nodejs.cn/download/ 下载对应的版本, 安装 huya-danmu 模块, https://github.com/BacooTang/huya-danmu 有详细的安装方法,参照 huya-danmu 模块中 test.js 编写 huya.js 新文件,录视频的同时运行 huyaDanmu 批处理命令, 就不用在调整时间轴;
经过我多次调试,发现B站的textarea需要触发一个keydown事件之后才能发送。Events 可以使用 Event 构造函数创建如下:请使用 event constructors 来替代.创建一个指定类型的事件。其返回的对象必须先初始化并可以被传递
DPlayer 是一个支持弹幕的 HTML5 视频播放器。支持 Bilibili 视频和 danmaku,支持HLS,FLV,MPEG DASH,WebTorrent以及其他视频格式,支持截屏、热键、切换清晰度以及字幕等。
相信最近有很多B站的用户都注意到了不挡脸的弹幕,打开一则视频右下角的“智能防挡弹幕”功能后,弹幕就不会再覆盖人像,而是呈现从人体身后穿过的效果。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!