Portfolio
  • 01Home
  • 02Projects
  • 03About
  • 04Skills
  • 05Lab
  • 06Writing
  • 07Contact

© 2026 Hamza Syrage

LabView all
Arrow FieldCursorCursor SpotlightCursorGooey CursorCursorImage CompareMediaInteractive ChartDataMagnetic ButtonInteractionMarquee RevealTypographyMorphing ShapeAnimationsNested ViewsOverlaysOdometer CounterDataParticle ConstellationCanvasRipple ClickButtonsScroll RevealScrollShuffle GridLayoutStep WizardNavigationTabsNavigationTilt CardCards

UI Experiments

All Lab Entries
Interaction

Magnetic Button

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.

#Step 1: Pointer tracking

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.

Track raw offset
dx: 0   dy: 0
tsx
Loading...

#Step 2: Spring response

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.

Spring overshoots then settles
Spring physics
Stiffness150
Damping15
Mass0.1
tsx
Loading...

#Step 3: Button translation

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.

tsx
Loading...

#Configuration

Spring physics control the pull feel - snappy vs. lazy, stiff vs. springy.

Spring physics
Stiffness150
Damping15
Mass0.1
tsx
Loading...