Product media placeholder
Replace this area with a screenshot or short walkthrough video during the media sweep.
DOM-side radial-push writer. Treats the cursor as a solid ball and shoves each matched element AWAY from it along the unit vector connecting them. Each char/icon/cell gets 3 CSS vars written every frame — `--cursor-shift` (horizontal push px), `--cursor-lift` (vertical push px), `--cursor-tilt` (signed rotation deg) — so author-side CSS can compose them into any transform recipe. Per-element damped-spring physics gives an elastic settle: chars bounce back when the cursor moves away. Captures rest centres ONCE at bind time relative to `scopeSelector` (when set) so per-frame work is one BCR read for the scope plus pure math per element. Off-screen scopes cull the entire write loop.
Inputs
| Port | Type | Description |
|---|---|---|
cursorX | float | Cursor x in document coordinates (px). Wire from `pointer.x`. |
cursorY | float | Cursor y in document coordinates (px). Wire from `pointer.y`. |
Outputs
| Port | Type | Description |
|---|---|---|
| - | - | No ports declared. |
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
selector | elementSelector | "" | CSS selector for the elements to push. Each match becomes a bead in the row that the cursor pushes around. Author-side CSS reads `--cursor-shift` / `--cursor-lift` / `--cursor-tilt` and composes them into the element transform (e.g. `transform: translate(var(--cursor-shift), var(--cursor-lift)) rotate(var(--cursor-tilt))`). |
scopeSelector | elementSelector | "" | Optional ancestor selector. When set, rest centres are captured ONCE at bind relative to this element's BCR; per frame only the scope's BCR is read (1 layout flush instead of N). Use this when matched elements live inside a moving parent (carousel slot, scroll-pinned panel, FLIP layout) — the cached offsets stay correct because the parent translation applies to both cursor and elements equally. Off-screen scope skips the entire write loop. Leave empty to fall back to per-frame BCR per element (slow for 10+ elements). |
radius | float | 130 | Solid-ball radius. Elements within this distance of the cursor get pushed; outside, they sit at rest. Falloff is linear from 1.0 at cursor centre to 0 at the radius edge. min 1; step 5 |
pushAmount | float | 55 | Peak radial-push magnitude in px. Each element is displaced AWAY from the cursor along the unit vector connecting them, scaled by the linear falloff. Element directly above cursor goes UP by this amount; element to the right goes RIGHT, etc. — the cursor acts like a solid ball pushing the row aside. step 1 |
tiltAmount | float | 18 | Peak signed rotation in degrees, at cursor centre. Chars to the left of the cursor tilt one way, right the other (sign from horizontal component of push direction). step 1 |
stiffness | float | 220 | Spring stiffness (Hooke). Higher = snappier return. Typical 80–300. min 1; step 5 |
damping | float | 18 | Spring damping. Lower = more overshoot/oscillation. Critical damping is `2·sqrt(stiffness)` (~30 for stiffness 220). Pick lower (15–22) for visible spring feel; higher (30+) for smooth no-overshoot. min 0; step 1 |
Use cases
- Title hover splat — chars push outward from the cursor with a tilt, snap back on lift-off. Pair with `pointer.x` / `pointer.y`. Set `scopeSelector` to the title container so rest centres are stable across slide transitions.
- Icon row hump — icons within `radius` of the cursor get pushed sideways, leaving a wake. Decrease `pushAmount` for subtle, increase `tiltAmount` for dramatic angle play.
- Card grid jiggle — cards lean away from the cursor as it scrubs across, settling with a spring tail when the pointer leaves.
Related nodes
Envelope
Use cursorProximityWrite as the node type inside a graph node envelope. Add id, optional params, optional connections, and optional activeWhen based on the guide context.
Generated source
Registry faster-motion-docs/node-registry.jsonCategory page /help/faster-motion/faster-motion-node-category-animation/