/** * Edge auto-scroll for a drag over a scrollable container. * * @packageDocumentation */ /** * Scrolls a container while a drag hovers near its edges. * * ### Two deliberate departures from the previous implementation * * **Time-based, not frame-based.** Speed is expressed in pixels per *second* and * multiplied by the real elapsed time each frame. The previous fixed * pixels-per-frame model made scroll speed a function of display refresh rate — * identical drags scrolled twice as fast on a 120 Hz monitor as on a 60 Hz one. * This matches {@link ../renderer/auto-scroller!AutoScroller}, which the body * already uses for range selection. * * **The loop only runs while it has something to do.** The rAF chain starts when * the pointer enters an edge zone and stops when it leaves, instead of spinning * for the entire drag. Each idle frame previously cost a * `getBoundingClientRect()` — a forced layout — to discover it had nothing to do. * * The container rect is read once and cached; {@link invalidate} marks it stale * after anything that could move the container (a resize, a panel change). The * scroll itself does not move the container, so scrolling never invalidates. */ export declare class DragAutoscroll { private scrollEl; private rafId; private mouseX; private mouseY; private lastTs; private rectLeft; private rectTop; private rectWidth; private rectHeight; private rectValid; /** Invoked after any frame that actually scrolled, with the live cursor position. */ private onScrolled; /** * Binds the scrollable container. * * @param scrollEl - Element whose `scrollBy` is driven. Its rect is read lazily * on the first frame that needs it, not here, so attaching * mid-gesture costs no layout. */ attach(scrollEl: HTMLElement): void; /** * Registers a callback fired after each frame that scrolled, so the caller can * re-resolve which drop target now sits under the (unmoved) cursor. * * @param fn - Receives the current client coordinates, or `null` to unregister. */ setScrolledCallback(fn: ((x: number, y: number) => void) | null): void; /** Stops the loop and releases the container reference. */ detach(): void; /** * Marks the cached container rect stale. * * Call after a resize, a panel layout change, or anything else that moves the * container on screen. Not needed for ordinary scrolling, which changes the * container's content offset but not its position. */ invalidate(): void; /** * Records the cursor position and starts the loop when the pointer is inside an * edge zone. * * Safe to call at any rate — it is two number stores plus a zone test against * cached geometry, with no DOM access. * * @param x - Client x coordinate. * @param y - Client y coordinate. */ onMouseMove(x: number, y: number): void; /** * Starts the scroll loop unconditionally. * * Kept for callers that drive the cursor themselves; {@link onMouseMove} starts * the loop on demand, so most callers never need this. */ start(): void; /** Stops the scroll loop immediately. */ stop(): void; /** `true` while the scroll loop is running. */ get isScrolling(): boolean; private readonly tick; /** `true` when the cursor is close enough to an edge to warrant running the loop. */ private isInEdgeZone; /** Reads and caches the container rect if it is stale. */ private ensureRect; /** * Scroll speed (px/s) as a quadratic ramp: `SCROLL_SPEED_MAX` at the edge, * zero at {@link SCROLL_ZONE} away. Quadratic rather than linear so small * incursions into the zone creep rather than lurch. * * @param distanceFromEdge - Pixels from the edge; negative values (cursor past * the boundary) saturate at maximum speed. */ private speedAt; } //# sourceMappingURL=drag-autoscroll.d.ts.map