JS realizes video barrage effect

JS realizes video barrage effect

Use ES6 modular development and observer mode to achieve this. There are many forms of the observer pattern. Here we use the "register-notify-underegister" form. The TimeManager class can return a singleton. Each bullet comment is registered as an observer in the set table of the singleton of the TimeManager class. When there is data in the set of the singleton, the state of the observer is changed, the animation is executed, and all observers are notified to update the state. When the bullet screen moves beyond the video width, it will be deregistered from TimeManager. When all observed comments in the set table of the TimeManager singleton are unregistered, setInterval stops executing.

1. Bullet.js:

Observer: implements the bullet screen style and updates its own status with the update() method.

2. TimeManager.js

Observables and Subjects: You can add and delete observer objects, notify all observers when the state changes, and update the state.

3. Player.js

Player component: Simple player style, control buttons, etc. are all default styles. . .

4. Achievement effect:

5. Specific implementation:

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){
        // The outermost container of the player 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",
        })
        // Video playback part of the player: should include the top author and feedback bar, video status button, and video display part. . . .
        let videoWrap = document.createElement("div");
        Object.assign(videoWrap.style,{
            width:"100%",
            height:"447px",
            backgroundColor:"#000",
            position:"relative",
            top:0,
            display:"flex",
            flexDirection:"column",
        })
        // Create the upper layer of the player: including title, author, feedback and report, etc. . . .
        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",
        })
        // Video playback status switch // let videoState = document.createElement("div");
        // Video playback part 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,{
            // Video centering: The progress bar is lengthened, but the video is not lengthened and is directly centered:
            height:"100%",
            width:"100%",
        })
        videoContent.appendChild(video);
 
        // Video playback and bullet screen scrolling control bar: clarity/speed/loop/mirror/widescreen/full screen webpage/progress bar, etc.
        let videoControlWrap = document.createElement("div");
        Object.assign(videoControlWrap.style,{
            width:"100%",
            height:"44px",
            opacity:"0",
            position:"relative",
            bottom:"0",
        })
 
        // Send bullet screen at the bottom and set the style of sending bullet screen: such as bullet screen color/font size/scroll/hover/speed/font/shield, etc. . .
        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", //Frame style:
            backgroundColor:"#f4f4f4",
        })
        bottomArea.appendChild(this.input);
 
        videoWrap.appendChild(videoTop);
        videoWrap.appendChild(videoContent);
        videoWrap.appendChild(videoControlWrap);
 
        player.appendChild(videoWrap);
        player.appendChild(bottomArea);
        return player;
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
    </style>
</head>
<body>
    <script type="module">
        import Player from './js/Player.js';
        import TimeManager from './js/TimeManager.js';
        import Bullet from './js/Bullet.js';
 
        //Player usage let player = new Player("./test3.mp4");
        player.appendTo("body");
 
    </script>
</body>
</html>

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

You may also be interested in:
  • JavaScript css3 to implement simple video barrage function
  • JavaScript to achieve video barrage effect (two versions)
  • Example of video bullet screen effect implemented by JS

<<:  A brief discussion on the implementation of fuzzy query using wildcards in MySQL

>>:  Detailed explanation of Linux commands sort, uniq, tr tools

Blog    

Recommend

WeChat applet uses canvas to draw clocks

This article shares the specific code of using ca...

Detailed steps to install RabbitMQ in docker

Table of contents 1. Find the mirror 2. Download ...

Docker Compose network settings explained

Basic Concepts By default, Compose creates a netw...

Let's talk about the storage engine in MySQL

Basics In a relational database, each data table ...

Theory: The two years of user experience

<br />It has been no more than two years sin...

Solution to the error problem of Vscode remotely connecting to Ubuntu

1. Background of the incident: Because of work ne...

Explanation of Dockerfile instructions and basic structure

Using Dockerfile allows users to create custom im...

How to restore docker container data

The project test environment database data is los...

React mouse multi-selection function configuration method

Generally, lists have selection functions, and si...

DIV background semi-transparent text non-translucent style

DIV background is semi-transparent, but the words ...

Detailed steps to install MySQL on CentOS 7

In CentOS7, when we install MySQL, MariaDB will b...

Two ways to make IE6 display PNG-24 format images normally

Method 1: Please add the following code after <...

vue-cli4.5.x quickly builds a project

1. Install vue-cli npm i @vue/cli -g 2. Create a ...

HTML uses the title attribute to display text when the mouse hovers

Copy code The code is as follows: <a href=# ti...

js implements axios limit request queue

Table of contents The background is: What will ha...