react-confetti-burst 1.0.4 → 1.0.6

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 CHANGED
@@ -1,387 +1,532 @@
1
- # react-confetti-burst 🎉
2
-
3
- A high-performance, zero-dependency React confetti component with realistic particle physics using the native Canvas API.
4
-
5
- [![npm version](https://badge.fury.io/js/react-confetti-burst.svg)](https://badge.fury.io/js/react-confetti-burst)
6
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue)](https://www.typescriptlang.org/)
7
- [![Bundle Size](https://img.shields.io/bundlephobia/minzip/react-confetti-burst)](https://bundlephobia.com/package/react-confetti-burst)
8
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
-
10
- 🎮 **[Live Playground](https://ihakalanka.github.io/confetti-burst-playground/)** | 📦 **[GitHub](https://github.com/ihakalanka/react-confetti-burst)**
11
-
12
- ## Features
13
-
14
- - 🚀 **Zero dependencies** - Pure React + Canvas API
15
- - 🎯 **Directional bursts** - Up, down, left, right, radial, or custom angles
16
- - ⚡ **High performance** - Optimized canvas rendering with 60fps
17
- - 🎨 **Realistic physics** - Wobble, tilt, roll, and rotate effects
18
- - 📦 **Tiny bundle** - Minimal footprint
19
- - 🔷 **TypeScript first** - Full type safety built-in
20
- - ♿ **Accessible** - Respects `prefers-reduced-motion`
21
-
22
- ## Installation
23
-
24
- ```bash
25
- npm install react-confetti-burst
26
- # or
27
- yarn add react-confetti-burst
28
- # or
29
- pnpm add react-confetti-burst
30
- ```
31
-
32
- ## Quick Start
33
-
34
- ### The Simplest Way - ConfettiButton
35
-
36
- ```tsx
37
- import { ConfettiButton } from 'react-confetti-burst';
38
-
39
- function App() {
40
- return (
41
- <ConfettiButton>
42
- Click me! 🎉
43
- </ConfettiButton>
44
- );
45
- }
46
- ```
47
-
48
- ### Using the Hook - useConfetti
49
-
50
- ```tsx
51
- import { useConfetti } from 'react-confetti-burst';
52
-
53
- function App() {
54
- const { fire } = useConfetti();
55
-
56
- return (
57
- <button onClick={(e) => fire({ x: e.clientX, y: e.clientY })}>
58
- Celebrate!
59
- </button>
60
- );
61
- }
62
- ```
63
-
64
- ### Functional API - confetti()
65
-
66
- ```tsx
67
- import { confetti } from 'react-confetti-burst';
68
-
69
- // Basic burst from center
70
- confetti();
71
-
72
- // With options
73
- confetti({
74
- particleCount: 150,
75
- size: 4,
76
- spread: 70,
77
- origin: { x: 0.5, y: 0.5 }
78
- });
79
- ```
80
-
81
- ## confetti() Options
82
-
83
- | Option | Type | Default | Description |
84
- |--------|------|---------|-------------|
85
- | `particleCount` | `number` | `100` | Number of confetti particles to launch |
86
- | `size` | `number` | `4` | Base size of particles in pixels |
87
- | `angle` | `number` | `90` | Launch angle in degrees (90 = straight up) |
88
- | `spread` | `number` | `45` | Spread angle in degrees |
89
- | `startVelocity` | `number` | `45` | Initial velocity in pixels per frame |
90
- | `decay` | `number` | `0.94` | Speed decay factor (0-1) |
91
- | `gravity` | `number` | `1` | Gravity strength (1 = full, 0 = none) |
92
- | `drift` | `number` | `0` | Horizontal drift (-1 to 1) |
93
- | `ticks` | `number` | `200` | Animation duration in frames |
94
- | `origin` | `{ x, y }` | `{ x: 0.5, y: 0.5 }` | Origin position (0-1 coordinates) |
95
- | `colors` | `string[]` | Rainbow colors | Array of hex colors |
96
- | `shapes` | `string[]` | `['square', 'circle']` | Particle shapes |
97
- | `scalar` | `number` | `1` | Scale multiplier for particle size |
98
- | `flat` | `boolean` | `false` | Disable 3D effects (2D mode) |
99
- | `zIndex` | `number` | `100` | Canvas z-index |
100
- | `disableForReducedMotion` | `boolean` | `false` | Respect reduced motion preference |
101
-
102
- ## API Reference
103
-
104
- ### Components
105
-
106
- #### `<ConfettiButton>`
107
-
108
- A button that automatically fires confetti on click.
109
-
110
- ```tsx
111
- import { ConfettiButton } from 'react-confetti-burst';
112
-
113
- <ConfettiButton
114
- confettiOptions={{
115
- particleCount: 50,
116
- spread: 60,
117
- colors: ['#ff6b6b', '#4ecdc4', '#ffe66d'],
118
- }}
119
- >
120
- Click me!
121
- </ConfettiButton>
122
- ```
123
-
124
- **Props:**
125
- - `confettiOptions?: ConfettiBurstOptions` - Configuration for the confetti burst
126
- - `fireOnClick?: boolean` - Whether to fire on click (default: `true`)
127
- - All standard button HTML attributes
128
-
129
- #### `<ConfettiBurst>`
130
-
131
- Declarative component for conditional confetti.
132
-
133
- ```tsx
134
- import { ConfettiBurst } from 'react-confetti-burst';
135
-
136
- <ConfettiBurst
137
- active={showConfetti}
138
- origin={{ x: 500, y: 300 }}
139
- options={{ particleCount: 50 }}
140
- onComplete={() => setShowConfetti(false)}
141
- />
142
- ```
143
-
144
- ### Hooks
145
-
146
- #### `useConfetti()`
147
-
148
- The main hook for programmatic confetti control.
149
-
150
- ```tsx
151
- import { useConfetti } from 'react-confetti-burst';
152
-
153
- function App() {
154
- const { fire, fireFromElement, isActive, stopAll } = useConfetti();
155
-
156
- // Fire from a specific point
157
- const handleClick = (e: React.MouseEvent) => {
158
- fire({ x: e.clientX, y: e.clientY }, {
159
- particleCount: 50,
160
- direction: { direction: 'up', spread: 45 },
161
- });
162
- };
163
-
164
- // Fire from an element's center
165
- const buttonRef = useRef<HTMLButtonElement>(null);
166
- const handleButtonClick = () => {
167
- fireFromElement(buttonRef.current);
168
- };
169
-
170
- return (
171
- <>
172
- <div onClick={handleClick}>Click anywhere</div>
173
- <button ref={buttonRef} onClick={handleButtonClick}>
174
- Fire from me!
175
- </button>
176
- {isActive && <p>Animation running...</p>}
177
- <button onClick={stopAll}>Stop All</button>
178
- </>
179
- );
180
- }
181
- ```
182
-
183
- **Returns:**
184
- - `fire(origin, options?)` - Fire confetti from a point `{ x, y }`
185
- - `fireFromElement(element, options?)` - Fire from an element's center
186
- - `isActive` - Boolean indicating if any animation is running
187
- - `stopAll()` - Stop all active animations
188
-
189
- ### Functional API
190
-
191
- #### `confetti(options?)`
192
-
193
- Fire confetti imperatively from anywhere in your code.
194
-
195
- ```tsx
196
- import { confetti } from 'react-confetti-burst';
197
-
198
- // Simple burst
199
- confetti();
200
-
201
- // Customized burst
202
- confetti({
203
- particleCount: 100,
204
- spread: 70,
205
- origin: { x: 0.5, y: 0.5 },
206
- colors: ['#ff0000', '#00ff00', '#0000ff'],
207
- });
208
-
209
- // Directional burst
210
- confetti({
211
- particleCount: 50,
212
- direction: {
213
- direction: 'up',
214
- spread: 45,
215
- velocity: [20, 40],
216
- },
217
- });
218
- ```
219
-
220
- ## Configuration Options
221
-
222
- ### ConfettiBurstOptions (for React components/hooks)
223
-
224
- ```typescript
225
- interface ConfettiBurstOptions {
226
- // Number of particles (default: 100)
227
- particleCount?: number;
228
-
229
- // Base particle size in pixels (default: 4)
230
- size?: number;
231
-
232
- // Direction configuration
233
- direction?: {
234
- direction?: 'up' | 'down' | 'left' | 'right' | 'radial' | 'custom';
235
- angle?: number; // For 'custom' direction (degrees)
236
- spread?: number; // Spread angle (default: 45)
237
- velocity?: [number, number]; // Min/max velocity
238
- };
239
-
240
- // Particle appearance
241
- particle?: {
242
- size?: [number, number]; // Min/max size
243
- colors?: string[]; // Array of colors
244
- shapes?: ('square' | 'circle' | 'star' | 'triangle')[];
245
- opacity?: [number, number]; // Min/max opacity
246
- };
247
-
248
- // Physics
249
- physics?: {
250
- gravity?: number; // Gravity strength (default: 0.5)
251
- friction?: number; // Air friction (default: 0.99)
252
- wind?: number; // Horizontal wind force
253
- };
254
-
255
- // Lifecycle callbacks
256
- onStart?: () => void;
257
- onComplete?: () => void;
258
- }
259
- ```
260
-
261
- ## Particle Physics
262
-
263
- The confetti engine features realistic particle physics with four independent effects:
264
-
265
- - **Wobble** - Side-to-side sway like leaves falling
266
- - **Tilt** - 3D rotation creating a tumbling effect
267
- - **Roll** - Flip animation with darkening on the back side
268
- - **Rotate** - 2D spin around the z-axis
269
-
270
- Set `flat: true` to disable all 3D effects for a simpler 2D animation.
271
-
272
- ## Examples
273
-
274
- ### Directional Bursts
275
-
276
- ```tsx
277
- import { useConfetti } from 'react-confetti-burst';
278
-
279
- function DirectionalExample() {
280
- const { fire } = useConfetti();
281
-
282
- const fireUp = () => fire({ x: 400, y: 500 }, {
283
- direction: { direction: 'up', spread: 30 },
284
- });
285
-
286
- const fireRadial = () => fire({ x: 400, y: 300 }, {
287
- direction: { direction: 'radial' },
288
- });
289
-
290
- return (
291
- <>
292
- <button onClick={fireUp}>Fire Up ⬆️</button>
293
- <button onClick={fireRadial}>Radial Burst 💥</button>
294
- </>
295
- );
296
- }
297
- ```
298
-
299
- ### Custom Colors
300
-
301
- ```tsx
302
- <ConfettiButton
303
- confettiOptions={{
304
- particle: {
305
- colors: ['#FFD700', '#FF6B6B', '#4ECDC4', '#45B7D1'],
306
- },
307
- }}
308
- >
309
- Golden Burst ✨
310
- </ConfettiButton>
311
- ```
312
-
313
- ### Form Submission Success
314
-
315
- ```tsx
316
- import { confetti } from 'react-confetti-burst';
317
-
318
- async function handleSubmit(data: FormData) {
319
- const response = await submitForm(data);
320
-
321
- if (response.success) {
322
- confetti({
323
- particleCount: 150,
324
- size: 5,
325
- spread: 70,
326
- origin: { x: 0.5, y: 0.6 },
327
- });
328
- }
329
- }
330
- ```
331
-
332
- ### Firework Effect
333
-
334
- ```tsx
335
- import { confetti } from 'react-confetti-burst';
336
-
337
- // Built-in fireworks preset
338
- confetti.fireworks();
339
-
340
- // Or customize
341
- confetti.fireworks({
342
- particleCount: 50,
343
- colors: ['#ff0000', '#ffff00', '#00ff00'],
344
- });
345
- ```
346
-
347
- ### School Pride (Two-sided burst)
348
-
349
- ```tsx
350
- import { confetti } from 'react-confetti-burst';
351
-
352
- confetti.schoolPride({
353
- colors: ['#bb0000', '#ffffff'], // Your school colors
354
- });
355
- ```
356
-
357
- ### Snow Effect
358
-
359
- ```tsx
360
- import { confetti } from 'react-confetti-burst';
361
-
362
- confetti.snow({
363
- duration: 5000, // 5 seconds
364
- colors: ['#ffffff', '#e0e0e0'],
365
- });
366
- ```
367
-
368
- ## Browser Support
369
-
370
- - Chrome 60+
371
- - Firefox 55+
372
- - Safari 11+
373
- - Edge 79+
374
-
375
- ## Support
376
-
377
- If you find this package helpful, consider buying me a coffee! ☕
378
-
379
- <p><a href="https://www.buymeacoffee.com/akalankaih4"> <img align="left" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="akalankaih4" /></a></p><br><br>
380
-
381
- ## License
382
-
383
- MIT © [ihakalanka](https://github.com/ihakalanka)
384
-
385
- ## Contributing
386
-
387
- Contributions are welcome! Please read our [contributing guidelines](https://github.com/ihakalanka/react-confetti-burst/blob/main/CONTRIBUTING.md) before submitting a PR.
1
+ # react-confetti-burst 🎉
2
+
3
+ A high-performance, zero-dependency React confetti component with realistic particle physics using the native Canvas API.
4
+
5
+ [![npm version](https://badge.fury.io/js/react-confetti-burst.svg)](https://badge.fury.io/js/react-confetti-burst)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0%2B-blue)](https://www.typescriptlang.org/)
7
+ [![Bundle Size](https://img.shields.io/bundlephobia/minzip/react-confetti-burst)](https://bundlephobia.com/package/react-confetti-burst)
8
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
+
10
+ 🎮 **[Live Playground](https://ihakalanka.github.io/confetti-burst-playground/)** | 📦 **[GitHub](https://github.com/ihakalanka/react-confetti-burst)**
11
+
12
+ ## Features
13
+
14
+ - 🚀 **Zero dependencies** - Pure React + Canvas API
15
+ - 🎯 **Directional bursts** - Up, down, left, right, radial, or custom angles
16
+ - ⚡ **High performance** - Optimized canvas rendering with 60fps
17
+ - 🎨 **Realistic physics** - Wobble, tilt, roll, and rotate effects
18
+ - 📦 **Tiny bundle** - Tree-shakable presets for optimal bundle size
19
+ - 🔷 **TypeScript first** - Full type safety built-in
20
+ - ♿ **Accessible** - Respects `prefers-reduced-motion`
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ npm install react-confetti-burst
26
+ # or
27
+ yarn add react-confetti-burst
28
+ # or
29
+ pnpm add react-confetti-burst
30
+ ```
31
+
32
+ ## Quick Start
33
+
34
+ ### The Simplest Way - ConfettiButton
35
+
36
+ ```tsx
37
+ import { ConfettiButton } from 'react-confetti-burst';
38
+
39
+ function App() {
40
+ return (
41
+ <ConfettiButton>
42
+ Click me! 🎉
43
+ </ConfettiButton>
44
+ );
45
+ }
46
+ ```
47
+
48
+ ### Using the Hook - useConfetti
49
+
50
+ ```tsx
51
+ import { useConfetti } from 'react-confetti-burst';
52
+
53
+ function App() {
54
+ const { fire } = useConfetti();
55
+
56
+ return (
57
+ <button onClick={(e) => fire({ x: e.clientX, y: e.clientY })}>
58
+ Celebrate!
59
+ </button>
60
+ );
61
+ }
62
+ ```
63
+
64
+ ### Functional API - confetti()
65
+
66
+ ```tsx
67
+ import { confetti } from 'react-confetti-burst';
68
+
69
+ // Basic burst from center
70
+ confetti();
71
+
72
+ // With options
73
+ confetti({
74
+ particleCount: 150,
75
+ size: 4,
76
+ spread: 70,
77
+ origin: { x: 0.5, y: 0.5 }
78
+ });
79
+ ```
80
+
81
+ ## confetti() Options
82
+
83
+ | Option | Type | Default | Description |
84
+ |--------|------|---------|-------------|
85
+ | `particleCount` | `number` | `100` | Number of confetti particles to launch |
86
+ | `size` | `number` | `4` | Base size of particles in pixels |
87
+ | `angle` | `number` | `90` | Launch angle in degrees (90 = straight up) |
88
+ | `spread` | `number` | `45` | Spread angle in degrees |
89
+ | `startVelocity` | `number` | `45` | Initial velocity in pixels per frame |
90
+ | `decay` | `number` | `0.94` | Speed decay factor (0-1) |
91
+ | `gravity` | `number` | `1` | Gravity strength (1 = full, 0 = none) |
92
+ | `drift` | `number` | `0` | Horizontal drift (-1 to 1) |
93
+ | `ticks` | `number` | `200` | Animation duration in frames |
94
+ | `origin` | `{ x, y }` | `{ x: 0.5, y: 0.5 }` | Origin position (0-1 coordinates) |
95
+ | `colors` | `string[]` | Rainbow colors | Array of hex colors |
96
+ | `shapes` | `string[]` | `['square', 'circle']` | Particle shapes |
97
+ | `scalar` | `number` | `1` | Scale multiplier for particle size |
98
+ | `flat` | `boolean` | `false` | Disable 3D effects (2D mode) |
99
+ | `zIndex` | `number` | `100` | Canvas z-index |
100
+ | `disableForReducedMotion` | `boolean` | `false` | Respect reduced motion preference |
101
+
102
+ ## API Reference
103
+
104
+ ### Components
105
+
106
+ #### `<ConfettiButton>`
107
+
108
+ A button that automatically fires confetti on click.
109
+
110
+ ```tsx
111
+ import { ConfettiButton } from 'react-confetti-burst';
112
+
113
+ <ConfettiButton
114
+ confettiOptions={{
115
+ particleCount: 50,
116
+ spread: 60,
117
+ colors: ['#ff6b6b', '#4ecdc4', '#ffe66d'],
118
+ }}
119
+ >
120
+ Click me!
121
+ </ConfettiButton>
122
+ ```
123
+
124
+ **Props:**
125
+ - `confettiOptions?: ConfettiBurstOptions` - Configuration for the confetti burst
126
+ - `fireOnClick?: boolean` - Whether to fire on click (default: `true`)
127
+ - All standard button HTML attributes
128
+
129
+ #### `<ConfettiBurst>`
130
+
131
+ Declarative component for conditional confetti.
132
+
133
+ ```tsx
134
+ import { ConfettiBurst } from 'react-confetti-burst';
135
+
136
+ <ConfettiBurst
137
+ active={showConfetti}
138
+ origin={{ x: 500, y: 300 }}
139
+ options={{ particleCount: 50 }}
140
+ onComplete={() => setShowConfetti(false)}
141
+ />
142
+ ```
143
+
144
+ ### Hooks
145
+
146
+ #### `useConfetti()`
147
+
148
+ The main hook for programmatic confetti control.
149
+
150
+ ```tsx
151
+ import { useConfetti } from 'react-confetti-burst';
152
+
153
+ function App() {
154
+ const { fire, fireFromElement, isActive, stopAll } = useConfetti();
155
+
156
+ // Fire from a specific point
157
+ const handleClick = (e: React.MouseEvent) => {
158
+ fire({ x: e.clientX, y: e.clientY }, {
159
+ particleCount: 50,
160
+ direction: { direction: 'up', spread: 45 },
161
+ });
162
+ };
163
+
164
+ // Fire from an element's center
165
+ const buttonRef = useRef<HTMLButtonElement>(null);
166
+ const handleButtonClick = () => {
167
+ fireFromElement(buttonRef.current);
168
+ };
169
+
170
+ return (
171
+ <>
172
+ <div onClick={handleClick}>Click anywhere</div>
173
+ <button ref={buttonRef} onClick={handleButtonClick}>
174
+ Fire from me!
175
+ </button>
176
+ {isActive && <p>Animation running...</p>}
177
+ <button onClick={stopAll}>Stop All</button>
178
+ </>
179
+ );
180
+ }
181
+ ```
182
+
183
+ **Returns:**
184
+ - `fire(origin, options?)` - Fire confetti from a point `{ x, y }`
185
+ - `fireFromElement(element, options?)` - Fire from an element's center
186
+ - `isActive` - Boolean indicating if any animation is running
187
+ - `stopAll()` - Stop all active animations
188
+
189
+ ### Functional API
190
+
191
+ #### `confetti(options?)`
192
+
193
+ Fire confetti imperatively from anywhere in your code.
194
+
195
+ ```tsx
196
+ import { confetti } from 'react-confetti-burst';
197
+
198
+ // Simple burst
199
+ confetti();
200
+
201
+ // Customized burst
202
+ confetti({
203
+ particleCount: 100,
204
+ spread: 70,
205
+ origin: { x: 0.5, y: 0.5 },
206
+ colors: ['#ff0000', '#00ff00', '#0000ff'],
207
+ });
208
+
209
+ // Directional burst
210
+ confetti({
211
+ particleCount: 50,
212
+ direction: {
213
+ direction: 'up',
214
+ spread: 45,
215
+ velocity: [20, 40],
216
+ },
217
+ });
218
+ ```
219
+
220
+ ## Configuration Options
221
+
222
+ ### ConfettiBurstOptions (for React components/hooks)
223
+
224
+ ```typescript
225
+ interface ConfettiBurstOptions {
226
+ // Number of particles (default: 100)
227
+ particleCount?: number;
228
+
229
+ // Base particle size in pixels (default: 4)
230
+ size?: number;
231
+
232
+ // Direction configuration
233
+ direction?: {
234
+ direction?: 'up' | 'down' | 'left' | 'right' | 'radial' | 'custom';
235
+ angle?: number; // For 'custom' direction (degrees)
236
+ spread?: number; // Spread angle (default: 45)
237
+ velocity?: [number, number]; // Min/max velocity
238
+ };
239
+
240
+ // Particle appearance
241
+ particle?: {
242
+ size?: [number, number]; // Min/max size
243
+ colors?: string[]; // Array of colors
244
+ shapes?: ('square' | 'circle' | 'star' | 'triangle')[];
245
+ opacity?: [number, number]; // Min/max opacity
246
+ };
247
+
248
+ // Physics
249
+ physics?: {
250
+ gravity?: number; // Gravity strength (default: 0.5)
251
+ friction?: number; // Air friction (default: 0.99)
252
+ wind?: number; // Horizontal wind force
253
+ };
254
+
255
+ // Lifecycle callbacks
256
+ onStart?: () => void;
257
+ onComplete?: () => void;
258
+ }
259
+ ```
260
+
261
+ ## Particle Physics
262
+
263
+ The confetti engine features realistic particle physics with four independent effects:
264
+
265
+ - **Wobble** - Side-to-side sway like leaves falling
266
+ - **Tilt** - 3D rotation creating a tumbling effect
267
+ - **Roll** - Flip animation with darkening on the back side
268
+ - **Rotate** - 2D spin around the z-axis
269
+
270
+ Set `flat: true` to disable all 3D effects for a simpler 2D animation.
271
+
272
+ ## Examples
273
+
274
+ ### Directional Bursts
275
+
276
+ ```tsx
277
+ import { useConfetti } from 'react-confetti-burst';
278
+
279
+ function DirectionalExample() {
280
+ const { fire } = useConfetti();
281
+
282
+ const fireUp = () => fire({ x: 400, y: 500 }, {
283
+ direction: { direction: 'up', spread: 30 },
284
+ });
285
+
286
+ const fireRadial = () => fire({ x: 400, y: 300 }, {
287
+ direction: { direction: 'radial' },
288
+ });
289
+
290
+ return (
291
+ <>
292
+ <button onClick={fireUp}>Fire Up ⬆️</button>
293
+ <button onClick={fireRadial}>Radial Burst 💥</button>
294
+ </>
295
+ );
296
+ }
297
+ ```
298
+
299
+ ### Custom Colors
300
+
301
+ ```tsx
302
+ <ConfettiButton
303
+ confettiOptions={{
304
+ particle: {
305
+ colors: ['#FFD700', '#FF6B6B', '#4ECDC4', '#45B7D1'],
306
+ },
307
+ }}
308
+ >
309
+ Golden Burst ✨
310
+ </ConfettiButton>
311
+ ```
312
+
313
+ ### Form Submission Success
314
+
315
+ ```tsx
316
+ import { confetti } from 'react-confetti-burst';
317
+
318
+ async function handleSubmit(data: FormData) {
319
+ const response = await submitForm(data);
320
+
321
+ if (response.success) {
322
+ confetti({
323
+ particleCount: 150,
324
+ size: 5,
325
+ spread: 70,
326
+ origin: { x: 0.5, y: 0.6 },
327
+ });
328
+ }
329
+ }
330
+ ```
331
+
332
+ ### Firework Effect
333
+
334
+ ```tsx
335
+ import { confetti } from 'react-confetti-burst';
336
+
337
+ // Built-in fireworks preset
338
+ confetti.fireworks();
339
+
340
+ // Or customize
341
+ confetti.fireworks({
342
+ particleCount: 50,
343
+ colors: ['#ff0000', '#ffff00', '#00ff00'],
344
+ });
345
+ ```
346
+
347
+ ### School Pride (Two-sided burst)
348
+
349
+ ```tsx
350
+ import { confetti } from 'react-confetti-burst';
351
+
352
+ confetti.schoolPride({
353
+ colors: ['#bb0000', '#ffffff'], // Your school colors
354
+ });
355
+ ```
356
+
357
+ ### Snow Effect
358
+
359
+ ```tsx
360
+ import { confetti } from 'react-confetti-burst';
361
+
362
+ confetti.snow({
363
+ duration: 5000, // 5 seconds
364
+ colors: ['#ffffff', '#e0e0e0'],
365
+ });
366
+ ```
367
+
368
+ ## Presets
369
+
370
+ 16 built-in presets for quick setup:
371
+
372
+ ```tsx
373
+ import { getPreset, getPresetNames, confetti } from 'react-confetti-burst';
374
+
375
+ // List all available presets
376
+ console.log(getPresetNames());
377
+ // ['default', 'celebration', 'firework', 'snow', 'rain', 'sparkle',
378
+ // 'confetti', 'emoji', 'hearts', 'stars', 'money', 'pride',
379
+ // 'christmas', 'halloween', 'newYear', 'birthday']
380
+
381
+ // Use a preset with the React hook
382
+ const { fire } = useConfetti();
383
+ const preset = getPreset('celebration');
384
+ fire({ x: 500, y: 300 }, preset.options);
385
+ ```
386
+
387
+ | Preset | Description |
388
+ |--------|-------------|
389
+ | `default` | Balanced burst with realistic paper physics |
390
+ | `celebration` | Big party with lots of colorful confetti |
391
+ | `firework` | Firework explosion with secondary bursts |
392
+ | `snow` | Gentle falling snowflakes |
393
+ | `rain` | Rainfall effect |
394
+ | `sparkle` | Sparkling gold stars with glow |
395
+ | `confetti` | Classic continuous falling confetti |
396
+ | `emoji` | Emoji celebration (🎉🎊🥳✨🎈) |
397
+ | `hearts` | Floating hearts |
398
+ | `stars` | Shooting stars |
399
+ | `money` | Money rain (💰💵💸🤑💎) |
400
+ | `pride` | Rainbow pride celebration |
401
+ | `christmas` | Christmas themed (🎄🎅🎁❄️⭐) |
402
+ | `halloween` | Spooky Halloween (🎃👻🦇🕷️💀) |
403
+ | `newYear` | New Year fireworks |
404
+ | `birthday` | Birthday party (🎂🎁🎈🎉🥳) |
405
+
406
+ ## Custom Shapes
407
+
408
+ Create confetti with custom SVG paths, text, or emoji:
409
+
410
+ ```tsx
411
+ import { shapeFromPath, shapeFromText, shapesFromEmoji } from 'react-confetti-burst';
412
+
413
+ // SVG path shape
414
+ const star = shapeFromPath({
415
+ path: 'M0,-1 L0.588,0.809 L-0.951,-0.309 L0.951,-0.309 L-0.588,0.809 Z',
416
+ });
417
+
418
+ // Text/emoji shape
419
+ const heart = shapeFromText({ text: '❤️', scalar: 2 });
420
+
421
+ // Multiple emoji shapes
422
+ const partyEmoji = shapesFromEmoji(['🎉', '🎊', '✨', '🥳']);
423
+
424
+ // Use with confetti
425
+ fire({ x: 500, y: 300 }, {
426
+ particle: { shapes: [star, heart, ...partyEmoji] },
427
+ });
428
+ ```
429
+
430
+ ## Advanced Physics Configuration
431
+
432
+ Fine-tune particle behavior:
433
+
434
+ ```tsx
435
+ fire({ x: 500, y: 300 }, {
436
+ physics: {
437
+ gravity: 0.5, // Lower = floatier
438
+ drag: 0.05, // Air resistance
439
+ wind: 0.3, // Horizontal wind
440
+ windVariation: 0.1, // Wind randomness
441
+ wobble: true, // 3D wobble effect
442
+ wobbleSpeed: 2, // Wobble oscillation speed
443
+ flutter: true, // Paper-like flutter
444
+ flutterIntensity: 0.4, // Flutter strength
445
+ bounce: 0.5, // Floor bounce factor
446
+ floor: 600, // Y position of floor
447
+ },
448
+ });
449
+ ```
450
+
451
+ ## Performance Tips
452
+
453
+ - Keep `particleCount` under 200 for mobile devices
454
+ - Use `setMaxPoolSize()` to control memory usage
455
+ - Shapes like `'circle'` and `'square'` render faster than `'star'` or `'heart'`
456
+ - Set `flat: true` to disable 3D effects for better performance
457
+ - The library automatically caps device pixel ratio at 2x
458
+ - Particles are automatically culled when they leave the viewport
459
+
460
+ ## Browser Standalone (CDN)
461
+
462
+ Use without React via the IIFE browser build:
463
+
464
+ ```html
465
+ <script src="https://unpkg.com/react-confetti-burst/dist/confetti.browser.js"></script>
466
+ <script>
467
+ // Global `confetti` function is available
468
+ confetti({ particleCount: 100, spread: 70 });
469
+ </script>
470
+ ```
471
+
472
+ Or import via package exports:
473
+
474
+ ```js
475
+ import confetti from 'react-confetti-burst/browser';
476
+ ```
477
+
478
+ ## Migration from canvas-confetti
479
+
480
+ The `confetti()` function is API-compatible with canvas-confetti:
481
+
482
+ ```tsx
483
+ // canvas-confetti
484
+ import confetti from 'canvas-confetti';
485
+ confetti({ particleCount: 100, spread: 70 });
486
+
487
+ // react-confetti-burst (same API!)
488
+ import { confetti } from 'react-confetti-burst';
489
+ confetti({ particleCount: 100, spread: 70 });
490
+
491
+ // Additional methods
492
+ confetti.fireworks();
493
+ confetti.schoolPride({ colors: ['#bb0000', '#ffffff'] });
494
+ confetti.snow({ duration: 5000 });
495
+ confetti.burst({ x: 0.5, y: 0.3 });
496
+ confetti.reset();
497
+ ```
498
+
499
+ ## FAQ
500
+
501
+ **Q: Does it work with SSR/Next.js?**
502
+ A: Yes. All DOM access is guarded by `isBrowser()` checks. The library is safe to import in server environments.
503
+
504
+ **Q: Why doesn't confetti appear?**
505
+ A: Check if `prefers-reduced-motion` is enabled in your OS settings. The library respects this accessibility preference and will silently skip animations.
506
+
507
+ **Q: How do I control memory usage?**
508
+ A: Use `setMaxPoolSize(n)` to limit the particle object pool. The default is 500. Call `forceCleanup()` to immediately release all resources.
509
+
510
+ **Q: Can I use it without React?**
511
+ A: Yes! Use the browser standalone build (`dist/confetti.browser.js`) or the `confetti()` functional API which doesn't require React components.
512
+
513
+ ## Browser Support
514
+
515
+ - Chrome 60+
516
+ - Firefox 55+
517
+ - Safari 11+
518
+ - Edge 79+
519
+
520
+ ## Support
521
+
522
+ If you find this package helpful, consider buying me a coffee! ☕
523
+
524
+ <p><a href="https://www.buymeacoffee.com/akalankaih4"> <img align="left" src="https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png" height="50" width="210" alt="akalankaih4" /></a></p><br><br>
525
+
526
+ ## License
527
+
528
+ MIT © [ihakalanka](https://github.com/ihakalanka)
529
+
530
+ ## Contributing
531
+
532
+ Contributions are welcome! Please read our [contributing guidelines](https://github.com/ihakalanka/react-confetti-burst/blob/main/CONTRIBUTING.md) before submitting a PR.