jl-particle-interactive 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -0
- package/dist/components/ParticleCanvas.d.ts +3 -1
- package/dist/components/background/BackgroundParticleEngine.d.ts +6 -0
- package/dist/components/background/FollowPointerParticle.d.ts +23 -0
- package/dist/components/background/JellyfishParticleEngine.d.ts +6 -0
- package/dist/components/background/NetParticleEngine.d.ts +6 -0
- package/dist/components/{Particle.d.ts → text/Particle.d.ts} +4 -2
- package/dist/components/{TextParticleEngine.d.ts → text/TextParticleEngine.d.ts} +3 -3
- package/dist/hooks/background/useParticleMovement.d.ts +5 -0
- package/dist/hooks/background/useParticleOrientation.d.ts +3 -0
- package/dist/hooks/background/useParticleScaling.d.ts +2 -0
- package/dist/hooks/background/usePointerTracking.d.ts +8 -0
- package/dist/hooks/{useTextParticles.d.ts → text/useTextParticles.d.ts} +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/jl-particle-interactive.js +700 -208
- package/dist/jl-particle-interactive.umd.cjs +1 -1
- package/dist/types/background.d.ts +16 -0
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# jl-particle-interactive
|
|
2
|
+
|
|
3
|
+
Particle animations for React — text that comes alive and backgrounds that react to your cursor.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install jl-particle-interactive
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> Requires React 18+. No global CSS. No extra dependencies.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## What it offers
|
|
18
|
+
|
|
19
|
+
| Feature | Description |
|
|
20
|
+
|---|---|
|
|
21
|
+
| **Text particles** | Thousands of particles that form any text string |
|
|
22
|
+
| **Magnetic hover** | Particles are attracted to the cursor on hover |
|
|
23
|
+
| **Click interactions** | Attract or repel particles on click/tap |
|
|
24
|
+
| **Animated backgrounds** | NET, JELLYFISH, and FOLLOW_POINTER modes |
|
|
25
|
+
| **Customizable** | Colors, shapes, density, speed, and more |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { ParticleCanvas, TextParticleEngine } from 'jl-particle-interactive';
|
|
33
|
+
|
|
34
|
+
export default function App() {
|
|
35
|
+
return (
|
|
36
|
+
<ParticleCanvas height="60vh">
|
|
37
|
+
<TextParticleEngine text="Hello" />
|
|
38
|
+
</ParticleCanvas>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Examples
|
|
46
|
+
|
|
47
|
+
### Text with a color palette
|
|
48
|
+
|
|
49
|
+
Assign multiple colors and each particle picks one at random.
|
|
50
|
+
|
|
51
|
+
```tsx
|
|
52
|
+
<ParticleCanvas height="60vh">
|
|
53
|
+
<TextParticleEngine
|
|
54
|
+
text="React"
|
|
55
|
+
particleColor={['#ff6b6b', '#feca57', '#48dbfb']}
|
|
56
|
+
particleSize={1.5}
|
|
57
|
+
/>
|
|
58
|
+
</ParticleCanvas>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
### Repel on click
|
|
64
|
+
|
|
65
|
+
Particles flee from the cursor while the mouse button is held down.
|
|
66
|
+
|
|
67
|
+
```tsx
|
|
68
|
+
<ParticleCanvas height="60vh">
|
|
69
|
+
<TextParticleEngine
|
|
70
|
+
text="Boom"
|
|
71
|
+
clickMode="repel"
|
|
72
|
+
particleEase={2}
|
|
73
|
+
/>
|
|
74
|
+
</ParticleCanvas>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### Attract on click
|
|
80
|
+
|
|
81
|
+
The opposite — particles swarm toward the cursor on press.
|
|
82
|
+
|
|
83
|
+
```tsx
|
|
84
|
+
<ParticleCanvas height="60vh">
|
|
85
|
+
<TextParticleEngine
|
|
86
|
+
text="Pull"
|
|
87
|
+
clickMode="attract"
|
|
88
|
+
isMagnet={false}
|
|
89
|
+
/>
|
|
90
|
+
</ParticleCanvas>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
### Animated NET background
|
|
96
|
+
|
|
97
|
+
A connected particle network moves behind your content.
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
<ParticleCanvas
|
|
101
|
+
height="80vh"
|
|
102
|
+
background={{
|
|
103
|
+
name: 'NET',
|
|
104
|
+
color: '#4ecdc4',
|
|
105
|
+
lineDistance: 120,
|
|
106
|
+
density: 0.8,
|
|
107
|
+
}}
|
|
108
|
+
>
|
|
109
|
+
<TextParticleEngine text="Network" particleColor="#ffffff" />
|
|
110
|
+
</ParticleCanvas>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
### Jellyfish background
|
|
116
|
+
|
|
117
|
+
Smooth, organic blobs that drift across the canvas.
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
<ParticleCanvas
|
|
121
|
+
height="80vh"
|
|
122
|
+
background={{
|
|
123
|
+
name: 'JELLYFISH',
|
|
124
|
+
colors: ['#ff6b6b', '#a29bfe', '#00cec9'],
|
|
125
|
+
colorMode: 'wave',
|
|
126
|
+
}}
|
|
127
|
+
>
|
|
128
|
+
<TextParticleEngine text="Fluid" particleColor="#ffffff" />
|
|
129
|
+
</ParticleCanvas>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### Dynamic text
|
|
135
|
+
|
|
136
|
+
Change the `text` prop and the particles re-form automatically.
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
const words = ['Hello', 'World', 'React'];
|
|
140
|
+
|
|
141
|
+
export default function Carousel() {
|
|
142
|
+
const [index, setIndex] = useState(0);
|
|
143
|
+
|
|
144
|
+
useEffect(() => {
|
|
145
|
+
const id = setInterval(() => setIndex(i => (i + 1) % words.length), 2000);
|
|
146
|
+
return () => clearInterval(id);
|
|
147
|
+
}, []);
|
|
148
|
+
|
|
149
|
+
return (
|
|
150
|
+
<ParticleCanvas height="60vh">
|
|
151
|
+
<TextParticleEngine text={words[index]} />
|
|
152
|
+
</ParticleCanvas>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## API reference
|
|
160
|
+
|
|
161
|
+
### `<ParticleCanvas>`
|
|
162
|
+
|
|
163
|
+
| Prop | Type | Default | Description |
|
|
164
|
+
|---|---|---|---|
|
|
165
|
+
| `width` | `string \| number` | `'100%'` | Container width |
|
|
166
|
+
| `height` | `string \| number` | `'60vh'` | Container height |
|
|
167
|
+
| `backgroundColor` | `string` | `'#050505'` | Background color |
|
|
168
|
+
| `background` | `BackgroundCanvas` | `{ name: 'NONE' }` | Animated background config |
|
|
169
|
+
| `className` | `string` | `''` | Additional CSS class |
|
|
170
|
+
| `style` | `CSSProperties` | — | Inline style overrides |
|
|
171
|
+
|
|
172
|
+
### `<TextParticleEngine>`
|
|
173
|
+
|
|
174
|
+
| Prop | Type | Default | Description |
|
|
175
|
+
|---|---|---|---|
|
|
176
|
+
| `text` | `string` | **required** | Text the particles form |
|
|
177
|
+
| `particleColor` | `string \| string[]` | `'255, 255, 255'` | RGB string or array of hex colors |
|
|
178
|
+
| `particleSize` | `number` | `1` | Size multiplier |
|
|
179
|
+
| `particleDensity` | `number` | `1` | Particle count multiplier |
|
|
180
|
+
| `particleEase` | `number` | `1` | Return speed multiplier |
|
|
181
|
+
| `isMagnet` | `boolean` | `true` | Hover attraction effect |
|
|
182
|
+
| `clickMode` | `'none' \| 'attract' \| 'repel'` | `'none'` | Click/tap interaction |
|
|
183
|
+
| `particleShape` | `'circle' \| 'square' \| 'bean'` | `'circle'` | Particle shape |
|
|
184
|
+
| `backgroundColor` | `string` | `'#050505'` | Canvas background (hex) |
|
|
185
|
+
|
|
186
|
+
> **Color note:** `particleColor` accepts `'R, G, B'` strings (e.g. `'255, 100, 50'`) or hex strings in an array (e.g. `['#ff0000', '#00ff00']`). Alpha is handled internally.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ReactNode, CSSProperties } from 'react';
|
|
2
|
+
import { BackgroundCanvas } from '../types/background';
|
|
2
3
|
export interface ParticleCanvasProps {
|
|
3
4
|
children?: ReactNode;
|
|
4
5
|
width?: string | number;
|
|
@@ -6,5 +7,6 @@ export interface ParticleCanvasProps {
|
|
|
6
7
|
backgroundColor?: string;
|
|
7
8
|
className?: string;
|
|
8
9
|
style?: CSSProperties;
|
|
10
|
+
background?: BackgroundCanvas;
|
|
9
11
|
}
|
|
10
|
-
export default function ParticleCanvas({ children, width, height, backgroundColor, className, style, }: ParticleCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export default function ParticleCanvas({ children, width, height, backgroundColor, className, style, background, }: ParticleCanvasProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BackgroundCanvas } from '../../types/background';
|
|
2
|
+
export interface BackgroundParticleEngineProps {
|
|
3
|
+
config: BackgroundCanvas;
|
|
4
|
+
backgroundColor: string;
|
|
5
|
+
}
|
|
6
|
+
export default function BackgroundParticleEngine({ config, backgroundColor }: BackgroundParticleEngineProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ParticleOrientation } from '../../types/background';
|
|
2
|
+
export declare class FollowPointerParticle {
|
|
3
|
+
x: number;
|
|
4
|
+
y: number;
|
|
5
|
+
baseX: number;
|
|
6
|
+
baseY: number;
|
|
7
|
+
z: number;
|
|
8
|
+
vx: number;
|
|
9
|
+
vy: number;
|
|
10
|
+
color: string;
|
|
11
|
+
targetColor: string | null;
|
|
12
|
+
colorDelay: number;
|
|
13
|
+
angleTarget: number;
|
|
14
|
+
randomSpeed: number;
|
|
15
|
+
sizeBias: number;
|
|
16
|
+
scale: number;
|
|
17
|
+
dirX: number;
|
|
18
|
+
dirY: number;
|
|
19
|
+
initialized: boolean;
|
|
20
|
+
constructor(relX: number, relY: number, color: string);
|
|
21
|
+
update(mouseX: number | null, mouseY: number | null, swarmX: number, swarmY: number, screenW: number, screenH: number, time: number, orientation?: ParticleOrientation): void;
|
|
22
|
+
draw(ctx: CanvasRenderingContext2D, time: number, shape?: 'circle' | 'square' | 'bean'): void;
|
|
23
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BackgroundCanvas } from '../../types/background';
|
|
2
|
+
export interface JellyfishParticleEngineProps {
|
|
3
|
+
config: BackgroundCanvas;
|
|
4
|
+
backgroundColor: string;
|
|
5
|
+
}
|
|
6
|
+
export default function JellyfishParticleEngine({ config, backgroundColor }: JellyfishParticleEngineProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { BackgroundCanvas } from '../../types/background';
|
|
2
|
+
export interface NetParticleEngineProps {
|
|
3
|
+
config: BackgroundCanvas;
|
|
4
|
+
backgroundColor: string;
|
|
5
|
+
}
|
|
6
|
+
export default function NetParticleEngine({ config, backgroundColor }: NetParticleEngineProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ClickMode } from '
|
|
1
|
+
import { ClickMode } from '../../hooks/useParticleInteraction';
|
|
2
|
+
import { ParticleShape } from '../../types';
|
|
2
3
|
export declare class Particle {
|
|
3
4
|
x: number;
|
|
4
5
|
y: number;
|
|
@@ -15,7 +16,8 @@ export declare class Particle {
|
|
|
15
16
|
easeMultiplier: number;
|
|
16
17
|
floatSpeed: number;
|
|
17
18
|
floatOffset: number;
|
|
19
|
+
randomSpeed: number;
|
|
18
20
|
constructor(w: number, h: number, color?: string | string[]);
|
|
19
21
|
update(time: number, isActive: boolean, mx?: number | null, my?: number | null, isMouseDown?: boolean, isMagnet?: boolean, clickMode?: ClickMode): void;
|
|
20
|
-
draw(ctx: CanvasRenderingContext2D, shape?:
|
|
22
|
+
draw(ctx: CanvasRenderingContext2D, shape?: ParticleShape, time?: number): void;
|
|
21
23
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ClickMode } from '
|
|
2
|
-
import { ParticleShape } from '
|
|
1
|
+
import { ClickMode } from '../../hooks/useParticleInteraction';
|
|
2
|
+
import { ParticleShape } from '../../types';
|
|
3
3
|
export interface TextParticleEngineProps {
|
|
4
4
|
text: string;
|
|
5
5
|
particleColor?: string | string[];
|
|
@@ -11,4 +11,4 @@ export interface TextParticleEngineProps {
|
|
|
11
11
|
particleShape?: ParticleShape;
|
|
12
12
|
backgroundColor?: string;
|
|
13
13
|
}
|
|
14
|
-
export default function TextParticleEngine({ text, particleColor, particleSize, particleDensity, particleEase, isMagnet, clickMode, particleShape, backgroundColor }: TextParticleEngineProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export default function TextParticleEngine({ text, particleColor, particleSize, particleDensity, particleEase, isMagnet, clickMode, particleShape, backgroundColor, }: TextParticleEngineProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { FollowPointerParticle } from '../../components/background/FollowPointerParticle';
|
|
2
|
+
import { ParticleOrientation } from '../../types/background';
|
|
3
|
+
export declare function useParticleOrientation(particle: FollowPointerParticle, dxCenter: number, dyCenter: number, distToCenter: number, orientation: ParticleOrientation, time: number): void;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { FollowPointerParticle } from '../../components/background/FollowPointerParticle';
|
|
2
|
+
export declare function usePointerTracking(particle: FollowPointerParticle, mouseX: number | null, mouseY: number | null, swarmX: number, swarmY: number, time: number): {
|
|
3
|
+
forceX: number;
|
|
4
|
+
forceY: number;
|
|
5
|
+
dxCenter: number;
|
|
6
|
+
dyCenter: number;
|
|
7
|
+
distToCenter: number;
|
|
8
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export { default as ParticleCanvas } from './components/ParticleCanvas';
|
|
2
2
|
export type { ParticleCanvasProps } from './components/ParticleCanvas';
|
|
3
|
-
export { default as TextParticleEngine } from './components/TextParticleEngine';
|
|
4
|
-
export type { TextParticleEngineProps } from './components/TextParticleEngine';
|
|
3
|
+
export { default as TextParticleEngine } from './components/text/TextParticleEngine';
|
|
4
|
+
export type { TextParticleEngineProps } from './components/text/TextParticleEngine';
|
|
5
5
|
export { useParticleInteraction, getMagnetTarget } from './hooks/useParticleInteraction';
|
|
6
6
|
export type { ClickMode } from './hooks/useParticleInteraction';
|
|
7
|
-
export { useTextParticles } from './hooks/useTextParticles';
|
|
7
|
+
export { useTextParticles } from './hooks/text/useTextParticles';
|
|
8
8
|
export type { ParticleShape, ColorMode } from './types';
|
|
9
|
+
export type { BackgroundModeName, BackgroundCanvas, ParticleOrientation } from './types/background';
|