时间管理器——弹幕发布——单例模式——消息发布-订阅者

Posted 勇敢*牛牛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了时间管理器——弹幕发布——单例模式——消息发布-订阅者相关的知识,希望对你有一定的参考价值。

弹幕制作,单例模式,发布——订阅者模式

时间管理器

包含两种设计模式,
单例模式:单独唯一的实例:任何地方可以调用单例对象以及方法。
设计者模式

弹幕制作,单例模式,发布——订阅者模式

Main.ts

import Bubble from "./Bubble.js";

export default class Main
    constructor()
        var form:htmlFormElement = document.querySelector("form") as HTMLFormElement;/* ts断言是from标签 */
        console.log(form);
        form.addEventListener("submit",(e)=>this.submitHandler(e));/* 表单提交事件 */
        
    
    private submitHandler(e:Event):void/* 事件函数 */
        e.preventDefault();/* 阻止默认事件 */
        
    //    var fd = new FormData(e.currentTarget as HTMLFormElement)/* 收集表单数据,断言这个e.currentTarget就是 HTMLFormElement */
    //    var msg = fd.get("msg")/* 因为这个fd是一个set类型数据,所以用get获取数据,或者用这个for of循环 */
    //    console.log(msg);

        var input:HTMLInputElement = (e.currentTarget as HTMLFormElement).lastElementChild as HTMLInputElement;
        var msg = input.value;
        var bubble:Bubble = new Bubble(msg as string);/* 创建对象,执行构造函数 */
        bubble.appendTo("#pop")/* 将对象上的this.elem放在父容器位置 */
        input.value = ''

        
    


IUpdate接口

export default interface IUpdate
    updata():void/* IUpdate接口 */

Bubble.ts

import Component from "./Component.js";
import IUpdate from "./IUpdate.js";
import TimeManager from "./TimeManager.js";
/* 生成div弹幕盒子,放在这个弹幕区执行 */


export default class Bubble extends Component implements IUpdate
    private x:number = 0;/* 获取后面父容器的宽度 */
    private readonly speedX:number = 3;/* 修改弹幕的速度 */
    constructor(msg:string)/* 调用时传入msg */
        super("div");/* 继承Component生成这个对象上属性this.elem的值为div对象 */
        this.elem.textContent = msg;/* 插入内容 */
        Object.assign(this.elem.style,/* 设置样式 */
            position:"absolute",
        )
       
    
    /* 重新超类的这个appendTo将盒子放在弹幕区 */
    public appendTo(parent: string | HTMLElement): HTMLElement 
        parent = super.appendTo(parent);/* 获取超类返回的父容器 */
        var rect = parent.getBoundingClientRect();
        this.x = rect.width;/* 弹幕窗口盒子的宽度 */
        this.elem.style.left = rect.width+"px"/* 将弹幕div放在弹幕窗口的最右边 */
        this.elem.style.top = Math.random()*(rect.height-this.elem.offsetHeight)+"px";/* 修改这个元素的的top值,随机值每次 */
        TimeManager.instance.add(this)/* 添加之后执行时间管理器 */
        return parent;

    
    public updata(): void 
        this.x -= this.speedX;
        this.elem.style.left = this.x+"px"/* 给this.elem赋值为x位置 */
        if(this.x<=-this.elem.offsetWidth)/* 位置超出弹幕盒子 */
            TimeManager.instance.remove(this)/* 执行这个方法将 TimeManager管理器中的list列表中的对象删除 */
            this.elem.remove();
        
        this.elem.style.left = this.x+"px";/* 移动弹幕条 */
    

时间管理器

TimeManager.ts

/* 引入updata接口 */
import IUpdate from "./IUpdate.js";

export default class TimeManager 
    private static _instance:TimeManager;/* 存储单例对象 */
    private list:Set<IUpdate>= new Set()/* 存储有IUpdate的接口的对象 */
    private ids?:number;/* 执行帧动画标记 requestAnimationFrame */
    private constructor()

    
    public static get instance()/* 创建单例对象 */
        return TimeManager._instance || (TimeManager._instance = new TimeManager());
    

    /* 这两个方法有updata接口就能放进来 */
    public add(elem:IUpdate)
        this.list.add(elem)
        if(this.list.size>0 && !this.ids)
            this.animation();
        
    


    public remove(elem:IUpdate)
        /* 找见这个对象,并且删除在list中的这个对象 */
        if(this.list.has(elem)) this.list.delete(elem)
        if(this.list.size === 0 && this.ids)
            cancelAnimationFrame(this.ids);
            this.ids = undefined;
        
    
    private animation()/* 执行动画 */
        this.ids = requestAnimationFrame(()=>this.animation());
        this.list.forEach((item)=>
            item.updata()
        )
    

附加小红块的移动

import IUpdate from "./IUpdate.js";
import TimeManager from "./TimeManager.js";

export default class Rect implements IUpdate
    private elem:HTMLDivElement;
    private bool:boolean=false;
    private x:number=0;
    constructor()
        this.elem = document.querySelector(".div1") as HTMLDivElement;
        this.elem.addEventListener("click",(e)=>this.clickHandler(e))
    
    updata(): void 
        this.x++;
        this.elem.style.left = this.x+"px"
    
    private clickHandler(e:MouseEvent)
        this.bool = !this.bool;
        this.bool? TimeManager.instance.add(this):TimeManager.instance.remove(this);
    

以上是关于时间管理器——弹幕发布——单例模式——消息发布-订阅者的主要内容,如果未能解决你的问题,请参考以下文章

应用程序设置管理器的单例模式的替代方案

Java设计模式~单例模式

goeasy+jquery+ckplayer实现动态实时视频弹幕

消息队列原理

如何构建创造性设计模式:单例模式

Unity 单例模式