JS实现视频弹幕效果

使用ES6的模块化开发及观察者模式来实现。观察者模式有很多种形式,这里是使用“注册—通知—撤销注册”的形式。TimeManager类可以返回一个单例,每一条弹幕作为一个观察者,注册到TimeManager类的单例的set表中,当单例的set中有数据时,被观察者状态被改变,执行动画,并通知所有观察者进行update状态更新。弹幕移动超过视频宽度时,从TimeManager中注销。当TimeManager单例的set表中所有被观察弹幕都注销时,setInterval停止执行。
1、Bullet.js:
观察者:实现弹幕样式,和自身状态更新update()方法.
2、TimeManager.js
被观察者和Subject:可以增加和删除观察者对象,状态改变时通知所有观察者并更新状态。
3、Player.js
播放器组件:简单的播放器样式,控制按钮等都是默认样式。。。
4、实现效果:
JS实现视频弹幕效果
文章图片

5、具体实现:

import TimeManager from './TimeManager.js'; export default class Bullet{elem; x; speedX=2; width; constructor(txt){this.elem = this.createElem(txt); }createElem(txt){if(this.elem) returnlet div = document.createElement("div"); Object.assign(div.style,{position:"absolute",whiteSpace: "nowrap",fontSize:"16px",// color:"#000",color:"#e00",})div.textContent = txt; return div}appendTo(parent){if(typeof parent === "string") parent = document.querySelector(parent); parent.appendChild(this.elem); let rect = parent.getBoundingClientRect(); this.elem.style.top = Math.random()*rect.height/4 +"px"; this.width = this.elem.offsetWidth; this.x = rect.width; this.elem.style.left = this.x + "px"; TimeManager.instance.add(this); }update(){if(!this.elem) return; this.x -= this.speedX; this.elem.style.left = this.x +"px"; if(this.x<-this.width){this.elem.remove(); TimeManager.instance.remove(this); this.elem = null; }}}

export default class TimeManager{static _instance; list = new Set(); ids; constructor(){ }static get instance(){TimeManager._instance = TimeManager._instance? TimeManager._instance : new TimeManager(); return TimeManager._instance; }add(elem){if(!elem) returnif(elem.update) this.list.add(elem); if(!this.ids) this.ids = setInterval(()=>{this.update(); },16); }remove(elem){if(!elem) returnthis.list.delete(elem); if(this.list.size===0 && this.ids){clearInterval(this.ids); this.ids=0; }}update(){this.list.forEach(item=>{item.update(); })}}

import Bullet from './Bullet.js'; export default class Player extends EventTarget{ static WIDTH=638; static HEIGHT=493; elem; input; constructor(path){super(); this.elem = this.createElem(path); document.addEventListener("keyup",e=>this.keyHandler(e)); }keyHandler(e){if(e.keyCode !== 13) return; if(this.input.value.trim().length===0) return; let b = new Bullet(this.input.value); b.appendTo(this.elem); this.input.valuehttps://www.it610.com/article/= ""; }appendTo(parent){if(typeof parent==="string") parent = document.querySelector(parent); parent.appendChild(this.elem); }createElem(path){// 播放器最外层容器let player = document.createElement("div"); player.className = "player"; Object.assign(player.style,{width:Player.WIDTH+"px",height:Player.HEIGHT+"px",userSelect:"none",overflow: "hidden",position:"relative",verticalAlign:"baseline",})// 播放器视频播放部分:应包括顶部作者和反馈栏、视频状态按钮、视频展示部分。。。。let videoWrap = document.createElement("div"); Object.assign(videoWrap.style,{width:"100%",height:"447px",backgroundColor:"#000",position:"relative",top:0,display:"flex",flexDirection:"column",})// 创建播放器上层:包括标题,作者,反馈意见和举报等。。。。let videoTop = document.createElement("div"); Object.assign(videoTop.style,{width:"100%",height:"42px",position:"relative",top:"0px",left:"0px",opacity:"0",color:"#fff",pointerEvents:"none",// transition: "all .2s ease-in-out",transition: "all .2s",})// 视频播放状态开关// let videoState = document.createElement("div"); // 视频播放部分let videoContent = document.createElement("div"); Object.assign(videoContent.style,{width:"100%",// height:"100%",height:"361px",position:"relative",userSelect:"none",})let video = document.createElement("video"); video.src = https://www.it610.com/article/path; video.controls ="controls"; video.preload = "auto"; Object.assign(video.style,{// 视频居中:进度条被拉长,但是视频不会被拉长,直接居中:height:"100%",width:"100%",})videoContent.appendChild(video); // 视频播放和弹幕滚动控制栏:清晰度/倍速/循环/镜像/宽屏/网页全屏/进度条等、、、、、let videoControlWrap = document.createElement("div"); Object.assign(videoControlWrap.style,{width:"100%",height:"44px",opacity:"0",position:"relative",bottom:"0",}) // 底部发送弹幕及设置发送弹幕样式:例如弹幕颜色/字号/滚动/悬停/速度/字体/屏蔽等。。。let bottomArea = document.createElement("div"); Object.assign(bottomArea.style,{width:"100%",height:"46px",})this.input = document.createElement("input"); Object.assign(this.input.style,{width:"130px",height:"30px",color:"#212121",// border:"0px",lineHeight:"30px",boxSizing: "border-box",minWidth: "115px",padding:"0 5px",fontSize:"12px",border:"1px solid #e7e7e7",//外框样式:backgroundColor:"#f4f4f4",})bottomArea.appendChild(this.input); videoWrap.appendChild(videoTop); videoWrap.appendChild(videoContent); videoWrap.appendChild(videoControlWrap); player.appendChild(videoWrap); player.appendChild(bottomArea); return player; }}

Document - 锐客网

【JS实现视频弹幕效果】以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

    推荐阅读