OptionaladapterCombined adapter for scene-slot rendering, bounds computation, and move/resize/rotate gesture math. Optional — bare-Canvas consumers that don't need a scene slot may omit it.
Canvas threads this adapter into layer factories and gesture hooks. The
type is the move/resize/rotate intersection plus the optional scene-tree
methods (getLayers/getNode/getChildren) — present on a hierarchical
SceneCanvasAdapter, absent on flat adapters. The buildSceneLayer path
feature-detects them at draw time.
<SceneCanvas> synthesizes this from a Scene; bare-<Canvas> consumers
must supply it explicitly when using the scene or selection-overlay slots.
OptionalautoWhen true (default), the canvas element receives focus on pointerdown
so keyboard events (tool hotkeys, undo/redo) are captured without a
separate click-to-focus step. Set to false for canvases embedded inside
a larger focus-managed layout where auto-focus would steal focus from
sibling inputs.
OptionalbackgroundFillStyle applied to the full canvas surface behind the scene. Accepts the
kit's FillStyle union (solid / pattern / linear-gradient / radial-gradient /
conic-gradient) so consumers don't have to author a background node just to
colorize the canvas.
Rendered as a screen-space layer slotted before 'scene' — independent of
pan / zoom. Canvas owns this layer; <SceneCanvas> forwards its own
backgroundFill prop verbatim so consumer apps see no breaking change.
OptionalboundsOverride for committed bounds lookup. When supplied, takes precedence over
the geometry-derived fallback. Used by the selection overlay, the
multi-select union AABB, and helpersRef.getEffectiveBounds. Optional —
bare-Canvas consumers that use a custom bounds shape should supply this;
<SceneCanvas> derives it from its scene adapter and passes it via the
scene-slot layer config rather than this prop.
OptionalclassOptionalclientCustom pointer-to-world coordinate transform. When supplied, overrides the
default (clientX - canvasRect.left) / scale + pan calculation. Useful
for consumers that apply an additional CSS transform to the canvas element.
OptionalcursorDev HUD: when true, mounts a fixed-position widget showing live cursor coords in both viewport (client) and canvas (world) frames. Useful for diagnosing pointer-coord drift / pan-zoom misalignment without instrumenting events.
OptionaldebugDebug overlay configuration.
undefined (default): read ?debug=… from the URL.false: force off, ignore URL.DebugConfig object: force on with that config, ignore URL.When enabled, the Canvas appends a screen-space debug-overlay layer
at the top of the layer stack and threads a DebugSink into every
interaction hook so they record hit math + handle positions.
OptionaldebugTest-only escape hatch: writes the live debug sink to this ref so tests
can call snapshot() after a render. No effect when debug is off.
OptionaldecorationOptional mode-owned decoration layer. When supplied, Canvas inserts it between the scene-render slot and the tool-overlay slot so decoration draw commands (e.g. path-edit anchor dots) paint above scene content but below tool overlays (drag rects, etc.).
Slot ordering: scene → (scoping mask) → decoration → tool overlay → chrome.
Wired by the modality machine after it activates a mode whose
ModeDefinition supplies a paint() factory. Omitting this prop is a
no-op — existing consumers are unaffected.
OptionaldefaultInitial viewport for the uncontrolled path. Default {x:0, y:0}.
OptionaldprDrawing-buffer density (device pixels per CSS pixel). When omitted the
canvas reads window.devicePixelRatio per paint — the long-standing
screen behavior. Supplying it makes density an explicit parameter, the
same contract the headless renderSceneToPixels path follows (that
path never reads ambient density at all).
OptionalgeometryPose↔bounds projection for non-rect TPose types. When supplied, drives
the default boundsOf fallback and the selection-overlay bounds source so
non-rect poses (e.g. Path) don't require per-prop overrides.
Defaults to the rect identity (AUTO_POSE_DESCRIPTOR).
This is a math helper, not a scene-shaped concern — it converts a pose value to an AABB and extracts rotation for the selection chrome. Bare- Canvas consumers that use a non-rect pose type should supply this.
OptionalgestureIn-flight gesture state <Canvas> can't see for itself. Backs the
getGestureBounds / subscribeGestures / getGestureVersion trio on
helpersRef; wired by <SceneCanvas> from the gesture dispatcher
(createGestureSource). Leaving it unwired is fine — those three then
report "no gesture in flight" and never fire.
OptionalgetChrome-caps visibility resolver. When supplied, Canvas:
helpersForLayers.getIsVisible so
custom layers (notably composeAffordanceLayer) can gate
paint by chrome id;HitTestContext.isVisible
so the same gate applies to hit-testing.Called fresh per draw / per hitTest, so the consumer can return a
predicate that closes over per-frame ChromeCtx. Omit to leave
every chrome element visible (pre-chrome-caps behavior).
CSS-pixel height.
OptionalhelpersMutable ref Canvas writes overlay-aware pose/bounds lookups to on every
render. Custom layers can read it from inside their draw closure to
reflect in-flight gestures (move/resize/rotate) instead of the committed
scene. Both lookups apply when an id is in the active overlay; otherwise
they fall back to the adapter.
Useful for custom layers that render scene content outside of the standard slot system and need to stay in sync with gesture previews.
Layer map. See module docstring for slot semantics.
OptionalmodalityDev HUD: mounts a fixed-position widget below the pick HUD reporting
the active modality mode, the active-slot tool, and the hotkey stack.
Pass true to enable with no mode (renders — for the mode line —
useful until the modality machine is wired). Pass an object to supply
the current mode id.
OptionalonFires whenever the viewport changes — in both controlled and uncontrolled modes.
OptionalpickOptional single-best hit resolver for the pickHud — the id this point
would select on a bare click. When omitted the HUD skips the bold-best
highlight. <SceneCanvas> forwards its internalPickBest here so the
HUD shows the same best-candidate SceneCanvas would pick.
OptionalpickUsed by PickHud to display the list of ids under the cursor.
NOT used for tool routing — see getNodeAtPoint for that.
<SceneCanvas> passes its internal pick function here so the HUD
stays in sync with the scene's actual hit-test order.
OptionalpickDev HUD: when true, mounts a fixed-position widget just below the
cursor-coords HUD listing the ids returned by pickEvery(world) under
the cursor. Useful for diagnosing hit-test order and container/leaf
overlap during select-tool work.
OptionalpreviewExtra preview-bounds lookup checked after previewBoundsExtra's previewPose
fallback. Same shape as previewPoseExtra but returns AABB directly,
preferred when the in-flight handle can produce bounds without going
through geometry.getBounds(pose).
OptionalpreviewExtra source of ids whose committed paint should be suppressed during the
current frame (in addition to those reported by the tools' previewIds()).
Wired by <SceneCanvas> to expose the new gesture-dispatcher's in-flight
handles: as legacy hooks are removed from tools, the
source-hide for move/clone/etc. needs to follow the preview-ghost layer
onto the dispatcher's OngoingHandle.previewIds(). Optional — bare
<Canvas> consumers don't need to wire it.
OptionalpreviewExtra preview-pose lookup checked after the active tool's previewPose
misses. Wired by <SceneCanvas> to expose the gesture-dispatcher's
in-flight OngoingHandle.previewPose(id) so selection chrome (resize/
rotation handles, AABB outline) tracks the ghost during dispatcher-driven
drags. Returns null / undefined when no preview is in flight.
OptionalselectionCurrent selection state. Canvas is a pure pass-through — it owns no selection state of its own. When absent, Canvas behaves as if nothing is selected: no selection chrome, no select-on-click, no clear-on-background.
<SceneCanvas> always supplies this from its internal useSelection.
Bare-<Canvas> consumers may omit it for non-selection use cases (e.g.
force-graph renderers or read-only viewers).
OptionalshadersCustom shader programs to compile on the renderer. Each handle must come
from a module-level registerProgram() call. Compiled once per handle id
on first render (or on context restore). Pass a stable reference (e.g.
defined at module scope) — the array is read at renderer init time.
OptionalstyleOptionaltabOptionaltoolsTool primitive substrate. Pointer/keyboard/wheel events are routed
through tools.dispatcher.
OptionalviewControlled viewport. When supplied, Canvas does not own the value —
the consumer must supply onViewChange and re-render with the new
view. See View JSDoc for the camera-position convention.
OptionalviewOptional world-space rect that constrains pan. When supplied, every
setView call passes through clampView(next, viewBounds, {width, height})
before commit, keeping the visible rect inside viewBounds. If the visible
rect is larger than the bounds along an axis (zoomed out past extent), that
axis is centered. Has no effect on scale — wire useZoom bounds for that.
A viewport concern, not scene-shaped. Consumers that want the pan to stay inside a document page boundary should wire this with the page dimensions.
OptionalviewportPinch-zoom DOM listener attachment for the canvas surface. When supplied,
<Canvas> calls usePinchZoomTool with canvasRef so two-finger pinch
events are handled directly on the canvas element.
Hand tool registration, wheel pan/zoom action descriptors, and keyboard zoom shortcuts are SceneCanvas-level concerns and are NOT owned by Canvas. Those belong with the tool registry and gesture dispatcher that live in SceneCanvas.
When omitted, no pinch-zoom listener is attached.
CSS-pixel width.
Props for
<Canvas>— the low-level WebGL surface + viewport + pointer routing primitive.Canvas is scene-agnostic. It owns the GL surface, view state, pointer/ keyboard dispatch, and slot composition. It does NOT own selection state, picking logic, kind registries, or scene-aware overlays — those belong in
<SceneCanvas>.