Viewport Math (matrix.ts)
Stateless math functions for coordinate transformations, zoom anchoring, hit testing, and viewport interpolation.
Coordinate Conversion
screenToCanvas(pt, vp)
Converts viewport screen offset pixels to canvas (world) coordinates.
function screenToCanvas(pt: Vec2, vp: ViewportMatrix): Vec2canvasToScreen(pt, vp)
Converts canvas coordinates to screen offset pixels.
function canvasToScreen(pt: Vec2, vp: ViewportMatrix): Vec2Coordinate clarity is critical. Screen space uses clientX/clientY from DOM events. Canvas space uses scaled/translated world units. Always use these conversion functions — never mix coordinate spaces.
Zoom & Pan
calculateZoomAnchor(pivot, oldScale, newScale, vp)
Computes translation parameters to scale around a cursor point (preventing cursor drift during zoom).
function calculateZoomAnchor(
pivot: Vec2,
oldScale: number,
newScale: number,
vp: ViewportMatrix
): ViewportMatrixapplyWheelZoom(e, vp, bounds)
Applies zoom modifications from a wheel event.
function applyWheelZoom(e: WheelEvent, vp: ViewportMatrix, bounds: DOMRect): ViewportMatrixapplyPan(e, vp, prev)
Accumulates pan offsets from a pointer event.
function applyPan(e: PointerEvent, vp: ViewportMatrix, prev: Vec2): ViewportMatrixclampScale(scale)
Restricts zoom factor to bounds (ZOOM_MIN to ZOOM_MAX).
function clampScale(scale: number): numberHit Testing
isPointInElement(pt, rect)
Collision test: returns true if the point is inside the rectangle.
function isPointInElement(pt: Vec2, rect: Rect): booleanhitTestElements(pt, nodes)
Returns the ID of the topmost element covering the pointer position, or null.
function hitTestElements(pt: Vec2, nodes: ReadonlyArray<ResolvedNode>): string | nullgetAnchorPositions(rect)
Gets the coordinate positions for all eight resize handle anchors.
function getAnchorPositions(rect: Rect): Record<ResizeAnchor, Vec2>Interpolation
lerp(start, end, amt)
Standard linear interpolation helper.
function lerp(start: number, end: number, amt: number): numberlerpViewport(start, end, amt)
Smooth viewport transition interpolator for animated pans/zooms.
function lerpViewport(start: ViewportMatrix, end: ViewportMatrix, amt: number): ViewportMatrix