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 • 8.93 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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"}