partycles 0.1.0 → 0.3.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.
Files changed (93) hide show
  1. package/README.md +143 -5
  2. package/dist/animations/animations/aurora.d.ts +8 -0
  3. package/dist/animations/animations/aurora.d.ts.map +1 -0
  4. package/dist/animations/animations/balloons.d.ts +8 -0
  5. package/dist/animations/animations/balloons.d.ts.map +1 -0
  6. package/dist/animations/animations/coins.d.ts +8 -0
  7. package/dist/animations/animations/coins.d.ts.map +1 -0
  8. package/dist/animations/animations/emoji.d.ts +19 -0
  9. package/dist/animations/animations/emoji.d.ts.map +1 -0
  10. package/dist/animations/animations/fireflies.d.ts +8 -0
  11. package/dist/animations/animations/fireflies.d.ts.map +1 -0
  12. package/dist/animations/animations/galaxy.d.ts +8 -0
  13. package/dist/animations/animations/galaxy.d.ts.map +1 -0
  14. package/dist/animations/animations/index.d.ts.map +1 -1
  15. package/dist/animations/animations/lightning.d.ts +8 -0
  16. package/dist/animations/animations/lightning.d.ts.map +1 -0
  17. package/dist/animations/animations/music.d.ts +8 -0
  18. package/dist/animations/animations/music.d.ts.map +1 -0
  19. package/dist/animations/animations/paint.d.ts +8 -0
  20. package/dist/animations/animations/paint.d.ts.map +1 -0
  21. package/dist/animations/animations/petals.d.ts +8 -0
  22. package/dist/animations/animations/petals.d.ts.map +1 -0
  23. package/dist/animations/animations/snow.d.ts +8 -0
  24. package/dist/animations/animations/snow.d.ts.map +1 -0
  25. package/dist/animations/aurora.d.ts +8 -0
  26. package/dist/animations/aurora.d.ts.map +1 -0
  27. package/dist/animations/balloons.d.ts +8 -0
  28. package/dist/animations/balloons.d.ts.map +1 -0
  29. package/dist/animations/bubbles.esm.js +3 -3
  30. package/dist/animations/bubbles.esm.js.map +1 -1
  31. package/dist/animations/bubbles.js +3 -3
  32. package/dist/animations/bubbles.js.map +1 -1
  33. package/dist/animations/coins.d.ts +8 -0
  34. package/dist/animations/coins.d.ts.map +1 -0
  35. package/dist/animations/confetti.esm.js +1 -1
  36. package/dist/animations/confetti.esm.js.map +1 -1
  37. package/dist/animations/confetti.js +1 -1
  38. package/dist/animations/confetti.js.map +1 -1
  39. package/dist/animations/emoji.d.ts +19 -0
  40. package/dist/animations/emoji.d.ts.map +1 -0
  41. package/dist/animations/emoji.esm.js +58 -0
  42. package/dist/animations/emoji.esm.js.map +1 -0
  43. package/dist/animations/emoji.js +62 -0
  44. package/dist/animations/emoji.js.map +1 -0
  45. package/dist/animations/fireflies.d.ts +8 -0
  46. package/dist/animations/fireflies.d.ts.map +1 -0
  47. package/dist/animations/fireworks.esm.js +1 -1
  48. package/dist/animations/fireworks.esm.js.map +1 -1
  49. package/dist/animations/fireworks.js +1 -1
  50. package/dist/animations/fireworks.js.map +1 -1
  51. package/dist/animations/galaxy.d.ts +8 -0
  52. package/dist/animations/galaxy.d.ts.map +1 -0
  53. package/dist/animations/hearts.esm.js +1 -1
  54. package/dist/animations/hearts.esm.js.map +1 -1
  55. package/dist/animations/hearts.js +1 -1
  56. package/dist/animations/hearts.js.map +1 -1
  57. package/dist/animations/index.d.ts +1 -0
  58. package/dist/animations/index.d.ts.map +1 -1
  59. package/dist/animations/lightning.d.ts +8 -0
  60. package/dist/animations/lightning.d.ts.map +1 -0
  61. package/dist/animations/music.d.ts +8 -0
  62. package/dist/animations/music.d.ts.map +1 -0
  63. package/dist/animations/paint.d.ts +8 -0
  64. package/dist/animations/paint.d.ts.map +1 -0
  65. package/dist/animations/petals.d.ts +8 -0
  66. package/dist/animations/petals.d.ts.map +1 -0
  67. package/dist/animations/snow.d.ts +8 -0
  68. package/dist/animations/snow.d.ts.map +1 -0
  69. package/dist/animations/snow.esm.js +48 -0
  70. package/dist/animations/snow.esm.js.map +1 -0
  71. package/dist/animations/snow.js +51 -0
  72. package/dist/animations/snow.js.map +1 -0
  73. package/dist/animations/sparkles.esm.js +1 -1
  74. package/dist/animations/sparkles.esm.js.map +1 -1
  75. package/dist/animations/sparkles.js +1 -1
  76. package/dist/animations/sparkles.js.map +1 -1
  77. package/dist/animations/stars.esm.js +1 -1
  78. package/dist/animations/stars.esm.js.map +1 -1
  79. package/dist/animations/stars.js +1 -1
  80. package/dist/animations/stars.js.map +1 -1
  81. package/dist/animations/types.d.ts +1 -1
  82. package/dist/animations/types.d.ts.map +1 -1
  83. package/dist/animations/useReward.d.ts.map +1 -1
  84. package/dist/index.d.ts +1 -0
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.esm.js +769 -10
  87. package/dist/index.esm.js.map +1 -1
  88. package/dist/index.js +769 -9
  89. package/dist/index.js.map +1 -1
  90. package/dist/types.d.ts +1 -1
  91. package/dist/types.d.ts.map +1 -1
  92. package/dist/useReward.d.ts.map +1 -1
  93. package/package.json +1 -1
