gpu-curtains
Version:
gpu-curtains is a 3D WebGPU rendering engine. It can be used as a standalone 3D engine, but also includes extra classes focused on mapping 3d objects to DOM elements; It allows users to synchronize values such as position, sizing, or scale between them.
108 lines (107 loc) • 3.31 kB
JavaScript
import { throwError } from "../../utils/utils.mjs";
import { resizeManager } from "../../utils/ResizeManager.mjs";
//#region src/core/DOM/DOMElement.ts
/**
* Used to track a DOM Element size and position by using a resize observer provided by {@link ResizeManager}.<br>
* Execute callbacks when the bounding rectangle of the DOM Element changes, which means when its size and/or position change.
*/
var DOMElement = class {
/**
* DOMElement constructor
* @param parameters - {@link DOMElementParams | parameters} used to create our DOMElement
*/
constructor({ element = document.body, priority = 1, onSizeChanged = (boundingRect = null) => {}, onPositionChanged = (boundingRect = null) => {} } = {}) {
if (typeof element === "string") {
this.element = document.querySelector(element);
if (!this.element) throwError(`DOMElement: corresponding ${typeof element === "string" ? `'${element}' selector` : `${element} HTMLElement`} not found.`);
} else this.element = element;
this.priority = priority;
this.isResizing = false;
this.onSizeChanged = onSizeChanged;
this.onPositionChanged = onPositionChanged;
this.resizeManager = resizeManager;
this.resizeManager.observe({
element: this.element,
priority: this.priority,
callback: () => {
this.setSize();
}
});
this.setSize();
}
/**
* Check whether 2 bounding rectangles are equals
* @param rect1 - first bounding rectangle
* @param rect2 - second bounding rectangle
* @returns - whether the rectangles are equals or not
*/
compareBoundingRect(rect1, rect2) {
return ![
"x",
"y",
"left",
"top",
"right",
"bottom",
"width",
"height"
].some((k) => rect1[k] !== rect2[k]);
}
/**
* Get our element bounding rectangle
*/
get boundingRect() {
return this._boundingRect;
}
/**
* Set our element bounding rectangle
* @param boundingRect - new bounding rectangle
*/
set boundingRect(boundingRect) {
const isSameRect = !!this.boundingRect && this.compareBoundingRect(boundingRect, this.boundingRect);
this._boundingRect = {
top: boundingRect.top,
right: boundingRect.right,
bottom: boundingRect.bottom,
left: boundingRect.left,
width: boundingRect.width,
height: boundingRect.height,
x: boundingRect.x,
y: boundingRect.y
};
if (!isSameRect) this.onSizeChanged(this.boundingRect);
}
/**
* Update our element bounding rectangle because the scroll position has changed
* @param delta - scroll delta values along X and Y axis
*/
updateScrollPosition(delta = {
x: 0,
y: 0
}) {
if (this.isResizing) return;
this._boundingRect.top += delta.y;
this._boundingRect.left += delta.x;
if (delta.x || delta.y) this.onPositionChanged(this.boundingRect);
}
/**
* Set our element bounding rectangle, either by a value or a getBoundingClientRect call
* @param boundingRect - new bounding rectangle
*/
setSize(boundingRect = null) {
if (!this.element || this.isResizing) return;
this.isResizing = true;
this.boundingRect = boundingRect ?? this.element.getBoundingClientRect();
setTimeout(() => {
this.isResizing = false;
}, 10);
}
/**
* Destroy our DOMElement - remove from resize observer and clear throttle timeout
*/
destroy() {
this.resizeManager.unobserve(this.element);
}
};
//#endregion
export { DOMElement };