Files
Graphite/frontend/src/utility-functions/viewports.ts
Keavon Chambers ed7987c881 Split apart the frontend Editor type into SubscriptionsRouter and EditorHandle (#3923)
* Remove the unused Editor.raw/wasmMemory/wasmImport

* Split out Editor.subscriptions

* Replace editor.handle.* with editor.* (1 of 2)

* Replace editor.handle.* with editor.* (2 of 2)

* Replace Editor typedef with EditorHandle import

* Pluralize subscription-router and rename subscriptionsRef->subscriptionsRouter and editorRef->editorHandle

* Remove editor.ts

* Update the readme

* Fix demo art loading bug
2026-03-20 23:34:13 -07:00

53 lines
1.9 KiB
TypeScript

import type { EditorHandle } from "@graphite/../wasm/pkg/graphite_wasm";
export function setupViewportResizeObserver(editor: EditorHandle): () => void {
const viewports = Array.from(window.document.querySelectorAll("[data-viewport-container]"));
if (viewports.length <= 0) return () => {};
const viewport = viewports[0];
if (!(viewport instanceof HTMLElement)) return () => {};
const resizeObserver = new ResizeObserver((entries) => {
for (const entry of entries) {
const devicePixelRatio = window.devicePixelRatio || 1;
// Get exact device pixel dimensions from the browser
// Use devicePixelContentBoxSize for pixel-perfect rendering with fallback for Safari
let physicalWidth: number;
let physicalHeight: number;
if (entry.devicePixelContentBoxSize && entry.devicePixelContentBoxSize.length > 0) {
// Modern browsers (Chrome, Firefox): get exact device pixels from the browser
physicalWidth = entry.devicePixelContentBoxSize[0].inlineSize;
physicalHeight = entry.devicePixelContentBoxSize[0].blockSize;
} else {
// Fallback for Safari: calculate from contentBoxSize and devicePixelRatio
physicalWidth = entry.contentBoxSize[0].inlineSize * devicePixelRatio;
physicalHeight = entry.contentBoxSize[0].blockSize * devicePixelRatio;
}
// Compute the logical size which corresponds to the physical size
const logicalWidth = physicalWidth / devicePixelRatio;
const logicalHeight = physicalHeight / devicePixelRatio;
// Get viewport position
const bounds = entry.target.getBoundingClientRect();
// TODO: Consider passing physical sizes as well to eliminate pixel inaccuracies since width and height could be rounded differently
const scale = physicalWidth / logicalWidth;
if (!scale || scale <= 0) {
continue;
}
editor.updateViewport(bounds.x, bounds.y, logicalWidth, logicalHeight, scale);
}
});
resizeObserver.observe(viewport);
return () => {
resizeObserver.disconnect();
};
}