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