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

Recommend

DOCTYPE type detailed introduction

<br />We usually declare DOCTYPE in HTML in ...

Detailed explanation of template tag usage (including summary of usage in Vue)

Table of contents 1. Template tag in HTML5 2. Pro...

Create a code example of zabbix monitoring system based on Dockerfile

Use the for loop to import the zabbix image into ...

Methods of adaptive web design (good access experience on mobile phones)

1. Add the viewport tag to the HTML header. At th...

Detailed explanation of Xshell common problems and related configurations

This article introduces common problems of Xshell...

How to modify the location of data files in CentOS6.7 mysql5.6.33

Problem: The partition where MySQL stores data fi...

URL Rewrite Module 2.1 URL Rewrite Module Rule Writing

Table of contents Prerequisites Setting up a test...

How to convert Chinese into UTF-8 in HTML

In HTML, the Chinese phrase “學好好學” can be express...

The basic principles and detailed usage of viewport

1. Overview of viewport Mobile browsers usually r...

Detailed explanation of MySQL database isolation level and MVCC

Table of contents 1. Isolation Level READ UNCOMMI...

Select web page drop-down list and div layer covering problem

Questions about select elements in HTML have been...

Solution to Mysql binlog log file being too large

Table of contents 1. Related binlog configuration...

Example of how to embed H5 in WeChat applet webView

Preface WeChat Mini Programs provide new open cap...

Solution to win10 without Hyper-V

Are you still looking for a way to enable Hyper-v...

Docker container operation instructions summary and detailed explanation

1. Create and run a container docker run -it --rm...