A button that follows the cursor with spring-based pull.
A button that subtly shifts toward the cursor when hovered, using raw pointer position fed through a spring for organic movement.
Compute the offset between the cursor and the element's center using getBoundingClientRect. Store it in a useMotionValue, which avoids re-renders on every mouse move. The raw pixel offset is the natural displacement vector.
useMotionValue is purpose-built for high-frequency values. A regular useState re-renders the entire component on every pixel; a motion value updates the DOM attribute directly without touching React's reconciler.
Loading...
The raw offset fed directly into x/y is too responsive and jittery. Wrapping it in a spring adds weight. The dot now overshoots, then settles, following the cursor with a slight delay that reads as physical.
The spring config, stiffness, damping, and mass, controls the personality. Lower mass and higher stiffness feels snappy, like a magnet. Higher mass and lower damping feels lazy, like a rubber band.
Loading...
Replace the debug dot with an actual button. Apply the same spring values to its x and y. Add whileTap={{ scale: 0.96 }} for press feedback. The button now follows the cursor with a small, controlled displacement - 0.3 multiplier keeps the movement subtle.
The multiplier is the key design parameter. 0.3-0.5 gives a gentle magnetic pull. Going beyond 0.5 starts to feel like the button is running away.
Loading...
Spring physics control the pull feel - snappy vs. lazy, stiff vs. springy.
Loading...