From d9e72b2ff2ef563a6dce633a0364eb2dde966f12 Mon Sep 17 00:00:00 2001 From: Danila Poyarkov Date: Sat, 25 Apr 2026 12:32:12 +0300 Subject: [PATCH] fix(app): fit opened files to viewport --- packages/vue/src/shared/useCanvas.ts | 4 ++++ src/stores/editor.ts | 25 ++++++++++++++++++++++++- src/stores/tabs.ts | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/packages/vue/src/shared/useCanvas.ts b/packages/vue/src/shared/useCanvas.ts index 2819bf767..673be5846 100644 --- a/packages/vue/src/shared/useCanvas.ts +++ b/packages/vue/src/shared/useCanvas.ts @@ -68,6 +68,10 @@ export function useCanvas( const dpr = window.devicePixelRatio || 1 canvas.width = canvas.clientWidth * dpr canvas.height = canvas.clientHeight * dpr + const maybeSizedEditor = editor as Editor & { + setViewportSize?: (width: number, height: number) => void + } + maybeSizedEditor.setViewportSize?.(canvas.clientWidth, canvas.clientHeight) } function makeGLSurface(canvas: HTMLCanvasElement) { diff --git a/src/stores/editor.ts b/src/stores/editor.ts index 6bc907cbc..d8c9d0c85 100644 --- a/src/stores/editor.ts +++ b/src/stores/editor.ts @@ -112,7 +112,17 @@ export function createEditorStore(initialGraph?: SceneGraph) { scrubInputFocused: false }) - const editor = createEditor({ graph, state, loadFont, skipInitialGraphSetup: !!initialGraph }) + const viewportSize = { width: 0, height: 0 } + const editor = createEditor({ + graph, + state, + loadFont, + skipInitialGraphSetup: !!initialGraph, + getViewportSize: () => + viewportSize.width > 0 && viewportSize.height > 0 + ? viewportSize + : { width: window.innerWidth, height: window.innerHeight } + }) const io = new IORegistry(BUILTIN_IO_FORMATS) if (initialGraph) { @@ -853,6 +863,16 @@ export function createEditorStore(initialGraph?: SceneGraph) { return new Promise((r) => requestAnimationFrame(() => r())) } + function setViewportSize(width: number, height: number) { + viewportSize.width = width + viewportSize.height = height + } + + async function fitCurrentPageToViewport() { + await yieldToUI() + editor.zoomToFit() + } + function setDocumentSource( fileName: string, sourceFormat: string, @@ -900,6 +920,7 @@ export function createEditorStore(initialGraph?: SceneGraph) { const firstPage = editor.graph.getPages()[0] as SceneNode | undefined const pageId = firstPage?.id ?? editor.graph.rootId await editor.switchPage(pageId) + await fitCurrentPageToViewport() editor.requestRender() } catch (e) { console.error('Failed to open .fig file:', e) @@ -1265,6 +1286,8 @@ export function createEditorStore(initialGraph?: SceneGraph) { nodeEditDeleteSelected, nodeEditBreakAtVertex, openFigFile, + setViewportSize, + fitCurrentPageToViewport, saveFigFile, saveFigFileAs, setDocumentSource, diff --git a/src/stores/tabs.ts b/src/stores/tabs.ts index 83590496a..505988c97 100644 --- a/src/stores/tabs.ts +++ b/src/stores/tabs.ts @@ -115,6 +115,7 @@ export async function openFileInNewTab( store.state.selectedIds = new Set() const pageId = store.graph.getPages()[0]?.id ?? store.graph.rootId await store.switchPage(pageId) + await store.fitCurrentPageToViewport() } finally { store.state.loading = false }