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">
1 lines • 9.16 kB
Source Map (JSON)
{"version":3,"file":"CanvasObserver.mjs","sources":["../../src/dom/CanvasObserver.ts"],"sourcesContent":["import { type Renderer } from '../rendering/renderers/types';\nimport { UPDATE_PRIORITY } from '../ticker/const';\nimport { Ticker } from '../ticker/Ticker';\n\n/**\n * CanvasObserver class synchronizes the DOM element's transform with the canvas size and position.\n * It uses ResizeObserver for efficient updates and requestAnimationFrame for fallback.\n * This ensures that the DOM element is always correctly positioned and scaled relative to the canvas.\n * @internal\n */\nexport class CanvasObserver\n{\n /** A cached value of the last transform applied to the DOM element. */\n private _lastTransform = '';\n /** A ResizeObserver instance to observe changes in the canvas size. */\n private _observer: ResizeObserver | null = null;\n /** The canvas element that this observer is associated with. */\n private _canvas: HTMLCanvasElement;\n /** The DOM element that will be transformed based on the canvas size and position. */\n private readonly _domElement: HTMLElement;\n /** The renderer instance that this observer is associated with. */\n private readonly _renderer: Renderer;\n /** The last scale values applied to the DOM element, used to avoid unnecessary updates. */\n private _lastScaleX: number;\n /** The last scale values applied to the DOM element, used to avoid unnecessary updates. */\n private _lastScaleY: number;\n /** A flag to indicate whether the observer is attached to the Ticker for continuous updates. */\n private _tickerAttached = false;\n\n constructor(options: { domElement: HTMLElement; renderer: Renderer })\n {\n this._domElement = options.domElement;\n this._renderer = options.renderer;\n\n // We need to ensure that the canvas is not an OffscreenCanvas\n if (globalThis.OffscreenCanvas && this._renderer.canvas instanceof OffscreenCanvas) return;\n this._canvas = this._renderer.canvas;\n this._attachObserver();\n }\n\n /** The canvas element that this CanvasObserver is associated with. */\n public get canvas(): HTMLCanvasElement\n {\n return this._canvas;\n }\n\n /** Attaches the DOM element to the canvas parent if it is not already attached. */\n public ensureAttached()\n {\n if (!this._domElement.parentNode && this._canvas.parentNode)\n {\n this._canvas.parentNode.appendChild(this._domElement);\n this.updateTranslation();\n }\n }\n\n /**\n * Updates the transform of the DOM element based on the canvas size and position.\n * This method calculates the scale and translation needed to keep the DOM element in sync with the canvas.\n */\n public readonly updateTranslation = () =>\n {\n if (!this._canvas) return;\n\n const rect = this._canvas.getBoundingClientRect(); // still needed for left/top\n const contentWidth = this._canvas.width;\n const contentHeight = this._canvas.height;\n\n const sx = (rect.width / contentWidth) * this._renderer.resolution;\n const sy = (rect.height / contentHeight) * this._renderer.resolution;\n const tx = rect.left;\n const ty = rect.top;\n\n const newTransform = `translate(${tx}px, ${ty}px) scale(${sx}, ${sy})`;\n\n if (newTransform !== this._lastTransform)\n {\n this._domElement.style.transform = newTransform;\n this._lastTransform = newTransform;\n }\n };\n\n /** Sets up a ResizeObserver if available. This ensures that the DOM element is kept in sync with the canvas size . */\n private _attachObserver()\n {\n if ('ResizeObserver' in globalThis)\n {\n if (this._observer)\n {\n this._observer.disconnect();\n this._observer = null;\n }\n\n this._observer = new ResizeObserver((entries) =>\n {\n for (const entry of entries)\n {\n if (entry.target !== this._canvas)\n {\n continue;\n }\n\n const contentWidth = this.canvas.width;\n const contentHeight = this.canvas.height;\n const sx = (entry.contentRect.width / contentWidth) * this._renderer.resolution;\n const sy = (entry.contentRect.height / contentHeight) * this._renderer.resolution;\n\n // Only refetch position if scale actually changed\n const needsUpdate = this._lastScaleX !== sx || this._lastScaleY !== sy;\n\n if (needsUpdate)\n {\n this.updateTranslation(); // safely fetch `left` and `top` only when needed\n this._lastScaleX = sx;\n this._lastScaleY = sy;\n }\n }\n });\n this._observer.observe(this._canvas);\n }\n else if (!this._tickerAttached)\n {\n Ticker.shared.add(this.updateTranslation, this, UPDATE_PRIORITY.HIGH);\n }\n }\n\n /** Destroys the CanvasObserver instance, cleaning up observers and Ticker. */\n public destroy()\n {\n if (this._observer)\n {\n this._observer.disconnect();\n this._observer = null;\n }\n else if (this._tickerAttached)\n {\n Ticker.shared.remove(this.updateTranslation);\n }\n\n (this._domElement as null) = null;\n (this._renderer as null) = null;\n this._canvas = null;\n this._tickerAttached = false;\n this._lastTransform = '';\n this._lastScaleX = null;\n this._lastScaleY = null;\n }\n}\n"],"names":[],"mappings":"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"}