千家信息网

JS如何实现视频弹幕效果

发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,这篇文章主要为大家展示了"JS如何实现视频弹幕效果",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"JS如何实现视频弹幕效果"这篇文章吧。使用ES6的模块化开
千家信息网最后更新 2025年01月17日JS如何实现视频弹幕效果

这篇文章主要为大家展示了"JS如何实现视频弹幕效果",内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下"JS如何实现视频弹幕效果"这篇文章吧。

使用ES6的模块化开发及观察者模式来实现。观察者模式有很多种形式,这里是使用"注册-通知-撤销注册"的形式。TimeManager类可以返回一个单例,每一条弹幕作为一个观察者,注册到TimeManager类的单例的set表中,当单例的set中有数据时,被观察者状态被改变,执行动画,并通知所有观察者进行update状态更新。弹幕移动超过视频宽度时,从TimeManager中注销。当TimeManager单例的set表中所有被观察弹幕都注销时,setInterval停止执行。

1、Bullet.js:

观察者:实现弹幕样式,和自身状态更新update()方法.

2、TimeManager.js

被观察者和Subject:可以增加和删除观察者对象,状态改变时通知所有观察者并更新状态。

3、Player.js

播放器组件:简单的播放器样式,控制按钮等都是默认样式。。。

4、实现效果:

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) return        let 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) return        if(elem.update) this.list.add(elem);        if(!this.ids) this.ids = setInterval(()=>{            this.update();        },16);    }    remove(elem){        if(!elem) return        this.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.value = "";    }    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 = 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如何实现视频弹幕效果"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

0