@tsparticles/pjs 3.0.2 → 3.1.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.
@@ -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.2
7
+ * v3.1.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -140,6 +140,7 @@ __webpack_require__.d(__webpack_exports__, {
140
140
  colorToHsl: () => (/* reexport */ colorToHsl),
141
141
  colorToRgb: () => (/* reexport */ colorToRgb),
142
142
  deepExtend: () => (/* reexport */ deepExtend),
143
+ degToRad: () => (/* reexport */ degToRad),
143
144
  divMode: () => (/* reexport */ divMode),
144
145
  divModeExecute: () => (/* reexport */ divModeExecute),
145
146
  drawEffect: () => (/* reexport */ drawEffect),
@@ -172,6 +173,7 @@ __webpack_require__.d(__webpack_exports__, {
172
173
  getSize: () => (/* reexport */ getSize),
173
174
  getStyleFromHsl: () => (/* reexport */ getStyleFromHsl),
174
175
  getStyleFromRgb: () => (/* reexport */ getStyleFromRgb),
176
+ halfRandom: () => (/* reexport */ halfRandom),
175
177
  hasMatchMedia: () => (/* reexport */ hasMatchMedia),
176
178
  hslToRgb: () => (/* reexport */ hslToRgb),
177
179
  hslaToRgba: () => (/* reexport */ hslaToRgba),
@@ -191,6 +193,7 @@ __webpack_require__.d(__webpack_exports__, {
191
193
  loadFont: () => (/* reexport */ loadFont),
192
194
  loadOptions: () => (/* reexport */ loadOptions),
193
195
  loadParticlesOptions: () => (/* reexport */ loadParticlesOptions),
196
+ millisecondsToSeconds: () => (/* reexport */ millisecondsToSeconds),
194
197
  mix: () => (/* reexport */ mix),
195
198
  mouseDownEvent: () => (/* reexport */ mouseDownEvent),
196
199
  mouseLeaveEvent: () => (/* reexport */ mouseLeaveEvent),
@@ -202,6 +205,7 @@ __webpack_require__.d(__webpack_exports__, {
202
205
  paintImage: () => (/* reexport */ paintImage),
203
206
  parseAlpha: () => (/* reexport */ parseAlpha),
204
207
  particlesJS: () => (/* binding */ particlesJS),
208
+ percentDenominator: () => (/* reexport */ percentDenominator),
205
209
  randomInRange: () => (/* reexport */ randomInRange),
206
210
  rangeColorToHsl: () => (/* reexport */ rangeColorToHsl),
207
211
  rangeColorToRgb: () => (/* reexport */ rangeColorToRgb),
@@ -222,6 +226,9 @@ __webpack_require__.d(__webpack_exports__, {
222
226
  touchMoveEvent: () => (/* reexport */ touchMoveEvent),
223
227
  touchStartEvent: () => (/* reexport */ touchStartEvent),
224
228
  tsParticles: () => (/* reexport */ tsParticles),
229
+ updateAnimation: () => (/* reexport */ updateAnimation),
230
+ updateColor: () => (/* reexport */ updateColor),
231
+ updateColorValue: () => (/* reexport */ updateColorValue),
225
232
  visibilityChangeEvent: () => (/* reexport */ visibilityChangeEvent)
226
233
  });
227
234
 
@@ -239,9 +246,19 @@ const touchCancelEvent = "touchcancel";
239
246
  const resizeEvent = "resize";
240
247
  const visibilityChangeEvent = "visibilitychange";
241
248
  const errorPrefix = "tsParticles - Error";
249
+ const percentDenominator = 100;
250
+ const halfRandom = 0.5;
251
+ const millisecondsToSeconds = 1000;
242
252
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/Vector3d.js
243
253
 
244
254
 
255
+ const origin = {
256
+ x: 0,
257
+ y: 0,
258
+ z: 0
259
+ },
260
+ squareExp = 2,
261
+ inverseFactorNumerator = 1.0;
245
262
  class Vector3d {
246
263
  constructor(xOrCoords, y, z) {
247
264
  this._updateFromAngle = (angle, length) => {
@@ -252,17 +269,17 @@ class Vector3d {
252
269
  this.x = xOrCoords.x;
253
270
  this.y = xOrCoords.y;
254
271
  const coords3d = xOrCoords;
255
- this.z = coords3d.z ? coords3d.z : 0;
272
+ this.z = coords3d.z ? coords3d.z : origin.z;
256
273
  } else if (xOrCoords !== undefined && y !== undefined) {
257
274
  this.x = xOrCoords;
258
275
  this.y = y;
259
- this.z = z ?? 0;
276
+ this.z = z ?? origin.z;
260
277
  } else {
261
278
  throw new Error(`${errorPrefix} Vector3d not initialized correctly`);
262
279
  }
263
280
  }
264
281
  static get origin() {
265
- return Vector3d.create(0, 0, 0);
282
+ return Vector3d.create(origin.x, origin.y, origin.z);
266
283
  }
267
284
  get angle() {
268
285
  return Math.atan2(this.y, this.x);
@@ -308,7 +325,7 @@ class Vector3d {
308
325
  this.z /= n;
309
326
  }
310
327
  getLengthSq() {
311
- return this.x ** 2 + this.y ** 2;
328
+ return this.x ** squareExp + this.y ** squareExp;
312
329
  }
313
330
  mult(n) {
314
331
  return Vector3d.create(this.x * n, this.y * n, this.z * n);
@@ -319,19 +336,20 @@ class Vector3d {
319
336
  this.z *= n;
320
337
  }
321
338
  normalize() {
322
- const length = this.length;
323
- if (length != 0) {
324
- this.multTo(1.0 / length);
339
+ const length = this.length,
340
+ noLength = 0;
341
+ if (length != noLength) {
342
+ this.multTo(inverseFactorNumerator / length);
325
343
  }
326
344
  }
327
345
  rotate(angle) {
328
- return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), 0);
346
+ return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), origin.z);
329
347
  }
330
348
  setTo(c) {
331
349
  this.x = c.x;
332
350
  this.y = c.y;
333
351
  const v3d = c;
334
- this.z = v3d.z ? v3d.z : 0;
352
+ this.z = v3d.z ? v3d.z : origin.z;
335
353
  }
336
354
  sub(v) {
337
355
  return Vector3d.create(this.x - v.x, this.y - v.y, this.z - v.z);
@@ -344,12 +362,17 @@ class Vector3d {
344
362
  }
345
363
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/Vector.js
346
364
 
365
+ const Vector_origin = {
366
+ x: 0,
367
+ y: 0,
368
+ z: 0
369
+ };
347
370
  class Vector extends Vector3d {
348
371
  constructor(xOrCoords, y) {
349
- super(xOrCoords, y, 0);
372
+ super(xOrCoords, y, Vector_origin.z);
350
373
  }
351
374
  static get origin() {
352
- return Vector.create(0, 0);
375
+ return Vector.create(Vector_origin.x, Vector_origin.y);
353
376
  }
354
377
  static clone(source) {
355
378
  return Vector.create(source.x, source.y);
@@ -361,8 +384,11 @@ class Vector extends Vector3d {
361
384
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/NumberUtils.js
362
385
 
363
386
 
387
+
364
388
  let _random = Math.random;
365
- const easings = new Map();
389
+ const easings = new Map(),
390
+ NumberUtils_double = 2,
391
+ doublePI = Math.PI * NumberUtils_double;
366
392
  function addEasing(name, easing) {
367
393
  if (easings.get(name)) {
368
394
  return;
@@ -370,13 +396,15 @@ function addEasing(name, easing) {
370
396
  easings.set(name, easing);
371
397
  }
372
398
  function getEasing(name) {
373
- return easings.get(name) || (value => value);
399
+ return easings.get(name) ?? (value => value);
374
400
  }
375
401
  function setRandom(rnd = Math.random) {
376
402
  _random = rnd;
377
403
  }
378
404
  function getRandom() {
379
- return clamp(_random(), 0, 1 - 1e-16);
405
+ const min = 0,
406
+ max = 1;
407
+ return clamp(_random(), min, max - Number.EPSILON);
380
408
  }
381
409
  function clamp(num, min, max) {
382
410
  return Math.min(Math.max(num, min), max);
@@ -385,10 +413,11 @@ function mix(comp1, comp2, weight1, weight2) {
385
413
  return Math.floor((comp1 * weight1 + comp2 * weight2) / (weight1 + weight2));
386
414
  }
387
415
  function randomInRange(r) {
388
- const max = getRangeMax(r);
416
+ const max = getRangeMax(r),
417
+ minOffset = 0;
389
418
  let min = getRangeMin(r);
390
419
  if (max === min) {
391
- min = 0;
420
+ min = minOffset;
392
421
  }
393
422
  return getRandom() * (max - min) + min;
394
423
  }
@@ -414,43 +443,52 @@ function setRangeValue(source, value) {
414
443
  }
415
444
  function getDistances(pointA, pointB) {
416
445
  const dx = pointA.x - pointB.x,
417
- dy = pointA.y - pointB.y;
446
+ dy = pointA.y - pointB.y,
447
+ squareExp = 2;
418
448
  return {
419
449
  dx: dx,
420
450
  dy: dy,
421
- distance: Math.sqrt(dx ** 2 + dy ** 2)
451
+ distance: Math.sqrt(dx ** squareExp + dy ** squareExp)
422
452
  };
423
453
  }
424
454
  function getDistance(pointA, pointB) {
425
455
  return getDistances(pointA, pointB).distance;
426
456
  }
457
+ function degToRad(degrees) {
458
+ const PIDeg = 180;
459
+ return degrees * Math.PI / PIDeg;
460
+ }
427
461
  function getParticleDirectionAngle(direction, position, center) {
428
462
  if (isNumber(direction)) {
429
- return direction * Math.PI / 180;
463
+ return degToRad(direction);
430
464
  }
465
+ const empty = 0,
466
+ half = 0.5,
467
+ quarter = 0.25,
468
+ threeQuarter = half + quarter;
431
469
  switch (direction) {
432
470
  case "top":
433
- return -Math.PI * 0.5;
471
+ return -Math.PI * half;
434
472
  case "top-right":
435
- return -Math.PI * 0.25;
473
+ return -Math.PI * quarter;
436
474
  case "right":
437
- return 0;
475
+ return empty;
438
476
  case "bottom-right":
439
- return Math.PI * 0.25;
477
+ return Math.PI * quarter;
440
478
  case "bottom":
441
- return Math.PI * 0.5;
479
+ return Math.PI * half;
442
480
  case "bottom-left":
443
- return Math.PI * 0.75;
481
+ return Math.PI * threeQuarter;
444
482
  case "left":
445
483
  return Math.PI;
446
484
  case "top-left":
447
- return -Math.PI * 0.75;
485
+ return -Math.PI * threeQuarter;
448
486
  case "inside":
449
487
  return Math.atan2(center.y - position.y, center.x - position.x);
450
488
  case "outside":
451
489
  return Math.atan2(position.y - center.y, position.x - center.x);
452
490
  default:
453
- return getRandom() * Math.PI * 2;
491
+ return getRandom() * doublePI;
454
492
  }
455
493
  }
456
494
  function getParticleBaseVelocity(direction) {
@@ -460,18 +498,19 @@ function getParticleBaseVelocity(direction) {
460
498
  return baseVelocity;
461
499
  }
462
500
  function collisionVelocity(v1, v2, m1, m2) {
463
- return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * 2 * m2 / (m1 + m2), v1.y);
501
+ const double = 2;
502
+ return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * double * m2 / (m1 + m2), v1.y);
464
503
  }
465
504
  function calcPositionFromSize(data) {
466
- return data.position && data.position.x !== undefined && data.position.y !== undefined ? {
467
- x: data.position.x * data.size.width / 100,
468
- y: data.position.y * data.size.height / 100
505
+ return data.position?.x !== undefined && data.position.y !== undefined ? {
506
+ x: data.position.x * data.size.width / percentDenominator,
507
+ y: data.position.y * data.size.height / percentDenominator
469
508
  } : undefined;
470
509
  }
471
510
  function calcPositionOrRandomFromSize(data) {
472
511
  return {
473
- x: (data.position?.x ?? getRandom() * 100) * data.size.width / 100,
474
- y: (data.position?.y ?? getRandom() * 100) * data.size.height / 100
512
+ x: (data.position?.x ?? getRandom() * percentDenominator) * data.size.width / percentDenominator,
513
+ y: (data.position?.y ?? getRandom() * percentDenominator) * data.size.height / percentDenominator
475
514
  };
476
515
  }
477
516
  function calcPositionOrRandomFromSizeRanged(data) {
@@ -501,11 +540,16 @@ function calcExactPositionOrRandomFromSizeRanged(data) {
501
540
  });
502
541
  }
503
542
  function parseAlpha(input) {
504
- return input ? input.endsWith("%") ? parseFloat(input) / 100 : parseFloat(input) : 1;
543
+ const defaultAlpha = 1;
544
+ if (!input) {
545
+ return defaultAlpha;
546
+ }
547
+ return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
505
548
  }
506
549
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/Utils.js
507
550
 
508
551
 
552
+
509
553
  const _logger = {
510
554
  debug: console.debug,
511
555
  error: console.error,
@@ -536,11 +580,13 @@ function rectSideBounce(data) {
536
580
  rectOtherSide,
537
581
  velocity,
538
582
  factor
539
- } = data;
583
+ } = data,
584
+ half = 0.5,
585
+ minVelocity = 0;
540
586
  if (pOtherSide.min < rectOtherSide.min || pOtherSide.min > rectOtherSide.max || pOtherSide.max < rectOtherSide.min || pOtherSide.max > rectOtherSide.max) {
541
587
  return res;
542
588
  }
543
- 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) {
589
+ if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * half && velocity > minVelocity || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * half && velocity < minVelocity) {
544
590
  res.velocity = velocity * -factor;
545
591
  res.bounced = true;
546
592
  }
@@ -577,7 +623,8 @@ function safeMutationObserver(callback) {
577
623
  return new MutationObserver(callback);
578
624
  }
579
625
  function isInArray(value, array) {
580
- return value === array || isArray(array) && array.indexOf(value) > -1;
626
+ const invalidIndex = -1;
627
+ return value === array || isArray(array) && array.indexOf(value) > invalidIndex;
581
628
  }
582
629
  async function loadFont(font, weight) {
583
630
  try {
@@ -591,7 +638,8 @@ function itemFromArray(array, index, useIndex = true) {
591
638
  return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
592
639
  }
593
640
  function isPointInside(point, size, offset, radius, direction) {
594
- return areBoundsInside(calculateBounds(point, radius ?? 0), size, offset, direction);
641
+ const minRadius = 0;
642
+ return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
595
643
  }
596
644
  function areBoundsInside(bounds, size, offset, direction) {
597
645
  let inside = true;
@@ -688,8 +736,9 @@ function circleBounce(p1, p2) {
688
736
  {
689
737
  dx: xDist,
690
738
  dy: yDist
691
- } = getDistances(pos2, pos1);
692
- if (xVelocityDiff * xDist + yVelocityDiff * yDist < 0) {
739
+ } = getDistances(pos2, pos1),
740
+ minimumDistance = 0;
741
+ if (xVelocityDiff * xDist + yVelocityDiff * yDist < minimumDistance) {
693
742
  return;
694
743
  }
695
744
  const angle = -Math.atan2(yDist, xDist),
@@ -769,19 +818,24 @@ function rectBounce(particle, divBounds) {
769
818
  }
770
819
  }
771
820
  function executeOnSingleOrMultiple(obj, callback) {
772
- return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, 0);
821
+ const defaultIndex = 0;
822
+ return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, defaultIndex);
773
823
  }
774
824
  function itemFromSingleOrMultiple(obj, index, useIndex) {
775
825
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
776
826
  }
777
827
  function findItemFromSingleOrMultiple(obj, callback) {
778
- return isArray(obj) ? obj.find((t, index) => callback(t, index)) : callback(obj, 0) ? obj : undefined;
828
+ if (isArray(obj)) {
829
+ return obj.find((t, index) => callback(t, index));
830
+ }
831
+ const defaultIndex = 0;
832
+ return callback(obj, defaultIndex) ? obj : undefined;
779
833
  }
780
834
  function initParticleNumericAnimationValue(options, pxRatio) {
781
835
  const valueRange = options.value,
782
836
  animationOptions = options.animation,
783
837
  res = {
784
- delayTime: getRangeValue(animationOptions.delay) * 1000,
838
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
785
839
  enable: animationOptions.enable,
786
840
  value: getRangeValue(options.value) * pxRatio,
787
841
  max: getRangeMax(valueRange) * pxRatio,
@@ -789,9 +843,10 @@ function initParticleNumericAnimationValue(options, pxRatio) {
789
843
  loops: 0,
790
844
  maxLoops: getRangeValue(animationOptions.count),
791
845
  time: 0
792
- };
846
+ },
847
+ decayOffset = 1;
793
848
  if (animationOptions.enable) {
794
- res.decay = 1 - getRangeValue(animationOptions.decay);
849
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
795
850
  switch (animationOptions.mode) {
796
851
  case "increase":
797
852
  res.status = "increasing";
@@ -800,7 +855,7 @@ function initParticleNumericAnimationValue(options, pxRatio) {
800
855
  res.status = "decreasing";
801
856
  break;
802
857
  case "random":
803
- res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
858
+ res.status = getRandom() >= halfRandom ? "increasing" : "decreasing";
804
859
  break;
805
860
  }
806
861
  const autoStatus = animationOptions.mode === "auto";
@@ -821,7 +876,7 @@ function initParticleNumericAnimationValue(options, pxRatio) {
821
876
  default:
822
877
  res.value = randomInRange(res);
823
878
  if (autoStatus) {
824
- res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
879
+ res.status = getRandom() >= halfRandom ? "increasing" : "decreasing";
825
880
  }
826
881
  break;
827
882
  }
@@ -841,13 +896,13 @@ function getPositionOrSize(positionOrSize, canvasSize) {
841
896
  const isPosition = ("x" in positionOrSize);
842
897
  if (isPosition) {
843
898
  return {
844
- x: positionOrSize.x / 100 * canvasSize.width,
845
- y: positionOrSize.y / 100 * canvasSize.height
899
+ x: positionOrSize.x / percentDenominator * canvasSize.width,
900
+ y: positionOrSize.y / percentDenominator * canvasSize.height
846
901
  };
847
902
  } else {
848
903
  return {
849
- width: positionOrSize.width / 100 * canvasSize.width,
850
- height: positionOrSize.height / 100 * canvasSize.height
904
+ width: positionOrSize.width / percentDenominator * canvasSize.width,
905
+ height: positionOrSize.height / percentDenominator * canvasSize.height
851
906
  };
852
907
  }
853
908
  }
@@ -875,9 +930,85 @@ function isObject(arg) {
875
930
  function isArray(arg) {
876
931
  return Array.isArray(arg);
877
932
  }
933
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
934
+ switch (destroyType) {
935
+ case "max":
936
+ if (value >= maxValue) {
937
+ particle.destroy();
938
+ }
939
+ break;
940
+ case "min":
941
+ if (value <= minValue) {
942
+ particle.destroy();
943
+ }
944
+ break;
945
+ }
946
+ }
947
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
948
+ const minLoops = 0,
949
+ minDelay = 0,
950
+ identity = 1,
951
+ minVelocity = 0,
952
+ minDecay = 1;
953
+ if (particle.destroyed || !data || !data.enable || (data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops)) {
954
+ return;
955
+ }
956
+ const velocity = (data.velocity ?? minVelocity) * delta.factor,
957
+ minValue = data.min,
958
+ maxValue = data.max,
959
+ decay = data.decay ?? minDecay;
960
+ if (!data.time) {
961
+ data.time = 0;
962
+ }
963
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
964
+ data.time += delta.value;
965
+ }
966
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
967
+ return;
968
+ }
969
+ switch (data.status) {
970
+ case "increasing":
971
+ if (data.value >= maxValue) {
972
+ if (changeDirection) {
973
+ data.status = "decreasing";
974
+ } else {
975
+ data.value -= maxValue;
976
+ }
977
+ if (!data.loops) {
978
+ data.loops = minLoops;
979
+ }
980
+ data.loops++;
981
+ } else {
982
+ data.value += velocity;
983
+ }
984
+ break;
985
+ case "decreasing":
986
+ if (data.value <= minValue) {
987
+ if (changeDirection) {
988
+ data.status = "increasing";
989
+ } else {
990
+ data.value += maxValue;
991
+ }
992
+ if (!data.loops) {
993
+ data.loops = minLoops;
994
+ }
995
+ data.loops++;
996
+ } else {
997
+ data.value -= velocity;
998
+ }
999
+ }
1000
+ if (data.velocity && decay !== identity) {
1001
+ data.velocity *= decay;
1002
+ }
1003
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
1004
+ if (!particle.destroyed) {
1005
+ data.value = clamp(data.value, minValue, maxValue);
1006
+ }
1007
+ }
878
1008
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/ColorUtils.js
879
1009
 
880
1010
 
1011
+
881
1012
  const randomColorValue = "random",
882
1013
  midColorValue = "mid",
883
1014
  colorManagers = new Map();
@@ -895,12 +1026,15 @@ function stringToRgba(input) {
895
1026
  return r + r + g + g + b + b + (a !== undefined ? a + a : "");
896
1027
  }),
897
1028
  regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,
898
- result = regex.exec(hexFixed);
1029
+ result = regex.exec(hexFixed),
1030
+ radix = 16,
1031
+ defaultAlpha = 1,
1032
+ alphaFactor = 0xff;
899
1033
  return result ? {
900
- a: result[4] !== undefined ? parseInt(result[4], 16) / 0xff : 1,
901
- b: parseInt(result[3], 16),
902
- g: parseInt(result[2], 16),
903
- r: parseInt(result[1], 16)
1034
+ a: result[4] !== undefined ? parseInt(result[4], radix) / alphaFactor : defaultAlpha,
1035
+ b: parseInt(result[3], radix),
1036
+ g: parseInt(result[2], radix),
1037
+ r: parseInt(result[1], radix)
904
1038
  } : undefined;
905
1039
  }
906
1040
  function rangeColorToRgb(input, index, useIndex = true) {
@@ -956,28 +1090,37 @@ function rangeColorToHsl(color, index, useIndex = true) {
956
1090
  return rgb ? rgbToHsl(rgb) : undefined;
957
1091
  }
958
1092
  function rgbToHsl(color) {
959
- const r1 = color.r / 255,
960
- g1 = color.g / 255,
961
- b1 = color.b / 255,
1093
+ const rgbMax = 255,
1094
+ hMax = 360,
1095
+ sMax = 100,
1096
+ lMax = 100,
1097
+ hMin = 0,
1098
+ sMin = 0,
1099
+ hPhase = 60,
1100
+ half = 0.5,
1101
+ double = 2,
1102
+ r1 = color.r / rgbMax,
1103
+ g1 = color.g / rgbMax,
1104
+ b1 = color.b / rgbMax,
962
1105
  max = Math.max(r1, g1, b1),
963
1106
  min = Math.min(r1, g1, b1),
964
1107
  res = {
965
- h: 0,
966
- l: (max + min) * 0.5,
967
- s: 0
1108
+ h: hMin,
1109
+ l: (max + min) * half,
1110
+ s: sMin
968
1111
  };
969
1112
  if (max !== min) {
970
- res.s = res.l < 0.5 ? (max - min) / (max + min) : (max - min) / (2.0 - max - min);
971
- res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? 2.0 + (b1 - r1) / (max - min) : 4.0 + (r1 - g1) / (max - min);
1113
+ res.s = res.l < half ? (max - min) / (max + min) : (max - min) / (double - max - min);
1114
+ res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? double + (b1 - r1) / (max - min) : double * double + (r1 - g1) / (max - min);
972
1115
  }
973
- res.l *= 100;
974
- res.s *= 100;
975
- res.h *= 60;
976
- if (res.h < 0) {
977
- res.h += 360;
1116
+ res.l *= lMax;
1117
+ res.s *= sMax;
1118
+ res.h *= hPhase;
1119
+ if (res.h < hMin) {
1120
+ res.h += hMax;
978
1121
  }
979
- if (res.h >= 360) {
980
- res.h -= 360;
1122
+ if (res.h >= hMax) {
1123
+ res.h -= hMax;
981
1124
  }
982
1125
  return res;
983
1126
  }
@@ -988,43 +1131,59 @@ function stringToRgb(input) {
988
1131
  return stringToRgba(input);
989
1132
  }
990
1133
  function hslToRgb(hsl) {
991
- const h = (hsl.h % 360 + 360) % 360,
992
- s = Math.max(0, Math.min(100, hsl.s)),
993
- l = Math.max(0, Math.min(100, hsl.l)),
994
- hNormalized = h / 360,
995
- sNormalized = s / 100,
996
- lNormalized = l / 100;
997
- if (s === 0) {
998
- const grayscaleValue = Math.round(lNormalized * 255);
1134
+ const hMax = 360,
1135
+ sMax = 100,
1136
+ lMax = 100,
1137
+ sMin = 0,
1138
+ lMin = 0,
1139
+ h = (hsl.h % hMax + hMax) % hMax,
1140
+ s = Math.max(sMin, Math.min(sMax, hsl.s)),
1141
+ l = Math.max(lMin, Math.min(lMax, hsl.l)),
1142
+ hNormalized = h / hMax,
1143
+ sNormalized = s / sMax,
1144
+ lNormalized = l / lMax,
1145
+ rgbFactor = 255,
1146
+ triple = 3;
1147
+ if (s === sMin) {
1148
+ const grayscaleValue = Math.round(lNormalized * rgbFactor);
999
1149
  return {
1000
1150
  r: grayscaleValue,
1001
1151
  g: grayscaleValue,
1002
1152
  b: grayscaleValue
1003
1153
  };
1004
1154
  }
1005
- const channel = (temp1, temp2, temp3) => {
1006
- if (temp3 < 0) {
1007
- temp3 += 1;
1155
+ const half = 0.5,
1156
+ double = 2,
1157
+ channel = (temp1, temp2, temp3) => {
1158
+ const temp3Min = 0,
1159
+ temp3Max = 1,
1160
+ sextuple = 6;
1161
+ if (temp3 < temp3Min) {
1162
+ temp3++;
1008
1163
  }
1009
- if (temp3 > 1) {
1010
- temp3 -= 1;
1164
+ if (temp3 > temp3Max) {
1165
+ temp3--;
1011
1166
  }
1012
- if (temp3 * 6 < 1) {
1013
- return temp1 + (temp2 - temp1) * 6 * temp3;
1167
+ if (temp3 * sextuple < temp3Max) {
1168
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1014
1169
  }
1015
- if (temp3 * 2 < 1) {
1170
+ if (temp3 * double < temp3Max) {
1016
1171
  return temp2;
1017
1172
  }
1018
- if (temp3 * 3 < 2) {
1019
- return temp1 + (temp2 - temp1) * (2 / 3 - temp3) * 6;
1173
+ if (temp3 * triple < temp3Max * double) {
1174
+ const temp3Offset = double / triple;
1175
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1020
1176
  }
1021
1177
  return temp1;
1022
1178
  },
1023
- temp1 = lNormalized < 0.5 ? lNormalized * (1 + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1024
- temp2 = 2 * lNormalized - temp1,
1025
- red = Math.min(255, 255 * channel(temp2, temp1, hNormalized + 1 / 3)),
1026
- green = Math.min(255, 255 * channel(temp2, temp1, hNormalized)),
1027
- blue = Math.min(255, 255 * channel(temp2, temp1, hNormalized - 1 / 3));
1179
+ sNormalizedOffset = 1,
1180
+ temp1 = lNormalized < half ? lNormalized * (sNormalizedOffset + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1181
+ temp2 = double * lNormalized - temp1,
1182
+ phaseNumerator = 1,
1183
+ phaseThird = phaseNumerator / triple,
1184
+ red = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized + phaseThird)),
1185
+ green = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized)),
1186
+ blue = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized - phaseThird));
1028
1187
  return {
1029
1188
  r: Math.round(red),
1030
1189
  g: Math.round(green),
@@ -1041,18 +1200,22 @@ function hslaToRgba(hsla) {
1041
1200
  };
1042
1201
  }
1043
1202
  function getRandomRgbColor(min) {
1044
- const fixedMin = min ?? 0;
1203
+ const defaultMin = 0,
1204
+ fixedMin = min ?? defaultMin,
1205
+ rgbMax = 256;
1045
1206
  return {
1046
- b: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1047
- g: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1048
- r: Math.floor(randomInRange(setRangeValue(fixedMin, 256)))
1207
+ b: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
1208
+ g: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
1209
+ r: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax)))
1049
1210
  };
1050
1211
  }
1051
1212
  function getStyleFromRgb(color, opacity) {
1052
- return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? 1})`;
1213
+ const defaultOpacity = 1;
1214
+ return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? defaultOpacity})`;
1053
1215
  }
1054
1216
  function getStyleFromHsl(color, opacity) {
1055
- return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? 1})`;
1217
+ const defaultOpacity = 1;
1218
+ return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? defaultOpacity})`;
1056
1219
  }
1057
1220
  function colorMix(color1, color2, size1, size2) {
1058
1221
  let rgb1 = color1,
@@ -1138,25 +1301,120 @@ function getHslAnimationFromHsl(hsl, animationOptions, reduceFactor) {
1138
1301
  }
1139
1302
  function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
1140
1303
  colorValue.enable = colorAnimation.enable;
1304
+ const defaultVelocity = 0,
1305
+ decayOffset = 1,
1306
+ defaultLoops = 0,
1307
+ defaultTime = 0;
1141
1308
  if (colorValue.enable) {
1142
- colorValue.velocity = getRangeValue(colorAnimation.speed) / 100 * reduceFactor;
1143
- colorValue.decay = 1 - getRangeValue(colorAnimation.decay);
1309
+ colorValue.velocity = getRangeValue(colorAnimation.speed) / percentDenominator * reduceFactor;
1310
+ colorValue.decay = decayOffset - getRangeValue(colorAnimation.decay);
1144
1311
  colorValue.status = "increasing";
1145
- colorValue.loops = 0;
1312
+ colorValue.loops = defaultLoops;
1146
1313
  colorValue.maxLoops = getRangeValue(colorAnimation.count);
1147
- colorValue.time = 0;
1148
- colorValue.delayTime = getRangeValue(colorAnimation.delay) * 1000;
1314
+ colorValue.time = defaultTime;
1315
+ colorValue.delayTime = getRangeValue(colorAnimation.delay) * millisecondsToSeconds;
1149
1316
  if (!colorAnimation.sync) {
1150
1317
  colorValue.velocity *= getRandom();
1151
1318
  colorValue.value *= getRandom();
1152
1319
  }
1153
1320
  colorValue.initialValue = colorValue.value;
1321
+ colorValue.offset = setRangeValue(colorAnimation.offset);
1154
1322
  } else {
1155
- colorValue.velocity = 0;
1323
+ colorValue.velocity = defaultVelocity;
1324
+ }
1325
+ }
1326
+ function updateColorValue(data, range, decrease, delta) {
1327
+ const minLoops = 0,
1328
+ minDelay = 0,
1329
+ identity = 1,
1330
+ minVelocity = 0,
1331
+ minOffset = 0,
1332
+ velocityFactor = 3.6;
1333
+ if (!data || !data.enable || (data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops)) {
1334
+ return;
1335
+ }
1336
+ if (!data.time) {
1337
+ data.time = 0;
1338
+ }
1339
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1340
+ data.time += delta.value;
1341
+ }
1342
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1343
+ return;
1344
+ }
1345
+ const offset = data.offset ? randomInRange(data.offset) : minOffset,
1346
+ velocity = (data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor,
1347
+ decay = data.decay ?? identity,
1348
+ max = getRangeMax(range),
1349
+ min = getRangeMin(range);
1350
+ if (!decrease || data.status === "increasing") {
1351
+ data.value += velocity;
1352
+ if (data.value > max) {
1353
+ if (!data.loops) {
1354
+ data.loops = 0;
1355
+ }
1356
+ data.loops++;
1357
+ if (decrease) {
1358
+ data.status = "decreasing";
1359
+ } else {
1360
+ data.value -= max;
1361
+ }
1362
+ }
1363
+ } else {
1364
+ data.value -= velocity;
1365
+ const minValue = 0;
1366
+ if (data.value < minValue) {
1367
+ if (!data.loops) {
1368
+ data.loops = 0;
1369
+ }
1370
+ data.loops++;
1371
+ data.status = "increasing";
1372
+ }
1373
+ }
1374
+ if (data.velocity && decay !== identity) {
1375
+ data.velocity *= decay;
1376
+ }
1377
+ data.value = clamp(data.value, min, max);
1378
+ }
1379
+ function updateColor(color, delta) {
1380
+ if (!color) {
1381
+ return;
1382
+ }
1383
+ const {
1384
+ h,
1385
+ s,
1386
+ l
1387
+ } = color;
1388
+ const ranges = {
1389
+ h: {
1390
+ min: 0,
1391
+ max: 360
1392
+ },
1393
+ s: {
1394
+ min: 0,
1395
+ max: 100
1396
+ },
1397
+ l: {
1398
+ min: 0,
1399
+ max: 100
1400
+ }
1401
+ };
1402
+ if (h) {
1403
+ updateColorValue(h, ranges.h, false, delta);
1404
+ }
1405
+ if (s) {
1406
+ updateColorValue(s, ranges.s, true, delta);
1407
+ }
1408
+ if (l) {
1409
+ updateColorValue(l, ranges.l, true, delta);
1156
1410
  }
1157
1411
  }
1158
1412
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/CanvasUtils.js
1159
1413
 
1414
+ const CanvasUtils_origin = {
1415
+ x: 0,
1416
+ y: 0
1417
+ };
1160
1418
  function drawLine(context, begin, end) {
1161
1419
  context.beginPath();
1162
1420
  context.moveTo(begin.x, begin.y);
@@ -1165,44 +1423,46 @@ function drawLine(context, begin, end) {
1165
1423
  }
1166
1424
  function paintBase(context, dimension, baseColor) {
1167
1425
  context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
1168
- context.fillRect(0, 0, dimension.width, dimension.height);
1426
+ context.fillRect(CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1169
1427
  }
1170
1428
  function paintImage(context, dimension, image, opacity) {
1171
1429
  if (!image) {
1172
1430
  return;
1173
1431
  }
1174
1432
  context.globalAlpha = opacity;
1175
- context.drawImage(image, 0, 0, dimension.width, dimension.height);
1433
+ context.drawImage(image, CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1176
1434
  context.globalAlpha = 1;
1177
1435
  }
1178
1436
  function clear(context, dimension) {
1179
- context.clearRect(0, 0, dimension.width, dimension.height);
1437
+ context.clearRect(CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1180
1438
  }
1181
1439
  function drawParticle(data) {
1182
1440
  const {
1183
- container,
1184
- context,
1185
- particle,
1186
- delta,
1187
- colorStyles,
1188
- backgroundMask,
1189
- composite,
1190
- radius,
1191
- opacity,
1192
- shadow,
1193
- transform
1194
- } = data;
1195
- const pos = particle.getPosition(),
1196
- angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : 0),
1441
+ container,
1442
+ context,
1443
+ particle,
1444
+ delta,
1445
+ colorStyles,
1446
+ backgroundMask,
1447
+ composite,
1448
+ radius,
1449
+ opacity,
1450
+ shadow,
1451
+ transform
1452
+ } = data,
1453
+ pos = particle.getPosition(),
1454
+ defaultAngle = 0,
1455
+ angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : defaultAngle),
1197
1456
  rotateData = {
1198
1457
  sin: Math.sin(angle),
1199
1458
  cos: Math.cos(angle)
1200
1459
  },
1460
+ defaultTransformFactor = 1,
1201
1461
  transformData = {
1202
- a: rotateData.cos * (transform.a ?? 1),
1203
- b: rotateData.sin * (transform.b ?? 1),
1204
- c: -rotateData.sin * (transform.c ?? 1),
1205
- d: rotateData.cos * (transform.d ?? 1)
1462
+ a: rotateData.cos * (transform.a ?? defaultTransformFactor),
1463
+ b: rotateData.sin * (transform.b ?? defaultTransformFactor),
1464
+ c: -rotateData.sin * (transform.c ?? defaultTransformFactor),
1465
+ d: rotateData.cos * (transform.d ?? defaultTransformFactor)
1206
1466
  };
1207
1467
  context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
1208
1468
  if (backgroundMask) {
@@ -1218,7 +1478,8 @@ function drawParticle(data) {
1218
1478
  if (colorStyles.fill) {
1219
1479
  context.fillStyle = colorStyles.fill;
1220
1480
  }
1221
- const strokeWidth = particle.strokeWidth ?? 0;
1481
+ const minStrokeWidth = 0,
1482
+ strokeWidth = particle.strokeWidth ?? minStrokeWidth;
1222
1483
  context.lineWidth = strokeWidth;
1223
1484
  if (colorStyles.stroke) {
1224
1485
  context.strokeStyle = colorStyles.stroke;
@@ -1230,23 +1491,14 @@ function drawParticle(data) {
1230
1491
  radius,
1231
1492
  opacity,
1232
1493
  delta,
1233
- transformData
1494
+ transformData,
1495
+ strokeWidth
1234
1496
  };
1235
- context.beginPath();
1236
1497
  drawShape(drawData);
1237
- if (particle.shapeClose) {
1238
- context.closePath();
1239
- }
1240
- if (strokeWidth > 0) {
1241
- context.stroke();
1242
- }
1243
- if (particle.shapeFill) {
1244
- context.fill();
1245
- }
1246
1498
  drawShapeAfterDraw(drawData);
1247
1499
  drawEffect(drawData);
1248
1500
  context.globalCompositeOperation = "source-over";
1249
- context.setTransform(1, 0, 0, 1, 0, 0);
1501
+ context.resetTransform();
1250
1502
  }
1251
1503
  function drawEffect(data) {
1252
1504
  const {
@@ -1279,14 +1531,16 @@ function drawEffect(data) {
1279
1531
  }
1280
1532
  function drawShape(data) {
1281
1533
  const {
1282
- container,
1283
- context,
1284
- particle,
1285
- radius,
1286
- opacity,
1287
- delta,
1288
- transformData
1289
- } = data;
1534
+ container,
1535
+ context,
1536
+ particle,
1537
+ radius,
1538
+ opacity,
1539
+ delta,
1540
+ strokeWidth,
1541
+ transformData
1542
+ } = data,
1543
+ minStrokeWidth = 0;
1290
1544
  if (!particle.shape) {
1291
1545
  return;
1292
1546
  }
@@ -1294,6 +1548,7 @@ function drawShape(data) {
1294
1548
  if (!drawer) {
1295
1549
  return;
1296
1550
  }
1551
+ context.beginPath();
1297
1552
  drawer.draw({
1298
1553
  context,
1299
1554
  particle,
@@ -1305,6 +1560,15 @@ function drawShape(data) {
1305
1560
  ...transformData
1306
1561
  }
1307
1562
  });
1563
+ if (particle.shapeClose) {
1564
+ context.closePath();
1565
+ }
1566
+ if (strokeWidth > minStrokeWidth) {
1567
+ context.stroke();
1568
+ }
1569
+ if (particle.shapeFill) {
1570
+ context.fill();
1571
+ }
1308
1572
  }
1309
1573
  function drawShapeAfterDraw(data) {
1310
1574
  const {
@@ -1320,7 +1584,7 @@ function drawShapeAfterDraw(data) {
1320
1584
  return;
1321
1585
  }
1322
1586
  const drawer = container.shapeDrawers.get(particle.shape);
1323
- if (!drawer || !drawer.afterDraw) {
1587
+ if (!drawer?.afterDraw) {
1324
1588
  return;
1325
1589
  }
1326
1590
  drawer.afterDraw({
@@ -1348,10 +1612,11 @@ function drawParticlePlugin(context, plugin, particle, delta) {
1348
1612
  plugin.drawParticle(context, particle, delta);
1349
1613
  }
1350
1614
  function alterHsl(color, type, value) {
1615
+ const lFactor = 1;
1351
1616
  return {
1352
1617
  h: color.h,
1353
1618
  s: color.s,
1354
- l: color.l + (type === "darken" ? -1 : 1) * value
1619
+ l: color.l + (type === "darken" ? -lFactor : lFactor) * value
1355
1620
  };
1356
1621
  }
1357
1622
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Canvas.js
@@ -1360,9 +1625,10 @@ function alterHsl(color, type, value) {
1360
1625
 
1361
1626
 
1362
1627
  function setTransformValue(factor, newFactor, key) {
1363
- const newValue = newFactor[key];
1628
+ const newValue = newFactor[key],
1629
+ defaultValue = 1;
1364
1630
  if (newValue !== undefined) {
1365
- factor[key] = (factor[key] ?? 1) * newValue;
1631
+ factor[key] = (factor[key] ?? defaultValue) * newValue;
1366
1632
  }
1367
1633
  }
1368
1634
  class Canvas {
@@ -1370,7 +1636,7 @@ class Canvas {
1370
1636
  this.container = container;
1371
1637
  this._applyPostDrawUpdaters = particle => {
1372
1638
  for (const updater of this._postDrawUpdaters) {
1373
- updater.afterDraw && updater.afterDraw(particle);
1639
+ updater.afterDraw?.(particle);
1374
1640
  }
1375
1641
  };
1376
1642
  this._applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
@@ -1393,12 +1659,12 @@ class Canvas {
1393
1659
  setTransformValue(transform, updaterTransform, key);
1394
1660
  }
1395
1661
  }
1396
- updater.beforeDraw && updater.beforeDraw(particle);
1662
+ updater.beforeDraw?.(particle);
1397
1663
  }
1398
1664
  };
1399
1665
  this._applyResizePlugins = () => {
1400
1666
  for (const plugin of this._resizePlugins) {
1401
- plugin.resize && plugin.resize();
1667
+ plugin.resize?.();
1402
1668
  }
1403
1669
  };
1404
1670
  this._getPluginParticleColors = particle => {
@@ -1459,17 +1725,18 @@ class Canvas {
1459
1725
  if (!trail.enable) {
1460
1726
  return;
1461
1727
  }
1728
+ const factorNumerator = 1,
1729
+ opacity = factorNumerator / trail.length;
1462
1730
  if (trailFill.color) {
1463
1731
  const fillColor = rangeColorToRgb(trailFill.color);
1464
1732
  if (!fillColor) {
1465
1733
  return;
1466
1734
  }
1467
- const trail = options.particles.move.trail;
1468
1735
  this._trailFill = {
1469
1736
  color: {
1470
1737
  ...fillColor
1471
1738
  },
1472
- opacity: 1 / trail.length
1739
+ opacity
1473
1740
  };
1474
1741
  } else {
1475
1742
  await new Promise((resolve, reject) => {
@@ -1480,7 +1747,7 @@ class Canvas {
1480
1747
  img.addEventListener("load", () => {
1481
1748
  this._trailFill = {
1482
1749
  image: img,
1483
- opacity: 1 / trail.length
1750
+ opacity
1484
1751
  };
1485
1752
  resolve();
1486
1753
  });
@@ -1535,9 +1802,10 @@ class Canvas {
1535
1802
  return;
1536
1803
  }
1537
1804
  const priority = "important",
1538
- style = element.style;
1805
+ style = element.style,
1806
+ radix = 10;
1539
1807
  style.setProperty("position", "fixed", priority);
1540
- style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(10), priority);
1808
+ style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(radix), priority);
1541
1809
  style.setProperty("top", "0", priority);
1542
1810
  style.setProperty("left", "0", priority);
1543
1811
  style.setProperty("width", "100%", priority);
@@ -1560,10 +1828,11 @@ class Canvas {
1560
1828
  clear() {
1561
1829
  const options = this.container.actualOptions,
1562
1830
  trail = options.particles.move.trail,
1563
- trailFill = this._trailFill;
1831
+ trailFill = this._trailFill,
1832
+ minimumLength = 0;
1564
1833
  if (options.backgroundMask.enable) {
1565
1834
  this.paint();
1566
- } else if (trail.enable && trail.length > 0 && trailFill) {
1835
+ } else if (trail.enable && trail.length > minimumLength && trailFill) {
1567
1836
  if (trailFill.color) {
1568
1837
  this._paintBase(getStyleFromRgb(trailFill.color, trailFill.opacity));
1569
1838
  } else if (trailFill.image) {
@@ -1579,7 +1848,7 @@ class Canvas {
1579
1848
  this.stop();
1580
1849
  if (this._generated) {
1581
1850
  const element = this.element;
1582
- element && element.remove();
1851
+ element?.remove();
1583
1852
  } else {
1584
1853
  this._resetOriginalStyle();
1585
1854
  }
@@ -1599,8 +1868,9 @@ class Canvas {
1599
1868
  if (particle.spawning || particle.destroyed) {
1600
1869
  return;
1601
1870
  }
1602
- const radius = particle.getRadius();
1603
- if (radius <= 0) {
1871
+ const radius = particle.getRadius(),
1872
+ minimumSize = 0;
1873
+ if (radius <= minimumSize) {
1604
1874
  return;
1605
1875
  }
1606
1876
  const pfColor = particle.getFillColor(),
@@ -1619,8 +1889,11 @@ class Canvas {
1619
1889
  const container = this.container,
1620
1890
  options = container.actualOptions,
1621
1891
  zIndexOptions = particle.options.zIndex,
1622
- zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate,
1623
- opacity = particle.bubble.opacity ?? particle.opacity?.value ?? 1,
1892
+ zIndexFactorOffset = 1,
1893
+ zIndexFactor = zIndexFactorOffset - particle.zIndexFactor,
1894
+ zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate,
1895
+ defaultOpacity = 1,
1896
+ opacity = particle.bubble.opacity ?? particle.opacity?.value ?? defaultOpacity,
1624
1897
  strokeOpacity = particle.strokeOpacity ?? opacity,
1625
1898
  zOpacity = opacity * zOpacityFactor,
1626
1899
  zStrokeOpacity = strokeOpacity * zOpacityFactor,
@@ -1638,7 +1911,7 @@ class Canvas {
1638
1911
  colorStyles,
1639
1912
  backgroundMask: options.backgroundMask.enable,
1640
1913
  composite: options.backgroundMask.composite,
1641
- radius: radius * (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate,
1914
+ radius: radius * zIndexFactor ** zIndexOptions.sizeRate,
1642
1915
  opacity: zOpacity,
1643
1916
  shadow: particle.options.shadow,
1644
1917
  transform
@@ -1710,7 +1983,7 @@ class Canvas {
1710
1983
  if (plugin.resize) {
1711
1984
  this._resizePlugins.push(plugin);
1712
1985
  }
1713
- if (plugin.particleFillColor || plugin.particleStrokeColor) {
1986
+ if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
1714
1987
  this._colorPlugins.push(plugin);
1715
1988
  }
1716
1989
  }
@@ -1722,7 +1995,7 @@ class Canvas {
1722
1995
  if (updater.afterDraw) {
1723
1996
  this._postDrawUpdaters.push(updater);
1724
1997
  }
1725
- if (updater.getColorStyles || updater.getTransformValues || updater.beforeDraw) {
1998
+ if (updater.getColorStyles ?? updater.getTransformValues ?? updater.beforeDraw) {
1726
1999
  this._preDrawUpdaters.push(updater);
1727
2000
  }
1728
2001
  }
@@ -1808,6 +2081,7 @@ class Canvas {
1808
2081
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/EventListeners.js
1809
2082
 
1810
2083
 
2084
+ const EventListeners_double = 2;
1811
2085
  function manageListener(element, event, handler, add, options) {
1812
2086
  if (add) {
1813
2087
  let addOptions = {
@@ -1844,7 +2118,8 @@ class EventListeners {
1844
2118
  executeOnSingleOrMultiple(onClick.mode, mode => this.container.handleClickMode(mode));
1845
2119
  }
1846
2120
  if (e.type === "touchend") {
1847
- setTimeout(() => this._mouseTouchFinish(), 500);
2121
+ const touchDelay = 500;
2122
+ setTimeout(() => this._mouseTouchFinish(), touchDelay);
1848
2123
  }
1849
2124
  };
1850
2125
  this._handleThemeChange = e => {
@@ -1855,7 +2130,7 @@ class EventListeners {
1855
2130
  themeName = mediaEvent.matches ? defaultThemes.dark : defaultThemes.light,
1856
2131
  theme = options.themes.find(theme => theme.name === themeName);
1857
2132
  if (theme && theme.default.auto) {
1858
- container.loadTheme(themeName);
2133
+ void container.loadTheme(themeName);
1859
2134
  }
1860
2135
  };
1861
2136
  this._handleVisibilityChange = () => {
@@ -1877,15 +2152,16 @@ class EventListeners {
1877
2152
  }
1878
2153
  }
1879
2154
  };
1880
- this._handleWindowResize = async () => {
2155
+ this._handleWindowResize = () => {
1881
2156
  if (this._resizeTimeout) {
1882
2157
  clearTimeout(this._resizeTimeout);
1883
2158
  delete this._resizeTimeout;
1884
2159
  }
1885
- this._resizeTimeout = setTimeout(async () => {
2160
+ const handleResize = async () => {
1886
2161
  const canvas = this.container.canvas;
1887
- canvas && (await canvas.windowResize());
1888
- }, this.container.actualOptions.interactivity.events.resize.delay * 1000);
2162
+ await canvas?.windowResize();
2163
+ };
2164
+ this._resizeTimeout = setTimeout(() => void handleResize(), this.container.actualOptions.interactivity.events.resize.delay * millisecondsToSeconds);
1889
2165
  };
1890
2166
  this._manageInteractivityListeners = (mouseLeaveTmpEvent, add) => {
1891
2167
  const handlers = this._handlers,
@@ -1976,12 +2252,12 @@ class EventListeners {
1976
2252
  this._resizeObserver.disconnect();
1977
2253
  delete this._resizeObserver;
1978
2254
  } else if (!this._resizeObserver && add && canvasEl) {
1979
- this._resizeObserver = new ResizeObserver(async entries => {
2255
+ this._resizeObserver = new ResizeObserver(entries => {
1980
2256
  const entry = entries.find(e => e.target === canvasEl);
1981
2257
  if (!entry) {
1982
2258
  return;
1983
2259
  }
1984
- await this._handleWindowResize();
2260
+ this._handleWindowResize();
1985
2261
  });
1986
2262
  this._resizeObserver.observe(canvasEl);
1987
2263
  }
@@ -2043,7 +2319,7 @@ class EventListeners {
2043
2319
  options = container.actualOptions,
2044
2320
  interactivity = container.interactivity,
2045
2321
  canvasEl = container.canvas.element;
2046
- if (!interactivity || !interactivity.element) {
2322
+ if (!interactivity?.element) {
2047
2323
  return;
2048
2324
  }
2049
2325
  interactivity.mouse.inside = true;
@@ -2067,8 +2343,8 @@ class EventListeners {
2067
2343
  targetRect = target.getBoundingClientRect(),
2068
2344
  canvasRect = canvasEl.getBoundingClientRect();
2069
2345
  pos = {
2070
- x: mouseEvent.offsetX + 2 * sourceRect.left - (targetRect.left + canvasRect.left),
2071
- y: mouseEvent.offsetY + 2 * sourceRect.top - (targetRect.top + canvasRect.top)
2346
+ x: mouseEvent.offsetX + EventListeners_double * sourceRect.left - (targetRect.left + canvasRect.left),
2347
+ y: mouseEvent.offsetY + EventListeners_double * sourceRect.top - (targetRect.top + canvasRect.top)
2072
2348
  };
2073
2349
  } else {
2074
2350
  pos = {
@@ -2086,11 +2362,13 @@ class EventListeners {
2086
2362
  this._canPush = e.type !== "touchmove";
2087
2363
  if (canvasEl) {
2088
2364
  const touchEvent = e,
2089
- lastTouch = touchEvent.touches[touchEvent.touches.length - 1],
2090
- canvasRect = canvasEl.getBoundingClientRect();
2365
+ lengthOffset = 1,
2366
+ lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset],
2367
+ canvasRect = canvasEl.getBoundingClientRect(),
2368
+ defaultCoordinate = 0;
2091
2369
  pos = {
2092
- x: lastTouch.clientX - (canvasRect.left ?? 0),
2093
- y: lastTouch.clientY - (canvasRect.top ?? 0)
2370
+ x: lastTouch.clientX - (canvasRect.left ?? defaultCoordinate),
2371
+ y: lastTouch.clientY - (canvasRect.top ?? defaultCoordinate)
2094
2372
  };
2095
2373
  }
2096
2374
  }
@@ -2467,6 +2745,7 @@ class Interactivity {
2467
2745
  }
2468
2746
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/ManualParticle.js
2469
2747
 
2748
+ const defaultPosition = 50;
2470
2749
  class ManualParticle {
2471
2750
  load(data) {
2472
2751
  if (!data) {
@@ -2474,8 +2753,8 @@ class ManualParticle {
2474
2753
  }
2475
2754
  if (data.position) {
2476
2755
  this.position = {
2477
- x: data.position.x ?? 50,
2478
- y: data.position.y ?? 50,
2756
+ x: data.position.x ?? defaultPosition,
2757
+ y: data.position.y ?? defaultPosition,
2479
2758
  mode: data.position.mode ?? "percent"
2480
2759
  };
2481
2760
  }
@@ -3564,6 +3843,9 @@ class Options {
3564
3843
  if (data.clear !== undefined) {
3565
3844
  this.clear = data.clear;
3566
3845
  }
3846
+ if (data.key !== undefined) {
3847
+ this.key = data.key;
3848
+ }
3567
3849
  if (data.name !== undefined) {
3568
3850
  this.name = data.name;
3569
3851
  }
@@ -3676,12 +3958,14 @@ class InteractionManager {
3676
3958
  }
3677
3959
  async externalInteract(delta) {
3678
3960
  for (const interactor of this._externalInteractors) {
3679
- interactor.isEnabled() && (await interactor.interact(delta));
3961
+ if (interactor.isEnabled()) {
3962
+ await interactor.interact(delta);
3963
+ }
3680
3964
  }
3681
3965
  }
3682
3966
  handleClickMode(mode) {
3683
3967
  for (const interactor of this._externalInteractors) {
3684
- interactor.handleClickMode && interactor.handleClickMode(mode);
3968
+ interactor.handleClickMode?.(mode);
3685
3969
  }
3686
3970
  }
3687
3971
  init() {
@@ -3704,15 +3988,21 @@ class InteractionManager {
3704
3988
  interactor.clear(particle, delta);
3705
3989
  }
3706
3990
  for (const interactor of this._particleInteractors) {
3707
- interactor.isEnabled(particle) && (await interactor.interact(particle, delta));
3991
+ if (interactor.isEnabled(particle)) {
3992
+ await interactor.interact(particle, delta);
3993
+ }
3708
3994
  }
3709
3995
  }
3710
- async reset(particle) {
3996
+ reset(particle) {
3711
3997
  for (const interactor of this._externalInteractors) {
3712
- interactor.isEnabled() && interactor.reset(particle);
3998
+ if (interactor.isEnabled()) {
3999
+ interactor.reset(particle);
4000
+ }
3713
4001
  }
3714
4002
  for (const interactor of this._particleInteractors) {
3715
- interactor.isEnabled(particle) && interactor.reset(particle);
4003
+ if (interactor.isEnabled(particle)) {
4004
+ interactor.reset(particle);
4005
+ }
3716
4006
  }
3717
4007
  }
3718
4008
  }
@@ -3726,6 +4016,10 @@ class InteractionManager {
3726
4016
 
3727
4017
 
3728
4018
 
4019
+ const defaultRetryCount = 0,
4020
+ Particle_double = 2,
4021
+ half = 0.5,
4022
+ Particle_squareExp = 2;
3729
4023
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
3730
4024
  const effectData = effectOptions.options[effect];
3731
4025
  if (!effectData) {
@@ -3750,7 +4044,7 @@ function fixOutMode(data) {
3750
4044
  if (!isInArray(data.outMode, data.checkModes)) {
3751
4045
  return;
3752
4046
  }
3753
- const diameter = data.radius * 2;
4047
+ const diameter = data.radius * Particle_double;
3754
4048
  if (data.coord > data.maxCoord - diameter) {
3755
4049
  data.setCb(-data.radius);
3756
4050
  } else if (data.coord < diameter) {
@@ -3760,7 +4054,7 @@ function fixOutMode(data) {
3760
4054
  class Particle {
3761
4055
  constructor(engine, id, container, position, overrideOptions, group) {
3762
4056
  this.container = container;
3763
- this._calcPosition = (container, position, zIndex, tryCount = 0) => {
4057
+ this._calcPosition = (container, position, zIndex, tryCount = defaultRetryCount) => {
3764
4058
  for (const [, plugin] of container.plugins) {
3765
4059
  const pluginPos = plugin.particlePosition !== undefined ? plugin.particlePosition(position, this) : undefined;
3766
4060
  if (pluginPos) {
@@ -3800,7 +4094,8 @@ class Particle {
3800
4094
  fixVertical(outModes.top ?? outModes.default);
3801
4095
  fixVertical(outModes.bottom ?? outModes.default);
3802
4096
  if (this._checkOverlap(pos, tryCount)) {
3803
- return this._calcPosition(container, undefined, zIndex, tryCount + 1);
4097
+ const increment = 1;
4098
+ return this._calcPosition(container, undefined, zIndex, tryCount + increment);
3804
4099
  }
3805
4100
  return pos;
3806
4101
  };
@@ -3811,11 +4106,11 @@ class Particle {
3811
4106
  if (moveOptions.direction === "inside" || moveOptions.direction === "outside") {
3812
4107
  return res;
3813
4108
  }
3814
- const rad = Math.PI / 180 * getRangeValue(moveOptions.angle.value),
3815
- radOffset = Math.PI / 180 * getRangeValue(moveOptions.angle.offset),
4109
+ const rad = degToRad(getRangeValue(moveOptions.angle.value)),
4110
+ radOffset = degToRad(getRangeValue(moveOptions.angle.offset)),
3816
4111
  range = {
3817
- left: radOffset - rad * 0.5,
3818
- right: radOffset + rad * 0.5
4112
+ left: radOffset - rad * half,
4113
+ right: radOffset + rad * half
3819
4114
  };
3820
4115
  if (!moveOptions.straight) {
3821
4116
  res.angle += randomInRange(setRangeValue(range.left, range.right));
@@ -3825,7 +4120,7 @@ class Particle {
3825
4120
  }
3826
4121
  return res;
3827
4122
  };
3828
- this._checkOverlap = (pos, tryCount = 0) => {
4123
+ this._checkOverlap = (pos, tryCount = defaultRetryCount) => {
3829
4124
  const collisionsOptions = this.options.collisions,
3830
4125
  radius = this.getRadius();
3831
4126
  if (!collisionsOptions.enable) {
@@ -3835,8 +4130,9 @@ class Particle {
3835
4130
  if (overlapOptions.enable) {
3836
4131
  return false;
3837
4132
  }
3838
- const retries = overlapOptions.retries;
3839
- if (retries >= 0 && tryCount > retries) {
4133
+ const retries = overlapOptions.retries,
4134
+ minRetries = 0;
4135
+ if (retries >= minRetries && tryCount > retries) {
3840
4136
  throw new Error(`${errorPrefix} particle is overlapping and can't be placed`);
3841
4137
  }
3842
4138
  return !!this.container.particles.find(particle => getDistance(pos, particle.position) < radius + particle.getRadius());
@@ -3845,9 +4141,11 @@ class Particle {
3845
4141
  if (!color || !this.roll || !this.backColor && !this.roll.alter) {
3846
4142
  return color;
3847
4143
  }
3848
- const backFactor = this.roll.horizontal && this.roll.vertical ? 2 : 1,
3849
- backSum = this.roll.horizontal ? Math.PI * 0.5 : 0,
3850
- rolled = Math.floor(((this.roll.angle ?? 0) + backSum) / (Math.PI / backFactor)) % 2;
4144
+ const rollFactor = 1,
4145
+ none = 0,
4146
+ backFactor = this.roll.horizontal && this.roll.vertical ? Particle_double * rollFactor : rollFactor,
4147
+ backSum = this.roll.horizontal ? Math.PI * half : none,
4148
+ rolled = Math.floor(((this.roll.angle ?? none) + backSum) / (Math.PI / backFactor)) % Particle_double;
3851
4149
  if (!rolled) {
3852
4150
  return color;
3853
4151
  }
@@ -3861,13 +4159,15 @@ class Particle {
3861
4159
  };
3862
4160
  this._initPosition = position => {
3863
4161
  const container = this.container,
3864
- zIndexValue = getRangeValue(this.options.zIndex.value);
3865
- this.position = this._calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
4162
+ zIndexValue = getRangeValue(this.options.zIndex.value),
4163
+ minZ = 0;
4164
+ this.position = this._calcPosition(container, position, clamp(zIndexValue, minZ, container.zLayers));
3866
4165
  this.initialPosition = this.position.copy();
3867
- const canvasSize = container.canvas.size;
4166
+ const canvasSize = container.canvas.size,
4167
+ defaultRadius = 0;
3868
4168
  this.moveCenter = {
3869
4169
  ...getPosition(this.options.move.center, canvasSize),
3870
- radius: this.options.move.center.radius ?? 0,
4170
+ radius: this.options.move.center.radius ?? defaultRadius,
3871
4171
  mode: this.options.move.center.mode ?? "percent"
3872
4172
  };
3873
4173
  this.direction = getParticleDirectionAngle(this.options.move.direction, this.position, this.moveCenter);
@@ -3894,14 +4194,14 @@ class Particle {
3894
4194
  const container = this.container,
3895
4195
  pathGenerator = this.pathGenerator,
3896
4196
  shapeDrawer = container.shapeDrawers.get(this.shape);
3897
- shapeDrawer && shapeDrawer.particleDestroy && shapeDrawer.particleDestroy(this);
4197
+ shapeDrawer?.particleDestroy?.(this);
3898
4198
  for (const [, plugin] of container.plugins) {
3899
- plugin.particleDestroyed && plugin.particleDestroyed(this, override);
4199
+ plugin.particleDestroyed?.(this, override);
3900
4200
  }
3901
4201
  for (const updater of container.particles.updaters) {
3902
- updater.particleDestroyed && updater.particleDestroyed(this, override);
4202
+ updater.particleDestroyed?.(this, override);
3903
4203
  }
3904
- pathGenerator && pathGenerator.reset(this);
4204
+ pathGenerator?.reset(this);
3905
4205
  this._engine.dispatchEvent("particleDestroyed", {
3906
4206
  container: this.container,
3907
4207
  data: {
@@ -3921,7 +4221,7 @@ class Particle {
3921
4221
  return this._getRollColor(this.bubble.color ?? getHslFromAnimation(this.color));
3922
4222
  }
3923
4223
  getMass() {
3924
- return this.getRadius() ** 2 * Math.PI * 0.5;
4224
+ return this.getRadius() ** Particle_squareExp * Math.PI * half;
3925
4225
  }
3926
4226
  getPosition() {
3927
4227
  return {
@@ -3969,7 +4269,7 @@ class Particle {
3969
4269
  const effectOptions = particlesOptions.effect,
3970
4270
  shapeOptions = particlesOptions.shape;
3971
4271
  if (overrideOptions) {
3972
- if (overrideOptions.effect && overrideOptions.effect.type) {
4272
+ if (overrideOptions.effect?.type) {
3973
4273
  const overrideEffectType = overrideOptions.effect.type,
3974
4274
  effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
3975
4275
  if (effect) {
@@ -3977,7 +4277,7 @@ class Particle {
3977
4277
  effectOptions.load(overrideOptions.effect);
3978
4278
  }
3979
4279
  }
3980
- if (overrideOptions.shape && overrideOptions.shape.type) {
4280
+ if (overrideOptions.shape?.type) {
3981
4281
  const overrideShapeType = overrideOptions.shape.type,
3982
4282
  shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
3983
4283
  if (shape) {
@@ -4007,7 +4307,7 @@ class Particle {
4007
4307
  this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4008
4308
  this.options = particlesOptions;
4009
4309
  const pathOptions = this.options.move.path;
4010
- this.pathDelay = getRangeValue(pathOptions.delay.value) * 1000;
4310
+ this.pathDelay = getRangeValue(pathOptions.delay.value) * millisecondsToSeconds;
4011
4311
  if (pathOptions.generator) {
4012
4312
  this.pathGenerator = this._engine.getPathGenerator(pathOptions.generator);
4013
4313
  if (this.pathGenerator && container.addPath(pathOptions.generator, this.pathGenerator)) {
@@ -4026,7 +4326,8 @@ class Particle {
4026
4326
  this._initPosition(position);
4027
4327
  this.initialVelocity = this._calculateVelocity();
4028
4328
  this.velocity = this.initialVelocity.copy();
4029
- this.moveDecay = 1 - getRangeValue(this.options.move.decay);
4329
+ const decayOffset = 1;
4330
+ this.moveDecay = decayOffset - getRangeValue(this.options.move.decay);
4030
4331
  const particles = container.particles;
4031
4332
  particles.setLastZIndex(this.position.z);
4032
4333
  this.zIndexFactor = this.position.z / container.zLayers;
@@ -4038,7 +4339,7 @@ class Particle {
4038
4339
  container.effectDrawers.set(this.effect, effectDrawer);
4039
4340
  }
4040
4341
  }
4041
- if (effectDrawer && effectDrawer.loadEffect) {
4342
+ if (effectDrawer?.loadEffect) {
4042
4343
  effectDrawer.loadEffect(this);
4043
4344
  }
4044
4345
  let shapeDrawer = container.shapeDrawers.get(this.shape);
@@ -4048,7 +4349,7 @@ class Particle {
4048
4349
  container.shapeDrawers.set(this.shape, shapeDrawer);
4049
4350
  }
4050
4351
  }
4051
- if (shapeDrawer && shapeDrawer.loadShape) {
4352
+ if (shapeDrawer?.loadShape) {
4052
4353
  shapeDrawer.loadShape(this);
4053
4354
  }
4054
4355
  const sideCountFunc = shapeDrawer?.getSidesCount;
@@ -4061,16 +4362,12 @@ class Particle {
4061
4362
  updater.init(this);
4062
4363
  }
4063
4364
  for (const mover of particles.movers) {
4064
- mover.init && mover.init(this);
4065
- }
4066
- if (effectDrawer && effectDrawer.particleInit) {
4067
- effectDrawer.particleInit(container, this);
4068
- }
4069
- if (shapeDrawer && shapeDrawer.particleInit) {
4070
- shapeDrawer.particleInit(container, this);
4365
+ mover.init?.(this);
4071
4366
  }
4367
+ effectDrawer?.particleInit?.(container, this);
4368
+ shapeDrawer?.particleInit?.(container, this);
4072
4369
  for (const [, plugin] of container.plugins) {
4073
- plugin.particleCreated && plugin.particleCreated(this);
4370
+ plugin.particleCreated?.(this);
4074
4371
  }
4075
4372
  }
4076
4373
  isInsideCanvas() {
@@ -4084,7 +4381,7 @@ class Particle {
4084
4381
  }
4085
4382
  reset() {
4086
4383
  for (const updater of this.container.particles.updaters) {
4087
- updater.reset && updater.reset(this);
4384
+ updater.reset?.(this);
4088
4385
  }
4089
4386
  }
4090
4387
  }
@@ -4142,6 +4439,7 @@ class Rectangle extends Range {
4142
4439
 
4143
4440
 
4144
4441
 
4442
+ const Circle_squareExp = 2;
4145
4443
  class Circle extends Range {
4146
4444
  constructor(x, y, radius) {
4147
4445
  super(x, y);
@@ -4160,15 +4458,15 @@ class Circle extends Range {
4160
4458
  r = this.radius;
4161
4459
  if (range instanceof Circle) {
4162
4460
  const rSum = r + range.radius,
4163
- dist = Math.sqrt(distPos.x ** 2 + distPos.y ** 2);
4461
+ dist = Math.sqrt(distPos.x ** Circle_squareExp + distPos.y ** Circle_squareExp);
4164
4462
  return rSum > dist;
4165
4463
  } else if (range instanceof Rectangle) {
4166
4464
  const {
4167
4465
  width,
4168
4466
  height
4169
4467
  } = range.size,
4170
- edges = Math.pow(distPos.x - width, 2) + Math.pow(distPos.y - height, 2);
4171
- return edges <= r ** 2 || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
4468
+ edges = Math.pow(distPos.x - width, Circle_squareExp) + Math.pow(distPos.y - height, Circle_squareExp);
4469
+ return edges <= r ** Circle_squareExp || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
4172
4470
  }
4173
4471
  return false;
4174
4472
  }
@@ -4177,6 +4475,9 @@ class Circle extends Range {
4177
4475
 
4178
4476
 
4179
4477
 
4478
+ const QuadTree_half = 0.5,
4479
+ QuadTree_double = 2,
4480
+ subdivideCount = 4;
4180
4481
  class QuadTree {
4181
4482
  constructor(rectangle, capacity) {
4182
4483
  this.rectangle = rectangle;
@@ -4193,8 +4494,9 @@ class QuadTree {
4193
4494
  {
4194
4495
  capacity
4195
4496
  } = this;
4196
- for (let i = 0; i < 4; i++) {
4197
- 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));
4497
+ for (let i = 0; i < subdivideCount; i++) {
4498
+ const fixedIndex = i % QuadTree_double;
4499
+ this._subs.push(new QuadTree(new Rectangle(x + width * QuadTree_half * fixedIndex, y + height * QuadTree_half * (Math.round(i * QuadTree_half) - fixedIndex), width * QuadTree_half, height * QuadTree_half), capacity));
4198
4500
  }
4199
4501
  this._divided = true;
4200
4502
  };
@@ -4216,7 +4518,7 @@ class QuadTree {
4216
4518
  return this._subs.some(sub => sub.insert(point));
4217
4519
  }
4218
4520
  query(range, check, found) {
4219
- const res = found || [];
4521
+ const res = found ?? [];
4220
4522
  if (!range.intersects(this.rectangle)) {
4221
4523
  return [];
4222
4524
  }
@@ -4248,7 +4550,9 @@ class QuadTree {
4248
4550
 
4249
4551
 
4250
4552
 
4251
- const qTreeCapacity = 4;
4553
+ const qTreeCapacity = 4,
4554
+ Particles_squareExp = 2,
4555
+ defaultRemoveQuantity = 1;
4252
4556
  const qTreeRectangle = canvasSize => {
4253
4557
  const {
4254
4558
  height,
@@ -4277,7 +4581,8 @@ class Particles {
4277
4581
  }
4278
4582
  const densityFactor = this._initDensityFactor(numberOptions.density),
4279
4583
  optParticlesNumber = numberOptions.value,
4280
- optParticlesLimit = numberOptions.limit.value > 0 ? numberOptions.limit.value : optParticlesNumber,
4584
+ minLimit = 0,
4585
+ optParticlesLimit = numberOptions.limit.value > minLimit ? numberOptions.limit.value : optParticlesNumber,
4281
4586
  particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount,
4282
4587
  particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
4283
4588
  if (group === undefined) {
@@ -4292,13 +4597,14 @@ class Particles {
4292
4597
  }
4293
4598
  };
4294
4599
  this._initDensityFactor = densityOptions => {
4295
- const container = this._container;
4600
+ const container = this._container,
4601
+ defaultFactor = 1;
4296
4602
  if (!container.canvas.element || !densityOptions.enable) {
4297
- return 1;
4603
+ return defaultFactor;
4298
4604
  }
4299
4605
  const canvas = container.canvas.element,
4300
4606
  pxRatio = container.retina.pixelRatio;
4301
- return canvas.width * canvas.height / (densityOptions.height * densityOptions.width * pxRatio ** 2);
4607
+ return canvas.width * canvas.height / (densityOptions.height * densityOptions.width * pxRatio ** Particles_squareExp);
4302
4608
  };
4303
4609
  this._pushParticle = (position, overrideOptions, group, initializer) => {
4304
4610
  try {
@@ -4327,7 +4633,6 @@ class Particles {
4327
4633
  return particle;
4328
4634
  } catch (e) {
4329
4635
  getLogger().warning(`${errorPrefix} adding particle: ${e}`);
4330
- return;
4331
4636
  }
4332
4637
  };
4333
4638
  this._removeParticle = (index, group, override) => {
@@ -4335,9 +4640,10 @@ class Particles {
4335
4640
  if (!particle || particle.group !== group) {
4336
4641
  return false;
4337
4642
  }
4338
- const zIdx = this._zArray.indexOf(particle);
4339
- this._array.splice(index, 1);
4340
- this._zArray.splice(zIdx, 1);
4643
+ const zIdx = this._zArray.indexOf(particle),
4644
+ deleteCount = 1;
4645
+ this._array.splice(index, deleteCount);
4646
+ this._zArray.splice(zIdx, deleteCount);
4341
4647
  particle.destroy(override);
4342
4648
  this._engine.dispatchEvent("particleRemoved", {
4343
4649
  container: this._container,
@@ -4377,11 +4683,14 @@ class Particles {
4377
4683
  addParticle(position, overrideOptions, group, initializer) {
4378
4684
  const limitOptions = this._container.actualOptions.particles.number.limit,
4379
4685
  limit = group === undefined ? this._limit : this._groupLimits.get(group) ?? this._limit,
4380
- currentCount = this.count;
4381
- if (limit > 0) {
4686
+ currentCount = this.count,
4687
+ minLimit = 0;
4688
+ if (limit > minLimit) {
4382
4689
  if (limitOptions.mode === "delete") {
4383
- const countToRemove = currentCount + 1 - limit;
4384
- if (countToRemove > 0) {
4690
+ const countOffset = 1,
4691
+ minCount = 0,
4692
+ countToRemove = currentCount + countOffset - limit;
4693
+ if (countToRemove > minCount) {
4385
4694
  this.removeQuantity(countToRemove);
4386
4695
  }
4387
4696
  } else if (limitOptions.mode === "wait") {
@@ -4477,23 +4786,28 @@ class Particles {
4477
4786
  remove(particle, group, override) {
4478
4787
  this.removeAt(this._array.indexOf(particle), undefined, group, override);
4479
4788
  }
4480
- removeAt(index, quantity = 1, group, override) {
4481
- if (index < 0 || index > this.count) {
4789
+ removeAt(index, quantity = defaultRemoveQuantity, group, override) {
4790
+ const minIndex = 0;
4791
+ if (index < minIndex || index > this.count) {
4482
4792
  return;
4483
4793
  }
4484
4794
  let deleted = 0;
4485
4795
  for (let i = index; deleted < quantity && i < this.count; i++) {
4486
- this._removeParticle(i--, group, override) && deleted++;
4796
+ if (this._removeParticle(i--, group, override)) {
4797
+ deleted++;
4798
+ }
4487
4799
  }
4488
4800
  }
4489
4801
  removeQuantity(quantity, group) {
4490
- this.removeAt(0, quantity, group);
4802
+ const defaultIndex = 0;
4803
+ this.removeAt(defaultIndex, quantity, group);
4491
4804
  }
4492
4805
  setDensity() {
4493
4806
  const options = this._container.actualOptions,
4494
- groups = options.particles.groups;
4807
+ groups = options.particles.groups,
4808
+ manualCount = 0;
4495
4809
  for (const group in groups) {
4496
- this._applyDensity(groups[group], 0, group);
4810
+ this._applyDensity(groups[group], manualCount, group);
4497
4811
  }
4498
4812
  this._applyDensity(options.particles, options.manualParticles.length);
4499
4813
  }
@@ -4512,7 +4826,7 @@ class Particles {
4512
4826
  pathGenerator.update();
4513
4827
  }
4514
4828
  for (const [, plugin] of container.plugins) {
4515
- plugin.update && (await plugin.update(delta));
4829
+ await plugin.update?.(delta);
4516
4830
  }
4517
4831
  const resizeFactor = this._resizeFactor;
4518
4832
  for (const particle of this._array) {
@@ -4523,15 +4837,17 @@ class Particles {
4523
4837
  particle.initialPosition.y *= resizeFactor.height;
4524
4838
  }
4525
4839
  particle.ignoresResizeRatio = false;
4526
- await this._interactionManager.reset(particle);
4840
+ this._interactionManager.reset(particle);
4527
4841
  for (const [, plugin] of this._container.plugins) {
4528
4842
  if (particle.destroyed) {
4529
4843
  break;
4530
4844
  }
4531
- plugin.particleUpdate && plugin.particleUpdate(particle, delta);
4845
+ plugin.particleUpdate?.(particle, delta);
4532
4846
  }
4533
4847
  for (const mover of this.movers) {
4534
- mover.isEnabled(particle) && mover.move(particle, delta);
4848
+ if (mover.isEnabled(particle)) {
4849
+ mover.move(particle, delta);
4850
+ }
4535
4851
  }
4536
4852
  if (particle.destroyed) {
4537
4853
  particlesToDelete.add(particle);
@@ -4566,7 +4882,8 @@ class Particles {
4566
4882
  if (this._needsSort) {
4567
4883
  const zArray = this._zArray;
4568
4884
  zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
4569
- this._lastZIndex = zArray[zArray.length - 1].position.z;
4885
+ const lengthOffset = 1;
4886
+ this._lastZIndex = zArray[zArray.length - lengthOffset].position.z;
4570
4887
  this._needsSort = false;
4571
4888
  }
4572
4889
  }
@@ -4574,17 +4891,19 @@ class Particles {
4574
4891
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Retina.js
4575
4892
 
4576
4893
 
4894
+ const defaultRatio = 1,
4895
+ defaultReduceFactor = 1;
4577
4896
  class Retina {
4578
4897
  constructor(container) {
4579
4898
  this.container = container;
4580
- this.pixelRatio = 1;
4581
- this.reduceFactor = 1;
4899
+ this.pixelRatio = defaultRatio;
4900
+ this.reduceFactor = defaultReduceFactor;
4582
4901
  }
4583
4902
  init() {
4584
4903
  const container = this.container,
4585
4904
  options = container.actualOptions;
4586
- this.pixelRatio = !options.detectRetina || isSsr() ? 1 : window.devicePixelRatio;
4587
- this.reduceFactor = 1;
4905
+ this.pixelRatio = !options.detectRetina || isSsr() ? defaultRatio : window.devicePixelRatio;
4906
+ this.reduceFactor = defaultReduceFactor;
4588
4907
  const ratio = this.pixelRatio,
4589
4908
  canvas = container.canvas;
4590
4909
  if (canvas.element) {
@@ -4625,10 +4944,11 @@ class Retina {
4625
4944
  function guardCheck(container) {
4626
4945
  return container && !container.destroyed;
4627
4946
  }
4628
- function initDelta(value, fpsLimit = 60, smooth = false) {
4947
+ const defaultFps = 60;
4948
+ function initDelta(value, fpsLimit = defaultFps, smooth = false) {
4629
4949
  return {
4630
4950
  value,
4631
- factor: smooth ? 60 / fpsLimit : 60 * value / 1000
4951
+ factor: smooth ? defaultFps / fpsLimit : defaultFps * value / millisecondsToSeconds
4632
4952
  };
4633
4953
  }
4634
4954
  function loadContainerOptions(engine, container, ...sourceOptionsArr) {
@@ -4646,12 +4966,16 @@ class Container {
4646
4966
  if (entry.target !== this.interactivity.element) {
4647
4967
  continue;
4648
4968
  }
4649
- (entry.isIntersecting ? this.play : this.pause)();
4969
+ if (entry.isIntersecting) {
4970
+ this.play();
4971
+ } else {
4972
+ this.pause();
4973
+ }
4650
4974
  }
4651
4975
  };
4652
4976
  this._nextFrame = async timestamp => {
4653
4977
  try {
4654
- if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + 1000 / this.fpsLimit) {
4978
+ if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + millisecondsToSeconds / this.fpsLimit) {
4655
4979
  this.draw(false);
4656
4980
  return;
4657
4981
  }
@@ -4659,7 +4983,7 @@ class Container {
4659
4983
  const delta = initDelta(timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
4660
4984
  this.addLifeTime(delta.value);
4661
4985
  this._lastFrameTime = timestamp;
4662
- if (delta.value > 1000) {
4986
+ if (delta.value > millisecondsToSeconds) {
4663
4987
  this.draw(false);
4664
4988
  return;
4665
4989
  }
@@ -4746,8 +5070,9 @@ class Container {
4746
5070
  pos = {
4747
5071
  x: mouseEvent.offsetX || mouseEvent.clientX,
4748
5072
  y: mouseEvent.offsetY || mouseEvent.clientY
4749
- };
4750
- clickOrTouchHandler(e, pos, 1);
5073
+ },
5074
+ radius = 1;
5075
+ clickOrTouchHandler(e, pos, radius);
4751
5076
  };
4752
5077
  const touchStartHandler = () => {
4753
5078
  if (!guardCheck(this)) {
@@ -4768,18 +5093,20 @@ class Container {
4768
5093
  }
4769
5094
  if (touched && !touchMoved) {
4770
5095
  const touchEvent = e;
4771
- let lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
5096
+ const lengthOffset = 1;
5097
+ let lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset];
4772
5098
  if (!lastTouch) {
4773
- lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - 1];
5099
+ lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - lengthOffset];
4774
5100
  if (!lastTouch) {
4775
5101
  return;
4776
5102
  }
4777
5103
  }
4778
5104
  const element = this.canvas.element,
4779
5105
  canvasRect = element ? element.getBoundingClientRect() : undefined,
5106
+ minCoordinate = 0,
4780
5107
  pos = {
4781
- x: lastTouch.clientX - (canvasRect ? canvasRect.left : 0),
4782
- y: lastTouch.clientY - (canvasRect ? canvasRect.top : 0)
5108
+ x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
5109
+ y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate)
4783
5110
  };
4784
5111
  clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
4785
5112
  }
@@ -4822,10 +5149,10 @@ class Container {
4822
5149
  this.particles.destroy();
4823
5150
  this.canvas.destroy();
4824
5151
  for (const [, effectDrawer] of this.effectDrawers) {
4825
- effectDrawer.destroy && effectDrawer.destroy(this);
5152
+ effectDrawer.destroy?.(this);
4826
5153
  }
4827
5154
  for (const [, shapeDrawer] of this.shapeDrawers) {
4828
- shapeDrawer.destroy && shapeDrawer.destroy(this);
5155
+ shapeDrawer.destroy?.(this);
4829
5156
  }
4830
5157
  for (const key of this.effectDrawers.keys()) {
4831
5158
  this.effectDrawers.delete(key);
@@ -4836,9 +5163,11 @@ class Container {
4836
5163
  this._engine.clearPlugins(this);
4837
5164
  this.destroyed = true;
4838
5165
  const mainArr = this._engine.dom(),
4839
- idx = mainArr.findIndex(t => t === this);
4840
- if (idx >= 0) {
4841
- mainArr.splice(idx, 1);
5166
+ idx = mainArr.findIndex(t => t === this),
5167
+ minIndex = 0;
5168
+ if (idx >= minIndex) {
5169
+ const deleteCount = 1;
5170
+ mainArr.splice(idx, deleteCount);
4842
5171
  }
4843
5172
  this._engine.dispatchEvent("containerDestroyed", {
4844
5173
  container: this
@@ -4849,13 +5178,14 @@ class Container {
4849
5178
  return;
4850
5179
  }
4851
5180
  let refreshTime = force;
4852
- this._drawAnimationFrame = requestAnimationFrame(async timestamp => {
5181
+ const frame = async timestamp => {
4853
5182
  if (refreshTime) {
4854
5183
  this._lastFrameTime = undefined;
4855
5184
  refreshTime = false;
4856
5185
  }
4857
5186
  await this._nextFrame(timestamp);
4858
- });
5187
+ };
5188
+ this._drawAnimationFrame = requestAnimationFrame(timestamp => void frame(timestamp));
4859
5189
  }
4860
5190
  async export(type, options = {}) {
4861
5191
  for (const [, plugin] of this.plugins) {
@@ -4879,7 +5209,7 @@ class Container {
4879
5209
  }
4880
5210
  this.particles.handleClickMode(mode);
4881
5211
  for (const [, plugin] of this.plugins) {
4882
- plugin.handleClickMode && plugin.handleClickMode(mode);
5212
+ plugin.handleClickMode?.(mode);
4883
5213
  }
4884
5214
  }
4885
5215
  async init() {
@@ -4912,19 +5242,21 @@ class Container {
4912
5242
  this.canvas.initBackground();
4913
5243
  this.canvas.resize();
4914
5244
  this.zLayers = this.actualOptions.zLayers;
4915
- this._duration = getRangeValue(this.actualOptions.duration) * 1000;
4916
- this._delay = getRangeValue(this.actualOptions.delay) * 1000;
5245
+ this._duration = getRangeValue(this.actualOptions.duration) * millisecondsToSeconds;
5246
+ this._delay = getRangeValue(this.actualOptions.delay) * millisecondsToSeconds;
4917
5247
  this._lifeTime = 0;
4918
- this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 120;
5248
+ const defaultFpsLimit = 120,
5249
+ minFpsLimit = 0;
5250
+ this.fpsLimit = this.actualOptions.fpsLimit > minFpsLimit ? this.actualOptions.fpsLimit : defaultFpsLimit;
4919
5251
  this._smooth = this.actualOptions.smooth;
4920
5252
  for (const [, drawer] of this.effectDrawers) {
4921
- drawer.init && (await drawer.init(this));
5253
+ await drawer.init?.(this);
4922
5254
  }
4923
5255
  for (const [, drawer] of this.shapeDrawers) {
4924
- drawer.init && (await drawer.init(this));
5256
+ await drawer.init?.(this);
4925
5257
  }
4926
5258
  for (const [, plugin] of this.plugins) {
4927
- plugin.init && (await plugin.init());
5259
+ await plugin.init?.();
4928
5260
  }
4929
5261
  this._engine.dispatchEvent("containerInit", {
4930
5262
  container: this
@@ -4932,7 +5264,7 @@ class Container {
4932
5264
  this.particles.init();
4933
5265
  this.particles.setDensity();
4934
5266
  for (const [, plugin] of this.plugins) {
4935
- plugin.particlesSetup && plugin.particlesSetup();
5267
+ plugin.particlesSetup?.();
4936
5268
  }
4937
5269
  this._engine.dispatchEvent("particlesSetup", {
4938
5270
  container: this
@@ -4957,7 +5289,7 @@ class Container {
4957
5289
  return;
4958
5290
  }
4959
5291
  for (const [, plugin] of this.plugins) {
4960
- plugin.pause && plugin.pause();
5292
+ plugin.pause?.();
4961
5293
  }
4962
5294
  if (!this.pageHidden) {
4963
5295
  this._paused = true;
@@ -4988,7 +5320,7 @@ class Container {
4988
5320
  this._engine.dispatchEvent("containerPlay", {
4989
5321
  container: this
4990
5322
  });
4991
- this.draw(needsUpdate || false);
5323
+ this.draw(needsUpdate ?? false);
4992
5324
  }
4993
5325
  async refresh() {
4994
5326
  if (!guardCheck(this)) {
@@ -5013,20 +5345,21 @@ class Container {
5013
5345
  await this.init();
5014
5346
  this.started = true;
5015
5347
  await new Promise(resolve => {
5016
- this._delayTimeout = setTimeout(async () => {
5348
+ const start = async () => {
5017
5349
  this._eventListeners.addListeners();
5018
5350
  if (this.interactivity.element instanceof HTMLElement && this._intersectionObserver) {
5019
5351
  this._intersectionObserver.observe(this.interactivity.element);
5020
5352
  }
5021
5353
  for (const [, plugin] of this.plugins) {
5022
- plugin.start && (await plugin.start());
5354
+ await plugin.start?.();
5023
5355
  }
5024
5356
  this._engine.dispatchEvent("containerStarted", {
5025
5357
  container: this
5026
5358
  });
5027
5359
  this.play();
5028
5360
  resolve();
5029
- }, this._delay);
5361
+ };
5362
+ this._delayTimeout = setTimeout(() => void start(), this._delay);
5030
5363
  });
5031
5364
  }
5032
5365
  stop() {
@@ -5047,7 +5380,7 @@ class Container {
5047
5380
  this._intersectionObserver.unobserve(this.interactivity.element);
5048
5381
  }
5049
5382
  for (const [, plugin] of this.plugins) {
5050
- plugin.stop && plugin.stop();
5383
+ plugin.stop?.();
5051
5384
  }
5052
5385
  for (const key of this.plugins.keys()) {
5053
5386
  this.plugins.delete(key);
@@ -5084,7 +5417,7 @@ class EventDispatcher {
5084
5417
  }
5085
5418
  dispatchEvent(type, args) {
5086
5419
  const listeners = this._listeners.get(type);
5087
- listeners && listeners.forEach(handler => handler(args));
5420
+ listeners?.forEach(handler => handler(args));
5088
5421
  }
5089
5422
  hasEventListener(type) {
5090
5423
  return !!this._listeners.get(type);
@@ -5102,14 +5435,16 @@ class EventDispatcher {
5102
5435
  return;
5103
5436
  }
5104
5437
  const length = arr.length,
5105
- idx = arr.indexOf(listener);
5106
- if (idx < 0) {
5438
+ idx = arr.indexOf(listener),
5439
+ minIndex = 0;
5440
+ if (idx < minIndex) {
5107
5441
  return;
5108
5442
  }
5109
- if (length === 1) {
5443
+ const deleteCount = 1;
5444
+ if (length === deleteCount) {
5110
5445
  this._listeners.delete(type);
5111
5446
  } else {
5112
- arr.splice(idx, 1);
5447
+ arr.splice(idx, deleteCount);
5113
5448
  }
5114
5449
  }
5115
5450
  }
@@ -5167,21 +5502,23 @@ class Engine {
5167
5502
  return res;
5168
5503
  }
5169
5504
  get version() {
5170
- return "3.0.2";
5505
+ return "3.1.0";
5171
5506
  }
5172
5507
  addConfig(config) {
5173
- const name = config.name ?? "default";
5174
- this._configs.set(name, config);
5508
+ const key = config.key ?? config.name ?? "default";
5509
+ this._configs.set(key, config);
5175
5510
  this._eventDispatcher.dispatchEvent("configAdded", {
5176
5511
  data: {
5177
- name,
5512
+ name: key,
5178
5513
  config
5179
5514
  }
5180
5515
  });
5181
5516
  }
5182
5517
  async addEffect(effect, drawer, refresh = true) {
5183
5518
  executeOnSingleOrMultiple(effect, type => {
5184
- !this.getEffectDrawer(type) && this.effectDrawers.set(type, drawer);
5519
+ if (!this.getEffectDrawer(type)) {
5520
+ this.effectDrawers.set(type, drawer);
5521
+ }
5185
5522
  });
5186
5523
  await this.refresh(refresh);
5187
5524
  }
@@ -5201,20 +5538,28 @@ class Engine {
5201
5538
  await this.refresh(refresh);
5202
5539
  }
5203
5540
  async addPathGenerator(name, generator, refresh = true) {
5204
- !this.getPathGenerator(name) && this.pathGenerators.set(name, generator);
5541
+ if (!this.getPathGenerator(name)) {
5542
+ this.pathGenerators.set(name, generator);
5543
+ }
5205
5544
  await this.refresh(refresh);
5206
5545
  }
5207
5546
  async addPlugin(plugin, refresh = true) {
5208
- !this.getPlugin(plugin.id) && this.plugins.push(plugin);
5547
+ if (!this.getPlugin(plugin.id)) {
5548
+ this.plugins.push(plugin);
5549
+ }
5209
5550
  await this.refresh(refresh);
5210
5551
  }
5211
5552
  async addPreset(preset, options, override = false, refresh = true) {
5212
- (override || !this.getPreset(preset)) && this.presets.set(preset, options);
5553
+ if (override || !this.getPreset(preset)) {
5554
+ this.presets.set(preset, options);
5555
+ }
5213
5556
  await this.refresh(refresh);
5214
5557
  }
5215
5558
  async addShape(shape, drawer, refresh = true) {
5216
5559
  executeOnSingleOrMultiple(shape, type => {
5217
- !this.getShapeDrawer(type) && this.shapeDrawers.set(type, drawer);
5560
+ if (!this.getShapeDrawer(type)) {
5561
+ this.shapeDrawers.set(type, drawer);
5562
+ }
5218
5563
  });
5219
5564
  await this.refresh(refresh);
5220
5565
  }
@@ -5233,7 +5578,8 @@ class Engine {
5233
5578
  const dom = this.dom(),
5234
5579
  item = dom[index];
5235
5580
  if (!item || item.destroyed) {
5236
- dom.splice(index, 1);
5581
+ const deleteCount = 1;
5582
+ dom.splice(index, deleteCount);
5237
5583
  return;
5238
5584
  }
5239
5585
  return item;
@@ -5241,7 +5587,9 @@ class Engine {
5241
5587
  getAvailablePlugins(container) {
5242
5588
  const res = new Map();
5243
5589
  for (const plugin of this.plugins) {
5244
- plugin.needsPlugin(container.actualOptions) && res.set(plugin.id, plugin.getPlugin(container));
5590
+ if (plugin.needsPlugin(container.actualOptions)) {
5591
+ res.set(plugin.id, plugin.getPlugin(container));
5592
+ }
5245
5593
  }
5246
5594
  return res;
5247
5595
  }
@@ -5282,7 +5630,8 @@ class Engine {
5282
5630
  this._initialized = true;
5283
5631
  }
5284
5632
  async load(params) {
5285
- const id = params.id ?? `tsparticles${Math.floor(getRandom() * 10000)}`,
5633
+ const randomFactor = 10000,
5634
+ id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * randomFactor)}`,
5286
5635
  {
5287
5636
  index,
5288
5637
  url
@@ -5300,12 +5649,14 @@ class Engine {
5300
5649
  }
5301
5650
  const currentOptions = itemFromSingleOrMultiple(options, index),
5302
5651
  dom = this.dom(),
5303
- oldIndex = dom.findIndex(v => v.id.description === id);
5304
- if (oldIndex >= 0) {
5652
+ oldIndex = dom.findIndex(v => v.id.description === id),
5653
+ minIndex = 0;
5654
+ if (oldIndex >= minIndex) {
5305
5655
  const old = this.domItem(oldIndex);
5306
5656
  if (old && !old.destroyed) {
5307
5657
  old.destroy();
5308
- dom.splice(oldIndex, 1);
5658
+ const deleteCount = 1;
5659
+ dom.splice(oldIndex, deleteCount);
5309
5660
  }
5310
5661
  }
5311
5662
  let canvasEl;
@@ -5315,7 +5666,8 @@ class Engine {
5315
5666
  } else {
5316
5667
  const existingCanvases = domContainer.getElementsByTagName("canvas");
5317
5668
  if (existingCanvases.length) {
5318
- canvasEl = existingCanvases[0];
5669
+ const firstIndex = 0;
5670
+ canvasEl = existingCanvases[firstIndex];
5319
5671
  canvasEl.dataset[generatedAttribute] = "false";
5320
5672
  } else {
5321
5673
  canvasEl = document.createElement("canvas");
@@ -5330,8 +5682,9 @@ class Engine {
5330
5682
  canvasEl.style.height = "100%";
5331
5683
  }
5332
5684
  const newItem = new Container(this, id, currentOptions);
5333
- if (oldIndex >= 0) {
5334
- dom.splice(oldIndex, 0, newItem);
5685
+ if (oldIndex >= minIndex) {
5686
+ const deleteCount = 0;
5687
+ dom.splice(oldIndex, deleteCount, newItem);
5335
5688
  } else {
5336
5689
  dom.push(newItem);
5337
5690
  }
@@ -5350,14 +5703,14 @@ class Engine {
5350
5703
  return;
5351
5704
  }
5352
5705
  for (const updater of updaters) {
5353
- updater.loadOptions && updater.loadOptions(options, ...sourceOptions);
5706
+ updater.loadOptions?.(options, ...sourceOptions);
5354
5707
  }
5355
5708
  }
5356
5709
  async refresh(refresh = true) {
5357
5710
  if (!refresh) {
5358
5711
  return;
5359
5712
  }
5360
- this.dom().forEach(t => t.refresh());
5713
+ await Promise.allSettled(this.dom().map(t => t.refresh()));
5361
5714
  }
5362
5715
  removeEventListener(type, listener) {
5363
5716
  this._eventDispatcher.removeEventListener(type, listener);
@@ -5403,12 +5756,15 @@ class HslColorManager {
5403
5756
  return;
5404
5757
  }
5405
5758
  const regex = /hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.%]+)\s*)?\)/i,
5406
- result = regex.exec(input);
5759
+ result = regex.exec(input),
5760
+ minLength = 4,
5761
+ defaultAlpha = 1,
5762
+ radix = 10;
5407
5763
  return result ? hslaToRgba({
5408
- a: result.length > 4 ? parseAlpha(result[5]) : 1,
5409
- h: parseInt(result[1], 10),
5410
- l: parseInt(result[3], 10),
5411
- s: parseInt(result[2], 10)
5764
+ a: result.length > minLength ? parseAlpha(result[5]) : defaultAlpha,
5765
+ h: parseInt(result[1], radix),
5766
+ l: parseInt(result[3], radix),
5767
+ s: parseInt(result[2], radix)
5412
5768
  }) : undefined;
5413
5769
  }
5414
5770
  }
@@ -5442,12 +5798,15 @@ class RgbColorManager {
5442
5798
  return;
5443
5799
  }
5444
5800
  const regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.%]+)\s*)?\)/i,
5445
- result = regex.exec(input);
5801
+ result = regex.exec(input),
5802
+ radix = 10,
5803
+ minLength = 4,
5804
+ defaultAlpha = 1;
5446
5805
  return result ? {
5447
- a: result.length > 4 ? parseAlpha(result[5]) : 1,
5448
- b: parseInt(result[3], 10),
5449
- g: parseInt(result[2], 10),
5450
- r: parseInt(result[1], 10)
5806
+ a: result.length > minLength ? parseAlpha(result[5]) : defaultAlpha,
5807
+ b: parseInt(result[3], radix),
5808
+ g: parseInt(result[2], radix),
5809
+ r: parseInt(result[1], radix)
5451
5810
  } : undefined;
5452
5811
  }
5453
5812
  }
@@ -5468,15 +5827,15 @@ function init() {
5468
5827
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/ExternalInteractorBase.js
5469
5828
  class ExternalInteractorBase {
5470
5829
  constructor(container) {
5471
- this.container = container;
5472
5830
  this.type = "external";
5831
+ this.container = container;
5473
5832
  }
5474
5833
  }
5475
5834
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/ParticlesInteractorBase.js
5476
5835
  class ParticlesInteractorBase {
5477
5836
  constructor(container) {
5478
- this.container = container;
5479
5837
  this.type = "particles";
5838
+ this.container = container;
5480
5839
  }
5481
5840
  }
5482
5841
  ;// CONCATENATED MODULE: ../../engine/dist/browser/exports.js
@@ -5580,6 +5939,10 @@ if (!isSsr()) {
5580
5939
 
5581
5940
  ;// CONCATENATED MODULE: ./dist/browser/marcbruederlin/Particles.js
5582
5941
 
5942
+ const linksMinDistance = 120,
5943
+ moveMinSpeed = 0.5,
5944
+ particlesMinCount = 100,
5945
+ sizeMinValue = 3;
5583
5946
  class Particles_Particles {
5584
5947
  static init(options) {
5585
5948
  const particles = new Particles_Particles(),
@@ -5591,9 +5954,9 @@ class Particles_Particles {
5591
5954
  if (!el) {
5592
5955
  throw new Error("No element found for selector");
5593
5956
  }
5594
- tsParticles.load({
5595
- id: selector.replace(".", "").replace("!", ""),
5957
+ void tsParticles.load({
5596
5958
  element: el,
5959
+ id: selector.replace(".", "").replace("!", ""),
5597
5960
  options: {
5598
5961
  fullScreen: {
5599
5962
  enable: false
@@ -5604,20 +5967,20 @@ class Particles_Particles {
5604
5967
  },
5605
5968
  links: {
5606
5969
  color: "random",
5607
- distance: options.minDistance ?? 120,
5970
+ distance: options.minDistance ?? linksMinDistance,
5608
5971
  enable: options.connectParticles ?? false
5609
5972
  },
5610
5973
  move: {
5611
5974
  enable: true,
5612
- speed: options.speed ?? 0.5
5975
+ speed: options.speed ?? moveMinSpeed
5613
5976
  },
5614
5977
  number: {
5615
- value: options.maxParticles ?? 100
5978
+ value: options.maxParticles ?? particlesMinCount
5616
5979
  },
5617
5980
  size: {
5618
5981
  value: {
5619
5982
  min: 1,
5620
- max: options.sizeVariations ?? 3
5983
+ max: options.sizeVariations ?? sizeMinValue
5621
5984
  }
5622
5985
  }
5623
5986
  },
@@ -5653,129 +6016,132 @@ class Particles_Particles {
5653
6016
  }
5654
6017
  destroy() {
5655
6018
  const container = this._container;
5656
- container && container.destroy();
6019
+ container?.destroy();
5657
6020
  }
5658
6021
  pauseAnimation() {
5659
6022
  const container = this._container;
5660
- container && container.pause();
6023
+ container?.pause();
5661
6024
  }
5662
6025
  resumeAnimation() {
5663
6026
  const container = this._container;
5664
- container && container.play();
6027
+ container?.play();
5665
6028
  }
5666
6029
  }
5667
6030
  ;// CONCATENATED MODULE: ./dist/browser/VincentGarreau/particles.js
5668
6031
 
5669
- const defaultPjsOptions = {
5670
- particles: {
5671
- number: {
5672
- value: 400,
5673
- density: {
5674
- enable: true,
5675
- value_area: 800
5676
- }
5677
- },
5678
- color: {
5679
- value: "#fff"
5680
- },
5681
- shape: {
5682
- type: "circle",
5683
- stroke: {
5684
- width: 0,
5685
- color: "#ff0000"
6032
+ const defaultMinOpacity = 0,
6033
+ defaultMinSize = 0,
6034
+ speedFactor = 3,
6035
+ defaultPjsOptions = {
6036
+ particles: {
6037
+ number: {
6038
+ value: 400,
6039
+ density: {
6040
+ enable: true,
6041
+ value_area: 800
6042
+ }
5686
6043
  },
5687
- polygon: {
5688
- nb_sides: 5
6044
+ color: {
6045
+ value: "#fff"
5689
6046
  },
5690
- image: {
5691
- src: "",
5692
- width: 100,
5693
- height: 100
5694
- }
5695
- },
5696
- opacity: {
5697
- value: 1,
5698
- random: false,
5699
- anim: {
5700
- enable: false,
5701
- speed: 2,
5702
- opacity_min: 0,
5703
- sync: false
5704
- }
5705
- },
5706
- size: {
5707
- value: 20,
5708
- random: false,
5709
- anim: {
5710
- enable: false,
5711
- speed: 20,
5712
- size_min: 0,
5713
- sync: false
5714
- }
5715
- },
5716
- line_linked: {
5717
- enable: true,
5718
- distance: 100,
5719
- color: "#fff",
5720
- opacity: 1,
5721
- width: 1
5722
- },
5723
- move: {
5724
- enable: true,
5725
- speed: 2,
5726
- direction: "none",
5727
- random: false,
5728
- straight: false,
5729
- out_mode: "out",
5730
- bounce: false,
5731
- attract: {
5732
- enable: false,
5733
- rotateX: 3000,
5734
- rotateY: 3000
5735
- }
5736
- }
5737
- },
5738
- interactivity: {
5739
- detect_on: "canvas",
5740
- events: {
5741
- onhover: {
5742
- enable: true,
5743
- mode: "grab"
6047
+ shape: {
6048
+ type: "circle",
6049
+ stroke: {
6050
+ width: 0,
6051
+ color: "#ff0000"
6052
+ },
6053
+ polygon: {
6054
+ nb_sides: 5
6055
+ },
6056
+ image: {
6057
+ src: "",
6058
+ width: 100,
6059
+ height: 100
6060
+ }
5744
6061
  },
5745
- onclick: {
5746
- enable: true,
5747
- mode: "push"
6062
+ opacity: {
6063
+ value: 1,
6064
+ random: false,
6065
+ anim: {
6066
+ enable: false,
6067
+ speed: 2,
6068
+ opacity_min: 0,
6069
+ sync: false
6070
+ }
5748
6071
  },
5749
- resize: true
5750
- },
5751
- modes: {
5752
- grab: {
5753
- distance: 100,
5754
- line_linked: {
5755
- opacity: 1
6072
+ size: {
6073
+ value: 20,
6074
+ random: false,
6075
+ anim: {
6076
+ enable: false,
6077
+ speed: 20,
6078
+ size_min: 0,
6079
+ sync: false
5756
6080
  }
5757
6081
  },
5758
- bubble: {
5759
- distance: 200,
5760
- size: 80,
5761
- duration: 0.4,
6082
+ line_linked: {
6083
+ enable: true,
6084
+ distance: 100,
6085
+ color: "#fff",
5762
6086
  opacity: 1,
5763
- speed: 3
6087
+ width: 1
5764
6088
  },
5765
- repulse: {
5766
- distance: 200,
5767
- duration: 0.4
5768
- },
5769
- push: {
5770
- particles_nb: 4
6089
+ move: {
6090
+ enable: true,
6091
+ speed: 2,
6092
+ direction: "none",
6093
+ random: false,
6094
+ straight: false,
6095
+ out_mode: "out",
6096
+ bounce: false,
6097
+ attract: {
6098
+ enable: false,
6099
+ rotateX: 3000,
6100
+ rotateY: 3000
6101
+ }
6102
+ }
6103
+ },
6104
+ interactivity: {
6105
+ detect_on: "canvas",
6106
+ events: {
6107
+ onhover: {
6108
+ enable: true,
6109
+ mode: "grab"
6110
+ },
6111
+ onclick: {
6112
+ enable: true,
6113
+ mode: "push"
6114
+ },
6115
+ resize: true
5771
6116
  },
5772
- remove: {
5773
- particles_nb: 2
6117
+ modes: {
6118
+ grab: {
6119
+ distance: 100,
6120
+ line_linked: {
6121
+ opacity: 1
6122
+ }
6123
+ },
6124
+ bubble: {
6125
+ distance: 200,
6126
+ size: 80,
6127
+ duration: 0.4,
6128
+ opacity: 1,
6129
+ speed: 3
6130
+ },
6131
+ repulse: {
6132
+ distance: 200,
6133
+ duration: 0.4
6134
+ },
6135
+ push: {
6136
+ particles_nb: 4
6137
+ },
6138
+ remove: {
6139
+ particles_nb: 2
6140
+ }
5774
6141
  }
5775
- }
5776
- },
5777
- retina_detect: false
5778
- };
6142
+ },
6143
+ retina_detect: false
6144
+ };
5779
6145
  const initParticlesJS = engine => {
5780
6146
  const particlesJS = (tagId, options) => {
5781
6147
  const fixedOptions = deepExtend(defaultPjsOptions, options);
@@ -5863,7 +6229,7 @@ const initParticlesJS = engine => {
5863
6229
  },
5864
6230
  opacity: {
5865
6231
  value: fixedOptions.particles.opacity.random ? {
5866
- min: fixedOptions.particles.opacity.anim.enable ? fixedOptions.particles.opacity.anim.opacity_min : 0,
6232
+ min: fixedOptions.particles.opacity.anim.enable ? fixedOptions.particles.opacity.anim.opacity_min : defaultMinOpacity,
5867
6233
  max: fixedOptions.particles.opacity.value
5868
6234
  } : fixedOptions.particles.opacity.value,
5869
6235
  animation: {
@@ -5874,7 +6240,7 @@ const initParticlesJS = engine => {
5874
6240
  },
5875
6241
  size: {
5876
6242
  value: fixedOptions.particles.size.random ? {
5877
- min: fixedOptions.particles.size.anim.enable ? fixedOptions.particles.size.anim.size_min : 0,
6243
+ min: fixedOptions.particles.size.anim.enable ? fixedOptions.particles.size.anim.size_min : defaultMinSize,
5878
6244
  max: fixedOptions.particles.size.value
5879
6245
  } : fixedOptions.particles.size.value,
5880
6246
  animation: {
@@ -5892,7 +6258,7 @@ const initParticlesJS = engine => {
5892
6258
  },
5893
6259
  move: {
5894
6260
  enable: fixedOptions.particles.move.enable,
5895
- speed: fixedOptions.particles.move.speed / 3,
6261
+ speed: fixedOptions.particles.move.speed / speedFactor,
5896
6262
  direction: fixedOptions.particles.move.direction,
5897
6263
  random: fixedOptions.particles.move.random,
5898
6264
  straight: fixedOptions.particles.move.straight,