pixi.js
Version:
<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">
100 lines (97 loc) • 3.79 kB
JavaScript
import { UPDATE_PRIORITY } from '../ticker/const.mjs';
import { Ticker } from '../ticker/Ticker.mjs';
"use strict";
class CanvasObserver {
constructor(options) {
/** A cached value of the last transform applied to the DOM element. */
this._lastTransform = "";
/** A ResizeObserver instance to observe changes in the canvas size. */
this._observer = null;
/** A flag to indicate whether the observer is attached to the Ticker for continuous updates. */
this._tickerAttached = false;
/**
* Updates the transform of the DOM element based on the canvas size and position.
* This method calculates the scale and translation needed to keep the DOM element in sync with the canvas.
*/
this.updateTranslation = () => {
if (!this._canvas)
return;
const rect = this._canvas.getBoundingClientRect();
const contentWidth = this._canvas.width;
const contentHeight = this._canvas.height;
const sx = rect.width / contentWidth * this._renderer.resolution;
const sy = rect.height / contentHeight * this._renderer.resolution;
const tx = rect.left;
const ty = rect.top;
const newTransform = `translate(${tx}px, ${ty}px) scale(${sx}, ${sy})`;
if (newTransform !== this._lastTransform) {
this._domElement.style.transform = newTransform;
this._lastTransform = newTransform;
}
};
this._domElement = options.domElement;
this._renderer = options.renderer;
if (globalThis.OffscreenCanvas && this._renderer.canvas instanceof OffscreenCanvas)
return;
this._canvas = this._renderer.canvas;
this._attachObserver();
}
/** The canvas element that this CanvasObserver is associated with. */
get canvas() {
return this._canvas;
}
/** Attaches the DOM element to the canvas parent if it is not already attached. */
ensureAttached() {
if (!this._domElement.parentNode && this._canvas.parentNode) {
this._canvas.parentNode.appendChild(this._domElement);
this.updateTranslation();
}
}
/** Sets up a ResizeObserver if available. This ensures that the DOM element is kept in sync with the canvas size . */
_attachObserver() {
if ("ResizeObserver" in globalThis) {
if (this._observer) {
this._observer.disconnect();
this._observer = null;
}
this._observer = new ResizeObserver((entries) => {
for (const entry of entries) {
if (entry.target !== this._canvas) {
continue;
}
const contentWidth = this.canvas.width;
const contentHeight = this.canvas.height;
const sx = entry.contentRect.width / contentWidth * this._renderer.resolution;
const sy = entry.contentRect.height / contentHeight * this._renderer.resolution;
const needsUpdate = this._lastScaleX !== sx || this._lastScaleY !== sy;
if (needsUpdate) {
this.updateTranslation();
this._lastScaleX = sx;
this._lastScaleY = sy;
}
}
});
this._observer.observe(this._canvas);
} else if (!this._tickerAttached) {
Ticker.shared.add(this.updateTranslation, this, UPDATE_PRIORITY.HIGH);
}
}
/** Destroys the CanvasObserver instance, cleaning up observers and Ticker. */
destroy() {
if (this._observer) {
this._observer.disconnect();
this._observer = null;
} else if (this._tickerAttached) {
Ticker.shared.remove(this.updateTranslation);
}
this._domElement = null;
this._renderer = null;
this._canvas = null;
this._tickerAttached = false;
this._lastTransform = "";
this._lastScaleX = null;
this._lastScaleY = null;
}
}
export { CanvasObserver };
//# sourceMappingURL=CanvasObserver.mjs.map