import { DEFAULT_RULE, type RgRule } from "../core/rule.js"; import { type RgTheme, type RgThemeInput } from "../core/theme.js"; import { type LaneView } from "./view.js"; /** per-frame context handed to a source's draw(). */ export interface LaneEnv { theme: RgTheme; rule: RgRule; size: { width: number; height: number; }; /** readable flow-axis step (world units per readable cell) at this zoom */ lodStep: number; } /** a 1-D dataset the lane can render. World coords run along the flow axis. */ export interface LaneSource { /** short label (shown in the debug HUD) */ title: string; /** flow-axis world bounds, for scroll clamping */ extent(): { min: number; max: number; }; /** * bounds the initial auto-fit frames (default: extent). Lets a source bias * the default view — e.g. the deep-time lane fits the PAST, leaving the * sparse far-future reachable by scrolling within the full extent. */ fitExtent?(): { min: number; max: number; }; /** draw the currently visible window; width is pinned, so lay x out in px */ draw(ctx: CanvasRenderingContext2D, view: LaneView, env: LaneEnv): void; /** * comfortable max zoom (px per world unit). Default 240 — one world unit can * grow to a large-but-finite row. Sources with tiny units may raise it. */ maxZoom?: number; /** extra HUD line (e.g. hovered path / value under the cursor) */ hudLine?: (view: LaneView, pointerY?: number) => string | null; /** * notable points the zoom anchor gravitates toward: world-y plus an optional * screen-x (e.g. a track centre). When the cursor is near one, zooming keeps * THAT point fixed (so a not-quite-aimed target doesn't drift off-screen); * far from any, plain cursor zoom. With x, the pull is track-aware — an event * in the hovered track wins over an equally-timed event in another track. The * pull is a smooth gaussian, not a hard snap. */ snapTargets?: (view: LaneView) => { y: number; x?: number; }[]; /** * double-click focus: given the click's screen-y, return the world center to * scroll to and the zoom to scale to (the target's natural scale), or null. */ focusAt?: (screenY: number, view: LaneView) => { center: number; zoom: number; } | null; /** * how empty the current viewport is (0 = dense, 1 = void). Scrolling into * emptiness auto-zooms-out proportionally (rate = scroll-speed × emptiness), * so the UI never dwells on a silly blank stretch. Omit → no auto-zoom. */ emptiness?: (view: LaneView) => number; } export interface LaneOptions { source: LaneSource; theme?: RgThemeInput; rule?: Partial; debug?: HTMLElement | null; /** cap the backing-store scale (raster cost grows with dpr²) */ maxDpr?: number; /** * keyboard navigation (default true), CapsLockX AccModel physics (see * core/accModel.ts): R/F zoom in/out, W/S (and ↑/↓) scroll — both with * time-based acceleration, so a longer hold travels faster. Identical feel * to the infinite-canvas viewer. */ keyboard?: boolean; /** accel rates (units per first-second of hold); defaults 1600 / 1600 */ keyboardSpeed?: { scroll?: number; zoom?: number; }; /** * the zoom-center indicator (dotted cursor line + snapped-anchor ring). * Default true; hosts with their own pointer affordances (e.g. the * calendar's crosshair + cell highlight) turn it off. */ zoomIndicator?: boolean; onFrame?: (view: LaneView) => void; } export interface Lane { readonly view: LaneView; invalidate(): void; setSource(source: LaneSource): void; setTheme(theme: RgThemeInput): void; /** re-fit the whole extent into the viewport */ fit(): void; /** restore an explicit view (won't be clobbered by auto-fit) */ setView(v: { scrollY?: number; zoomY?: number; }): void; /** animate to a focus target (center world-y + zoom), like double-click */ focus(target: { center: number; zoom: number; }): void; /** true while a focus() animation is in flight (hosts gate view rewrites) */ isAnimating(): boolean; /** enable/disable scroll-into-emptiness auto-zoom-out (default OFF) */ setAutoZoomOut(on: boolean): void; destroy(): void; } export declare function createLane(canvas: HTMLCanvasElement, opts: LaneOptions): Lane; export { DEFAULT_RULE }; //# sourceMappingURL=lane.d.ts.map