useMagneticIntent
Traditional magnetic hover buttons only react once the pointer enters their bounding box, feeling sluggish and delayed. useMagneticIntent fuses pointer trajectory prediction with proximity falloff, beginning attraction physics while the cursor is still travelling towards the target.
The useMagneticIntent hook binds a DOM element to an anticipatory magnetic pull. It computes an engagement value from 0.0 to 1.0 based on the maximum of PointerIntent approach confidence and geometric proximity falloff.
The hook reads element anchor bounds in the conductor input lane before any subscriber writes, and updates DOM transform properties in the render lane. This separation guarantees zero forced synchronous reflows even when dozens of magnetic elements animate concurrently.
Anchor positions are automatically compensated against current translation offsets (anchor = rectCenter - currentOffset), preventing the element from chasing its own displaced centre. When running on touch devices or under reduced motion preferences, the hook gracefully sits idle and leaves the element at rest.
◆Multi-Element Magnetic Grid
Quick start
Attach the returned ref to your button. The hook manages spring-damped translation and scale transforms automatically.
The hook takes exclusive ownership of the element inline transform while mounted, restoring original inline styles on unmount.
Input Lane Separation & Anchor Stability
How the magnetic physics pipeline prevents layout thrashing and anchor drift across multi-element pages.
Calling getBoundingClientRect() inside render callbacks forces synchronous layout recalculation when multiple elements animate. MagneticElement schedules anchor measurements strictly in the input lane, caching rects across frames and re-measuring only during scroll, resize, or periodic heartbeats.
As the element translates towards the pointer, its live bounding box moves with it. To prevent runaway drift, the anchor coordinate is calculated by subtracting the current translation offset from the element centre: anchorX = rect.left + width/2 - currentOffsetX.
API Reference
Syntax
Binds an element to predictive magnetic pull with spring-damped tracking.
Parameters
| Parameters.field | Type | Default | Description |
|---|---|---|---|
| options.strength | number | 12 | Maximum offset in pixels at full magnetic engagement. |
| options.reach | number | 90 | Proximity radius in pixels from resting centre where attraction begins. |
| options.speed | number | 12 | Spring follow and release speed. Higher values create a tighter, snappier chase. |
| options.scale | number | 1.04 | Scale multiplier applied at full engagement. Set to 1.0 to disable scaling. |
| options.anticipate | boolean | true | Enables trajectory prediction to start reaching before cursor contact. Disable for dense grids. |
Return Value
Ref to attach to target element and boolean active status (true when running on fine pointer).
Properties & State
| Properties.field | Type | Description |
|---|---|---|
| ref | RefObject<T | null> | DOM ref attached to the element whose transform is animated. |
| active | boolean | True when running on a fine pointer without reduced-motion constraints. |
Inline Transform Restoration & Teardown
MagneticElement preserves original inline styles and restores them cleanly upon unmount.
Lifecycle & Invariant Guarantees
- →Zero forced synchronous reflows: Measurements execute in the input lane before any transform writes occur, preventing multi-element layout thrashing.
- →Style state preservation: Previous inline transform strings are recorded and restored exactly when the component unmounts.
- →Accessibility and touch safety: Bails out automatically on touch-only devices and when prefers-reduced-motion is active.
- →Frame-rate independent damping: Spring physics use delta-time damping, behaving consistently across 60Hz, 120Hz, and 240Hz screens.
◆Production Examples
Battle-tested production patterns ready to copy directly into your codebase.
Single hero action button with anticipatory pull enabled for high-fidelity desktop experience.
When NOT to use this
Rules & Gotchas
- →Enable anticipate for single CTAs, disable for dense grids: Anticipation executes trajectory prediction per element. Keep enabled for hero buttons and disabled for tile grids.
- →Keep strength modest on interactive controls: Excessive travel distance makes buttons harder to click. Keep strength between 8px and 16px for interactive elements.
- →Separate compound transforms onto child nodes: The hook takes exclusive ownership of the ref node inline transform. Place static rotations on child elements.
- →Preserve accessible focus styling: Magnetic attraction is a visual enhancement; keyboard focus outlines and accessibility labels must remain fully functional.