通过点击发送按钮或者敲回车实现发送弹幕
HTML文档
bullet.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.wrap{
width: 536px;
height: 540px;
position: relative;
overflow: hidden;
}
input{
width: 460px;
height: 30px;
line-height: 30px;
font-size: 18px;
border: 1px solid #000000;
vertical-align: middle;
}
button{
width: 50px;
height: 30px;
border: 1px solid #cccccc;
border-radius: 10px;
font-size: 16px;
color: rgb(168, 155, 164);
float: right;
}
</style>
<body>
<div class="wrap">
<!-- 插入视频 并设置控制面板controls -->
<video src="./test3.mp4" controls></video>
<div class="input-wrap">
<input type="text">
<button>发送</button>
</div>
</div>
<script type="module">
import Bullet from "./Bullet.js";
var input=document.querySelector("input");
var button = document.querySelector("button");
// 点击发送 或者 敲回车 实现发送弹幕
// 对 发送按钮 做侦听事件
button.addEventListener("click",clickHandler);
// 对 敲回车 做侦听事件
document.addEventListener("keyup",keyHandler);
function clickHandler(e){
if(input.value.trim().length===0) return;
done();
}
function keyHandler(e){
// 判断是否是回车键
if(e.keyCode!==13) return;
if(input.value.trim().length===0) return;
done();
}
function done(){
// 创建弹幕
var bullet=new Bullet(input.value);
// 将弹幕div放入到视频容器中
bullet.appendTo(".wrap");
// 发送弹幕后,将每次输入框的内容清空
input.value="";
}
</script>
</body>
</html>
JS文档
Bullet.js
import TimeManager from "./TimeManager.js";
export default class Bullet{
rect;
x;
width;
// 控制弹幕移动速度
speed=2;
constructor(txt){
// 创建弹幕
this.elem = this.createElem(txt);
}
createElem(txt){
if(this.elem) return this.elem;
var div = document.createElement("div");
Object.assign(div.style,{
position: "absolute",
whiteSpace: "nowrap",
// 设置弹幕文字的颜色
color : "pink",
})
// 将输入框的内容传入弹幕中
div.textContent = txt;
return div;
}
// 将弹幕插入到视频容器中
appendTo(parent){
if(typeof parent==="string") parent=document.querySelector(parent);
parent.appendChild(this.elem);
// 设置弹幕初始位置
this.rect = parent.getBoundingClientRect();
Object.assign(this.elem.style,{
top:Math.random()*this.rect.height/4+"px",
left:this.rect.width+"px",
})
// 获取当前父容器视口宽度
this.x = this.rect.width;
// 获取每条弹幕自身宽度
this.width = this.elem.offsetWidth;
// 利用TimeManager 将弹幕放入执行动画的list中 弹幕执行动画
TimeManager.instance.add(this);
}
// 弹幕的动画设置
update(){
// 弹幕内容为空时,不执行动画
if(!this.width) return;
// 通过改变弹幕距离父容器左边的位置来让弹幕实现从右向左移动的效果
this.x-=this.speed;
this.elem.style.left = this.x+"px";
// 当弹幕完全移出视频容器时,将其从list列表中移除,就停止动画
// 并且将其弹幕div删除
if(this.x<-this.width){
TimeManager.instance.remove(this);
this.elem.remove();
this.elem=null;
}
}
}
TimeManager.js
这个文件实际上是创建单例并将其放入list中,list是管理动画的列表,通过将弹幕放入到list中来控制是否播放动画。
export default class TimeManager{
// 创建单例
static _instance;
// 将执行动画的项放入list中
list=new Set();
// 动画
ids;
// 创建构造函数
constructor(){
}
// 创建单例
static get instance(){
if(!TimeManager._instance){
Object.defineProperty(TimeManager,"_instance",{
value:new TimeManager()
})
}
// 函数必须要有返回值
return TimeManager._instance;
}
// 添加
// 将项添加到list中,并根据条件执行动画
add(elem){
this.list.add(elem);
if(this.list.size>0 && !this.ids)
this.ids = setInterval(()=>this.update(),16);
}
// 删除
// 将项从list中删除,清除动画
remove(elem){
this.list.delete(elem);
if(this.list.size===0 && this.ids){
clearInterval(this.ids);
this.ids = undefined;
}
}
// 更新
// 对list中的每一项执行动画
update(elem){
this.list.forEach(item=>{
// 如果该项有update方法时 就执行update方法,就是项对应的动画设置
if(item.update) item.update();
})
}
}
本文介绍了一种基于HTML和JavaScript实现的弹幕发送及动画效果的方法。通过点击按钮或按回车键发送弹幕,利用自定义的Bullet类创建弹幕元素,并通过TimeManager类管理弹幕的动画播放。
1637

被折叠的 条评论
为什么被折叠?



