Quick Start
1. Add to your HTML <head>:
Code snippet omitted: it ships with the download.
2. Add before the closing </body> tag:
Code snippet omitted: it ships with the download.
No GSAP plugins are required. GSAP core is the only dependency.
3. Add the headline anywhere in your <body>:
Code snippet omitted: it ships with the download.
Wrap each visual line in a .erh-line span. The script splits every line into per-letter spans automatically. If you omit .erh-line, the whole element is treated as a single line.
How It Behaves
- Desktop (fine pointer): letters flee the cursor. Move slowly and they nudge; whip the cursor through them and they are thrown far, then spring back with an elastic overshoot. Fast motion also blurs and shrinks the letters slightly.
- Touch (coarse pointer): there is no cursor, so tapping the headline fires a one-shot scatter-and-settle from the point you tapped.
- Keyboard: the headline is focusable. Press Enter or Space to scatter the letters.
- Reduced motion: the headline is shown as plain, fully legible static text with no interaction.
Options
Set these as data attributes on the [data-repel] element.
| Attribute | Values | Default | Description |
|---|---|---|---|
data-repel-radius |
Any number (px) | 130 |
Radius of the repulsion field around the pointer |
data-repel-strength |
Any number | 62 |
Base push distance for a stationary cursor |
data-repel-speed |
Any number | 1 |
How much cursor speed multiplies the throw (0 = speed ignored) |
data-repel-blur |
Any number (px) | 6 |
Peak motion blur; set 0 to disable the smear |
Accessibility
- Reduced motion: with
prefers-reduced-motion: reduce, no interaction is wired and the headline renders as ordinary static text. Nothing is hidden by CSS, so the headline is fully legible even before (or without) JavaScript. - Keyboard: the headline is focusable (
tabindex="0",role="button") and Enter or Space triggers the scatter, mirroring the pointer interaction. - Touch: coarse-pointer devices get a tap-to-scatter equivalent of the cursor moment.
Performance Notes
- Letters are driven with
gsap.quickToandgsap.quickSetter, and a singlegsap.tickerloop handles all letters; no per-frame tween is created while the cursor moves. - The secondary channels (blur, scale, opacity) are derived from each letter's real motion each frame, and the per-frame write is skipped entirely once a letter is at rest.
- Best suited to a single large headline (a display face with a few short words). Very long paragraphs of text are not the target use case.
Dependencies
Required:
- GSAP 3.12+ (core only)
Optional:
- None. No GSAP plugins and no Lenis are used.
Worked examples, the events and programmatic API, and the class reference ship with the download, alongside the full source.