Skip to content

Dynamics.applyRepulsion()

Adds a physics-based "push" effect to elements. When the source (like your mouse pointer) gets close, the elements are pushed away. When it moves away, the elements spring back to their original places.


1. Interactive Typography

You can apply this push effect to a group of elements, like individual letters in a word. They will scatter when your mouse gets near and snap back into place when you leave.

Hover over the text
REPULSION
60 FPS
js
import { Dynamics } from 'animx/dynamics'

const letters = document.querySelectorAll('.letter');

Dynamics.applyRepulsion(letters, {
  source: 'pointer',
  force: 1500,     // Strong push
  radius: 100,     // Medium radius
  damping: 14,     // Fast snap back with little wobble
  stiffness: 120   // Tense springs
});

2. Unbound Displacement

If you set stiffness to 0, the element won't spring back. Once you push it, it keeps sliding! You'll want to use bounds so it doesn't fly off the screen.

Interact with the element
60 FPS
js
Dynamics.applyRepulsion('.orb', {
  source: 'pointer',
  force: 1800,
  radius: 150,
  damping: 8,
  stiffness: 0,    // No anchor pulling it back!
  mass: 1.2,
  bounds: '.stage', // Bounce off the walls
  bounce: 0.6
});

3. Displacement Grids

By using a lower force but a huge radius on a large grid of dots, you can create a beautiful, rippling wave effect. This is great for interactive backgrounds.

Hover over the grid
60 FPS
js
Dynamics.applyRepulsion('.matrix-dots', {
  source: 'pointer',
  force: 400,      // Gentle nudge
  radius: 200,     // Huge radius for a wide wave
  damping: 10,     // Medium drift
  mass: 1.5        // Heavy, sluggish movement
});

4. Multi-Element Tracking

The source pushing the elements doesn't have to be the mouse pointer. You can use other DOM elements. In this example, two animated orbs act as moving repellers.

60 FPS
js
// 1. Move the sources with standard tweens
AnimX.timeline({ repeat: -1, yoyo: true })
  .animate('.red-orb', { x: 300, y: 150, duration: 2.5, ease: 'sine.inOut' });

AnimX.timeline({ repeat: -1, yoyo: true })
  .animate('.blue-orb', { x: -300, y: 150, duration: 2.5, ease: 'sine.inOut' }, 0);

// 2. Apply repulsion using BOTH elements as sources simultaneously
Dynamics.applyRepulsion('.dots', { 
  source: ['.red-orb', '.blue-orb'], 
  force: 2000, 
  radius: 120, 
  damping: 12 
});

Properties & Methods

Flexible Types

Properties like source and bounds accept multiple formats natively. You can pass a CSS selector, a DOM Element, or even a coordinate object for bounds (e.g., { minX: 0 }). Learn more in the Flexible Types guide.

OptionTypeDefaultDescription
sourcestring | Element'pointer'What causes the push. Use 'pointer' for the mouse/finger, or provide a DOM element.
forcenumber1000How strong the push is.
radiusnumber150How close the source needs to be (in pixels) before the element reacts.
dampingnumber12Friction. Higher values make the element slide less and stop faster.
massnumber1How heavy the element feels. Lower values make it fly away faster.
stiffnessnumber80How hard the element tries to spring back to its original place.
boundsstring | Element | { minX?: number, maxX?: number, minY?: number, maxY?: number }nullKeeps the elements inside a box so they don't fly off screen.
bouncenumber0.5How bouncy the element is when it hits the bounds (0 to 1).

Return Instance

MethodDescription
kill()Stops the physics and cleans up event listeners.