package/dist/index.esm.js CHANGED
@@ -28,7 +28,7 @@ const createParticleStyle = (particle, containerRect) => {
28
28
 
29
29
  const defaultColors = ['#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4caf50', '#8bc34a', '#cddc39', '#ffeb3b', '#ffc107', '#ff9800', '#ff5722'];
30
30
  const createConfettiParticles = (origin, config) => {
31
- const { particleCount = 50, startVelocity = 55, colors = defaultColors, elementSize = 20 } = config;
31
+ const { particleCount = 50, startVelocity = 20, colors = defaultColors, elementSize = 20 } = config;
32
32
  const particles = [];
33
33
  for (let i = 0; i < particleCount; i++) {
34
34
  const angle = randomInRange(0, 360);
@@ -60,7 +60,7 @@ const renderConfettiParticle = (particle) => {
60
60
  };
61
61
 
62
62
  const createSparkleParticles = (origin, config) => {
63
- const { particleCount = 35, spread = 120, startVelocity = 45, elementSize = 25, colors = ['#FFD700', '#FFFFFF'] } = config;
63
+ const { particleCount = 35, spread = 120, startVelocity = 15, elementSize = 25, colors = ['#FFD700', '#FFFFFF'] } = config;
64
64
  const particles = [];
65
65
  for (let i = 0; i < particleCount; i++) {
66
66
  const velocityScale = startVelocity / 45; // Scale based on default
@@ -90,7 +90,7 @@ const renderSparkleParticle = (particle) => {
90
90
 
91
91
  const heartColors = ['#ff1744', '#e91e63', '#ff4569', '#ff6b6b', '#ee5a70'];
92
92
  const createHeartParticles = (origin, config) => {
93
- const { particleCount = 25, startVelocity = 30, colors = heartColors, elementSize = 30 } = config;
93
+ const { particleCount = 25, startVelocity = 12, colors = heartColors, elementSize = 30 } = config;
94
94
  const particles = [];
95
95
  for (let i = 0; i < particleCount; i++) {
96
96
  const angle = randomInRange(-45, -135);
@@ -120,7 +120,7 @@ const renderHeartParticle = (particle) => {
120
120
 
121
121
  const fireworkColors = ['#ff0000', '#00ff00', '#0000ff', '#ffff00', '#ff00ff', '#00ffff', '#ffffff'];
122
122
  const createFireworkParticles = (origin, config) => {
123
- const { particleCount = 60, startVelocity = 50, colors = fireworkColors, elementSize = 8 } = config;
123
+ const { particleCount = 60, startVelocity = 25, colors = fireworkColors, elementSize = 8 } = config;
124
124
  const particles = [];
125
125
  for (let i = 0; i < particleCount; i++) {
126
126
  const angle = (360 / particleCount) * i + randomInRange(-5, 5);
@@ -159,15 +159,15 @@ const renderFireworkParticle = (particle) => {
159
159
 
160
160
  const bubbleColors = ['rgba(66, 165, 245, 0.4)', 'rgba(41, 182, 246, 0.4)', 'rgba(38, 198, 218, 0.4)', 'rgba(129, 212, 250, 0.4)'];
161
161
  const createBubbleParticles = (origin, config) => {
162
- const { particleCount = 30, spread = 80, startVelocity = 30, colors = bubbleColors, elementSize = 40 } = config;
162
+ const { particleCount = 30, spread = 80, startVelocity = 8, colors = bubbleColors, elementSize = 40 } = config;
163
163
  const particles = [];
164
164
  for (let i = 0; i < particleCount; i++) {
165
165
  particles.push({
166
166
  id: generateId(),
167
167
  x: origin.x + randomInRange(-spread, spread),
168
168
  y: origin.y,
169
- vx: randomInRange(-3, 3),
170
- vy: -randomInRange(startVelocity * 0.7, startVelocity * 1.2),
169
+ vx: randomInRange(-2, 2),
170
+ vy: -randomInRange(startVelocity * 0.3, startVelocity * 0.6),
171
171
  life: config.lifetime || 160,
172
172
  opacity: 0.7,
173
173
  size: randomInRange(elementSize * 0.4, elementSize * 1.2),
@@ -194,7 +194,7 @@ const renderBubbleParticle = (particle) => {
194
194
 
195
195
  const starColors = ['#FFD700', '#FFA500', '#FF6347', '#FFE4B5'];
196
196
  const createStarParticles = (origin, config) => {
197
- const { particleCount = 40, startVelocity = 35, colors = starColors, elementSize = 30 } = config;
197
+ const { particleCount = 40, startVelocity = 18, colors = starColors, elementSize = 30 } = config;
198
198
  const particles = [];
199
199
  for (let i = 0; i < particleCount; i++) {
200
200
  const angle = randomInRange(0, 360);
@@ -221,6 +221,719 @@ const renderStarParticle = (particle) => {
221
221
  React.createElement("path", { d: "M12,17.27L18.18,21L16.54,13.97L22,9.24L14.81,8.62L12,2L9.19,8.62L2,9.24L7.45,13.97L5.82,21L12,17.27Z" })));
222
222
  };
223
223
 
224
+ const snowColors = ['#FFFFFF', '#F0F8FF', '#F5F5F5', '#FAFAFA'];
225
+ const createSnowParticles = (origin, config) => {
226
+ const { particleCount = 50, spread = 200, startVelocity = 3, colors = snowColors, elementSize = 15 } = config;
227
+ const particles = [];
228
+ for (let i = 0; i < particleCount; i++) {
229
+ // Spread particles across the width, starting from above viewport
230
+ const x = origin.x + randomInRange(-spread * 2, spread * 2);
231
+ const y = origin.y - randomInRange(100, 300); // Start above the trigger point
232
+ particles.push({
233
+ id: generateId(),
234
+ x,
235
+ y,
236
+ vx: randomInRange(-0.5, 0.5), // Gentle horizontal drift
237
+ vy: randomInRange(startVelocity * 0.5, startVelocity * 1.2),
238
+ life: config.lifetime || 300, // Longer lifetime for snow
239
+ opacity: randomInRange(0.4, 0.9),
240
+ size: randomInRange(elementSize * 0.3, elementSize),
241
+ rotation: randomInRange(0, 360),
242
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
243
+ });
244
+ }
245
+ return particles;
246
+ };
247
+ const renderSnowParticle = (particle) => {
248
+ return (React.createElement("div", { key: particle.id, style: {
249
+ width: `${particle.size}px`,
250
+ height: `${particle.size}px`,
251
+ backgroundColor: particle.color,
252
+ borderRadius: '50%',
253
+ boxShadow: `
254
+ 0 0 ${particle.size * 0.5}px rgba(255, 255, 255, 0.8),
255
+ inset 0 0 ${particle.size * 0.3}px rgba(255, 255, 255, 0.5)
256
+ `,
257
+ filter: 'blur(0.5px)',
258
+ } }));
259
+ };
260
+
261
+ // Default emoji sets for different moods
262
+ const defaultEmojis = ['🎉', '🎊', '🎈', '🎁', '✨', '🌟', '💫', '🎯'];
263
+ const celebrationEmojis = ['🎉', '🎊', '🥳', '🎈', '🎁', '🍾', '🥂', '🎆'];
264
+ const loveEmojis = ['❤️', '💕', '💖', '💝', '💗', '💓', '💞', '💘'];
265
+ const happyEmojis = ['😊', '😄', '🥰', '😍', '🤗', '😘', '😁', '🤩'];
266
+ const natureEmojis = ['🌸', '🌺', '🌻', '🌹', '🌷', '🌼', '🍀', '🌿'];
267
+ const foodEmojis = ['🍕', '🍔', '🍟', '🌮', '🍿', '🍩', '🍪', '🧁'];
268
+ const createEmojiParticles = (origin, config) => {
269
+ const { particleCount = 30, spread = 100, startVelocity = 15, elementSize = 35, emojis = defaultEmojis } = config;
270
+ const particles = [];
271
+ for (let i = 0; i < particleCount; i++) {
272
+ const angle = randomInRange(-45, -135);
273
+ const velocity = randomInRange(startVelocity * 0.5, startVelocity * 1.2);
274
+ particles.push({
275
+ id: generateId(),
276
+ x: origin.x + randomInRange(-spread, spread),
277
+ y: origin.y,
278
+ vx: Math.cos((angle * Math.PI) / 180) * velocity,
279
+ vy: Math.sin((angle * Math.PI) / 180) * velocity,
280
+ life: config.lifetime || 180,
281
+ opacity: 1,
282
+ size: randomInRange(elementSize * 0.7, elementSize * 1.3),
283
+ rotation: randomInRange(-45, 45),
284
+ color: '', // Not used for emojis
285
+ element: emojis[Math.floor(Math.random() * emojis.length)]
286
+ });
287
+ }
288
+ return particles;
289
+ };
290
+ const renderEmojiParticle = (particle) => {
291
+ return (React.createElement("div", { key: particle.id, style: {
292
+ fontSize: `${particle.size}px`,
293
+ lineHeight: 1,
294
+ userSelect: 'none',
295
+ filter: particle.opacity < 0.5 ? 'blur(1px)' : undefined,
296
+ } }, particle.element));
297
+ };
298
+ // Export preset emoji sets for easy use
299
+ const emojiPresets = {
300
+ celebration: celebrationEmojis,
301
+ love: loveEmojis,
302
+ happy: happyEmojis,
303
+ nature: natureEmojis,
304
+ food: foodEmojis,
305
+ default: defaultEmojis
306
+ };
307
+
308
+ const coinColors = ['#FFD700', '#FFA500', '#FFB300', '#FFC700'];
309
+ const createCoinParticles = (origin, config) => {
310
+ const { particleCount = 30, spread = 70, startVelocity = 25, colors = coinColors, elementSize = 25 } = config;
311
+ const particles = [];
312
+ for (let i = 0; i < particleCount; i++) {
313
+ const angle = randomInRange(-spread / 2, spread / 2) * (Math.PI / 180);
314
+ const velocity = randomInRange(startVelocity * 0.5, startVelocity);
315
+ particles.push({
316
+ id: generateId(),
317
+ x: origin.x,
318
+ y: origin.y,
319
+ vx: Math.sin(angle) * velocity,
320
+ vy: -Math.cos(angle) * velocity,
321
+ life: config.lifetime || 120,
322
+ opacity: 1,
323
+ size: randomInRange(elementSize * 0.8, elementSize * 1.2),
324
+ rotation: randomInRange(0, 360),
325
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
326
+ });
327
+ }
328
+ return particles;
329
+ };
330
+ const renderCoinParticle = (particle) => {
331
+ const spinSpeed = 8; // Degrees per frame
332
+ const currentRotation = particle.rotation + (120 - particle.life) * spinSpeed;
333
+ return (React.createElement("div", { key: particle.id, style: {
334
+ width: `${particle.size}px`,
335
+ height: `${particle.size}px`,
336
+ background: `radial-gradient(ellipse at 30% 30%, ${particle.color}, #B8860B)`,
337
+ borderRadius: '50%',
338
+ transform: `rotateY(${currentRotation}deg)`,
339
+ transformStyle: 'preserve-3d',
340
+ boxShadow: `
341
+ inset -2px -2px 4px rgba(0, 0, 0, 0.3),
342
+ inset 2px 2px 4px rgba(255, 255, 255, 0.5),
343
+ 0 2px 4px rgba(0, 0, 0, 0.3)
344
+ `,
345
+ border: `1px solid ${particle.color}`,
346
+ position: 'relative',
347
+ overflow: 'hidden',
348
+ } },
349
+ React.createElement("div", { style: {
350
+ position: 'absolute',
351
+ top: '50%',
352
+ left: '50%',
353
+ transform: 'translate(-50%, -50%)',
354
+ fontSize: `${particle.size * 0.5}px`,
355
+ fontWeight: 'bold',
356
+ color: '#B8860B',
357
+ textShadow: '1px 1px 1px rgba(0, 0, 0, 0.3)',
358
+ fontFamily: 'Arial, sans-serif',
359
+ } }, "$")));
360
+ };
361
+
362
+ const lightningColors = ['#FFFF00', '#FFFFFF', '#00FFFF', '#FF00FF'];
363
+ const createLightningParticles = (origin, config) => {
364
+ const { particleCount = 20, spread = 360, startVelocity = 50, colors = lightningColors, elementSize = 30 } = config;
365
+ const particles = [];
366
+ for (let i = 0; i < particleCount; i++) {
367
+ const angle = randomInRange(0, spread) * (Math.PI / 180);
368
+ const velocity = randomInRange(startVelocity * 0.7, startVelocity * 1.3);
369
+ particles.push({
370
+ id: generateId(),
371
+ x: origin.x,
372
+ y: origin.y,
373
+ vx: Math.sin(angle) * velocity,
374
+ vy: -Math.abs(Math.cos(angle) * velocity * 0.5), // Mostly horizontal movement
375
+ life: config.lifetime || 60, // Quick flashes
376
+ opacity: 1,
377
+ size: randomInRange(elementSize * 0.5, elementSize * 1.5),
378
+ rotation: randomInRange(0, 360),
379
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
380
+ });
381
+ }
382
+ return particles;
383
+ };
384
+ const renderLightningParticle = (particle) => {
385
+ // Create zigzag pattern based on particle life
386
+ const zigzagOffset = Math.sin(particle.life * 0.5) * 10;
387
+ return (React.createElement("div", { key: particle.id, style: {
388
+ width: `${particle.size}px`,
389
+ height: `${particle.size * 0.3}px`,
390
+ position: 'relative',
391
+ filter: `blur(0.5px) brightness(2)`,
392
+ transform: `translateX(${zigzagOffset}px) rotate(${particle.rotation}deg)`,
393
+ } },
394
+ React.createElement("div", { style: {
395
+ position: 'absolute',
396
+ width: '100%',
397
+ height: '100%',
398
+ background: particle.color,
399
+ clipPath: 'polygon(0% 0%, 60% 0%, 40% 45%, 100% 45%, 0% 100%, 40% 55%, 20% 55%, 35% 100%)',
400
+ boxShadow: `
401
+ 0 0 10px ${particle.color},
402
+ 0 0 20px ${particle.color},
403
+ 0 0 30px ${particle.color}
404
+ `,
405
+ } }),
406
+ React.createElement("div", { style: {
407
+ position: 'absolute',
408
+ top: '-50%',
409
+ left: '-50%',
410
+ width: '200%',
411
+ height: '200%',
412
+ background: `radial-gradient(circle, ${particle.color}88 0%, transparent 70%)`,
413
+ animation: `electricPulse ${randomInRange(100, 200)}ms infinite`,
414
+ } })));
415
+ };
416
+
417
+ const petalColors = ['#FFB6C1', '#FFC0CB', '#FF69B4', '#FF1493', '#FFF0F5'];
418
+ const createPetalParticles = (origin, config) => {
419
+ const { particleCount = 40, spread = 100, startVelocity = 8, colors = petalColors, elementSize = 20 } = config;
420
+ const particles = [];
421
+ for (let i = 0; i < particleCount; i++) {
422
+ const angle = randomInRange(-spread / 2, spread / 2) * (Math.PI / 180);
423
+ const velocity = randomInRange(startVelocity * 0.3, startVelocity);
424
+ particles.push({
425
+ id: generateId(),
426
+ x: origin.x + randomInRange(-20, 20),
427
+ y: origin.y - randomInRange(0, 30),
428
+ vx: Math.sin(angle) * velocity,
429
+ vy: randomInRange(2, 5), // Gentle fall
430
+ life: config.lifetime || 200,
431
+ opacity: randomInRange(0.7, 1),
432
+ size: randomInRange(elementSize * 0.7, elementSize * 1.3),
433
+ rotation: randomInRange(0, 360),
434
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
435
+ });
436
+ }
437
+ return particles;
438
+ };
439
+ const renderPetalParticle = (particle) => {
440
+ // Create spiral motion
441
+ const spiralPhase = (200 - particle.life) * 0.1;
442
+ const spiralX = Math.sin(spiralPhase) * 15;
443
+ const wobble = Math.sin(particle.life * 0.1) * 10;
444
+ return (React.createElement("div", { key: particle.id, style: {
445
+ width: `${particle.size}px`,
446
+ height: `${particle.size * 1.2}px`,
447
+ position: 'relative',
448
+ transform: `translateX(${spiralX}px) rotate(${particle.rotation + wobble}deg)`,
449
+ transformStyle: 'preserve-3d',
450
+ } },
451
+ React.createElement("div", { style: {
452
+ width: '100%',
453
+ height: '100%',
454
+ background: `radial-gradient(ellipse at 50% 30%, ${particle.color}, ${particle.color}DD)`,
455
+ borderRadius: '0% 100% 0% 100%',
456
+ position: 'absolute',
457
+ boxShadow: `
458
+ inset 1px 1px 3px rgba(255, 255, 255, 0.5),
459
+ 0 2px 4px rgba(0, 0, 0, 0.1)
460
+ `,
461
+ border: `1px solid ${particle.color}CC`,
462
+ transform: 'rotateY(45deg)',
463
+ } }),
464
+ React.createElement("div", { style: {
465
+ width: '100%',
466
+ height: '100%',
467
+ background: `radial-gradient(ellipse at 50% 30%, ${particle.color}EE, ${particle.color}BB)`,
468
+ borderRadius: '0% 100% 0% 100%',
469
+ position: 'absolute',
470
+ transform: 'rotate(45deg) scale(0.9)',
471
+ opacity: 0.8,
472
+ } })));
473
+ };
474
+
475
+ const auroraColors = ['#00ff88', '#00ffaa', '#00ddff', '#0099ff', '#0066ff', '#9933ff', '#ff00ff'];
476
+ const createAuroraParticles = (origin, config) => {
477
+ const { particleCount = 15, spread = 200, startVelocity = 3, colors = auroraColors, elementSize = 100 } = config;
478
+ const particles = [];
479
+ for (let i = 0; i < particleCount; i++) {
480
+ const angle = (i / particleCount) * spread - spread / 2;
481
+ const offset = randomInRange(-30, 30);
482
+ particles.push({
483
+ id: generateId(),
484
+ x: origin.x + angle + offset,
485
+ y: origin.y,
486
+ vx: randomInRange(-1, 1),
487
+ vy: -startVelocity,
488
+ life: config.lifetime || 250,
489
+ opacity: 0,
490
+ size: randomInRange(elementSize * 0.8, elementSize * 1.2),
491
+ rotation: randomInRange(-15, 15),
492
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
493
+ });
494
+ }
495
+ return particles;
496
+ };
497
+ const renderAuroraParticle = (particle) => {
498
+ // Create flowing wave motion
499
+ const wave = Math.sin(particle.life * 0.05) * 20;
500
+ const fadeIn = Math.min(1, (250 - particle.life) / 50);
501
+ const fadeOut = particle.life / 250;
502
+ const opacity = Math.min(fadeIn, fadeOut) * 0.4;
503
+ return (React.createElement("div", { key: particle.id, style: {
504
+ width: `${particle.size}px`,
505
+ height: `${particle.size * 0.3}px`,
506
+ position: 'relative',
507
+ transform: `translateX(${wave}px) rotate(${particle.rotation}deg)`,
508
+ filter: 'blur(2px)',
509
+ } },
510
+ React.createElement("div", { style: {
511
+ width: '100%',
512
+ height: '100%',
513
+ background: `linear-gradient(90deg, transparent, ${particle.color}, transparent)`,
514
+ borderRadius: '50%',
515
+ opacity,
516
+ boxShadow: `0 0 ${particle.size * 0.5}px ${particle.color}`,
517
+ animation: 'shimmer 2s infinite',
518
+ } }),
519
+ React.createElement("div", { style: {
520
+ position: 'absolute',
521
+ top: '20%',
522
+ left: '10%',
523
+ width: '80%',
524
+ height: '60%',
525
+ background: `radial-gradient(ellipse at center, ${particle.color}44, transparent)`,
526
+ borderRadius: '50%',
527
+ opacity: opacity * 0.5,
528
+ filter: 'blur(4px)',
529
+ } })));
530
+ };
531
+
532
+ const fireflyColors = ['#FFFF99', '#FFFFCC', '#FFFF66', '#FFFFAA'];
533
+ const createFireflyParticles = (origin, config) => {
534
+ const { particleCount = 20, spread = 150, startVelocity = 2, colors = fireflyColors, elementSize = 8 } = config;
535
+ const particles = [];
536
+ for (let i = 0; i < particleCount; i++) {
537
+ const angle = randomInRange(0, 360) * (Math.PI / 180);
538
+ const velocity = randomInRange(startVelocity * 0.3, startVelocity);
539
+ particles.push({
540
+ id: generateId(),
541
+ x: origin.x + randomInRange(-spread / 2, spread / 2),
542
+ y: origin.y + randomInRange(-20, 20),
543
+ vx: Math.cos(angle) * velocity,
544
+ vy: Math.sin(angle) * velocity * 0.5, // More horizontal movement
545
+ life: config.lifetime || 300,
546
+ opacity: 0,
547
+ size: randomInRange(elementSize * 0.6, elementSize),
548
+ rotation: randomInRange(0, 360), // Used for blink timing
549
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
550
+ });
551
+ }
552
+ return particles;
553
+ };
554
+ const renderFireflyParticle = (particle) => {
555
+ // Create organic floating motion
556
+ const floatX = Math.sin(particle.life * 0.02 + particle.rotation) * 15;
557
+ const floatY = Math.cos(particle.life * 0.03 + particle.rotation) * 10;
558
+ // Blinking effect - each firefly has its own rhythm based on rotation
559
+ const blinkCycle = Math.sin(particle.life * 0.1 + particle.rotation * 0.1);
560
+ const isBlinking = blinkCycle > 0.3;
561
+ const glowIntensity = isBlinking ? 1 : 0.1;
562
+ // Fade in/out
563
+ const fadeIn = Math.min(1, (300 - particle.life) / 30);
564
+ const fadeOut = particle.life / 300;
565
+ const baseFade = Math.min(fadeIn, fadeOut);
566
+ return (React.createElement("div", { key: particle.id, style: {
567
+ width: `${particle.size}px`,
568
+ height: `${particle.size}px`,
569
+ position: 'relative',
570
+ transform: `translate(${floatX}px, ${floatY}px)`,
571
+ } },
572
+ React.createElement("div", { style: {
573
+ width: '100%',
574
+ height: '100%',
575
+ background: particle.color,
576
+ borderRadius: '50%',
577
+ opacity: baseFade * glowIntensity,
578
+ boxShadow: `
579
+ 0 0 ${particle.size}px ${particle.color},
580
+ 0 0 ${particle.size * 2}px ${particle.color},
581
+ 0 0 ${particle.size * 3}px ${particle.color}88
582
+ `,
583
+ transition: 'opacity 0.3s ease',
584
+ } }),
585
+ React.createElement("div", { style: {
586
+ position: 'absolute',
587
+ top: '50%',
588
+ left: '50%',
589
+ width: `${particle.size * 4}px`,
590
+ height: `${particle.size * 4}px`,
591
+ background: `radial-gradient(circle, ${particle.color}44 0%, transparent 70%)`,
592
+ borderRadius: '50%',
593
+ transform: 'translate(-50%, -50%)',
594
+ opacity: baseFade * glowIntensity * 0.5,
595
+ transition: 'opacity 0.3s ease',
596
+ } })));
597
+ };
598
+
599
+ const paintColors = ['#FF006E', '#FB5607', '#FFBE0B', '#8338EC', '#3A86FF', '#06FFB4'];
600
+ const createPaintParticles = (origin, config) => {
601
+ const { particleCount = 25, spread = 120, startVelocity = 35, colors = paintColors, elementSize = 30 } = config;
602
+ const particles = [];
603
+ for (let i = 0; i < particleCount; i++) {
604
+ const angle = randomInRange(-spread / 2, spread / 2) * (Math.PI / 180);
605
+ const velocity = randomInRange(startVelocity * 0.5, startVelocity);
606
+ const isMainSplat = i < 5; // First few particles are bigger splats
607
+ particles.push({
608
+ id: generateId(),
609
+ x: origin.x,
610
+ y: origin.y,
611
+ vx: Math.sin(angle) * velocity * (isMainSplat ? 0.3 : 1),
612
+ vy: -Math.cos(angle) * velocity * 0.7 + (isMainSplat ? 5 : 0),
613
+ life: config.lifetime || 150,
614
+ opacity: 1,
615
+ size: isMainSplat
616
+ ? randomInRange(elementSize * 1.5, elementSize * 2.5)
617
+ : randomInRange(elementSize * 0.3, elementSize),
618
+ rotation: randomInRange(0, 360),
619
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
620
+ });
621
+ }
622
+ return particles;
623
+ };
624
+ const renderPaintParticle = (particle) => {
625
+ // Paint splatter gets more stretched as it flies
626
+ const stretch = 1 + (Math.abs(particle.vx) + Math.abs(particle.vy)) * 0.01;
627
+ const squish = 1 / stretch;
628
+ // Drip effect for some particles
629
+ const isDripping = particle.size > 15 && particle.rotation > 180;
630
+ const dripLength = isDripping ? particle.size * 0.5 : 0;
631
+ return (React.createElement("div", { key: particle.id, style: {
632
+ width: `${particle.size}px`,
633
+ height: `${particle.size}px`,
634
+ position: 'relative',
635
+ transform: `
636
+ scaleX(${stretch})
637
+ scaleY(${squish})
638
+ rotate(${Math.atan2(particle.vy, particle.vx) * 180 / Math.PI}deg)
639
+ `,
640
+ } },
641
+ React.createElement("div", { style: {
642
+ width: '100%',
643
+ height: '100%',
644
+ background: particle.color,
645
+ borderRadius: '50%',
646
+ position: 'relative',
647
+ boxShadow: `inset -2px -2px 4px rgba(0,0,0,0.2)`,
648
+ } },
649
+ React.createElement("div", { style: {
650
+ position: 'absolute',
651
+ top: '20%',
652
+ left: '20%',
653
+ width: '30%',
654
+ height: '30%',
655
+ background: particle.color,
656
+ borderRadius: '50%',
657
+ opacity: 0.8,
658
+ transform: `translate(${randomInRange(-5, 5)}px, ${randomInRange(-5, 5)}px)`,
659
+ } }),
660
+ React.createElement("div", { style: {
661
+ position: 'absolute',
662
+ bottom: '15%',
663
+ right: '15%',
664
+ width: '25%',
665
+ height: '25%',
666
+ background: particle.color,
667
+ borderRadius: '50%',
668
+ opacity: 0.7,
669
+ } })),
670
+ isDripping && (React.createElement("div", { style: {
671
+ position: 'absolute',
672
+ bottom: `-${dripLength}px`,
673
+ left: '40%',
674
+ width: '20%',
675
+ height: `${dripLength}px`,
676
+ background: particle.color,
677
+ borderRadius: '0 0 50% 50%',
678
+ opacity: 0.9,
679
+ } }))));
680
+ };
681
+
682
+ const musicColors = ['#FF006E', '#8338EC', '#3A86FF', '#FB5607', '#FFBE0B'];
683
+ const createMusicParticles = (origin, config) => {
684
+ const { particleCount = 20, spread = 100, startVelocity = 8, colors = musicColors, elementSize = 25 } = config;
685
+ const particles = [];
686
+ const notes = ['♪', '♫', '♬', '♩', '♭', '♯'];
687
+ for (let i = 0; i < particleCount; i++) {
688
+ const angle = randomInRange(-spread / 2, spread / 2) * (Math.PI / 180);
689
+ const velocity = randomInRange(startVelocity * 0.5, startVelocity);
690
+ particles.push({
691
+ id: generateId(),
692
+ x: origin.x + randomInRange(-20, 20),
693
+ y: origin.y,
694
+ vx: Math.sin(angle) * velocity * 0.3,
695
+ vy: -Math.abs(Math.cos(angle)) * velocity * 0.5, // Always go up slowly
696
+ life: config.lifetime || 200,
697
+ opacity: 1,
698
+ size: randomInRange(elementSize * 0.8, elementSize * 1.2),
699
+ rotation: i % notes.length, // Store which note to use
700
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
701
+ });
702
+ }
703
+ return particles;
704
+ };
705
+ const renderMusicParticle = (particle) => {
706
+ const notes = ['♪', '♫', '♬', '♩', '♭', '♯'];
707
+ const note = notes[Math.floor(particle.rotation)];
708
+ // Wave motion as notes float up
709
+ const waveX = Math.sin(particle.life * 0.05) * 20;
710
+ const wobble = Math.sin(particle.life * 0.1) * 10;
711
+ // Fade in/out
712
+ const maxLife = 300; // Use longer lifetime for proper fading
713
+ const fadeIn = particle.life > (maxLife - 20) ? (maxLife - particle.life) / 20 : 1;
714
+ const fadeOut = particle.life < 50 ? particle.life / 50 : 1;
715
+ const opacity = Math.min(fadeIn, fadeOut) * particle.opacity;
716
+ return (React.createElement("div", { key: particle.id, style: {
717
+ fontSize: `${particle.size}px`,
718
+ fontWeight: 'bold',
719
+ position: 'relative',
720
+ transform: `
721
+ translateX(${waveX}px)
722
+ rotate(${wobble}deg)
723
+ scale(${0.8 + opacity * 0.2})
724
+ `,
725
+ color: particle.color,
726
+ opacity,
727
+ textShadow: `
728
+ 0 0 10px ${particle.color}88,
729
+ 0 0 20px ${particle.color}44,
730
+ 2px 2px 3px rgba(0,0,0,0.3)
731
+ `,
732
+ transition: 'transform 0.3s ease',
733
+ userSelect: 'none',
734
+ } },
735
+ note,
736
+ React.createElement("div", { style: {
737
+ position: 'absolute',
738
+ top: '40%',
739
+ left: '-20%',
740
+ width: '140%',
741
+ height: '1px',
742
+ background: `linear-gradient(90deg, transparent, ${particle.color}33, transparent)`,
743
+ opacity: opacity * 0.5,
744
+ } }),
745
+ React.createElement("div", { style: {
746
+ position: 'absolute',
747
+ top: '60%',
748
+ left: '-20%',
749
+ width: '140%',
750
+ height: '1px',
751
+ background: `linear-gradient(90deg, transparent, ${particle.color}33, transparent)`,
752
+ opacity: opacity * 0.3,
753
+ } })));
754
+ };
755
+
756
+ const balloonColors = ['#FF006E', '#FB5607', '#FFBE0B', '#8338EC', '#3A86FF', '#06FFB4', '#FF4081'];
757
+ const createBalloonParticles = (origin, config) => {
758
+ const { particleCount = 15, spread = 80, startVelocity = 10, colors = balloonColors, elementSize = 35 } = config;
759
+ const particles = [];
760
+ for (let i = 0; i < particleCount; i++) {
761
+ const angle = randomInRange(-spread / 2, spread / 2) * (Math.PI / 180);
762
+ const velocity = randomInRange(startVelocity * 0.7, startVelocity);
763
+ particles.push({
764
+ id: generateId(),
765
+ x: origin.x + randomInRange(-30, 30),
766
+ y: origin.y + randomInRange(0, 20),
767
+ vx: Math.sin(angle) * velocity * 0.2,
768
+ vy: -velocity * 0.4, // Balloons float up slowly
769
+ life: config.lifetime || 250,
770
+ opacity: 0.9,
771
+ size: randomInRange(elementSize * 0.8, elementSize * 1.2),
772
+ rotation: randomInRange(-10, 10),
773
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
774
+ });
775
+ }
776
+ return particles;
777
+ };
778
+ const renderBalloonParticle = (particle) => {
779
+ // Gentle swaying motion
780
+ const sway = Math.sin(particle.life * 0.03) * 15;
781
+ const bob = Math.sin(particle.life * 0.05) * 5;
782
+ // Fade out near the end
783
+ const fadeOut = particle.life > 50 ? 1 : particle.life / 50;
784
+ return (React.createElement("div", { key: particle.id, style: {
785
+ width: `${particle.size}px`,
786
+ height: `${particle.size * 1.2}px`,
787
+ position: 'relative',
788
+ transform: `
789
+ translateX(${sway}px)
790
+ translateY(${bob}px)
791
+ rotate(${particle.rotation + sway * 0.2}deg)
792
+ `,
793
+ opacity: particle.opacity * fadeOut,
794
+ } },
795
+ React.createElement("div", { style: {
796
+ width: '100%',
797
+ height: '100%',
798
+ background: `radial-gradient(circle at 30% 30%, ${particle.color}ee, ${particle.color})`,
799
+ borderRadius: '50% 50% 50% 50% / 60% 60% 40% 40%',
800
+ position: 'relative',
801
+ boxShadow: `
802
+ inset -5px -5px 10px rgba(0,0,0,0.2),
803
+ 0 4px 8px rgba(0,0,0,0.2)
804
+ `,
805
+ } },
806
+ React.createElement("div", { style: {
807
+ position: 'absolute',
808
+ top: '15%',
809
+ left: '20%',
810
+ width: '25%',
811
+ height: '30%',
812
+ background: 'radial-gradient(circle, rgba(255,255,255,0.8) 0%, transparent 70%)',
813
+ borderRadius: '50%',
814
+ transform: 'rotate(-20deg)',
815
+ } }),
816
+ React.createElement("div", { style: {
817
+ position: 'absolute',
818
+ bottom: '-5px',
819
+ left: '50%',
820
+ transform: 'translateX(-50%)',
821
+ width: '0',
822
+ height: '0',
823
+ borderLeft: '4px solid transparent',
824
+ borderRight: '4px solid transparent',
825
+ borderTop: `8px solid ${particle.color}`,
826
+ } })),
827
+ React.createElement("svg", { style: {
828
+ position: 'absolute',
829
+ top: '100%',
830
+ left: '50%',
831
+ transform: 'translateX(-50%)',
832
+ width: '2px',
833
+ height: `${particle.size * 2}px`,
834
+ opacity: 0.6,
835
+ } },
836
+ React.createElement("path", { d: `M1 0 Q ${1 + Math.sin(particle.life * 0.1) * 3} ${particle.size} 1 ${particle.size * 2}`, stroke: particle.color, strokeWidth: "1.5", fill: "none", opacity: "0.4" }))));
837
+ };
838
+
839
+ const galaxyColors = ['#FFFFFF', '#FFF9C4', '#BBDEFB', '#C5CAE9', '#D1C4E9', '#FFE082', '#FFCCBC'];
840
+ const createGalaxyParticles = (origin, config) => {
841
+ const { particleCount = 60, spread = 200, startVelocity = 15, colors = galaxyColors, elementSize = 8 } = config;
842
+ const particles = [];
843
+ for (let i = 0; i < particleCount; i++) {
844
+ // Create spiral distribution
845
+ const progress = i / particleCount;
846
+ const spiralAngle = progress * Math.PI * 4; // 2 full rotations
847
+ const radius = progress * spread;
848
+ // Add some randomness to make it look natural
849
+ const angleOffset = randomInRange(-0.3, 0.3);
850
+ const radiusOffset = randomInRange(-10, 10);
851
+ const finalAngle = spiralAngle + angleOffset;
852
+ const finalRadius = radius + radiusOffset;
853
+ // Position based on spiral
854
+ const offsetX = Math.cos(finalAngle) * finalRadius;
855
+ const offsetY = Math.sin(finalAngle) * finalRadius;
856
+ // Velocity follows the spiral tangent
857
+ const tangentAngle = finalAngle + Math.PI / 2;
858
+ const speed = startVelocity * (1 - progress * 0.5); // Outer stars move slower
859
+ particles.push({
860
+ id: generateId(),
861
+ x: origin.x,
862
+ y: origin.y,
863
+ vx: Math.cos(tangentAngle) * speed * 0.3 + offsetX * 0.02,
864
+ vy: Math.sin(tangentAngle) * speed * 0.3 + offsetY * 0.02,
865
+ life: config.lifetime || 250,
866
+ opacity: 0,
867
+ size: randomInRange(elementSize * 0.3, elementSize) * (1 - progress * 0.5), // Smaller at edges
868
+ rotation: randomInRange(0, 360),
869
+ color: colors[Math.floor(Math.random() * colors.length)] || colors[0],
870
+ });
871
+ }
872
+ return particles;
873
+ };
874
+ const renderGalaxyParticle = (particle) => {
875
+ // Particles slowly rotate around center while expanding
876
+ const age = (250 - particle.life) / 250;
877
+ const expansionRate = 1 + age * 0.5;
878
+ // Fade in quickly, fade out slowly
879
+ const fadeIn = Math.min(1, (250 - particle.life) / 30);
880
+ const fadeOut = particle.life / 250;
881
+ const opacity = Math.min(fadeIn, fadeOut);
882
+ // Twinkle effect
883
+ const twinkle = Math.sin(particle.life * 0.2 + particle.rotation) * 0.3 + 0.7;
884
+ return (React.createElement("div", { key: particle.id, style: {
885
+ width: `${particle.size}px`,
886
+ height: `${particle.size}px`,
887
+ position: 'relative',
888
+ transform: `scale(${expansionRate})`,
889
+ opacity: opacity * twinkle,
890
+ } },
891
+ React.createElement("div", { style: {
892
+ width: '100%',
893
+ height: '100%',
894
+ background: particle.color,
895
+ borderRadius: '50%',
896
+ boxShadow: `
897
+ 0 0 ${particle.size}px ${particle.color},
898
+ 0 0 ${particle.size * 2}px ${particle.color}88,
899
+ 0 0 ${particle.size * 3}px ${particle.color}44
900
+ `,
901
+ position: 'relative',
902
+ } },
903
+ React.createElement("div", { style: {
904
+ position: 'absolute',
905
+ top: '50%',
906
+ left: '50%',
907
+ width: `${particle.size * 3}px`,
908
+ height: '1px',
909
+ background: `linear-gradient(90deg, transparent, ${particle.color}, transparent)`,
910
+ transform: `translate(-50%, -50%) rotate(${particle.rotation}deg)`,
911
+ opacity: twinkle,
912
+ } }),
913
+ React.createElement("div", { style: {
914
+ position: 'absolute',
915
+ top: '50%',
916
+ left: '50%',
917
+ width: '1px',
918
+ height: `${particle.size * 3}px`,
919
+ background: `linear-gradient(180deg, transparent, ${particle.color}, transparent)`,
920
+ transform: `translate(-50%, -50%) rotate(${particle.rotation}deg)`,
921
+ opacity: twinkle,
922
+ } })),
923
+ particle.size > 5 && (React.createElement("div", { style: {
924
+ position: 'absolute',
925
+ top: '50%',
926
+ left: '50%',
927
+ width: `${particle.size * 6}px`,
928
+ height: `${particle.size * 6}px`,
929
+ background: `radial-gradient(circle, ${particle.color}22 0%, transparent 70%)`,
930
+ borderRadius: '50%',
931
+ transform: 'translate(-50%, -50%)',
932
+ opacity: opacity * 0.3,
933
+ filter: 'blur(3px)',
934
+ } }))));
935
+ };
936
+
224
937
  const animations = {
225
938
  confetti: {
226
939
  createParticles: createConfettiParticles,
@@ -246,6 +959,50 @@ const animations = {
246
959
  createParticles: createStarParticles,
247
960
  renderParticle: renderStarParticle,
248
961
  },
962
+ snow: {
963
+ createParticles: createSnowParticles,
964
+ renderParticle: renderSnowParticle,
965
+ },
966
+ emoji: {
967
+ createParticles: createEmojiParticles,
968
+ renderParticle: renderEmojiParticle,
969
+ },
970
+ coins: {
971
+ createParticles: createCoinParticles,
972
+ renderParticle: renderCoinParticle,
973
+ },
974
+ lightning: {
975
+ createParticles: createLightningParticles,
976
+ renderParticle: renderLightningParticle,
977
+ },
978
+ petals: {
979
+ createParticles: createPetalParticles,
980
+ renderParticle: renderPetalParticle,
981
+ },
982
+ aurora: {
983
+ createParticles: createAuroraParticles,
984
+ renderParticle: renderAuroraParticle,
985
+ },
986
+ fireflies: {
987
+ createParticles: createFireflyParticles,
988
+ renderParticle: renderFireflyParticle,
989
+ },
990
+ paint: {
991
+ createParticles: createPaintParticles,
992
+ renderParticle: renderPaintParticle,
993
+ },
994
+ music: {
995
+ createParticles: createMusicParticles,
996
+ renderParticle: renderMusicParticle,
997
+ },
998
+ balloons: {
999
+ createParticles: createBalloonParticles,
1000
+ renderParticle: renderBalloonParticle,
1001
+ },
1002
+ galaxy: {
1003
+ createParticles: createGalaxyParticles,
1004
+ renderParticle: renderGalaxyParticle,
1005
+ },
249
1006
  };
250
1007
 
251
1008
  const useReward = (elementId, animationType, config) => {
@@ -286,7 +1043,9 @@ const useReward = (elementId, animationType, config) => {
286
1043
  const root = createRoot(container);
287
1044
  rootRef.current = root;
288
1045
  const containerRect = container.getBoundingClientRect();
289
- const gravity = (_b = (_a = config === null || config === void 0 ? void 0 : config.physics) === null || _a === void 0 ? void 0 : _a.gravity) !== null && _b !== void 0 ? _b : 0.35;
1046
+ // Default gravity varies by animation type
1047
+ const defaultGravity = animationType === 'bubbles' ? -0.1 : animationType === 'snow' ? 0.05 : 0.35;
1048
+ const gravity = (_b = (_a = config === null || config === void 0 ? void 0 : config.physics) === null || _a === void 0 ? void 0 : _a.gravity) !== null && _b !== void 0 ? _b : defaultGravity;
290
1049
  const friction = (_d = (_c = config === null || config === void 0 ? void 0 : config.physics) === null || _c === void 0 ? void 0 : _c.friction) !== null && _d !== void 0 ? _d : 0.98;
291
1050
  const wind = (_f = (_e = config === null || config === void 0 ? void 0 : config.physics) === null || _e === void 0 ? void 0 : _e.wind) !== null && _f !== void 0 ? _f : 0;
292
1051
  const updateParticles = () => {
@@ -370,5 +1129,5 @@ const useReward = (elementId, animationType, config) => {
370
1129
  return { reward, isAnimating };
371
1130
  };
372
1131
 
373
- export { useReward };
1132
+ export { emojiPresets, useReward };
374
1133
  //# sourceMappingURL=index.esm.js.map