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:
|
<<: A brief discussion on the implementation of fuzzy query using wildcards in MySQL
>>: Detailed explanation of Linux commands sort, uniq, tr tools
<br />We usually declare DOCTYPE in HTML in ...
Table of contents 1. Template tag in HTML5 2. Pro...
Use the for loop to import the zabbix image into ...
1. Add the viewport tag to the HTML header. At th...
This article introduces common problems of Xshell...
Problem: The partition where MySQL stores data fi...
Table of contents Prerequisites Setting up a test...
In HTML, the Chinese phrase “學好好學” can be express...
1. Overview of viewport Mobile browsers usually r...
Table of contents 1. Isolation Level READ UNCOMMI...
Questions about select elements in HTML have been...
Table of contents 1. Related binlog configuration...
Preface WeChat Mini Programs provide new open cap...
Are you still looking for a way to enable Hyper-v...
1. Create and run a container docker run -it --rm...