/** * The canvas control channel, in its own dependency-free module. * * Play, Comments and App steer the camera through this object; Canvas assigns * the real implementations when it mounts. Living here rather than inside * Canvas.tsx keeps the play/focus surfaces importable WITHOUT the canvas - a * locked-shell bundle mounts the stage chrome and the canvas code never enters * it (01-sharing ยง5.1's all-boards rule). Before Canvas mounts (or when it * never does), every call is a harmless no-op. */ /** B0.2: one wheel event, whatever its origin - a shell-document wheel over the canvas, or * a wheel forwarded from a passive frame's iframe. clientX/Y are shell-viewport pixels. */ export interface CanvasWheelInput { deltaX: number; deltaY: number; deltaMode: number ctrlKey: boolean; metaKey: boolean; clientX: number; clientY: number } export const canvasCtl = { fitNode(_key: string) {}, fitNodes(_keys: string[]) {}, fitAll() {}, zoomTo(_scale: number) {}, zoom100() { canvasCtl.zoomTo(1) }, wheel(_input: CanvasWheelInput) {}, /** Call right BEFORE a layout change the human did not ask for (a content-driven reflow): the * node they are looking at keeps its place on screen through it - scroll anchoring. */ holdView() {}, /** Is the camera mid-flight (a fit, a zoom)? A content-driven reflow waits for it to land: a fit * aimed at the frames a link names must not land on where they were before the rows moved. */ cameraBusy(): boolean { return false }, /** What the camera shows now, in world px (null with no canvas) - a load's visible cohort when no fit landed. */ view(): { x: number; y: number; w: number; h: number } | null { return null }, /** Where a rect on screen now will be once the camera lands from the flight it is on (a fit, a zoom) - itself while * the camera rests: the boot queue ranks a board's first frame on the view the person will see (admission.ts). */ landing(r: DOMRect): DOMRect { return r }, /** The camera now, `{ x, y, s }` as the world is drawn (null with no canvas): the white-out probes' bracket (spec 28 * A3.8 #16) and a hide mid-flight (A3.8 #43). Assigned by Canvas.tsx from its camera. */ transform(): { x: number; y: number; s: number } | null { return null }, }