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 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 '../hooks/useParticleInteraction';
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?: 'circle' | 'square'): void;
22
+ draw(ctx: CanvasRenderingContext2D, shape?: ParticleShape, time?: number): void;
21
23
  }
@@ -1,5 +1,5 @@
1
- import { ClickMode } from '../hooks/useParticleInteraction';
2
- import { ParticleShape } from '../types';
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,5 @@
1
+ import { FollowPointerParticle } from '../../components/background/FollowPointerParticle';
2
+ export declare function useParticleMovement(particle: FollowPointerParticle, swarmX: number, swarmY: number, time: number): {
3
+ forceX: number;
4
+ forceY: number;
5
+ };
@@ -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,2 @@
1
+ import { FollowPointerParticle } from '../../components/background/FollowPointerParticle';
2
+ export declare function useParticleScaling(particle: FollowPointerParticle, distToCenter: 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
+ };
@@ -1,5 +1,5 @@
1
1
  import { default as React } from 'react';
2
- import { Particle } from '../components/Particle';
2
+ import { Particle } from '../../components/text/Particle';
3
3
  declare function getPixelsForText(text: string, width: number, height: number): {
4
4
  x: number;
5
5
  y: number;
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';