Skip to main content

Camera

The camera is the viewport โ€” the zoom and pan that map world coordinates onto the screen. Camera state lives in the scene's viewport but is editor-local: it is never recorded in undo history.

Zoomโ€‹

import { Editor } from "@oh-just-another/state";

editor.zoomIn();
editor.zoomOut();
editor.resetZoom();
editor.zoomToFit(); // fit the whole scene (optional padding, default 40)
editor.zoomToSelection(); // fit the current selection (default padding 80)
editor.revealNearestContent(); // "Back to content": centre the element nearest the camera, never zooming in
editor.insertScene(fragment, worldPoint); // merge an imported scene at a point (fresh ids, links kept, one undo step)
editor.setZoom(4); // absolute level (400 %) about the viewport centre, clamped

For zoom anchored at a point (e.g. wheel-zoom toward the cursor), use zoomAt(factor, anchorWorld) โ€” the anchor world point stays put while everything scales around it.

const anchor = editor.screenToWorld({ x: clientX, y: clientY });
editor.zoomAt(1.1, anchor);

Start viewโ€‹

A document can carry a saved camera (viewport.startView, exported with the scene): a freshly opened scene lands there, and the canvas menu's "Set start view" jumps back to it.

editor.setCurrentViewAsStart(); // save the current pan + zoom
editor.goToStartView(); // jump to it (no-op when none is saved)
editor.clearStartView();
editor.startView; // { pan, zoom } | null

Pan and viewport sizeโ€‹

panBy(deltaScreen) moves the camera by a screen-pixel delta. Tell the engine the canvas size with setViewportSize whenever the host element resizes.

editor.panBy({ x: 0, y: -40 }); // pan up
editor.setViewportSize(el.clientWidth, el.clientHeight);

Coordinate conversionโ€‹

screenToWorld projects a host-local screen point into world space โ€” the bridge for any pointer-driven camera or hit-test logic.

const world = editor.screenToWorld({ x: 120, y: 80 });

From the React componentโ€‹

The EditorAPI handle surfaces zoomToFit directly; anything else is reachable through the live editor engine.

import { useRef } from "react";
import { Editor, type EditorAPI } from "@oh-just-another/editor";

function Host() {
const ref = useRef<EditorAPI>(null);
const fit = () => ref.current?.zoomToFit();
const panUp = () => ref.current?.editor?.panBy({ x: 0, y: -40 });
return <Editor ref={ref} />;
}

Pan and zoom gestures (middle-mouse, Space+drag, wheel, pinch) work in any tool mode. Listen to the typed viewport event to react to camera changes.