jl-particle-interactive
v1.0.2
Published
Canvas-based React library for particle text animations and interactive backgrounds — spring physics, magnetic hover, click attract/repel, NET/JELLYFISH modes. TypeScript. Zero dependencies.
Maintainers
Readme
jl-particle-interactive — React Canvas Particle Animations
A canvas-based React library for rendering text and backgrounds as thousands of animated particles. Letters form from particle swarms, respond to magnetic hover, attract or repel on click, and backgrounds come alive with NET graphs, JELLYFISH glows, or pointer-following swarms. Built with zero runtime dependencies, full TypeScript support, and DPR-aware rendering for sharp output on retina displays.
Installation
npm install jl-particle-interactiveRequires React 18+. No global CSS. Zero runtime dependencies.
Live documentation & playground
The library ships with a full documentation site and an interactive playground so you can see every feature in action and tune the props in real time before writing any code.
| Resource | URL | What you get | |---|---|---| | 📖 Documentation | https://jl-particles-interactive-web-e3hr-ten.vercel.app/ | Live examples, API reference, and use-case guides for every component and background mode | | 🎮 Interactive playground | https://jl-particles-interactive-web-e3hr-ten.vercel.app/demo | A hands-on screen where you can change text, colors, shapes, density, click modes and background modes, then immediately see how the particles behave |
Tip: Open the playground in a new tab and experiment with the controls — the same props you tweak there map 1:1 to the ones documented below, so once you find a look you like, just copy the values into your own
<ParticleCanvas>or<ParticleBackground>.
Why jl-particle-interactive?
| Feature | jl-particle-interactive | tsparticles | particles.js | |---|---|---|---| | Text that forms from particles | ✓ (native, spatial coherence) | Plugin only (complex setup) | ✗ | | Spring physics + float noise | ✓ | ✗ | ✗ | | Magnetic hover / click interact | ✓ (attract & repel) | ✗ | ✗ | | Ready-made background presets | ✓ NET, JELLYFISH, FOLLOW_POINTER | General engine (DIY) | General engine (DIY) | | Runtime dependencies | Zero | 14+ packages | 0 (vanilla JS only) | | React integration | Native React hooks | Wrapper package needed | Manual integration | | TypeScript | Strict mode | Partial | ✗ | | DPR-aware (retina) | ✓ | ✗ | ✗ |
Use cases
- Hero section animated titles — Text materializes from particle chaos on page load
- Loading screens — Words form and dissolve while content loads
- Interactive word carousels — Cycle through words; particles re-form smoothly
- Animated backgrounds — NET graph, JELLYFISH glow, or pointer-following swarm behind any content
Framework compatibility
| Framework | Supported |
|---|---|
| Vite + React | ✓ |
| Next.js (App Router & Pages) | ✓ (client components only — add 'use client') |
| Create React App | ✓ |
| Remix | ✓ (client-side only) |
| Astro | ✓ (inside client:only components) |
| TypeScript | ✓ (strict mode, declarations included) |
What it offers
| Feature | Description | |---|---| | Text particles | Thousands of canvas particles that form any text string using pixel-sampling with spatial coherence — letters look sharp at any size | | Magnetic hover | Particles are attracted to the cursor on hover (~173px radius spring force) | | Click interactions | Attract or repel particles on click/tap — particles flee or swarm toward the pointer | | Animated backgrounds | NET (connected node graph), JELLYFISH (organic glow rings), and FOLLOW_POINTER (swarm) modes | | Spring physics | Each particle uses spring + friction + float-noise physics — movement feels natural, never robotic | | Customizable | Colors (hex or RGB palettes), shapes (circle, square, bean), density, speed, ease, and more |
Quick start
import { ParticleCanvas, TextParticleEngine } from 'jl-particle-interactive';
export default function App() {
return (
<ParticleCanvas height="60vh">
<TextParticleEngine text="Hello" />
</ParticleCanvas>
);
}🎮 Want to see it before you code? Open the interactive playground and tweak text, colors, shapes, density, click modes and background modes in real time. When you like the result, copy the same prop values into the snippet above.
Text examples
1. Free-floating particles
When text is an empty string, particles scatter and drift freely across the canvas — great for ambient loading screens or decorative backgrounds.
import { ParticleCanvas, TextParticleEngine } from 'jl-particle-interactive';
export default function FloatingParticles() {
return (
<ParticleCanvas height="60vh" backgroundColor="#050505">
<TextParticleEngine
text=""
particleColor={['#60a5fa', '#a78bfa', '#34d399']}
particleSize={1.2}
isMagnet={true}
/>
</ParticleCanvas>
);
}2. Hello 🖐️ — magnetic hover + color palette
Particles form the text and spring toward the cursor on hover. Click and hold to repel them outward.
import { ParticleCanvas, TextParticleEngine } from 'jl-particle-interactive';
export default function HelloParticles() {
return (
<ParticleCanvas height="60vh" backgroundColor="#050505">
<TextParticleEngine
text="Hello 🖐️"
particleColor={['#f472b6', '#fb923c', '#facc15', '#34d399', '#60a5fa']}
particleSize={1.3}
particleEase={1.2}
isMagnet={true}
clickMode="repel"
particleShape="circle"
/>
</ParticleCanvas>
);
}3. Word carousel — cycles every 3 seconds
The particles re-form automatically each time the text prop changes. No extra animation code needed.
import { useEffect, useState } from 'react';
import { ParticleCanvas, TextParticleEngine } from 'jl-particle-interactive';
const words = ['Create', 'Inspire', 'React'];
export default function WordCarousel() {
const [index, setIndex] = useState(0);
useEffect(() => {
const id = setInterval(() => setIndex(i => (i + 1) % words.length), 3000);
return () => clearInterval(id);
}, []);
return (
<ParticleCanvas height="60vh" backgroundColor="#050505">
<TextParticleEngine
text={words[index]}
particleColor={['#60a5fa', '#a78bfa', '#f472b6']}
particleSize={1.5}
particleEase={1.2}
isMagnet={true}
particleShape="bean"
/>
</ParticleCanvas>
);
}4. Multiline text
You can pass an array of strings to display multiple lines of text simultaneously. The engine automatically scales the font and centers all the lines vertically.
import { ParticleCanvas, TextParticleEngine } from 'jl-particle-interactive';
export default function MultilineParticles() {
return (
<ParticleCanvas height="60vh" backgroundColor="#050505">
<TextParticleEngine
text={['Creative', 'Interactive', 'Particles']}
particleColor={['#60a5fa', '#34d399', '#f472b6']}
particleSize={1.2}
isMagnet={true}
/>
</ParticleCanvas>
);
}Background examples
Use <ParticleBackground> for standalone animated backgrounds. Set the mode with the name prop and pass all options through config.
1. FOLLOW_POINTER — swarm that follows the cursor
Particles form a loose swarm that chases the cursor across the canvas.
import { ParticleBackground } from 'jl-particle-interactive';
export default function FollowPointerDemo() {
return (
<ParticleBackground
name="FOLLOW_POINTER"
height="60vh"
backgroundColor="#050505"
config={{
orientation: 'diagonal',
density: 1,
shape: 'bean',
colors: ['#00d4ff', '#6ee7b7', '#facc15'],
colorMode: 'wave',
particleSpeed: 1,
pointerTrackingSpeed: 0.06,
}}
/>
);
}2. NET — connected node graph
Particles bounce around and draw lines between nearby nodes. Great for tech-style hero sections.
import { ParticleBackground } from 'jl-particle-interactive';
export default function NetDemo() {
return (
<ParticleBackground
name="NET"
height="60vh"
backgroundColor="#050505"
config={{
density: 0.9,
shape: 'circle',
colors: ['#7dd3fc', '#60a5fa', '#a78bfa'],
colorMode: 'mixed',
particleSpeed: 1,
pointerTrackingSpeed: 0.08,
}}
/>
);
}3. JELLYFISH — organic pulsing glow
Soft concentric rings expand and contract in a slow breathing cycle. Particles drift with organic float noise.
import { ParticleBackground } from 'jl-particle-interactive';
export default function JellyfishDemo() {
return (
<ParticleBackground
name="JELLYFISH"
height="60vh"
backgroundColor="#050505"
config={{
density: 1.1,
shape: 'circle',
colors: ['#f472b6', '#a78bfa', '#22d3ee'],
colorMode: 'wave',
particleSpeed: 1,
pointerTrackingSpeed: 0.02,
}}
/>
);
}API reference
<ParticleBackground>
Standalone background component. Use this when you want an animated background without any text particles.
| Prop | Type | Default | Description |
|---|---|---|---|
| name | 'NONE' \| 'FOLLOW_POINTER' \| 'NET' \| 'JELLYFISH' | required | Background engine to render |
| config | BackgroundConfig | undefined | All engine options (see table below) |
| width | string \| number | '100%' | Container width |
| height | string \| number | '60vh' | Container height |
| backgroundColor | string | '#050505' | Background fill color |
| className | string | '' | Additional CSS class |
| style | CSSProperties | — | Inline style overrides |
BackgroundConfig (config prop options)
All fields are optional. Pass any combination inside the config prop of <ParticleBackground>.
| Option | Type | Applies to | Description |
|---|---|---|---|
| density | number | all modes | Particle count multiplier. Base counts: FOLLOW_POINTER=350, NET≈300, JELLYFISH=350 |
| color | string | all modes | Single hex color for all particles |
| colors | string[] | all modes | Palette of hex colors; overrides color |
| colorMode | 'wave' \| 'mixed' | all modes | How colors propagate across particles |
| shape | 'circle' \| 'square' \| 'bean' | all modes | Particle drawing shape |
| particleSpeed | number | all modes | Animation speed multiplier |
| pointerTrackingSpeed | number | all modes | How fast particles follow the cursor (lower = floatier) |
| orientation | 'vertical' \| 'horizontal' \| 'diagonal' | FOLLOW_POINTER only | Swarm drift direction |
| interactionRadius | number | — | Declared in type; not applied in current version |
| lineDistance | number | — | Declared in type; not applied in current version |
<ParticleCanvas>
Container that combines text particles with an optional background. Use background to activate a background engine alongside <TextParticleEngine> children.
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | — | Content rendered above background (z-index 10) |
| width | string \| number | '100%' | Container width |
| height | string \| number | '60vh' | Container height |
| backgroundColor | string | '#050505' | Background fill color |
| background | BackgroundCanvas | { name: 'NONE' } | Background engine config (flat object with name + all options) |
| className | string | '' | Additional CSS class |
| style | CSSProperties | — | Inline style overrides |
<TextParticleEngine>
| Prop | Type | Default | Description |
|---|---|---|---|
| text | string \| string[] | required | Text the particles form (array for multiple lines) |
| particleColor | string \| string[] | '255, 255, 255' | RGB string or array of hex colors |
| particleSize | number | 1 | Size multiplier |
| particleDensity | number | 1 | Particle count multiplier |
| particleEase | number | 1 | Return speed multiplier |
| isMagnet | boolean | true | Hover attraction effect |
| clickMode | 'none' \| 'attract' \| 'repel' | 'none' | Click/tap interaction |
| particleShape | 'circle' \| 'square' \| 'bean' | 'circle' | Particle shape |
| backgroundColor | string | '#050505' | Canvas background (hex) |
Color note:
particleColoraccepts'R, G, B'strings (e.g.'255, 100, 50') or hex strings in an array (e.g.['#ff0000', '#00ff00']). Alpha is handled internally.
License
MIT
