You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tobspr_shapez.io/src/js/game/hud/dynamic_dom_attach.js

80 lines
2.4 KiB

4 years ago
import { GameRoot } from "../root";
// Automatically attaches and detaches elements from the dom
// Also supports detaching elements after a given time, useful if there is a
// hide animation like for the tooltips
// Also attaches a class name if desired
export class DynamicDomAttach {
constructor(root, element, { timeToKeepSeconds = 0, attachClass = null } = {}) {
/** @type {GameRoot} */
this.root = root;
/** @type {HTMLElement} */
this.element = element;
this.parent = this.element.parentElement;
this.attachClass = attachClass;
this.timeToKeepSeconds = timeToKeepSeconds;
this.lastVisibleTime = 0;
// We start attached, so detach the node first
this.attached = true;
this.internalDetach();
this.internalIsClassAttached = false;
this.classAttachTimeout = null;
}
internalAttach() {
if (!this.attached) {
this.parent.appendChild(this.element);
assert(this.element.parentElement === this.parent, "Invalid parent #1");
this.attached = true;
}
}
internalDetach() {
if (this.attached) {
assert(this.element.parentElement === this.parent, "Invalid parent #2");
this.element.parentElement.removeChild(this.element);
this.attached = false;
}
}
isAttached() {
return this.attached;
}
update(isVisible) {
if (isVisible) {
this.lastVisibleTime = this.root ? this.root.time.realtimeNow() : 0;
this.internalAttach();
} else {
if (!this.root || this.root.time.realtimeNow() - this.lastVisibleTime >= this.timeToKeepSeconds) {
this.internalDetach();
}
}
if (this.attachClass && isVisible !== this.internalIsClassAttached) {
// State changed
this.internalIsClassAttached = isVisible;
if (this.classAttachTimeout) {
clearTimeout(this.classAttachTimeout);
this.classAttachTimeout = null;
}
if (isVisible) {
this.classAttachTimeout = setTimeout(() => {
this.element.classList.add(this.attachClass);
}, 15);
} else {
this.element.classList.remove(this.attachClass);
}
}
}
}