diff --git a/src/lib/components/CanvasView.svelte b/src/lib/components/CanvasView.svelte index 0cfdd1f..d401e9b 100644 --- a/src/lib/components/CanvasView.svelte +++ b/src/lib/components/CanvasView.svelte @@ -28,11 +28,11 @@ let stage: HTMLDivElement; const cssVars = pageCssVars(); - // Background grid: one cell per active page, aligned to its edges (A4 at the origin if none). - const grid = $derived.by(() => { - const r = (doc.activeId && doc.rects.get(doc.activeId)) || { x: 0, y: 0, ...A4 }; - const s = viewport.scale; - return { w: r.width * s, h: r.height * s, x: viewport.x + r.x * s, y: viewport.y + r.y * s }; + // Background grid: world-anchored, stepping up ×4 when zoomed out so lines never get denser than ~12px. + const gridStep = $derived.by(() => { + let step = 24 * viewport.scale; + while (step < 12) step *= 4; + return step; }); // ---- autosave -------------------------------------------------------- @@ -529,7 +529,7 @@ class:panning class:erasing={tools.tool === 'eraser'} bind:this={stage} - style="background-size: {grid.w}px {grid.h}px; background-position: {grid.x}px {grid.y}px" + style="--grid: {gridStep}px; background-position: {viewport.x}px {viewport.y}px" onpointerdown={onPointerDown} onpointermove={onPointerMove} onpointerup={onPointerUp} @@ -672,6 +672,7 @@ background-image: linear-gradient(to right, var(--grid-line) 1px, transparent 1px), linear-gradient(to bottom, var(--grid-line) 1px, transparent 1px); + background-size: var(--grid) var(--grid); } .stage :global(.cm-content) { user-select: text;