gibbon.js
Version:
Actor/Component system for use with pixi.js.
167 lines (133 loc) • 4.01 kB
text/typescript
import { Component } from '../core/component';
import { Point } from 'pixi.js';
export type HtmlWrapperOpts = {
/**
* Automatically remove html element from dom when component destroyed.
* Default is true.
*/
autoRemove?: boolean,
/**
* Html Element positioning mode.
*/
position?: 'relative' | 'absolute' | 'sticky' | 'fixed' | 'static',
/**
* Create named element if not found.
*/
createElement?: boolean
}
/**
* Displays raw HtmlElement.
* Should not be used for intensive animation, effects.
*/
export class HtmlWrapper extends Component {
get element() { return this._elm; }
set element(v: HTMLElement | undefined | null) {
this._elm = v;
if (v) {
this._display = v.style.display;
}
}
get width(): number {
return this._elm?.clientWidth ?? 0;
}
set width(v: number) {
if (this._elm) {
this._elm.style.minWidth = this._elm.style.maxWidth = this._elm.style.width = `${v}px`;
}
}
get height(): number {
return this._elm?.clientHeight ?? 0;
}
set height(v: number) {
if (this._elm) {
this._elm.style.minHeight =
this._elm.style.maxHeight = this._elm.style.height = `${v}px`;
}
}
set x(x: number) {
if (this._elm) {
this._elm.style.left = `${x}px`;
}
super.x = x;
}
set y(v: number) {
if (this._elm) {
this._elm.style.top = `${v}px`;
}
super.y = v;
}
set position(p: Point) {
if (this._elm) {
this._elm.style.left = `${p.x}px`;
this._elm.style.top = `${p.y}px`;
}
super.position = p;
}
set display(s: string | undefined) {
this._display = s;
if (this._elm) {
this._elm.style.display = s ?? 'none';
}
}
get visible() {
return this._elm?.style.display !== 'none' && this.enabled;
}
set visible(b: boolean) {
this.enabled = b;
}
get display() { return this._elm?.style.display }
protected _elm?: HTMLElement | null;
/// display to restore after hiding.
protected _display?: string;
autoRemove: boolean;
/**
*
* @param elm - html element or unique id of element in document.
* @param opts
*/
constructor(elm?: HTMLElement | string, opts?: HtmlWrapperOpts) {
super();
this.initElement(elm, opts);
this._display = this._elm?.style.display;
this.autoRemove = opts?.autoRemove ?? true;
if (this._elm) {
if (opts?.position != null) {
this._elm.style.position = opts?.position;
}
}
}
onEnable() {
if (this._elm) {
this._elm.style.display = this._display ?? 'block';
}
}
onDisable() {
if (this._elm) {
this._elm.style.display = 'none';
}
}
private initElement(elmId?: string | HTMLElement | null, opts?: HtmlWrapperOpts) {
if (typeof elmId === 'string') {
this._elm = document.getElementById(elmId);
if (this._elm == null && opts?.createElement) {
this._elm = this.createNamedDiv(elmId);
}
} else if (elmId == null && opts?.createElement === true) {
this._elm = this.createNamedDiv();
} else {
this._elm = elmId;
}
}
private createNamedDiv(elmId?: string) {
const elm = document.createElement('div');
if (elmId) elm.id = elmId;
document.body.appendChild(elm);
return elm;
}
onDestroy(): void {
if (this.autoRemove) {
this._elm?.remove();
}
this._elm = null;
}
}