usePointerIntent
Waiting for a mouseenter or hover event to begin loading assets introduces 100ms to 300ms of user-perceived interaction lag. usePointerIntent projects the cursor's smoothed velocity vector forward to predict target arrival before contact, pre-warming network fetches, WebGL shaders, or magnetic physics in advance.
The usePointerIntent hook provides an early warning signal before hover contact occurs. It casts the cursor's smoothed velocity vector from the SensorBus forward in time and calculates time-to-impact against an inflated target bounding box.
Confidence rises smoothly towards 1.0 with damping and asymmetric hysteresis (entry threshold 0.35, exit threshold 0.18 for normal sensitivity) to eliminate signal chattering near element borders.
The hook exposes two consumption channels: intent (a boolean React state for triggering network pre-fetches or component warming) and confidenceRef (a zero-re-render ref containing 0.0 to 1.0 confidence for per-frame magnetic pull, CSS variables, or WebGL uniforms).
◆Real Payloads & Network Head-Start Benchmark
Quick start
Attach the returned ref to your element and guard the pre-fetch or pre-render work behind an idempotent latch.
Read confidenceRef.current inside a FrameConductor callback for continuous, zero-re-render visuals.
Sensitivity Presets & Trajectory Tuning
The mathematical thresholds governing lookahead horizon, rect inflation, and hysteresis boundaries.
| Sensitivity | Horizon | Extend | Min Speed | Enter / Exit |
|---|---|---|---|---|
| "low" | 0.30 s | 8 px | 120 px/s | 0.50 / 0.30 (strict intent) |
| "normal" | 0.50 s | 12 px | 80 px/s | 0.35 / 0.18 (balanced default) |
| "high" | 0.80 s | 20 px | 50 px/s | 0.25 / 0.12 (eager pre-warming) |
API Reference
Syntax
Monitors cursor velocity from SensorBus and emits predictive intent state and damped confidence.
Parameters
| Parameters.field | Type | Default | Description |
|---|---|---|---|
| options.sensitivity | "low" | "normal" | "high" | "normal" | Preset balancing lookahead horizon, target inflation, and hysteresis thresholds. |
| options.dynamic | boolean | false | Re-measures element bounding rect every approach frame. Enable for carousels or moving targets. |
| options.onIntentChange | (intent: boolean) => void | undefined | Callback invoked whenever intent flips between true and false. |
Return Value
Contains DOM ref, reactive boolean intent state, and non-reactive confidenceRef.
Properties & State
| Properties.field | Type | Description |
|---|---|---|
| ref | RefObject<T | null> | Hybrid ref attached to the target interactive element. |
| intent | boolean | React state. Flips to true on predicted approach and false when cursor veers away. |
| confidenceRef | RefObject<number> | 0.0 to 1.0 smoothed confidence value. Updated per frame in render lane without triggering re-renders. |
Instance & SensorBus Retain Cleanup
PointerIntent retains the shared SensorBus on mount and cleans up subscriptions on unmount.
Lifecycle & Invariant Guarantees
- →Zero re-renders for continuous confidence: Confidence values are mirrored directly into confidenceRef, enabling 60fps animations with zero React state thrash.
- →Asymmetric hysteresis: Higher entry confidence (0.35) and lower exit confidence (0.18) prevent signal chatter when cursor hovers near borders.
- →Velocity damping: Velocities are smoothed in the SensorBus input lane, preventing single-frame pointer noise from triggering false alarms.
- →Safe touch fallback: On touch devices without cursor hover trajectories, intent gracefully activates upon actual touch contact.
◆Production Examples
Battle-tested production patterns ready to copy directly into your codebase.
Pre-fetch video segments when the cursor is travelling towards a playable card.
When NOT to use this
Rules & Gotchas
- →Ensure pre-warming work is idempotent: Intent can flip true, false, and true again as hands waver. Latch work behind a ref so network fetches execute once.
- →Provide functional fallback for touch and keyboard: Touch devices do not emit approach trajectories. Ensure content loads reliably on direct click and focus.
- →Use confidenceRef for frame transforms, intent for logic: Reading confidence in useState causes continuous 60fps re-renders; read confidenceRef inside conductor callbacks.
- →Enable dynamic only for moving targets: dynamic: true measures layout rects on approach frames. Keep false for static elements to avoid layout reads.