@tsparticles/slim 3.0.0-beta.3 → 3.0.0-beta.5

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.
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v3.0.0-beta.3
7
+ * v3.0.0-beta.5
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -97,6 +97,7 @@ __webpack_require__.d(__webpack_exports__, {
97
97
  ParticlesDensity: () => (/* reexport */ ParticlesDensity),
98
98
  ParticlesInteractorBase: () => (/* reexport */ ParticlesInteractorBase),
99
99
  ParticlesNumber: () => (/* reexport */ ParticlesNumber),
100
+ ParticlesNumberLimit: () => (/* reexport */ ParticlesNumberLimit),
100
101
  ParticlesOptions: () => (/* reexport */ ParticlesOptions),
101
102
  Point: () => (/* reexport */ Point),
102
103
  Range: () => (/* reexport */ Range),
@@ -140,13 +141,13 @@ __webpack_require__.d(__webpack_exports__, {
140
141
  deepExtend: () => (/* reexport */ deepExtend),
141
142
  divMode: () => (/* reexport */ divMode),
142
143
  divModeExecute: () => (/* reexport */ divModeExecute),
144
+ drawEffect: () => (/* reexport */ drawEffect),
143
145
  drawLine: () => (/* reexport */ drawLine),
144
146
  drawParticle: () => (/* reexport */ drawParticle),
145
147
  drawParticlePlugin: () => (/* reexport */ drawParticlePlugin),
146
148
  drawPlugin: () => (/* reexport */ drawPlugin),
147
149
  drawShape: () => (/* reexport */ drawShape),
148
- drawShapeAfterEffect: () => (/* reexport */ drawShapeAfterEffect),
149
- drawTriangle: () => (/* reexport */ drawTriangle),
150
+ drawShapeAfterDraw: () => (/* reexport */ drawShapeAfterDraw),
150
151
  errorPrefix: () => (/* reexport */ errorPrefix),
151
152
  executeOnSingleOrMultiple: () => (/* reexport */ executeOnSingleOrMultiple),
152
153
  findItemFromSingleOrMultiple: () => (/* reexport */ findItemFromSingleOrMultiple),
@@ -170,7 +171,6 @@ __webpack_require__.d(__webpack_exports__, {
170
171
  getSize: () => (/* reexport */ getSize),
171
172
  getStyleFromHsl: () => (/* reexport */ getStyleFromHsl),
172
173
  getStyleFromRgb: () => (/* reexport */ getStyleFromRgb),
173
- getValue: () => (/* reexport */ getValue),
174
174
  hasMatchMedia: () => (/* reexport */ hasMatchMedia),
175
175
  hslToRgb: () => (/* reexport */ hslToRgb),
176
176
  hslaToRgba: () => (/* reexport */ hslaToRgba),
@@ -410,17 +410,6 @@ function setRangeValue(source, value) {
410
410
  max: Math.max(max, value)
411
411
  } : setRangeValue(min, max);
412
412
  }
413
- function getValue(options) {
414
- const random = options.random,
415
- {
416
- enable,
417
- minimumValue
418
- } = isBoolean(random) ? {
419
- enable: random,
420
- minimumValue: 0
421
- } : random;
422
- return enable ? getRangeValue(setRangeValue(options.value, minimumValue)) : getRangeValue(options.value);
423
- }
424
413
  function getDistances(pointA, pointB) {
425
414
  const dx = pointA.x - pointB.x,
426
415
  dy = pointA.y - pointB.y;
@@ -439,21 +428,21 @@ function getParticleDirectionAngle(direction, position, center) {
439
428
  }
440
429
  switch (direction) {
441
430
  case "top":
442
- return -Math.PI / 2;
431
+ return -Math.PI * 0.5;
443
432
  case "top-right":
444
- return -Math.PI / 4;
433
+ return -Math.PI * 0.25;
445
434
  case "right":
446
435
  return 0;
447
436
  case "bottom-right":
448
- return Math.PI / 4;
437
+ return Math.PI * 0.25;
449
438
  case "bottom":
450
- return Math.PI / 2;
439
+ return Math.PI * 0.5;
451
440
  case "bottom-left":
452
- return 3 * Math.PI / 4;
441
+ return Math.PI * 0.75;
453
442
  case "left":
454
443
  return Math.PI;
455
444
  case "top-left":
456
- return -3 * Math.PI / 4;
445
+ return -Math.PI * 0.75;
457
446
  case "inside":
458
447
  return Math.atan2(center.y - position.y, center.x - position.x);
459
448
  case "outside":
@@ -549,7 +538,7 @@ function rectSideBounce(data) {
549
538
  if (pOtherSide.min < rectOtherSide.min || pOtherSide.min > rectOtherSide.max || pOtherSide.max < rectOtherSide.min || pOtherSide.max > rectOtherSide.max) {
550
539
  return res;
551
540
  }
552
- if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) / 2 && velocity > 0 || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) / 2 && velocity < 0) {
541
+ if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * 0.5 && velocity > 0 || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * 0.5 && velocity < 0) {
553
542
  res.velocity = velocity * -factor;
554
543
  res.bounced = true;
555
544
  }
@@ -685,7 +674,7 @@ function circleBounceDataFromParticle(p) {
685
674
  radius: p.getRadius(),
686
675
  mass: p.getMass(),
687
676
  velocity: p.velocity,
688
- factor: Vector.create(getValue(p.options.bounce.horizontal), getValue(p.options.bounce.vertical))
677
+ factor: Vector.create(getRangeValue(p.options.bounce.horizontal.value), getRangeValue(p.options.bounce.vertical.value))
689
678
  };
690
679
  }
691
680
  function circleBounce(p1, p2) {
@@ -719,6 +708,7 @@ function rectBounce(particle, divBounds) {
719
708
  const pPos = particle.getPosition(),
720
709
  size = particle.getRadius(),
721
710
  bounds = calculateBounds(pPos, size),
711
+ bounceOptions = particle.options.bounce,
722
712
  resH = rectSideBounce({
723
713
  pSide: {
724
714
  min: bounds.left,
@@ -737,7 +727,7 @@ function rectBounce(particle, divBounds) {
737
727
  max: divBounds.bottom
738
728
  },
739
729
  velocity: particle.velocity.x,
740
- factor: getValue(particle.options.bounce.horizontal)
730
+ factor: getRangeValue(bounceOptions.horizontal.value)
741
731
  });
742
732
  if (resH.bounced) {
743
733
  if (resH.velocity !== undefined) {
@@ -765,7 +755,7 @@ function rectBounce(particle, divBounds) {
765
755
  max: divBounds.right
766
756
  },
767
757
  velocity: particle.velocity.y,
768
- factor: getValue(particle.options.bounce.vertical)
758
+ factor: getRangeValue(bounceOptions.vertical.value)
769
759
  });
770
760
  if (resV.bounced) {
771
761
  if (resV.velocity !== undefined) {
@@ -892,24 +882,6 @@ const randomColorValue = "random",
892
882
  function addColorManager(manager) {
893
883
  colorManagers.set(manager.key, manager);
894
884
  }
895
- function hue2rgb(p, q, t) {
896
- if (t < 0) {
897
- t += 1;
898
- }
899
- if (t > 1) {
900
- t -= 1;
901
- }
902
- if (t < 1 / 6) {
903
- return p + (q - p) * 6 * t;
904
- }
905
- if (t < 1 / 2) {
906
- return q;
907
- }
908
- if (t < 2 / 3) {
909
- return p + (q - p) * (2 / 3 - t) * 6;
910
- }
911
- return p;
912
- }
913
885
  function stringToRgba(input) {
914
886
  for (const [, manager] of colorManagers) {
915
887
  if (input.startsWith(manager.stringPrefix)) {
@@ -989,7 +961,7 @@ function rgbToHsl(color) {
989
961
  min = Math.min(r1, g1, b1),
990
962
  res = {
991
963
  h: 0,
992
- l: (max + min) / 2,
964
+ l: (max + min) * 0.5,
993
965
  s: 0
994
966
  };
995
967
  if (max !== min) {
@@ -1014,29 +986,48 @@ function stringToRgb(input) {
1014
986
  return stringToRgba(input);
1015
987
  }
1016
988
  function hslToRgb(hsl) {
1017
- const result = {
1018
- b: 0,
1019
- g: 0,
1020
- r: 0
1021
- },
1022
- hslPercent = {
1023
- h: hsl.h / 360,
1024
- l: hsl.l / 100,
1025
- s: hsl.s / 100
989
+ const h = (hsl.h % 360 + 360) % 360,
990
+ s = Math.max(0, Math.min(100, hsl.s)),
991
+ l = Math.max(0, Math.min(100, hsl.l)),
992
+ hNormalized = h / 360,
993
+ sNormalized = s / 100,
994
+ lNormalized = l / 100;
995
+ if (s === 0) {
996
+ const grayscaleValue = Math.round(lNormalized * 255);
997
+ return {
998
+ r: grayscaleValue,
999
+ g: grayscaleValue,
1000
+ b: grayscaleValue
1026
1001
  };
1027
- if (!hslPercent.s) {
1028
- result.r = result.g = result.b = hslPercent.l;
1029
- } else {
1030
- const q = hslPercent.l < 0.5 ? hslPercent.l * (1 + hslPercent.s) : hslPercent.l + hslPercent.s - hslPercent.l * hslPercent.s,
1031
- p = 2 * hslPercent.l - q;
1032
- result.r = hue2rgb(p, q, hslPercent.h + 1 / 3);
1033
- result.g = hue2rgb(p, q, hslPercent.h);
1034
- result.b = hue2rgb(p, q, hslPercent.h - 1 / 3);
1035
1002
  }
1036
- result.r = Math.floor(result.r * 255);
1037
- result.g = Math.floor(result.g * 255);
1038
- result.b = Math.floor(result.b * 255);
1039
- return result;
1003
+ const channel = (temp1, temp2, temp3) => {
1004
+ if (temp3 < 0) {
1005
+ temp3 += 1;
1006
+ }
1007
+ if (temp3 > 1) {
1008
+ temp3 -= 1;
1009
+ }
1010
+ if (temp3 * 6 < 1) {
1011
+ return temp1 + (temp2 - temp1) * 6 * temp3;
1012
+ }
1013
+ if (temp3 * 2 < 1) {
1014
+ return temp2;
1015
+ }
1016
+ if (temp3 * 3 < 2) {
1017
+ return temp1 + (temp2 - temp1) * (2 / 3 - temp3) * 6;
1018
+ }
1019
+ return temp1;
1020
+ },
1021
+ temp1 = lNormalized < 0.5 ? lNormalized * (1 + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1022
+ temp2 = 2 * lNormalized - temp1,
1023
+ red = Math.min(255, 255 * channel(temp2, temp1, hNormalized + 1 / 3)),
1024
+ green = Math.min(255, 255 * channel(temp2, temp1, hNormalized)),
1025
+ blue = Math.min(255, 255 * channel(temp2, temp1, hNormalized - 1 / 3));
1026
+ return {
1027
+ r: Math.round(red),
1028
+ g: Math.round(green),
1029
+ b: Math.round(blue)
1030
+ };
1040
1031
  }
1041
1032
  function hslaToRgba(hsla) {
1042
1033
  const rgbResult = hslToRgb(hsla);
@@ -1170,13 +1161,6 @@ function drawLine(context, begin, end) {
1170
1161
  context.lineTo(end.x, end.y);
1171
1162
  context.closePath();
1172
1163
  }
1173
- function drawTriangle(context, p1, p2, p3) {
1174
- context.beginPath();
1175
- context.moveTo(p1.x, p1.y);
1176
- context.lineTo(p2.x, p2.y);
1177
- context.lineTo(p3.x, p3.y);
1178
- context.closePath();
1179
- }
1180
1164
  function paintBase(context, dimension, baseColor) {
1181
1165
  context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
1182
1166
  context.fillRect(0, 0, dimension.width, dimension.height);
@@ -1219,7 +1203,6 @@ function drawParticle(data) {
1219
1203
  d: rotateData.cos * (transform.d ?? 1)
1220
1204
  };
1221
1205
  context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
1222
- context.beginPath();
1223
1206
  if (backgroundMask) {
1224
1207
  context.globalCompositeOperation = composite;
1225
1208
  }
@@ -1246,20 +1229,47 @@ function drawParticle(data) {
1246
1229
  opacity,
1247
1230
  delta
1248
1231
  };
1232
+ context.beginPath();
1249
1233
  drawShape(drawData);
1234
+ if (particle.shapeClose) {
1235
+ context.closePath();
1236
+ }
1250
1237
  if (strokeWidth > 0) {
1251
1238
  context.stroke();
1252
1239
  }
1253
- if (particle.close) {
1254
- context.closePath();
1255
- }
1256
- if (particle.fill) {
1240
+ if (particle.shapeFill) {
1257
1241
  context.fill();
1258
1242
  }
1259
- drawShapeAfterEffect(drawData);
1243
+ drawShapeAfterDraw(drawData);
1244
+ drawEffect(drawData);
1260
1245
  context.globalCompositeOperation = "source-over";
1261
1246
  context.setTransform(1, 0, 0, 1, 0, 0);
1262
1247
  }
1248
+ function drawEffect(data) {
1249
+ const {
1250
+ container,
1251
+ context,
1252
+ particle,
1253
+ radius,
1254
+ opacity,
1255
+ delta
1256
+ } = data;
1257
+ if (!particle.effect) {
1258
+ return;
1259
+ }
1260
+ const drawer = container.effectDrawers.get(particle.effect);
1261
+ if (!drawer) {
1262
+ return;
1263
+ }
1264
+ drawer.draw({
1265
+ context,
1266
+ particle,
1267
+ radius,
1268
+ opacity,
1269
+ delta,
1270
+ pixelRatio: container.retina.pixelRatio
1271
+ });
1272
+ }
1263
1273
  function drawShape(data) {
1264
1274
  const {
1265
1275
  container,
@@ -1272,7 +1282,7 @@ function drawShape(data) {
1272
1282
  if (!particle.shape) {
1273
1283
  return;
1274
1284
  }
1275
- const drawer = container.drawers.get(particle.shape);
1285
+ const drawer = container.shapeDrawers.get(particle.shape);
1276
1286
  if (!drawer) {
1277
1287
  return;
1278
1288
  }
@@ -1285,7 +1295,7 @@ function drawShape(data) {
1285
1295
  pixelRatio: container.retina.pixelRatio
1286
1296
  });
1287
1297
  }
1288
- function drawShapeAfterEffect(data) {
1298
+ function drawShapeAfterDraw(data) {
1289
1299
  const {
1290
1300
  container,
1291
1301
  context,
@@ -1297,11 +1307,11 @@ function drawShapeAfterEffect(data) {
1297
1307
  if (!particle.shape) {
1298
1308
  return;
1299
1309
  }
1300
- const drawer = container.drawers.get(particle.shape);
1301
- if (!drawer || !drawer.afterEffect) {
1310
+ const drawer = container.shapeDrawers.get(particle.shape);
1311
+ if (!drawer || !drawer.afterDraw) {
1302
1312
  return;
1303
1313
  }
1304
- drawer.afterEffect({
1314
+ drawer.afterDraw({
1305
1315
  context,
1306
1316
  particle,
1307
1317
  radius,
@@ -1755,10 +1765,10 @@ class Canvas {
1755
1765
  this.element.width = size.width = this.element.offsetWidth * pxRatio;
1756
1766
  this.element.height = size.height = this.element.offsetHeight * pxRatio;
1757
1767
  if (this.container.started) {
1758
- this.resizeFactor = {
1768
+ container.particles.setResizeFactor({
1759
1769
  width: size.width / oldSize.width,
1760
1770
  height: size.height / oldSize.height
1761
- };
1771
+ });
1762
1772
  }
1763
1773
  return true;
1764
1774
  }
@@ -2228,10 +2238,10 @@ class BackgroundMask {
2228
2238
  this.composite = data.composite;
2229
2239
  }
2230
2240
  if (data.cover !== undefined) {
2231
- const cover = data.cover;
2232
- const color = isString(data.cover) ? {
2233
- color: data.cover
2234
- } : data.cover;
2241
+ const cover = data.cover,
2242
+ color = isString(data.cover) ? {
2243
+ color: data.cover
2244
+ } : data.cover;
2235
2245
  this.cover.load(cover.color !== undefined ? cover : {
2236
2246
  color: color
2237
2247
  });
@@ -2391,11 +2401,7 @@ class Events {
2391
2401
  });
2392
2402
  }
2393
2403
  this.onHover.load(data.onHover);
2394
- if (isBoolean(data.resize)) {
2395
- this.resize.enable = data.resize;
2396
- } else {
2397
- this.resize.load(data.resize);
2398
- }
2404
+ this.resize.load(data.resize);
2399
2405
  }
2400
2406
  }
2401
2407
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/Interactivity/Modes/Modes.js
@@ -2533,17 +2539,16 @@ class Theme {
2533
2539
  }
2534
2540
  }
2535
2541
  }
2536
- ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/ColorAnimation.js
2542
+ ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/AnimationOptions.js
2537
2543
 
2538
- class ColorAnimation {
2544
+ class AnimationOptions {
2539
2545
  constructor() {
2540
2546
  this.count = 0;
2541
2547
  this.enable = false;
2542
- this.offset = 0;
2543
2548
  this.speed = 1;
2544
- this.delay = 0;
2545
2549
  this.decay = 0;
2546
- this.sync = true;
2550
+ this.delay = 0;
2551
+ this.sync = false;
2547
2552
  }
2548
2553
  load(data) {
2549
2554
  if (!data) {
@@ -2555,9 +2560,6 @@ class ColorAnimation {
2555
2560
  if (data.enable !== undefined) {
2556
2561
  this.enable = data.enable;
2557
2562
  }
2558
- if (data.offset !== undefined) {
2559
- this.offset = setRangeValue(data.offset);
2560
- }
2561
2563
  if (data.speed !== undefined) {
2562
2564
  this.speed = setRangeValue(data.speed);
2563
2565
  }
@@ -2572,6 +2574,44 @@ class ColorAnimation {
2572
2574
  }
2573
2575
  }
2574
2576
  }
2577
+ class RangedAnimationOptions extends AnimationOptions {
2578
+ constructor() {
2579
+ super();
2580
+ this.mode = "auto";
2581
+ this.startValue = "random";
2582
+ }
2583
+ load(data) {
2584
+ super.load(data);
2585
+ if (!data) {
2586
+ return;
2587
+ }
2588
+ if (data.mode !== undefined) {
2589
+ this.mode = data.mode;
2590
+ }
2591
+ if (data.startValue !== undefined) {
2592
+ this.startValue = data.startValue;
2593
+ }
2594
+ }
2595
+ }
2596
+ ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/ColorAnimation.js
2597
+
2598
+
2599
+ class ColorAnimation extends AnimationOptions {
2600
+ constructor() {
2601
+ super();
2602
+ this.offset = 0;
2603
+ this.sync = true;
2604
+ }
2605
+ load(data) {
2606
+ super.load(data);
2607
+ if (!data) {
2608
+ return;
2609
+ }
2610
+ if (data.offset !== undefined) {
2611
+ this.offset = setRangeValue(data.offset);
2612
+ }
2613
+ }
2614
+ }
2575
2615
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/HslAnimation.js
2576
2616
 
2577
2617
  class HslAnimation {
@@ -2659,99 +2699,19 @@ class CollisionsOverlap {
2659
2699
  }
2660
2700
  }
2661
2701
  }
2662
- ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/AnimationOptions.js
2663
-
2664
- class AnimationOptions {
2665
- constructor() {
2666
- this.count = 0;
2667
- this.enable = false;
2668
- this.speed = 1;
2669
- this.decay = 0;
2670
- this.delay = 0;
2671
- this.sync = false;
2672
- }
2673
- load(data) {
2674
- if (!data) {
2675
- return;
2676
- }
2677
- if (data.count !== undefined) {
2678
- this.count = setRangeValue(data.count);
2679
- }
2680
- if (data.enable !== undefined) {
2681
- this.enable = data.enable;
2682
- }
2683
- if (data.speed !== undefined) {
2684
- this.speed = setRangeValue(data.speed);
2685
- }
2686
- if (data.decay !== undefined) {
2687
- this.decay = setRangeValue(data.decay);
2688
- }
2689
- if (data.delay !== undefined) {
2690
- this.delay = setRangeValue(data.delay);
2691
- }
2692
- if (data.sync !== undefined) {
2693
- this.sync = data.sync;
2694
- }
2695
- }
2696
- }
2697
- class RangedAnimationOptions extends AnimationOptions {
2698
- constructor() {
2699
- super();
2700
- this.mode = "auto";
2701
- this.startValue = "random";
2702
- }
2703
- load(data) {
2704
- super.load(data);
2705
- if (!data) {
2706
- return;
2707
- }
2708
- if (data.mode !== undefined) {
2709
- this.mode = data.mode;
2710
- }
2711
- if (data.startValue !== undefined) {
2712
- this.startValue = data.startValue;
2713
- }
2714
- }
2715
- }
2716
- ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/Random.js
2717
- class Random {
2718
- constructor() {
2719
- this.enable = false;
2720
- this.minimumValue = 0;
2721
- }
2722
- load(data) {
2723
- if (!data) {
2724
- return;
2725
- }
2726
- if (data.enable !== undefined) {
2727
- this.enable = data.enable;
2728
- }
2729
- if (data.minimumValue !== undefined) {
2730
- this.minimumValue = data.minimumValue;
2731
- }
2732
- }
2733
- }
2734
2702
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/ValueWithRandom.js
2735
2703
 
2736
2704
 
2737
-
2738
-
2739
2705
  class ValueWithRandom {
2740
2706
  constructor() {
2741
- this.random = new Random();
2742
2707
  this.value = 0;
2743
2708
  }
2744
2709
  load(data) {
2745
2710
  if (!data) {
2746
2711
  return;
2747
2712
  }
2748
- if (isBoolean(data.random)) {
2749
- this.random.enable = data.random;
2750
- } else {
2751
- this.random.load(data.random);
2752
- }
2753
2713
  if (data.value !== undefined) {
2754
- this.value = setRangeValue(data.value, this.random.enable ? this.random.minimumValue : undefined);
2714
+ this.value = setRangeValue(data.value);
2755
2715
  }
2756
2716
  }
2757
2717
  }
@@ -2785,7 +2745,6 @@ class RangedAnimationValueWithRandom extends AnimationValueWithRandom {
2785
2745
  class ParticlesBounceFactor extends ValueWithRandom {
2786
2746
  constructor() {
2787
2747
  super();
2788
- this.random.minimumValue = 0.1;
2789
2748
  this.value = 1;
2790
2749
  }
2791
2750
  }
@@ -2836,6 +2795,39 @@ class Collisions {
2836
2795
  this.overlap.load(data.overlap);
2837
2796
  }
2838
2797
  }
2798
+ ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/Particles/Effect/Effect.js
2799
+
2800
+ class Effect {
2801
+ constructor() {
2802
+ this.close = true;
2803
+ this.fill = true;
2804
+ this.options = {};
2805
+ this.type = [];
2806
+ }
2807
+ load(data) {
2808
+ if (!data) {
2809
+ return;
2810
+ }
2811
+ const options = data.options;
2812
+ if (options !== undefined) {
2813
+ for (const effect in options) {
2814
+ const item = options[effect];
2815
+ if (item) {
2816
+ this.options[effect] = deepExtend(this.options[effect] ?? {}, item);
2817
+ }
2818
+ }
2819
+ }
2820
+ if (data.close !== undefined) {
2821
+ this.close = data.close;
2822
+ }
2823
+ if (data.fill !== undefined) {
2824
+ this.fill = data.fill;
2825
+ }
2826
+ if (data.type !== undefined) {
2827
+ this.type = data.type;
2828
+ }
2829
+ }
2830
+ }
2839
2831
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/Particles/Move/MoveAngle.js
2840
2832
 
2841
2833
  class MoveAngle {
@@ -3164,11 +3156,10 @@ class OpacityAnimation extends RangedAnimationOptions {
3164
3156
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/Particles/Opacity/Opacity.js
3165
3157
 
3166
3158
 
3167
- class Opacity extends ValueWithRandom {
3159
+ class Opacity extends RangedAnimationValueWithRandom {
3168
3160
  constructor() {
3169
3161
  super();
3170
3162
  this.animation = new OpacityAnimation();
3171
- this.random.minimumValue = 0.1;
3172
3163
  this.value = 1;
3173
3164
  }
3174
3165
  load(data) {
@@ -3206,12 +3197,31 @@ class ParticlesDensity {
3206
3197
  }
3207
3198
  }
3208
3199
  }
3200
+ ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/Particles/Number/ParticlesNumberLimit.js
3201
+ class ParticlesNumberLimit {
3202
+ constructor() {
3203
+ this.mode = "delete";
3204
+ this.value = 0;
3205
+ }
3206
+ load(data) {
3207
+ if (!data) {
3208
+ return;
3209
+ }
3210
+ if (data.mode !== undefined) {
3211
+ this.mode = data.mode;
3212
+ }
3213
+ if (data.value !== undefined) {
3214
+ this.value = data.value;
3215
+ }
3216
+ }
3217
+ }
3209
3218
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/Particles/Number/ParticlesNumber.js
3210
3219
 
3220
+
3211
3221
  class ParticlesNumber {
3212
3222
  constructor() {
3213
3223
  this.density = new ParticlesDensity();
3214
- this.limit = 0;
3224
+ this.limit = new ParticlesNumberLimit();
3215
3225
  this.value = 0;
3216
3226
  }
3217
3227
  load(data) {
@@ -3219,10 +3229,7 @@ class ParticlesNumber {
3219
3229
  return;
3220
3230
  }
3221
3231
  this.density.load(data.density);
3222
- const limit = data.limit;
3223
- if (limit !== undefined) {
3224
- this.limit = limit;
3225
- }
3232
+ this.limit.load(data.limit);
3226
3233
  if (data.value !== undefined) {
3227
3234
  this.value = data.value;
3228
3235
  }
@@ -3317,11 +3324,10 @@ class SizeAnimation extends RangedAnimationOptions {
3317
3324
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/Particles/Size/Size.js
3318
3325
 
3319
3326
 
3320
- class Size extends ValueWithRandom {
3327
+ class Size extends RangedAnimationValueWithRandom {
3321
3328
  constructor() {
3322
3329
  super();
3323
3330
  this.animation = new SizeAnimation();
3324
- this.random.minimumValue = 1;
3325
3331
  this.value = 3;
3326
3332
  }
3327
3333
  load(data) {
@@ -3395,6 +3401,7 @@ class ZIndex extends ValueWithRandom {
3395
3401
 
3396
3402
 
3397
3403
 
3404
+
3398
3405
  class ParticlesOptions {
3399
3406
  constructor(engine, container) {
3400
3407
  this._engine = engine;
@@ -3403,6 +3410,7 @@ class ParticlesOptions {
3403
3410
  this.collisions = new Collisions();
3404
3411
  this.color = new AnimatableColor();
3405
3412
  this.color.value = "#fff";
3413
+ this.effect = new Effect();
3406
3414
  this.groups = {};
3407
3415
  this.move = new Move();
3408
3416
  this.number = new ParticlesNumber();
@@ -3418,22 +3426,26 @@ class ParticlesOptions {
3418
3426
  if (!data) {
3419
3427
  return;
3420
3428
  }
3421
- this.bounce.load(data.bounce);
3422
- this.color.load(AnimatableColor.create(this.color, data.color));
3423
3429
  if (data.groups !== undefined) {
3424
- for (const group in data.groups) {
3430
+ for (const group of Object.keys(data.groups)) {
3431
+ if (!Object.hasOwn(data.groups, group)) {
3432
+ continue;
3433
+ }
3425
3434
  const item = data.groups[group];
3426
3435
  if (item !== undefined) {
3427
3436
  this.groups[group] = deepExtend(this.groups[group] ?? {}, item);
3428
3437
  }
3429
3438
  }
3430
3439
  }
3431
- this.move.load(data.move);
3432
- this.number.load(data.number);
3433
- this.opacity.load(data.opacity);
3434
3440
  if (data.reduceDuplicates !== undefined) {
3435
3441
  this.reduceDuplicates = data.reduceDuplicates;
3436
3442
  }
3443
+ this.bounce.load(data.bounce);
3444
+ this.color.load(AnimatableColor.create(this.color, data.color));
3445
+ this.effect.load(data.effect);
3446
+ this.move.load(data.move);
3447
+ this.number.load(data.number);
3448
+ this.opacity.load(data.opacity);
3437
3449
  this.shape.load(data.shape);
3438
3450
  this.size.load(data.size);
3439
3451
  this.shadow.load(data.shadow);
@@ -3692,6 +3704,16 @@ class InteractionManager {
3692
3704
 
3693
3705
 
3694
3706
 
3707
+ function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
3708
+ const effectData = effectOptions.options[effect];
3709
+ if (!effectData) {
3710
+ return;
3711
+ }
3712
+ return deepExtend({
3713
+ close: effectOptions.close,
3714
+ fill: effectOptions.fill
3715
+ }, itemFromSingleOrMultiple(effectData, id, reduceDuplicates));
3716
+ }
3695
3717
  function loadShapeData(shape, shapeOptions, id, reduceDuplicates) {
3696
3718
  const shapeData = shapeOptions.options[shape];
3697
3719
  if (!shapeData) {
@@ -3770,8 +3792,8 @@ class Particle {
3770
3792
  const rad = Math.PI / 180 * getRangeValue(moveOptions.angle.value),
3771
3793
  radOffset = Math.PI / 180 * getRangeValue(moveOptions.angle.offset),
3772
3794
  range = {
3773
- left: radOffset - rad / 2,
3774
- right: radOffset + rad / 2
3795
+ left: radOffset - rad * 0.5,
3796
+ right: radOffset + rad * 0.5
3775
3797
  };
3776
3798
  if (!moveOptions.straight) {
3777
3799
  res.angle += randomInRange(setRangeValue(range.left, range.right));
@@ -3802,7 +3824,7 @@ class Particle {
3802
3824
  return color;
3803
3825
  }
3804
3826
  const backFactor = this.roll.horizontal && this.roll.vertical ? 2 : 1,
3805
- backSum = this.roll.horizontal ? Math.PI / 2 : 0,
3827
+ backSum = this.roll.horizontal ? Math.PI * 0.5 : 0,
3806
3828
  rolled = Math.floor(((this.roll.angle ?? 0) + backSum) / (Math.PI / backFactor)) % 2;
3807
3829
  if (!rolled) {
3808
3830
  return color;
@@ -3848,20 +3870,16 @@ class Particle {
3848
3870
  this.bubble.inRange = false;
3849
3871
  this.slow.inRange = false;
3850
3872
  const container = this.container,
3851
- pathGenerator = this.pathGenerator;
3873
+ pathGenerator = this.pathGenerator,
3874
+ shapeDrawer = container.shapeDrawers.get(this.shape);
3875
+ shapeDrawer && shapeDrawer.particleDestroy && shapeDrawer.particleDestroy(this);
3852
3876
  for (const [, plugin] of container.plugins) {
3853
- if (plugin.particleDestroyed) {
3854
- plugin.particleDestroyed(this, override);
3855
- }
3877
+ plugin.particleDestroyed && plugin.particleDestroyed(this, override);
3856
3878
  }
3857
3879
  for (const updater of container.particles.updaters) {
3858
- if (updater.particleDestroyed) {
3859
- updater.particleDestroyed(this, override);
3860
- }
3861
- }
3862
- if (pathGenerator) {
3863
- pathGenerator.reset(this);
3880
+ updater.particleDestroyed && updater.particleDestroyed(this, override);
3864
3881
  }
3882
+ pathGenerator && pathGenerator.reset(this);
3865
3883
  }
3866
3884
  draw(delta) {
3867
3885
  const container = this.container,
@@ -3875,7 +3893,7 @@ class Particle {
3875
3893
  return this._getRollColor(this.bubble.color ?? getHslFromAnimation(this.color));
3876
3894
  }
3877
3895
  getMass() {
3878
- return this.getRadius() ** 2 * Math.PI / 2;
3896
+ return this.getRadius() ** 2 * Math.PI * 0.5;
3879
3897
  }
3880
3898
  getPosition() {
3881
3899
  return {
@@ -3895,9 +3913,11 @@ class Particle {
3895
3913
  engine = this._engine;
3896
3914
  this.id = id;
3897
3915
  this.group = group;
3898
- this.fill = true;
3916
+ this.effectClose = true;
3917
+ this.effectFill = true;
3918
+ this.shapeClose = true;
3919
+ this.shapeFill = true;
3899
3920
  this.pathRotation = false;
3900
- this.close = true;
3901
3921
  this.lastPathTime = 0;
3902
3922
  this.destroyed = false;
3903
3923
  this.unbreakable = false;
@@ -3911,22 +3931,40 @@ class Particle {
3911
3931
  const pxRatio = container.retina.pixelRatio,
3912
3932
  mainOptions = container.actualOptions,
3913
3933
  particlesOptions = loadParticlesOptions(this._engine, container, mainOptions.particles),
3934
+ effectType = particlesOptions.effect.type,
3914
3935
  shapeType = particlesOptions.shape.type,
3915
3936
  {
3916
3937
  reduceDuplicates
3917
3938
  } = particlesOptions;
3939
+ this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
3918
3940
  this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
3919
- const shapeOptions = particlesOptions.shape;
3920
- if (overrideOptions && overrideOptions.shape && overrideOptions.shape.type) {
3921
- const overrideShapeType = overrideOptions.shape.type,
3922
- shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
3923
- if (shape) {
3924
- this.shape = shape;
3925
- shapeOptions.load(overrideOptions.shape);
3941
+ const effectOptions = particlesOptions.effect,
3942
+ shapeOptions = particlesOptions.shape;
3943
+ if (overrideOptions) {
3944
+ if (overrideOptions.effect && overrideOptions.effect.type) {
3945
+ const overrideEffectType = overrideOptions.effect.type,
3946
+ effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
3947
+ if (effect) {
3948
+ this.effect = effect;
3949
+ effectOptions.load(overrideOptions.effect);
3950
+ }
3951
+ }
3952
+ if (overrideOptions.shape && overrideOptions.shape.type) {
3953
+ const overrideShapeType = overrideOptions.shape.type,
3954
+ shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
3955
+ if (shape) {
3956
+ this.shape = shape;
3957
+ shapeOptions.load(overrideOptions.shape);
3958
+ }
3926
3959
  }
3927
3960
  }
3961
+ this.effectData = loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates);
3928
3962
  this.shapeData = loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates);
3929
3963
  particlesOptions.load(overrideOptions);
3964
+ const effectData = this.effectData;
3965
+ if (effectData) {
3966
+ particlesOptions.load(effectData.particles);
3967
+ }
3930
3968
  const shapeData = this.shapeData;
3931
3969
  if (shapeData) {
3932
3970
  particlesOptions.load(shapeData.particles);
@@ -3935,11 +3973,13 @@ class Particle {
3935
3973
  interactivity.load(container.actualOptions.interactivity);
3936
3974
  interactivity.load(particlesOptions.interactivity);
3937
3975
  this.interactivity = interactivity;
3938
- this.fill = shapeData?.fill ?? particlesOptions.shape.fill;
3939
- this.close = shapeData?.close ?? particlesOptions.shape.close;
3976
+ this.effectFill = effectData?.fill ?? particlesOptions.effect.fill;
3977
+ this.effectClose = effectData?.close ?? particlesOptions.effect.close;
3978
+ this.shapeFill = shapeData?.fill ?? particlesOptions.shape.fill;
3979
+ this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
3940
3980
  this.options = particlesOptions;
3941
3981
  const pathOptions = this.options.move.path;
3942
- this.pathDelay = getValue(pathOptions.delay) * 1000;
3982
+ this.pathDelay = getRangeValue(pathOptions.delay.value) * 1000;
3943
3983
  if (pathOptions.generator) {
3944
3984
  this.pathGenerator = this._engine.getPathGenerator(pathOptions.generator);
3945
3985
  if (this.pathGenerator && container.addPath(pathOptions.generator, this.pathGenerator)) {
@@ -3960,34 +4000,46 @@ class Particle {
3960
4000
  this.velocity = this.initialVelocity.copy();
3961
4001
  this.moveDecay = 1 - getRangeValue(this.options.move.decay);
3962
4002
  const particles = container.particles;
3963
- particles.needsSort = particles.needsSort || particles.lastZIndex < this.position.z;
3964
- particles.lastZIndex = this.position.z;
4003
+ particles.setLastZIndex(this.position.z);
3965
4004
  this.zIndexFactor = this.position.z / container.zLayers;
3966
4005
  this.sides = 24;
3967
- let drawer = container.drawers.get(this.shape);
3968
- if (!drawer) {
3969
- drawer = this._engine.getShapeDrawer(this.shape);
3970
- if (drawer) {
3971
- container.drawers.set(this.shape, drawer);
4006
+ let effectDrawer = container.effectDrawers.get(this.effect);
4007
+ if (!effectDrawer) {
4008
+ effectDrawer = this._engine.getEffectDrawer(this.effect);
4009
+ if (effectDrawer) {
4010
+ container.effectDrawers.set(this.effect, effectDrawer);
3972
4011
  }
3973
4012
  }
3974
- if (drawer && drawer.loadShape) {
3975
- drawer.loadShape(this);
4013
+ if (effectDrawer && effectDrawer.loadEffect) {
4014
+ effectDrawer.loadEffect(this);
3976
4015
  }
3977
- const sideCountFunc = drawer?.getSidesCount;
4016
+ let shapeDrawer = container.shapeDrawers.get(this.shape);
4017
+ if (!shapeDrawer) {
4018
+ shapeDrawer = this._engine.getShapeDrawer(this.shape);
4019
+ if (shapeDrawer) {
4020
+ container.shapeDrawers.set(this.shape, shapeDrawer);
4021
+ }
4022
+ }
4023
+ if (shapeDrawer && shapeDrawer.loadShape) {
4024
+ shapeDrawer.loadShape(this);
4025
+ }
4026
+ const sideCountFunc = shapeDrawer?.getSidesCount;
3978
4027
  if (sideCountFunc) {
3979
4028
  this.sides = sideCountFunc(this);
3980
4029
  }
3981
4030
  this.spawning = false;
3982
4031
  this.shadowColor = rangeColorToRgb(this.options.shadow.color);
3983
- for (const updater of container.particles.updaters) {
4032
+ for (const updater of particles.updaters) {
3984
4033
  updater.init(this);
3985
4034
  }
3986
- for (const mover of container.particles.movers) {
4035
+ for (const mover of particles.movers) {
3987
4036
  mover.init && mover.init(this);
3988
4037
  }
3989
- if (drawer && drawer.particleInit) {
3990
- drawer.particleInit(container, this);
4038
+ if (effectDrawer && effectDrawer.particleInit) {
4039
+ effectDrawer.particleInit(container, this);
4040
+ }
4041
+ if (shapeDrawer && shapeDrawer.particleInit) {
4042
+ shapeDrawer.particleInit(container, this);
3991
4043
  }
3992
4044
  for (const [, plugin] of container.plugins) {
3993
4045
  plugin.particleCreated && plugin.particleCreated(this);
@@ -4114,7 +4166,7 @@ class QuadTree {
4114
4166
  capacity
4115
4167
  } = this;
4116
4168
  for (let i = 0; i < 4; i++) {
4117
- this._subs.push(new QuadTree(new Rectangle(x + width / 2 * (i % 2), y + height / 2 * (Math.round(i / 2) - i % 2), width / 2, height / 2), capacity));
4169
+ this._subs.push(new QuadTree(new Rectangle(x + width * 0.5 * (i % 2), y + height * 0.5 * (Math.round(i * 0.5) - i % 2), width * 0.5, height * 0.5), capacity));
4118
4170
  }
4119
4171
  this._divided = true;
4120
4172
  };
@@ -4170,21 +4222,36 @@ class QuadTree {
4170
4222
 
4171
4223
  const qTreeCapacity = 4;
4172
4224
  const qTreeRectangle = canvasSize => {
4173
- return new Rectangle(-canvasSize.width / 4, -canvasSize.height / 4, canvasSize.width * 3 / 2, canvasSize.height * 3 / 2);
4225
+ const {
4226
+ height,
4227
+ width
4228
+ } = canvasSize,
4229
+ posOffset = -0.25,
4230
+ sizeFactor = 1.5;
4231
+ return new Rectangle(posOffset * width, posOffset * height, sizeFactor * width, sizeFactor * height);
4174
4232
  };
4175
4233
  class Particles {
4176
4234
  constructor(engine, container) {
4177
4235
  this._applyDensity = (options, manualCount, group) => {
4236
+ const numberOptions = options.number;
4178
4237
  if (!options.number.density?.enable) {
4238
+ if (group === undefined) {
4239
+ this._limit = numberOptions.limit.value;
4240
+ } else {
4241
+ this._groupLimits.set(group, numberOptions.limit.value);
4242
+ }
4179
4243
  return;
4180
4244
  }
4181
- const numberOptions = options.number,
4182
- densityFactor = this._initDensityFactor(numberOptions.density),
4245
+ const densityFactor = this._initDensityFactor(numberOptions.density),
4183
4246
  optParticlesNumber = numberOptions.value,
4184
- optParticlesLimit = numberOptions.limit > 0 ? numberOptions.limit : optParticlesNumber,
4247
+ optParticlesLimit = numberOptions.limit.value > 0 ? numberOptions.limit.value : optParticlesNumber,
4185
4248
  particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount,
4186
4249
  particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
4187
- this.limit = numberOptions.limit * densityFactor;
4250
+ if (group === undefined) {
4251
+ this._limit = numberOptions.limit.value * densityFactor;
4252
+ } else {
4253
+ this._groupLimits.set(group, numberOptions.limit.value * densityFactor);
4254
+ }
4188
4255
  if (particlesCount < particlesNumber) {
4189
4256
  this.push(Math.abs(particlesNumber - particlesCount), undefined, options, group);
4190
4257
  } else if (particlesCount > particlesNumber) {
@@ -4202,7 +4269,7 @@ class Particles {
4202
4269
  };
4203
4270
  this._pushParticle = (position, overrideOptions, group, initializer) => {
4204
4271
  try {
4205
- let particle = this.pool.pop();
4272
+ let particle = this._pool.pop();
4206
4273
  if (particle) {
4207
4274
  particle.init(this._nextId, position, overrideOptions, group);
4208
4275
  } else {
@@ -4239,7 +4306,7 @@ class Particles {
4239
4306
  const zIdx = this._zArray.indexOf(particle);
4240
4307
  this._array.splice(index, 1);
4241
4308
  this._zArray.splice(zIdx, 1);
4242
- this.pool.push(particle);
4309
+ this._pool.push(particle);
4243
4310
  this._engine.dispatchEvent("particleRemoved", {
4244
4311
  container: this._container,
4245
4312
  data: {
@@ -4253,10 +4320,11 @@ class Particles {
4253
4320
  this._nextId = 0;
4254
4321
  this._array = [];
4255
4322
  this._zArray = [];
4256
- this.pool = [];
4257
- this.limit = 0;
4258
- this.needsSort = false;
4259
- this.lastZIndex = 0;
4323
+ this._pool = [];
4324
+ this._limit = 0;
4325
+ this._groupLimits = new Map();
4326
+ this._needsSort = false;
4327
+ this._lastZIndex = 0;
4260
4328
  this._interactionManager = new InteractionManager(engine, container);
4261
4329
  const canvasSize = container.canvas.size;
4262
4330
  this.quadTree = new QuadTree(qTreeRectangle(canvasSize), qTreeCapacity);
@@ -4274,19 +4342,22 @@ class Particles {
4274
4342
  }
4275
4343
  }
4276
4344
  addParticle(position, overrideOptions, group, initializer) {
4277
- this.pushing = true;
4278
- const container = this._container,
4279
- options = container.actualOptions,
4280
- limit = options.particles.number.limit;
4345
+ const limitOptions = this._container.actualOptions.particles.number.limit,
4346
+ limit = group === undefined ? this._limit : this._groupLimits.get(group) ?? this._limit,
4347
+ currentCount = this.count;
4281
4348
  if (limit > 0) {
4282
- const countToRemove = this.count + 1 - limit;
4283
- if (countToRemove > 0) {
4284
- this.removeQuantity(countToRemove);
4349
+ if (limitOptions.mode === "delete") {
4350
+ const countToRemove = currentCount + 1 - limit;
4351
+ if (countToRemove > 0) {
4352
+ this.removeQuantity(countToRemove);
4353
+ }
4354
+ } else if (limitOptions.mode === "wait") {
4355
+ if (currentCount >= limit) {
4356
+ return;
4357
+ }
4285
4358
  }
4286
4359
  }
4287
- const res = this._pushParticle(position, overrideOptions, group, initializer);
4288
- this.pushing = false;
4289
- return res;
4360
+ return this._pushParticle(position, overrideOptions, group, initializer);
4290
4361
  }
4291
4362
  clear() {
4292
4363
  this._array = [];
@@ -4325,8 +4396,8 @@ class Particles {
4325
4396
  init() {
4326
4397
  const container = this._container,
4327
4398
  options = container.actualOptions;
4328
- this.lastZIndex = 0;
4329
- this.needsSort = false;
4399
+ this._lastZIndex = 0;
4400
+ this._needsSort = false;
4330
4401
  let handled = false;
4331
4402
  this.updaters = this._engine.getUpdaters(container, true);
4332
4403
  this._interactionManager.init();
@@ -4393,6 +4464,13 @@ class Particles {
4393
4464
  }
4394
4465
  this._applyDensity(options.particles, options.manualParticles.length);
4395
4466
  }
4467
+ setLastZIndex(zIndex) {
4468
+ this._lastZIndex = zIndex;
4469
+ this._needsSort = this._needsSort || this._lastZIndex < zIndex;
4470
+ }
4471
+ setResizeFactor(factor) {
4472
+ this._resizeFactor = factor;
4473
+ }
4396
4474
  async update(delta) {
4397
4475
  const container = this._container,
4398
4476
  particlesToDelete = new Set();
@@ -4401,10 +4479,10 @@ class Particles {
4401
4479
  pathGenerator.update();
4402
4480
  }
4403
4481
  for (const [, plugin] of container.plugins) {
4404
- plugin.update && plugin.update(delta);
4482
+ plugin.update && (await plugin.update(delta));
4405
4483
  }
4484
+ const resizeFactor = this._resizeFactor;
4406
4485
  for (const particle of this._array) {
4407
- const resizeFactor = container.canvas.resizeFactor;
4408
4486
  if (resizeFactor && !particle.ignoresResizeRatio) {
4409
4487
  particle.position.x *= resizeFactor.width;
4410
4488
  particle.position.y *= resizeFactor.height;
@@ -4432,7 +4510,7 @@ class Particles {
4432
4510
  const checkDelete = p => !particlesToDelete.has(p);
4433
4511
  this._array = this.filter(checkDelete);
4434
4512
  this._zArray = this._zArray.filter(checkDelete);
4435
- this.pool.push(...particlesToDelete);
4513
+ this._pool.push(...particlesToDelete);
4436
4514
  }
4437
4515
  await this._interactionManager.externalInteract(delta);
4438
4516
  for (const particle of this._array) {
@@ -4443,12 +4521,12 @@ class Particles {
4443
4521
  await this._interactionManager.particlesInteract(particle, delta);
4444
4522
  }
4445
4523
  }
4446
- delete container.canvas.resizeFactor;
4447
- if (this.needsSort) {
4524
+ delete this._resizeFactor;
4525
+ if (this._needsSort) {
4448
4526
  const zArray = this._zArray;
4449
4527
  zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
4450
- this.lastZIndex = zArray[zArray.length - 1].position.z;
4451
- this.needsSort = false;
4528
+ this._lastZIndex = zArray[zArray.length - 1].position.z;
4529
+ this._needsSort = false;
4452
4530
  }
4453
4531
  }
4454
4532
  }
@@ -4475,7 +4553,6 @@ class Retina {
4475
4553
  }
4476
4554
  const particles = options.particles,
4477
4555
  moveOptions = particles.move;
4478
- this.attractDistance = getRangeValue(moveOptions.attract.distance) * ratio;
4479
4556
  this.maxSpeed = getRangeValue(moveOptions.gravity.maxSpeed) * ratio;
4480
4557
  this.sizeAnimationSpeed = getRangeValue(particles.size.animation.speed) * ratio;
4481
4558
  }
@@ -4485,7 +4562,6 @@ class Retina {
4485
4562
  moveOptions = options.move,
4486
4563
  moveDistance = moveOptions.distance,
4487
4564
  props = particle.retina;
4488
- props.attractDistance = getRangeValue(moveOptions.attract.distance) * ratio;
4489
4565
  props.moveDrift = getRangeValue(moveOptions.drift) * ratio;
4490
4566
  props.moveSpeed = getRangeValue(moveOptions.speed) * ratio;
4491
4567
  props.sizeAnimationSpeed = getRangeValue(options.size.animation.speed) * ratio;
@@ -4534,14 +4610,14 @@ class Container {
4534
4610
  };
4535
4611
  this._nextFrame = async timestamp => {
4536
4612
  try {
4537
- if (!this.smooth && this.lastFrameTime !== undefined && timestamp < this.lastFrameTime + 1000 / this.fpsLimit) {
4613
+ if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + 1000 / this.fpsLimit) {
4538
4614
  this.draw(false);
4539
4615
  return;
4540
4616
  }
4541
- this.lastFrameTime ??= timestamp;
4542
- const delta = initDelta(timestamp - this.lastFrameTime, this.fpsLimit, this.smooth);
4617
+ this._lastFrameTime ??= timestamp;
4618
+ const delta = initDelta(timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
4543
4619
  this.addLifeTime(delta.value);
4544
- this.lastFrameTime = timestamp;
4620
+ this._lastFrameTime = timestamp;
4545
4621
  if (delta.value > 1000) {
4546
4622
  this.draw(false);
4547
4623
  return;
@@ -4561,7 +4637,7 @@ class Container {
4561
4637
  this._engine = engine;
4562
4638
  this.id = Symbol(id);
4563
4639
  this.fpsLimit = 120;
4564
- this.smooth = false;
4640
+ this._smooth = false;
4565
4641
  this._delay = 0;
4566
4642
  this._duration = 0;
4567
4643
  this._lifeTime = 0;
@@ -4569,7 +4645,7 @@ class Container {
4569
4645
  this.started = false;
4570
4646
  this.destroyed = false;
4571
4647
  this._paused = true;
4572
- this.lastFrameTime = 0;
4648
+ this._lastFrameTime = 0;
4573
4649
  this.zLayers = 100;
4574
4650
  this.pageHidden = false;
4575
4651
  this._sourceOptions = sourceOptions;
@@ -4585,7 +4661,8 @@ class Container {
4585
4661
  }
4586
4662
  };
4587
4663
  this.plugins = new Map();
4588
- this.drawers = new Map();
4664
+ this.effectDrawers = new Map();
4665
+ this.shapeDrawers = new Map();
4589
4666
  this._options = loadContainerOptions(this._engine, this);
4590
4667
  this.actualOptions = loadContainerOptions(this._engine, this);
4591
4668
  this._eventListeners = new EventListeners(this);
@@ -4703,11 +4780,17 @@ class Container {
4703
4780
  this.stop();
4704
4781
  this.particles.destroy();
4705
4782
  this.canvas.destroy();
4706
- for (const [, drawer] of this.drawers) {
4707
- drawer.destroy && drawer.destroy(this);
4783
+ for (const [, effectDrawer] of this.effectDrawers) {
4784
+ effectDrawer.destroy && effectDrawer.destroy(this);
4785
+ }
4786
+ for (const [, shapeDrawer] of this.shapeDrawers) {
4787
+ shapeDrawer.destroy && shapeDrawer.destroy(this);
4708
4788
  }
4709
- for (const key of this.drawers.keys()) {
4710
- this.drawers.delete(key);
4789
+ for (const key of this.effectDrawers.keys()) {
4790
+ this.effectDrawers.delete(key);
4791
+ }
4792
+ for (const key of this.shapeDrawers.keys()) {
4793
+ this.shapeDrawers.delete(key);
4711
4794
  }
4712
4795
  this._engine.clearPlugins(this);
4713
4796
  this.destroyed = true;
@@ -4727,7 +4810,7 @@ class Container {
4727
4810
  let refreshTime = force;
4728
4811
  this._drawAnimationFrame = requestAnimationFrame(async timestamp => {
4729
4812
  if (refreshTime) {
4730
- this.lastFrameTime = undefined;
4813
+ this._lastFrameTime = undefined;
4731
4814
  refreshTime = false;
4732
4815
  }
4733
4816
  await this._nextFrame(timestamp);
@@ -4762,11 +4845,18 @@ class Container {
4762
4845
  if (!guardCheck(this)) {
4763
4846
  return;
4764
4847
  }
4848
+ const effects = this._engine.getSupportedEffects();
4849
+ for (const type of effects) {
4850
+ const drawer = this._engine.getEffectDrawer(type);
4851
+ if (drawer) {
4852
+ this.effectDrawers.set(type, drawer);
4853
+ }
4854
+ }
4765
4855
  const shapes = this._engine.getSupportedShapes();
4766
4856
  for (const type of shapes) {
4767
4857
  const drawer = this._engine.getShapeDrawer(type);
4768
4858
  if (drawer) {
4769
- this.drawers.set(type, drawer);
4859
+ this.shapeDrawers.set(type, drawer);
4770
4860
  }
4771
4861
  }
4772
4862
  this._options = loadContainerOptions(this._engine, this, this._initialSourceOptions, this.sourceOptions);
@@ -4785,8 +4875,11 @@ class Container {
4785
4875
  this._delay = getRangeValue(this.actualOptions.delay) * 1000;
4786
4876
  this._lifeTime = 0;
4787
4877
  this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 120;
4788
- this.smooth = this.actualOptions.smooth;
4789
- for (const [, drawer] of this.drawers) {
4878
+ this._smooth = this.actualOptions.smooth;
4879
+ for (const [, drawer] of this.effectDrawers) {
4880
+ drawer.init && (await drawer.init(this));
4881
+ }
4882
+ for (const [, drawer] of this.shapeDrawers) {
4790
4883
  drawer.init && (await drawer.init(this));
4791
4884
  }
4792
4885
  for (const [, plugin] of this.plugins) {
@@ -4927,10 +5020,10 @@ class Container {
4927
5020
  this.actualOptions.responsive = [];
4928
5021
  const newMaxWidth = this.actualOptions.setResponsive(this.canvas.size.width, this.retina.pixelRatio, this._options);
4929
5022
  this.actualOptions.setTheme(this._currentTheme);
4930
- if (this.responsiveMaxWidth === newMaxWidth) {
5023
+ if (this._responsiveMaxWidth === newMaxWidth) {
4931
5024
  return false;
4932
5025
  }
4933
- this.responsiveMaxWidth = newMaxWidth;
5026
+ this._responsiveMaxWidth = newMaxWidth;
4934
5027
  return true;
4935
5028
  }
4936
5029
  }
@@ -5021,7 +5114,8 @@ class Engine {
5021
5114
  this.movers = new Map();
5022
5115
  this.updaters = new Map();
5023
5116
  this.presets = new Map();
5024
- this.drawers = new Map();
5117
+ this.effectDrawers = new Map();
5118
+ this.shapeDrawers = new Map();
5025
5119
  this.pathGenerators = new Map();
5026
5120
  }
5027
5121
  get configs() {
@@ -5032,7 +5126,7 @@ class Engine {
5032
5126
  return res;
5033
5127
  }
5034
5128
  get version() {
5035
- return "3.0.0-beta.3";
5129
+ return "3.0.0-beta.5";
5036
5130
  }
5037
5131
  addConfig(config) {
5038
5132
  const name = config.name ?? "default";
@@ -5044,6 +5138,12 @@ class Engine {
5044
5138
  }
5045
5139
  });
5046
5140
  }
5141
+ async addEffect(effect, drawer, refresh = true) {
5142
+ executeOnSingleOrMultiple(effect, type => {
5143
+ !this.getEffectDrawer(type) && this.effectDrawers.set(type, drawer);
5144
+ });
5145
+ await this.refresh(refresh);
5146
+ }
5047
5147
  addEventListener(type, listener) {
5048
5148
  this._eventDispatcher.addEventListener(type, listener);
5049
5149
  }
@@ -5073,7 +5173,7 @@ class Engine {
5073
5173
  }
5074
5174
  async addShape(shape, drawer, refresh = true) {
5075
5175
  executeOnSingleOrMultiple(shape, type => {
5076
- !this.getShapeDrawer(type) && this.drawers.set(type, drawer);
5176
+ !this.getShapeDrawer(type) && this.shapeDrawers.set(type, drawer);
5077
5177
  });
5078
5178
  await this.refresh(refresh);
5079
5179
  }
@@ -5104,6 +5204,9 @@ class Engine {
5104
5204
  }
5105
5205
  return res;
5106
5206
  }
5207
+ getEffectDrawer(type) {
5208
+ return this.effectDrawers.get(type);
5209
+ }
5107
5210
  getInteractors(container, force = false) {
5108
5211
  return getItemsFromInitializer(container, this.interactors, this._initializers.interactors, force);
5109
5212
  }
@@ -5120,10 +5223,13 @@ class Engine {
5120
5223
  return this.presets.get(preset);
5121
5224
  }
5122
5225
  getShapeDrawer(type) {
5123
- return this.drawers.get(type);
5226
+ return this.shapeDrawers.get(type);
5227
+ }
5228
+ getSupportedEffects() {
5229
+ return this.effectDrawers.keys();
5124
5230
  }
5125
5231
  getSupportedShapes() {
5126
- return this.drawers.keys();
5232
+ return this.shapeDrawers.keys();
5127
5233
  }
5128
5234
  getUpdaters(container, force = false) {
5129
5235
  return getItemsFromInitializer(container, this.updaters, this._initializers.updaters, force);
@@ -5419,7 +5525,6 @@ class ParticlesInteractorBase {
5419
5525
 
5420
5526
 
5421
5527
 
5422
-
5423
5528
 
5424
5529
 
5425
5530
  ;// CONCATENATED MODULE: ../../engine/dist/browser/index.js
@@ -5432,140 +5537,6 @@ if (!isSsr()) {
5432
5537
 
5433
5538
 
5434
5539
 
5435
- ;// CONCATENATED MODULE: ../pjs/dist/browser/marcbruederlin/Particles.js
5436
-
5437
- class Particles_Particles {
5438
- static init(options) {
5439
- const particles = new Particles_Particles(),
5440
- selector = options.selector;
5441
- if (!selector) {
5442
- throw new Error("No selector provided");
5443
- }
5444
- const el = document.querySelector(selector);
5445
- if (!el) {
5446
- throw new Error("No element found for selector");
5447
- }
5448
- tsParticles.load({
5449
- id: selector.replace(".", "").replace("!", ""),
5450
- element: el,
5451
- options: {
5452
- fullScreen: {
5453
- enable: false
5454
- },
5455
- particles: {
5456
- color: {
5457
- value: options.color ?? "!000000"
5458
- },
5459
- links: {
5460
- color: "random",
5461
- distance: options.minDistance ?? 120,
5462
- enable: options.connectParticles ?? false
5463
- },
5464
- move: {
5465
- enable: true,
5466
- speed: options.speed ?? 0.5
5467
- },
5468
- number: {
5469
- value: options.maxParticles ?? 100
5470
- },
5471
- size: {
5472
- value: {
5473
- min: 1,
5474
- max: options.sizeVariations ?? 3
5475
- }
5476
- }
5477
- },
5478
- responsive: options.responsive?.map(responsive => ({
5479
- maxWidth: responsive.breakpoint,
5480
- options: {
5481
- particles: {
5482
- color: {
5483
- value: responsive.options?.color
5484
- },
5485
- links: {
5486
- distance: responsive.options?.minDistance,
5487
- enable: responsive.options?.connectParticles
5488
- },
5489
- number: {
5490
- value: options.maxParticles
5491
- },
5492
- move: {
5493
- enable: true,
5494
- speed: responsive.options?.speed
5495
- },
5496
- size: {
5497
- value: responsive.options?.sizeVariations
5498
- }
5499
- }
5500
- }
5501
- }))
5502
- }
5503
- }).then(container => {
5504
- particles._container = container;
5505
- });
5506
- return particles;
5507
- }
5508
- destroy() {
5509
- const container = this._container;
5510
- container && container.destroy();
5511
- }
5512
- pauseAnimation() {
5513
- const container = this._container;
5514
- container && container.pause();
5515
- }
5516
- resumeAnimation() {
5517
- const container = this._container;
5518
- container && container.play();
5519
- }
5520
- }
5521
- ;// CONCATENATED MODULE: ../pjs/dist/browser/VincentGarreau/particles.js
5522
- const initParticlesJS = engine => {
5523
- const particlesJS = (tagId, options) => {
5524
- return engine.load({
5525
- id: tagId,
5526
- options
5527
- });
5528
- };
5529
- particlesJS.load = (tagId, pathConfigJson, callback) => {
5530
- engine.load({
5531
- id: tagId,
5532
- url: pathConfigJson
5533
- }).then(container => {
5534
- if (container) {
5535
- callback(container);
5536
- }
5537
- }).catch(() => {
5538
- callback(undefined);
5539
- });
5540
- };
5541
- particlesJS.setOnClickHandler = callback => {
5542
- engine.setOnClickHandler(callback);
5543
- };
5544
- const pJSDom = engine.dom();
5545
- return {
5546
- particlesJS,
5547
- pJSDom
5548
- };
5549
- };
5550
-
5551
- ;// CONCATENATED MODULE: ../pjs/dist/browser/index.js
5552
-
5553
-
5554
- const initPjs = engine => {
5555
- const {
5556
- particlesJS,
5557
- pJSDom
5558
- } = initParticlesJS(engine);
5559
- window.particlesJS = particlesJS;
5560
- window.pJSDom = pJSDom;
5561
- window.Particles = Particles_Particles;
5562
- return {
5563
- particlesJS,
5564
- pJSDom,
5565
- Particles: Particles_Particles
5566
- };
5567
- };
5568
-
5569
5540
  ;// CONCATENATED MODULE: ../../move/base/dist/browser/Utils.js
5570
5541
 
5571
5542
  function applyDistance(particle) {
@@ -5587,10 +5558,10 @@ function applyDistance(particle) {
5587
5558
  if ((hDistance && dxFixed >= hDistance || vDistance && dyFixed >= vDistance) && !particle.misplaced) {
5588
5559
  particle.misplaced = !!hDistance && dxFixed > hDistance || !!vDistance && dyFixed > vDistance;
5589
5560
  if (hDistance) {
5590
- particle.velocity.x = particle.velocity.y / 2 - particle.velocity.x;
5561
+ particle.velocity.x = particle.velocity.y * 0.5 - particle.velocity.x;
5591
5562
  }
5592
5563
  if (vDistance) {
5593
- particle.velocity.y = particle.velocity.x / 2 - particle.velocity.y;
5564
+ particle.velocity.y = particle.velocity.x * 0.5 - particle.velocity.y;
5594
5565
  }
5595
5566
  } else if ((!hDistance || dxFixed < hDistance) && (!vDistance || dyFixed < vDistance) && particle.misplaced) {
5596
5567
  particle.misplaced = false;
@@ -5648,15 +5619,16 @@ function spin(particle, moveSpeed) {
5648
5619
  particle.position.x = particle.spin.center.x + particle.spin.radius * updateFunc.x(particle.spin.angle);
5649
5620
  particle.position.y = particle.spin.center.y + particle.spin.radius * updateFunc.y(particle.spin.angle);
5650
5621
  particle.spin.radius += particle.spin.acceleration;
5651
- const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height);
5652
- if (particle.spin.radius > maxCanvasSize / 2) {
5653
- particle.spin.radius = maxCanvasSize / 2;
5622
+ const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height),
5623
+ halfMaxSize = maxCanvasSize * 0.5;
5624
+ if (particle.spin.radius > halfMaxSize) {
5625
+ particle.spin.radius = halfMaxSize;
5654
5626
  particle.spin.acceleration *= -1;
5655
5627
  } else if (particle.spin.radius < 0) {
5656
5628
  particle.spin.radius = 0;
5657
5629
  particle.spin.acceleration *= -1;
5658
5630
  }
5659
- particle.spin.angle += moveSpeed / 100 * (1 - particle.spin.radius / maxCanvasSize);
5631
+ particle.spin.angle += moveSpeed * 0.01 * (1 - particle.spin.radius / maxCanvasSize);
5660
5632
  }
5661
5633
  function applyPath(particle, delta) {
5662
5634
  const particlesOptions = particle.options,
@@ -5700,8 +5672,8 @@ class BaseMover {
5700
5672
  y: 50
5701
5673
  },
5702
5674
  spinCenter = {
5703
- x: spinPos.x / 100 * container.canvas.size.width,
5704
- y: spinPos.y / 100 * container.canvas.size.height
5675
+ x: spinPos.x * 0.01 * container.canvas.size.width,
5676
+ y: spinPos.y * 0.01 * container.canvas.size.height
5705
5677
  },
5706
5678
  pos = particle.getPosition(),
5707
5679
  distance = getDistance(pos, spinCenter),
@@ -6024,7 +5996,7 @@ function bounceHorizontal(data) {
6024
5996
  const velocity = data.particle.velocity.x;
6025
5997
  let bounced = false;
6026
5998
  if (data.direction === "right" && data.bounds.right >= data.canvasSize.width && velocity > 0 || data.direction === "left" && data.bounds.left <= 0 && velocity < 0) {
6027
- const newVelocity = getValue(data.particle.options.bounce.horizontal);
5999
+ const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
6028
6000
  data.particle.velocity.x *= -newVelocity;
6029
6001
  bounced = true;
6030
6002
  }
@@ -6053,7 +6025,7 @@ function bounceVertical(data) {
6053
6025
  const velocity = data.particle.velocity.y;
6054
6026
  let bounced = false;
6055
6027
  if (data.direction === "bottom" && data.bounds.bottom >= data.canvasSize.height && velocity > 0 || data.direction === "top" && data.bounds.top <= 0 && velocity < 0) {
6056
- const newVelocity = getValue(data.particle.options.bounce.vertical);
6028
+ const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
6057
6029
  data.particle.velocity.y *= -newVelocity;
6058
6030
  bounced = true;
6059
6031
  }
@@ -6466,6 +6438,88 @@ async function loadEasingQuadPlugin() {
6466
6438
  addEasing("ease-out-quad", value => 1 - (1 - value) ** 2);
6467
6439
  addEasing("ease-in-out-quad", value => value < 0.5 ? 2 * value ** 2 : 1 - (-2 * value + 2) ** 2 / 2);
6468
6440
  }
6441
+ ;// CONCATENATED MODULE: ../../shapes/emoji/dist/browser/EmojiDrawer.js
6442
+
6443
+ const validTypes = ["emoji"];
6444
+ const defaultFont = '"Twemoji Mozilla", Apple Color Emoji, "Segoe UI Emoji", "Noto Color Emoji", "EmojiOne Color"';
6445
+ class EmojiDrawer {
6446
+ constructor() {
6447
+ this._emojiShapeDict = new Map();
6448
+ }
6449
+ destroy() {
6450
+ for (const [, emojiData] of this._emojiShapeDict) {
6451
+ emojiData?.close();
6452
+ }
6453
+ }
6454
+ draw(data) {
6455
+ const {
6456
+ context,
6457
+ particle,
6458
+ radius,
6459
+ opacity
6460
+ } = data,
6461
+ emojiData = particle.emojiData;
6462
+ if (!emojiData) {
6463
+ return;
6464
+ }
6465
+ context.globalAlpha = opacity;
6466
+ context.drawImage(emojiData, -radius, -radius, radius * 2, radius * 2);
6467
+ context.globalAlpha = 1;
6468
+ }
6469
+ async init(container) {
6470
+ const options = container.actualOptions;
6471
+ if (validTypes.find(t => isInArray(t, options.particles.shape.type))) {
6472
+ const promises = [loadFont(defaultFont)],
6473
+ shapeOptions = validTypes.map(t => options.particles.shape.options[t]).find(t => !!t);
6474
+ if (shapeOptions) {
6475
+ executeOnSingleOrMultiple(shapeOptions, shape => {
6476
+ shape.font && promises.push(loadFont(shape.font));
6477
+ });
6478
+ }
6479
+ await Promise.all(promises);
6480
+ }
6481
+ }
6482
+ particleDestroy(particle) {
6483
+ delete particle.emojiData;
6484
+ }
6485
+ particleInit(container, particle) {
6486
+ if (!particle.emojiData) {
6487
+ const shapeData = particle.shapeData;
6488
+ if (!shapeData?.value) {
6489
+ return;
6490
+ }
6491
+ const emoji = itemFromSingleOrMultiple(shapeData.value, particle.randomIndexData),
6492
+ font = shapeData.font ?? defaultFont;
6493
+ if (!emoji) {
6494
+ return;
6495
+ }
6496
+ const key = `${emoji}_${font}`,
6497
+ existingData = this._emojiShapeDict.get(key);
6498
+ if (existingData) {
6499
+ particle.emojiData = existingData;
6500
+ return;
6501
+ }
6502
+ const canvasSize = getRangeMax(particle.size.value) * 2,
6503
+ canvas = new OffscreenCanvas(canvasSize, canvasSize);
6504
+ const context = canvas.getContext("2d");
6505
+ if (!context) {
6506
+ return;
6507
+ }
6508
+ context.font = `400 ${getRangeMax(particle.size.value) * 2}px ${font}`;
6509
+ context.textBaseline = "middle";
6510
+ context.textAlign = "center";
6511
+ context.fillText(emoji, getRangeMax(particle.size.value), getRangeMax(particle.size.value));
6512
+ const emojiData = canvas.transferToImageBitmap();
6513
+ this._emojiShapeDict.set(key, emojiData);
6514
+ particle.emojiData = emojiData;
6515
+ }
6516
+ }
6517
+ }
6518
+ ;// CONCATENATED MODULE: ../../shapes/emoji/dist/browser/index.js
6519
+
6520
+ async function loadEmojiShape(engine, refresh = true) {
6521
+ await engine.addShape(validTypes, new EmojiDrawer(), refresh);
6522
+ }
6469
6523
  ;// CONCATENATED MODULE: ../../interactions/external/attract/dist/browser/Options/Classes/Attract.js
6470
6524
  class Attract {
6471
6525
  constructor() {
@@ -6503,6 +6557,7 @@ class Attract {
6503
6557
  ;// CONCATENATED MODULE: ../../interactions/external/attract/dist/browser/Attractor.js
6504
6558
 
6505
6559
 
6560
+ const attractMode = "attract";
6506
6561
  class Attractor extends ExternalInteractorBase {
6507
6562
  constructor(engine, container) {
6508
6563
  super(container);
@@ -6574,7 +6629,7 @@ class Attractor extends ExternalInteractorBase {
6574
6629
  this.handleClickMode = mode => {
6575
6630
  const options = this.container.actualOptions,
6576
6631
  attract = options.interactivity.modes.attract;
6577
- if (!attract || mode !== "attract") {
6632
+ if (!attract || mode !== attractMode) {
6578
6633
  return;
6579
6634
  }
6580
6635
  if (!container.attract) {
@@ -6623,9 +6678,9 @@ class Attractor extends ExternalInteractorBase {
6623
6678
  hoverMode = events.onHover.mode,
6624
6679
  clickEnabled = events.onClick.enable,
6625
6680
  clickMode = events.onClick.mode;
6626
- if (mouseMoveStatus && hoverEnabled && isInArray("attract", hoverMode)) {
6681
+ if (mouseMoveStatus && hoverEnabled && isInArray(attractMode, hoverMode)) {
6627
6682
  this._hoverAttract();
6628
- } else if (clickEnabled && isInArray("attract", clickMode)) {
6683
+ } else if (clickEnabled && isInArray(attractMode, clickMode)) {
6629
6684
  this._clickAttract();
6630
6685
  }
6631
6686
  }
@@ -6639,7 +6694,7 @@ class Attractor extends ExternalInteractorBase {
6639
6694
  }
6640
6695
  const hoverMode = events.onHover.mode,
6641
6696
  clickMode = events.onClick.mode;
6642
- return isInArray("attract", hoverMode) || isInArray("attract", clickMode);
6697
+ return isInArray(attractMode, hoverMode) || isInArray(attractMode, clickMode);
6643
6698
  }
6644
6699
  loadModeOptions(options, ...sources) {
6645
6700
  if (!options.attract) {
@@ -6675,6 +6730,7 @@ class Bounce {
6675
6730
  ;// CONCATENATED MODULE: ../../interactions/external/bounce/dist/browser/Bouncer.js
6676
6731
 
6677
6732
 
6733
+ const bounceMode = "bounce";
6678
6734
  class Bouncer extends ExternalInteractorBase {
6679
6735
  constructor(container) {
6680
6736
  super(container);
@@ -6742,10 +6798,10 @@ class Bouncer extends ExternalInteractorBase {
6742
6798
  hoverEnabled = events.onHover.enable,
6743
6799
  hoverMode = events.onHover.mode,
6744
6800
  divs = events.onDiv;
6745
- if (mouseMoveStatus && hoverEnabled && isInArray("bounce", hoverMode)) {
6801
+ if (mouseMoveStatus && hoverEnabled && isInArray(bounceMode, hoverMode)) {
6746
6802
  this._processMouseBounce();
6747
6803
  } else {
6748
- divModeExecute("bounce", divs, (selector, div) => this._singleSelectorBounce(selector, div));
6804
+ divModeExecute(bounceMode, divs, (selector, div) => this._singleSelectorBounce(selector, div));
6749
6805
  }
6750
6806
  }
6751
6807
  isEnabled(particle) {
@@ -6754,7 +6810,7 @@ class Bouncer extends ExternalInteractorBase {
6754
6810
  mouse = container.interactivity.mouse,
6755
6811
  events = (particle?.interactivity ?? options.interactivity).events,
6756
6812
  divs = events.onDiv;
6757
- return mouse.position && events.onHover.enable && isInArray("bounce", events.onHover.mode) || isDivModeEnabled("bounce", divs);
6813
+ return mouse.position && events.onHover.enable && isInArray(bounceMode, events.onHover.mode) || isDivModeEnabled(bounceMode, divs);
6758
6814
  }
6759
6815
  loadModeOptions(options, ...sources) {
6760
6816
  if (!options.bounce) {
@@ -6857,6 +6913,7 @@ function calculateBubbleValue(particleValue, modeValue, optionsValue, ratio) {
6857
6913
 
6858
6914
 
6859
6915
 
6916
+ const bubbleMode = "bubble";
6860
6917
  class Bubbler extends ExternalInteractorBase {
6861
6918
  constructor(container) {
6862
6919
  super(container);
@@ -7093,7 +7150,7 @@ class Bubbler extends ExternalInteractorBase {
7093
7150
  container.bubble = {};
7094
7151
  }
7095
7152
  this.handleClickMode = mode => {
7096
- if (mode !== "bubble") {
7153
+ if (mode !== bubbleMode) {
7097
7154
  return;
7098
7155
  }
7099
7156
  if (!container.bubble) {
@@ -7132,12 +7189,12 @@ class Bubbler extends ExternalInteractorBase {
7132
7189
  clickEnabled = onClick.enable,
7133
7190
  clickMode = onClick.mode,
7134
7191
  divs = events.onDiv;
7135
- if (hoverEnabled && isInArray("bubble", hoverMode)) {
7192
+ if (hoverEnabled && isInArray(bubbleMode, hoverMode)) {
7136
7193
  this._hoverBubble();
7137
- } else if (clickEnabled && isInArray("bubble", clickMode)) {
7194
+ } else if (clickEnabled && isInArray(bubbleMode, clickMode)) {
7138
7195
  this._clickBubble();
7139
7196
  } else {
7140
- divModeExecute("bubble", divs, (selector, div) => this._singleSelectorHover(delta, selector, div));
7197
+ divModeExecute(bubbleMode, divs, (selector, div) => this._singleSelectorHover(delta, selector, div));
7141
7198
  }
7142
7199
  }
7143
7200
  isEnabled(particle) {
@@ -7150,11 +7207,11 @@ class Bubbler extends ExternalInteractorBase {
7150
7207
  onDiv,
7151
7208
  onHover
7152
7209
  } = events,
7153
- divBubble = isDivModeEnabled("bubble", onDiv);
7210
+ divBubble = isDivModeEnabled(bubbleMode, onDiv);
7154
7211
  if (!(divBubble || onHover.enable && mouse.position || onClick.enable && mouse.clickPosition)) {
7155
7212
  return false;
7156
7213
  }
7157
- return isInArray("bubble", onHover.mode) || isInArray("bubble", onClick.mode) || divBubble;
7214
+ return isInArray(bubbleMode, onHover.mode) || isInArray(bubbleMode, onClick.mode) || divBubble;
7158
7215
  }
7159
7216
  loadModeOptions(options, ...sources) {
7160
7217
  if (!options.bubble) {
@@ -7261,6 +7318,7 @@ function drawConnection(container, p1, p2) {
7261
7318
 
7262
7319
 
7263
7320
 
7321
+ const connectMode = "connect";
7264
7322
  class Connector extends ExternalInteractorBase {
7265
7323
  constructor(container) {
7266
7324
  super(container);
@@ -7308,7 +7366,7 @@ class Connector extends ExternalInteractorBase {
7308
7366
  if (!(events.onHover.enable && mouse.position)) {
7309
7367
  return false;
7310
7368
  }
7311
- return isInArray("connect", events.onHover.mode);
7369
+ return isInArray(connectMode, events.onHover.mode);
7312
7370
  }
7313
7371
  loadModeOptions(options, ...sources) {
7314
7372
  if (!options.connect) {
@@ -7362,18 +7420,6 @@ class Grab {
7362
7420
  this.distance = 100;
7363
7421
  this.links = new GrabLinks();
7364
7422
  }
7365
- get lineLinked() {
7366
- return this.links;
7367
- }
7368
- set lineLinked(value) {
7369
- this.links = value;
7370
- }
7371
- get line_linked() {
7372
- return this.links;
7373
- }
7374
- set line_linked(value) {
7375
- this.links = value;
7376
- }
7377
7423
  load(data) {
7378
7424
  if (!data) {
7379
7425
  return;
@@ -7381,7 +7427,7 @@ class Grab {
7381
7427
  if (data.distance !== undefined) {
7382
7428
  this.distance = data.distance;
7383
7429
  }
7384
- this.links.load(data.links ?? data.lineLinked ?? data.line_linked);
7430
+ this.links.load(data.links);
7385
7431
  }
7386
7432
  }
7387
7433
  ;// CONCATENATED MODULE: ../../interactions/external/grab/dist/browser/Utils.js
@@ -7402,6 +7448,7 @@ function drawGrab(container, particle, lineColor, opacity, mousePos) {
7402
7448
 
7403
7449
 
7404
7450
 
7451
+ const grabMode = "grab";
7405
7452
  class Grabber extends ExternalInteractorBase {
7406
7453
  constructor(container) {
7407
7454
  super(container);
@@ -7459,7 +7506,7 @@ class Grabber extends ExternalInteractorBase {
7459
7506
  const container = this.container,
7460
7507
  mouse = container.interactivity.mouse,
7461
7508
  events = (particle?.interactivity ?? container.actualOptions.interactivity).events;
7462
- return events.onHover.enable && !!mouse.position && isInArray("grab", events.onHover.mode);
7509
+ return events.onHover.enable && !!mouse.position && isInArray(grabMode, events.onHover.mode);
7463
7510
  }
7464
7511
  loadModeOptions(options, ...sources) {
7465
7512
  if (!options.grab) {
@@ -7482,11 +7529,12 @@ async function loadExternalGrabInteraction(engine, refresh = true) {
7482
7529
 
7483
7530
  ;// CONCATENATED MODULE: ../../interactions/external/pause/dist/browser/Pauser.js
7484
7531
 
7532
+ const pauseMode = "pause";
7485
7533
  class Pauser extends ExternalInteractorBase {
7486
7534
  constructor(container) {
7487
7535
  super(container);
7488
7536
  this.handleClickMode = mode => {
7489
- if (mode !== "pause") {
7537
+ if (mode !== pauseMode) {
7490
7538
  return;
7491
7539
  }
7492
7540
  const container = this.container;
@@ -7518,12 +7566,6 @@ class Push {
7518
7566
  this.groups = [];
7519
7567
  this.quantity = 4;
7520
7568
  }
7521
- get particles_nb() {
7522
- return this.quantity;
7523
- }
7524
- set particles_nb(value) {
7525
- this.quantity = setRangeValue(value);
7526
- }
7527
7569
  load(data) {
7528
7570
  if (!data) {
7529
7571
  return;
@@ -7537,7 +7579,7 @@ class Push {
7537
7579
  if (!this.groups.length) {
7538
7580
  this.default = true;
7539
7581
  }
7540
- const quantity = data.quantity ?? data.particles_nb;
7582
+ const quantity = data.quantity;
7541
7583
  if (quantity !== undefined) {
7542
7584
  this.quantity = setRangeValue(quantity);
7543
7585
  }
@@ -7546,11 +7588,12 @@ class Push {
7546
7588
  ;// CONCATENATED MODULE: ../../interactions/external/push/dist/browser/Pusher.js
7547
7589
 
7548
7590
 
7591
+ const pushMode = "push";
7549
7592
  class Pusher extends ExternalInteractorBase {
7550
7593
  constructor(container) {
7551
7594
  super(container);
7552
7595
  this.handleClickMode = mode => {
7553
- if (mode !== "push") {
7596
+ if (mode !== pushMode) {
7554
7597
  return;
7555
7598
  }
7556
7599
  const container = this.container,
@@ -7597,17 +7640,11 @@ class Remove {
7597
7640
  constructor() {
7598
7641
  this.quantity = 2;
7599
7642
  }
7600
- get particles_nb() {
7601
- return this.quantity;
7602
- }
7603
- set particles_nb(value) {
7604
- this.quantity = setRangeValue(value);
7605
- }
7606
7643
  load(data) {
7607
7644
  if (!data) {
7608
7645
  return;
7609
7646
  }
7610
- const quantity = data.quantity ?? data.particles_nb;
7647
+ const quantity = data.quantity;
7611
7648
  if (quantity !== undefined) {
7612
7649
  this.quantity = setRangeValue(quantity);
7613
7650
  }
@@ -7616,13 +7653,14 @@ class Remove {
7616
7653
  ;// CONCATENATED MODULE: ../../interactions/external/remove/dist/browser/Remover.js
7617
7654
 
7618
7655
 
7656
+ const removeMode = "remove";
7619
7657
  class Remover extends ExternalInteractorBase {
7620
7658
  constructor(container) {
7621
7659
  super(container);
7622
7660
  this.handleClickMode = mode => {
7623
7661
  const container = this.container,
7624
7662
  options = container.actualOptions;
7625
- if (!options.interactivity.modes.remove || mode !== "remove") {
7663
+ if (!options.interactivity.modes.remove || mode !== removeMode) {
7626
7664
  return;
7627
7665
  }
7628
7666
  const removeNb = getRangeValue(options.interactivity.modes.remove.quantity);
@@ -7723,6 +7761,7 @@ class Repulse extends RepulseBase {
7723
7761
  ;// CONCATENATED MODULE: ../../interactions/external/repulse/dist/browser/Repulser.js
7724
7762
 
7725
7763
 
7764
+ const repulseMode = "repulse";
7726
7765
  class Repulser extends ExternalInteractorBase {
7727
7766
  constructor(engine, container) {
7728
7767
  super(container);
@@ -7795,14 +7834,21 @@ class Repulser extends ExternalInteractorBase {
7795
7834
  if (!repulseOptions) {
7796
7835
  return;
7797
7836
  }
7837
+ const {
7838
+ easing,
7839
+ speed,
7840
+ factor,
7841
+ maxSpeed
7842
+ } = repulseOptions,
7843
+ easingFunc = getEasing(easing),
7844
+ velocity = (divRepulse?.speed ?? speed) * factor;
7798
7845
  for (const particle of query) {
7799
7846
  const {
7800
7847
  dx,
7801
7848
  dy,
7802
7849
  distance
7803
7850
  } = getDistances(particle.position, position),
7804
- velocity = (divRepulse?.speed ?? repulseOptions.speed) * repulseOptions.factor,
7805
- repulseFactor = clamp(getEasing(repulseOptions.easing)(1 - distance / repulseRadius) * velocity, 0, repulseOptions.maxSpeed),
7851
+ repulseFactor = clamp(easingFunc(1 - distance / repulseRadius) * velocity, 0, maxSpeed),
7806
7852
  normVec = Vector.create(distance === 0 ? velocity : dx / distance * repulseFactor, distance === 0 ? velocity : dy / distance * repulseFactor);
7807
7853
  particle.position.addTo(normVec);
7808
7854
  }
@@ -7840,7 +7886,7 @@ class Repulser extends ExternalInteractorBase {
7840
7886
  this.handleClickMode = mode => {
7841
7887
  const options = this.container.actualOptions,
7842
7888
  repulseOpts = options.interactivity.modes.repulse;
7843
- if (!repulseOpts || mode !== "repulse") {
7889
+ if (!repulseOpts || mode !== repulseMode) {
7844
7890
  return;
7845
7891
  }
7846
7892
  if (!container.repulse) {
@@ -7888,12 +7934,12 @@ class Repulser extends ExternalInteractorBase {
7888
7934
  clickEnabled = click.enable,
7889
7935
  clickMode = click.mode,
7890
7936
  divs = events.onDiv;
7891
- if (mouseMoveStatus && hoverEnabled && isInArray("repulse", hoverMode)) {
7937
+ if (mouseMoveStatus && hoverEnabled && isInArray(repulseMode, hoverMode)) {
7892
7938
  this._hoverRepulse();
7893
- } else if (clickEnabled && isInArray("repulse", clickMode)) {
7939
+ } else if (clickEnabled && isInArray(repulseMode, clickMode)) {
7894
7940
  this._clickRepulse();
7895
7941
  } else {
7896
- divModeExecute("repulse", divs, (selector, div) => this._singleSelectorRepulse(selector, div));
7942
+ divModeExecute(repulseMode, divs, (selector, div) => this._singleSelectorRepulse(selector, div));
7897
7943
  }
7898
7944
  }
7899
7945
  isEnabled(particle) {
@@ -7904,13 +7950,13 @@ class Repulser extends ExternalInteractorBase {
7904
7950
  divs = events.onDiv,
7905
7951
  hover = events.onHover,
7906
7952
  click = events.onClick,
7907
- divRepulse = isDivModeEnabled("repulse", divs);
7953
+ divRepulse = isDivModeEnabled(repulseMode, divs);
7908
7954
  if (!(divRepulse || hover.enable && mouse.position || click.enable && mouse.clickPosition)) {
7909
7955
  return false;
7910
7956
  }
7911
7957
  const hoverMode = hover.mode,
7912
7958
  clickMode = click.mode;
7913
- return isInArray("repulse", hoverMode) || isInArray("repulse", clickMode) || divRepulse;
7959
+ return isInArray(repulseMode, hoverMode) || isInArray(repulseMode, clickMode) || divRepulse;
7914
7960
  }
7915
7961
  loadModeOptions(options, ...sources) {
7916
7962
  if (!options.repulse) {
@@ -7954,6 +8000,7 @@ class Slow {
7954
8000
  ;// CONCATENATED MODULE: ../../interactions/external/slow/dist/browser/Slower.js
7955
8001
 
7956
8002
 
8003
+ const slowMode = "slow";
7957
8004
  class Slower extends ExternalInteractorBase {
7958
8005
  constructor(container) {
7959
8006
  super(container);
@@ -7977,7 +8024,7 @@ class Slower extends ExternalInteractorBase {
7977
8024
  const container = this.container,
7978
8025
  mouse = container.interactivity.mouse,
7979
8026
  events = (particle?.interactivity ?? container.actualOptions.interactivity).events;
7980
- return events.onHover.enable && !!mouse.position && isInArray("slow", events.onHover.mode);
8027
+ return events.onHover.enable && !!mouse.position && isInArray(slowMode, events.onHover.mode);
7981
8028
  }
7982
8029
  loadModeOptions(options, ...sources) {
7983
8030
  if (!options.slow) {
@@ -8660,8 +8707,9 @@ class ImageDrawer {
8660
8707
  pos = {
8661
8708
  x: -radius,
8662
8709
  y: -radius
8663
- };
8664
- context.drawImage(element, pos.x, pos.y, radius * 2, radius * 2 / ratio);
8710
+ },
8711
+ diameter = radius * 2;
8712
+ context.drawImage(element, pos.x, pos.y, diameter, diameter / ratio);
8665
8713
  }
8666
8714
  context.globalAlpha = 1;
8667
8715
  }
@@ -8684,8 +8732,11 @@ class ImageDrawer {
8684
8732
  if (!this._engine.images) {
8685
8733
  this._engine.images = [];
8686
8734
  }
8687
- const imageData = particle.shapeData,
8688
- image = this._engine.images.find(t => t.name === imageData.name || t.source === imageData.src);
8735
+ const imageData = particle.shapeData;
8736
+ if (!imageData) {
8737
+ return;
8738
+ }
8739
+ const image = this._engine.images.find(t => t.name === imageData.name || t.source === imageData.src);
8689
8740
  if (!image) {
8690
8741
  this.loadImageShape(imageData).then(() => {
8691
8742
  this.loadShape(particle);
@@ -8700,8 +8751,11 @@ class ImageDrawer {
8700
8751
  this._engine.images = [];
8701
8752
  }
8702
8753
  const images = this._engine.images,
8703
- imageData = particle.shapeData,
8704
- color = particle.getFillColor(),
8754
+ imageData = particle.shapeData;
8755
+ if (!imageData) {
8756
+ return;
8757
+ }
8758
+ const color = particle.getFillColor(),
8705
8759
  image = images.find(t => t.name === imageData.name || t.source === imageData.src);
8706
8760
  if (!image) {
8707
8761
  return;
@@ -8734,16 +8788,16 @@ class ImageDrawer {
8734
8788
  if (!imageRes.ratio) {
8735
8789
  imageRes.ratio = 1;
8736
8790
  }
8737
- const fill = imageData.fill ?? particle.fill,
8738
- close = imageData.close ?? particle.close,
8791
+ const fill = imageData.fill ?? particle.shapeFill,
8792
+ close = imageData.close ?? particle.shapeClose,
8739
8793
  imageShape = {
8740
8794
  image: imageRes,
8741
8795
  fill,
8742
8796
  close
8743
8797
  };
8744
8798
  particle.image = imageShape.image;
8745
- particle.fill = imageShape.fill;
8746
- particle.close = imageShape.close;
8799
+ particle.shapeFill = imageShape.fill;
8800
+ particle.shapeClose = imageShape.close;
8747
8801
  })();
8748
8802
  }
8749
8803
  }
@@ -8876,7 +8930,6 @@ class LifeDelay extends ValueWithRandom {
8876
8930
  class LifeDuration extends ValueWithRandom {
8877
8931
  constructor() {
8878
8932
  super();
8879
- this.random.minimumValue = 0.0001;
8880
8933
  this.sync = false;
8881
8934
  }
8882
8935
  load(data) {
@@ -9054,8 +9107,8 @@ class ParallaxMover {
9054
9107
  }
9055
9108
  const canvasSize = container.canvas.size,
9056
9109
  canvasCenter = {
9057
- x: canvasSize.width / 2,
9058
- y: canvasSize.height / 2
9110
+ x: canvasSize.width * 0.5,
9111
+ y: canvasSize.height * 0.5
9059
9112
  },
9060
9113
  parallaxSmooth = parallaxOptions.smooth,
9061
9114
  factor = particle.getRadius() / parallaxForce,
@@ -9084,8 +9137,11 @@ class Attractor_Attractor extends ParticlesInteractorBase {
9084
9137
  clear() {}
9085
9138
  init() {}
9086
9139
  async interact(p1) {
9087
- const container = this.container,
9088
- distance = p1.retina.attractDistance ?? container.retina.attractDistance,
9140
+ const container = this.container;
9141
+ if (p1.attractDistance === undefined) {
9142
+ p1.attractDistance = getRangeValue(p1.options.move.attract.distance) * container.retina.pixelRatio;
9143
+ }
9144
+ const distance = p1.attractDistance,
9089
9145
  pos1 = p1.getPosition(),
9090
9146
  query = container.particles.quadTree.queryCircle(pos1, distance);
9091
9147
  for (const p2 of query) {
@@ -9490,7 +9546,7 @@ class Linker extends ParticlesInteractorBase {
9490
9546
  options.links = new Links();
9491
9547
  }
9492
9548
  for (const source of sources) {
9493
- options.links.load(source?.links ?? source?.lineLinked ?? source?.line_linked);
9549
+ options.links.load(source?.links);
9494
9550
  }
9495
9551
  }
9496
9552
  reset() {}
@@ -9502,6 +9558,13 @@ async function loadLinksInteraction(engine, refresh = true) {
9502
9558
  }
9503
9559
  ;// CONCATENATED MODULE: ../../interactions/particles/links/dist/browser/Utils.js
9504
9560
 
9561
+ function drawTriangle(context, p1, p2, p3) {
9562
+ context.beginPath();
9563
+ context.moveTo(p1.x, p1.y);
9564
+ context.lineTo(p2.x, p2.y);
9565
+ context.lineTo(p3.x, p3.y);
9566
+ context.closePath();
9567
+ }
9505
9568
  function drawLinkLine(params) {
9506
9569
  let drawn = false;
9507
9570
  const {
@@ -10236,82 +10299,6 @@ class StrokeColorUpdater {
10236
10299
  async function loadStrokeColorUpdater(engine, refresh = true) {
10237
10300
  await engine.addParticleUpdater("strokeColor", container => new StrokeColorUpdater(container), refresh);
10238
10301
  }
10239
- ;// CONCATENATED MODULE: ../../shapes/text/dist/browser/TextDrawer.js
10240
-
10241
- const validTypes = ["text", "character", "char"];
10242
- class TextDrawer {
10243
- draw(data) {
10244
- const {
10245
- context,
10246
- particle,
10247
- radius,
10248
- opacity
10249
- } = data,
10250
- character = particle.shapeData;
10251
- if (character === undefined) {
10252
- return;
10253
- }
10254
- const textData = character.value;
10255
- if (textData === undefined) {
10256
- return;
10257
- }
10258
- if (particle.text === undefined) {
10259
- particle.text = itemFromSingleOrMultiple(textData, particle.randomIndexData);
10260
- }
10261
- const text = particle.text,
10262
- style = character.style ?? "",
10263
- weight = character.weight ?? "400",
10264
- size = Math.round(radius) * 2,
10265
- font = character.font ?? "Verdana",
10266
- fill = particle.fill,
10267
- offsetX = text.length * radius / 2;
10268
- context.font = `${style} ${weight} ${size}px "${font}"`;
10269
- const pos = {
10270
- x: -offsetX,
10271
- y: radius / 2
10272
- };
10273
- context.globalAlpha = opacity;
10274
- if (fill) {
10275
- context.fillText(text, pos.x, pos.y);
10276
- } else {
10277
- context.strokeText(text, pos.x, pos.y);
10278
- }
10279
- context.globalAlpha = 1;
10280
- }
10281
- getSidesCount() {
10282
- return 12;
10283
- }
10284
- async init(container) {
10285
- const options = container.actualOptions;
10286
- if (validTypes.find(t => isInArray(t, options.particles.shape.type))) {
10287
- const shapeOptions = validTypes.map(t => options.particles.shape.options[t]).find(t => !!t),
10288
- promises = [];
10289
- executeOnSingleOrMultiple(shapeOptions, shape => {
10290
- promises.push(loadFont(shape.font, shape.weight));
10291
- });
10292
- await Promise.all(promises);
10293
- }
10294
- }
10295
- particleInit(container, particle) {
10296
- if (!particle.shape || !validTypes.includes(particle.shape)) {
10297
- return;
10298
- }
10299
- const character = particle.shapeData;
10300
- if (character === undefined) {
10301
- return;
10302
- }
10303
- const textData = character.value;
10304
- if (textData === undefined) {
10305
- return;
10306
- }
10307
- particle.text = itemFromSingleOrMultiple(textData, particle.randomIndexData);
10308
- }
10309
- }
10310
- ;// CONCATENATED MODULE: ../../shapes/text/dist/browser/index.js
10311
-
10312
- async function loadTextShape(engine, refresh = true) {
10313
- await engine.addShape(validTypes, new TextDrawer(), refresh);
10314
- }
10315
10302
  ;// CONCATENATED MODULE: ./dist/browser/index.js
10316
10303
 
10317
10304
 
@@ -10336,11 +10323,9 @@ async function loadTextShape(engine, refresh = true) {
10336
10323
 
10337
10324
 
10338
10325
 
10339
-
10340
10326
 
10341
10327
 
10342
10328
  async function loadSlim(engine, refresh = true) {
10343
- initPjs(engine);
10344
10329
  await loadParallaxMover(engine, false);
10345
10330
  await loadExternalAttractInteraction(engine, false);
10346
10331
  await loadExternalBounceInteraction(engine, false);
@@ -10356,12 +10341,12 @@ async function loadSlim(engine, refresh = true) {
10356
10341
  await loadParticlesCollisionsInteraction(engine, false);
10357
10342
  await loadParticlesLinksInteraction(engine, false);
10358
10343
  await loadEasingQuadPlugin();
10344
+ await loadEmojiShape(engine, false);
10359
10345
  await loadImageShape(engine, false);
10360
10346
  await loadLineShape(engine, false);
10361
10347
  await loadPolygonShape(engine, false);
10362
10348
  await loadSquareShape(engine, false);
10363
10349
  await loadStarShape(engine, false);
10364
- await loadTextShape(engine, false);
10365
10350
  await loadLifeUpdater(engine, false);
10366
10351
  await loadRotateUpdater(engine, false);
10367
10352
  await loadStrokeColorUpdater(engine, false);