Hover✨ Premium

Repel Particles

100 DOM particles flee the cursor within an 80 px radius with proportional force, then smoothly interpolate back to their origin.

JSParticlesPhysics

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. Hover has 48 effects, including 5 free. Explore the category →

3 usage examples

Full-screen hero background — branding and visual identity studio — Repel Particles example 1

① Full-screen hero background — branding and visual identity studio

WhenThe visitor moves the mouse over the hero; particles scatter from the cursor and spring back, turning a static background into a living surface without loading any image.
WhyA fleeing-particle background adds depth and motion to a studio whose identity rests on precision and space — without distracting from the text, which stays legible in the foreground.
SettingsZone covering the full section (position:absolute;inset:0). HSL 220–280° particles. Text at z-index 10 with pointer-events:none except on the CTA.
"Live flow" widget — analytics dashboard — Repel Particles example 2

② "Live flow" widget — analytics dashboard

WhenIn the main column of a dashboard, a "Connection Flow" card displays particles that flee the cursor — a metaphor for active sessions dispersing under load.
WhyA reactive particle widget in a data dashboard gives a sense of liveness without a complex animated chart; fleeing particles suggest the movement of real flows.
SettingsZone limited to the widget area (position:absolute;inset:0 on the fx-0372-root). Particles reduced to 4×4 px to fit the interface density.
Category gallery — effect or resource library — Repel Particles example 3

③ Category gallery — effect or resource library

WhenEach category card in a navigation grid hosts its own particle instance; hovering a card makes its particles flee the cursor independently from the others.
WhyThree independent small instances (one per card) show that the effect does not require a large canvas: even at 160×278 px, 100 particles create a reactive and legible micro-universe.
SettingsOne .fx-0372-root instance per card, each at position:absolute;inset:0. Dark gradient overlay at z-index 10 for category label legibility.

How it works

On load, the script creates 100 <div class="rpe-particle"> elements inside .rpe-zone and assigns each a random position (left, top in percentage). Each particle stores its origin coordinates. The particles are DOM elements, not a canvas: each can be styled individually in CSS.

A mousemove listener on the zone updates the cursor position. The requestAnimationFrame loop computes the Euclidean distance from each particle to the cursor. If that distance is under 80 px, the particle is repelled with a force inversely proportional to the distance (force = (100 − dist) / 100 × maxForce); its temporary position is offset in the direction away from the cursor. Outside the radius, the position interpolates back to the origin: x += (origX − x) × 0.05 per frame. An IntersectionObserver stops the loop when the zone leaves the screen.

Under prefers-reduced-motion: reduce, the loop does not start; particles stay at their initial position, the background remains visible and static. On touch screens, touchmove updates the virtual cursor position so particles flee the finger too.

Accessibility

  • Reduced motion: under prefers-reduced-motion: reduce, the animation loop does not start. Particles stay at their initial position: the background remains decorative but static.
  • Decorative role: particles convey no information; they are implicitly hidden from assistive technologies by their empty content. No text or functional content should be placed inside particles.
  • Touch: the touchmove event on the zone updates the virtual cursor position. Particles flee the finger on touchscreens too.
  • No critical interaction: particle fleeing is purely decorative. No user action should depend on particle positions — they are not buttons or targets.

Browser compatibility

DOM + requestAnimationFrame + 2.2 KB of JavaScript, no dependency. 100 DOM elements transformed per frame: measured at under 2 ms of JS per frame in Chromium on desktop. On low-end mobile, reduce to 50 particles if animation stutters. IntersectionObserver available since Chrome 51, Firefox 55 and Safari 12.1. Measured in Chromium 151, Firefox 153 and WebKit 26.

Chrome 51+✓ Full
Firefox 55+✓ Full
Safari 12.1+✓ Full
Edge 79+✓ Full
Mobile iOS 12.2+✓ Full (touch)
Android Chrome 51+✓ Full (touch)

Without JavaScript, the 100 divs are not created; the .rpe-zone area renders empty. Without IntersectionObserver, the loop also runs off screen — CPU impact proportional to the particle count.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0372-root">
  <div class="rpe-zone">
    <span class="rpe-label" aria-hidden="true">Move your mouse</span>
    <!-- The 100 div.rpe-particle elements are created by JS -->
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Number of particles (JS — count = 100) 100 particles Lower to 50 for a lighter effect; raise to 150 for a denser background. Avoid more than 200 on low-end mobile.
Flee radius (JS — if (dist < 80)) 80 px Raise to 120-160 px for a reaction as soon as the cursor gets close; lower to 40 px for a subtler effect.
Max force (JS — maxForce) 40 px Raise to 80-80 px for particles that flee far; lower to 15-20 px for a discreet shift.
Return speed (JS — lerp = 0.05) 0.05 (5% per frame) 0.02 gives a slower, smoother return; 0.15 gives a snappy return. At 1, particles return instantly.
Particle appearance (CSS — .rpe-particle) white 3×3 px square, opacity 0.7, border-radius 50% Change size, colour, shape (remove border-radius for squares) or add an emoji as the particle div's HTML content.

FAQ

DOM divs let you style each particle individually in CSS (different colour, shape, size per class or index) and put any content inside them (emoji, SVG icon). A canvas is faster for 500+ particles or drawing effects; for 100 simple divs, the impact is negligible on desktop and acceptable on mobile.
Yes. Modify the .rpe-particle CSS (or add variant classes) or inject a character into the divs when creating them: p.textContent = '★' inside the creation loop.
Yes. The touchmove event updates the virtual cursor position by extracting touches[0].clientX/Y. Particles flee the finger just as they flee the mouse.