@vectorvesper/motion/reactReact · Trajectory Prediction

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

LIVE NETWORK TIMING
Demo loads on scroll

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.

SensitivityHorizonExtendMin SpeedEnter / Exit
"low"0.30 s8 px120 px/s0.50 / 0.30 (strict intent)
"normal"0.50 s12 px80 px/s0.35 / 0.18 (balanced default)
"high"0.80 s20 px50 px/s0.25 / 0.12 (eager pre-warming)

API Reference

Syntax

Monitors cursor velocity from SensorBus and emits predictive intent state and damped confidence.

Parameters

Parameters.fieldTypeDefaultDescription
options.sensitivity"low" | "normal" | "high""normal"Preset balancing lookahead horizon, target inflation, and hysteresis thresholds.
options.dynamicbooleanfalseRe-measures element bounding rect every approach frame. Enable for carousels or moving targets.
options.onIntentChange(intent: boolean) => voidundefinedCallback invoked whenever intent flips between true and false.

Return Value

UsePointerIntentReturn<T>

Contains DOM ref, reactive boolean intent state, and non-reactive confidenceRef.

Properties & State

Properties.fieldTypeDescription
refRefObject<T | null>Hybrid ref attached to the target interactive element.
intentbooleanReact state. Flips to true on predicted approach and false when cursor veers away.
confidenceRefRefObject<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.

1. React Hook UsageAutomatic Cleanup
2. Vanilla JS UsageManual Destroy

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

The interaction cost is trivial (e.g. swapping a CSS class or opening a small tooltip).
→ instead Use standard CSS :hover or native onMouseEnter. Ray casting is unnecessary for instantaneous operations.
The pre-fetch payload is large on metered networks without explicit user commitment.
→ instead Require direct hover or focus. Pre-fetching large payloads on missed sweeps wastes bandwidth.
Continuously pulling elements towards cursor.
→ instead Use useMagneticIntent, which directly wraps this signal with spring physics and transforms.

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.

Related Motion Components