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