@tsparticles/basic 3.0.3 → 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.3
7
+ * v3.1.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -139,6 +139,7 @@ __webpack_require__.d(__webpack_exports__, {
139
139
  colorToHsl: () => (/* reexport */ colorToHsl),
140
140
  colorToRgb: () => (/* reexport */ colorToRgb),
141
141
  deepExtend: () => (/* reexport */ deepExtend),
142
+ degToRad: () => (/* reexport */ degToRad),
142
143
  divMode: () => (/* reexport */ divMode),
143
144
  divModeExecute: () => (/* reexport */ divModeExecute),
144
145
  drawEffect: () => (/* reexport */ drawEffect),
@@ -171,6 +172,7 @@ __webpack_require__.d(__webpack_exports__, {
171
172
  getSize: () => (/* reexport */ getSize),
172
173
  getStyleFromHsl: () => (/* reexport */ getStyleFromHsl),
173
174
  getStyleFromRgb: () => (/* reexport */ getStyleFromRgb),
175
+ halfRandom: () => (/* reexport */ halfRandom),
174
176
  hasMatchMedia: () => (/* reexport */ hasMatchMedia),
175
177
  hslToRgb: () => (/* reexport */ hslToRgb),
176
178
  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),
@@ -200,6 +203,7 @@ __webpack_require__.d(__webpack_exports__, {
200
203
  paintBase: () => (/* reexport */ paintBase),
201
204
  paintImage: () => (/* reexport */ paintImage),
202
205
  parseAlpha: () => (/* reexport */ parseAlpha),
206
+ percentDenominator: () => (/* reexport */ percentDenominator),
203
207
  randomInRange: () => (/* reexport */ randomInRange),
204
208
  rangeColorToHsl: () => (/* reexport */ rangeColorToHsl),
205
209
  rangeColorToRgb: () => (/* reexport */ rangeColorToRgb),
@@ -220,6 +224,9 @@ __webpack_require__.d(__webpack_exports__, {
220
224
  touchMoveEvent: () => (/* reexport */ touchMoveEvent),
221
225
  touchStartEvent: () => (/* reexport */ touchStartEvent),
222
226
  tsParticles: () => (/* reexport */ tsParticles),
227
+ updateAnimation: () => (/* reexport */ updateAnimation),
228
+ updateColor: () => (/* reexport */ updateColor),
229
+ updateColorValue: () => (/* reexport */ updateColorValue),
223
230
  visibilityChangeEvent: () => (/* reexport */ visibilityChangeEvent)
224
231
  });
225
232
 
@@ -237,9 +244,19 @@ const touchCancelEvent = "touchcancel";
237
244
  const resizeEvent = "resize";
238
245
  const visibilityChangeEvent = "visibilitychange";
239
246
  const errorPrefix = "tsParticles - Error";
247
+ const percentDenominator = 100;
248
+ const halfRandom = 0.5;
249
+ const millisecondsToSeconds = 1000;
240
250
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/Vector3d.js
241
251
 
242
252
 
253
+ const origin = {
254
+ x: 0,
255
+ y: 0,
256
+ z: 0
257
+ },
258
+ squareExp = 2,
259
+ inverseFactorNumerator = 1.0;
243
260
  class Vector3d {
244
261
  constructor(xOrCoords, y, z) {
245
262
  this._updateFromAngle = (angle, length) => {
@@ -250,17 +267,17 @@ class Vector3d {
250
267
  this.x = xOrCoords.x;
251
268
  this.y = xOrCoords.y;
252
269
  const coords3d = xOrCoords;
253
- this.z = coords3d.z ? coords3d.z : 0;
270
+ this.z = coords3d.z ? coords3d.z : origin.z;
254
271
  } else if (xOrCoords !== undefined && y !== undefined) {
255
272
  this.x = xOrCoords;
256
273
  this.y = y;
257
- this.z = z ?? 0;
274
+ this.z = z ?? origin.z;
258
275
  } else {
259
276
  throw new Error(`${errorPrefix} Vector3d not initialized correctly`);
260
277
  }
261
278
  }
262
279
  static get origin() {
263
- return Vector3d.create(0, 0, 0);
280
+ return Vector3d.create(origin.x, origin.y, origin.z);
264
281
  }
265
282
  get angle() {
266
283
  return Math.atan2(this.y, this.x);
@@ -306,7 +323,7 @@ class Vector3d {
306
323
  this.z /= n;
307
324
  }
308
325
  getLengthSq() {
309
- return this.x ** 2 + this.y ** 2;
326
+ return this.x ** squareExp + this.y ** squareExp;
310
327
  }
311
328
  mult(n) {
312
329
  return Vector3d.create(this.x * n, this.y * n, this.z * n);
@@ -317,19 +334,20 @@ class Vector3d {
317
334
  this.z *= n;
318
335
  }
319
336
  normalize() {
320
- const length = this.length;
321
- if (length != 0) {
322
- this.multTo(1.0 / length);
337
+ const length = this.length,
338
+ noLength = 0;
339
+ if (length != noLength) {
340
+ this.multTo(inverseFactorNumerator / length);
323
341
  }
324
342
  }
325
343
  rotate(angle) {
326
- return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), 0);
344
+ 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);
327
345
  }
328
346
  setTo(c) {
329
347
  this.x = c.x;
330
348
  this.y = c.y;
331
349
  const v3d = c;
332
- this.z = v3d.z ? v3d.z : 0;
350
+ this.z = v3d.z ? v3d.z : origin.z;
333
351
  }
334
352
  sub(v) {
335
353
  return Vector3d.create(this.x - v.x, this.y - v.y, this.z - v.z);
@@ -342,12 +360,17 @@ class Vector3d {
342
360
  }
343
361
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/Vector.js
344
362
 
363
+ const Vector_origin = {
364
+ x: 0,
365
+ y: 0,
366
+ z: 0
367
+ };
345
368
  class Vector extends Vector3d {
346
369
  constructor(xOrCoords, y) {
347
- super(xOrCoords, y, 0);
370
+ super(xOrCoords, y, Vector_origin.z);
348
371
  }
349
372
  static get origin() {
350
- return Vector.create(0, 0);
373
+ return Vector.create(Vector_origin.x, Vector_origin.y);
351
374
  }
352
375
  static clone(source) {
353
376
  return Vector.create(source.x, source.y);
@@ -359,8 +382,11 @@ class Vector extends Vector3d {
359
382
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/NumberUtils.js
360
383
 
361
384
 
385
+
362
386
  let _random = Math.random;
363
- const easings = new Map();
387
+ const easings = new Map(),
388
+ NumberUtils_double = 2,
389
+ doublePI = Math.PI * NumberUtils_double;
364
390
  function addEasing(name, easing) {
365
391
  if (easings.get(name)) {
366
392
  return;
@@ -368,13 +394,15 @@ function addEasing(name, easing) {
368
394
  easings.set(name, easing);
369
395
  }
370
396
  function getEasing(name) {
371
- return easings.get(name) || (value => value);
397
+ return easings.get(name) ?? (value => value);
372
398
  }
373
399
  function setRandom(rnd = Math.random) {
374
400
  _random = rnd;
375
401
  }
376
402
  function getRandom() {
377
- return clamp(_random(), 0, 1 - 1e-16);
403
+ const min = 0,
404
+ max = 1;
405
+ return clamp(_random(), min, max - Number.EPSILON);
378
406
  }
379
407
  function clamp(num, min, max) {
380
408
  return Math.min(Math.max(num, min), max);
@@ -383,10 +411,11 @@ function mix(comp1, comp2, weight1, weight2) {
383
411
  return Math.floor((comp1 * weight1 + comp2 * weight2) / (weight1 + weight2));
384
412
  }
385
413
  function randomInRange(r) {
386
- const max = getRangeMax(r);
414
+ const max = getRangeMax(r),
415
+ minOffset = 0;
387
416
  let min = getRangeMin(r);
388
417
  if (max === min) {
389
- min = 0;
418
+ min = minOffset;
390
419
  }
391
420
  return getRandom() * (max - min) + min;
392
421
  }
@@ -412,43 +441,52 @@ function setRangeValue(source, value) {
412
441
  }
413
442
  function getDistances(pointA, pointB) {
414
443
  const dx = pointA.x - pointB.x,
415
- dy = pointA.y - pointB.y;
444
+ dy = pointA.y - pointB.y,
445
+ squareExp = 2;
416
446
  return {
417
447
  dx: dx,
418
448
  dy: dy,
419
- distance: Math.sqrt(dx ** 2 + dy ** 2)
449
+ distance: Math.sqrt(dx ** squareExp + dy ** squareExp)
420
450
  };
421
451
  }
422
452
  function getDistance(pointA, pointB) {
423
453
  return getDistances(pointA, pointB).distance;
424
454
  }
455
+ function degToRad(degrees) {
456
+ const PIDeg = 180;
457
+ return degrees * Math.PI / PIDeg;
458
+ }
425
459
  function getParticleDirectionAngle(direction, position, center) {
426
460
  if (isNumber(direction)) {
427
- return direction * Math.PI / 180;
461
+ return degToRad(direction);
428
462
  }
463
+ const empty = 0,
464
+ half = 0.5,
465
+ quarter = 0.25,
466
+ threeQuarter = half + quarter;
429
467
  switch (direction) {
430
468
  case "top":
431
- return -Math.PI * 0.5;
469
+ return -Math.PI * half;
432
470
  case "top-right":
433
- return -Math.PI * 0.25;
471
+ return -Math.PI * quarter;
434
472
  case "right":
435
- return 0;
473
+ return empty;
436
474
  case "bottom-right":
437
- return Math.PI * 0.25;
475
+ return Math.PI * quarter;
438
476
  case "bottom":
439
- return Math.PI * 0.5;
477
+ return Math.PI * half;
440
478
  case "bottom-left":
441
- return Math.PI * 0.75;
479
+ return Math.PI * threeQuarter;
442
480
  case "left":
443
481
  return Math.PI;
444
482
  case "top-left":
445
- return -Math.PI * 0.75;
483
+ return -Math.PI * threeQuarter;
446
484
  case "inside":
447
485
  return Math.atan2(center.y - position.y, center.x - position.x);
448
486
  case "outside":
449
487
  return Math.atan2(position.y - center.y, position.x - center.x);
450
488
  default:
451
- return getRandom() * Math.PI * 2;
489
+ return getRandom() * doublePI;
452
490
  }
453
491
  }
454
492
  function getParticleBaseVelocity(direction) {
@@ -458,18 +496,19 @@ function getParticleBaseVelocity(direction) {
458
496
  return baseVelocity;
459
497
  }
460
498
  function collisionVelocity(v1, v2, m1, m2) {
461
- return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * 2 * m2 / (m1 + m2), v1.y);
499
+ const double = 2;
500
+ return Vector.create(v1.x * (m1 - m2) / (m1 + m2) + v2.x * double * m2 / (m1 + m2), v1.y);
462
501
  }
463
502
  function calcPositionFromSize(data) {
464
- return data.position && data.position.x !== undefined && data.position.y !== undefined ? {
465
- x: data.position.x * data.size.width / 100,
466
- y: data.position.y * data.size.height / 100
503
+ return data.position?.x !== undefined && data.position.y !== undefined ? {
504
+ x: data.position.x * data.size.width / percentDenominator,
505
+ y: data.position.y * data.size.height / percentDenominator
467
506
  } : undefined;
468
507
  }
469
508
  function calcPositionOrRandomFromSize(data) {
470
509
  return {
471
- x: (data.position?.x ?? getRandom() * 100) * data.size.width / 100,
472
- y: (data.position?.y ?? getRandom() * 100) * data.size.height / 100
510
+ x: (data.position?.x ?? getRandom() * percentDenominator) * data.size.width / percentDenominator,
511
+ y: (data.position?.y ?? getRandom() * percentDenominator) * data.size.height / percentDenominator
473
512
  };
474
513
  }
475
514
  function calcPositionOrRandomFromSizeRanged(data) {
@@ -499,11 +538,16 @@ function calcExactPositionOrRandomFromSizeRanged(data) {
499
538
  });
500
539
  }
501
540
  function parseAlpha(input) {
502
- return input ? input.endsWith("%") ? parseFloat(input) / 100 : parseFloat(input) : 1;
541
+ const defaultAlpha = 1;
542
+ if (!input) {
543
+ return defaultAlpha;
544
+ }
545
+ return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
503
546
  }
504
547
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/Utils.js
505
548
 
506
549
 
550
+
507
551
  const _logger = {
508
552
  debug: console.debug,
509
553
  error: console.error,
@@ -534,11 +578,13 @@ function rectSideBounce(data) {
534
578
  rectOtherSide,
535
579
  velocity,
536
580
  factor
537
- } = data;
581
+ } = data,
582
+ half = 0.5,
583
+ minVelocity = 0;
538
584
  if (pOtherSide.min < rectOtherSide.min || pOtherSide.min > rectOtherSide.max || pOtherSide.max < rectOtherSide.min || pOtherSide.max > rectOtherSide.max) {
539
585
  return res;
540
586
  }
541
- if (pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * 0.5 && velocity > 0 || pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * 0.5 && velocity < 0) {
587
+ 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) {
542
588
  res.velocity = velocity * -factor;
543
589
  res.bounced = true;
544
590
  }
@@ -575,7 +621,8 @@ function safeMutationObserver(callback) {
575
621
  return new MutationObserver(callback);
576
622
  }
577
623
  function isInArray(value, array) {
578
- return value === array || isArray(array) && array.indexOf(value) > -1;
624
+ const invalidIndex = -1;
625
+ return value === array || isArray(array) && array.indexOf(value) > invalidIndex;
579
626
  }
580
627
  async function loadFont(font, weight) {
581
628
  try {
@@ -589,7 +636,8 @@ function itemFromArray(array, index, useIndex = true) {
589
636
  return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
590
637
  }
591
638
  function isPointInside(point, size, offset, radius, direction) {
592
- return areBoundsInside(calculateBounds(point, radius ?? 0), size, offset, direction);
639
+ const minRadius = 0;
640
+ return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
593
641
  }
594
642
  function areBoundsInside(bounds, size, offset, direction) {
595
643
  let inside = true;
@@ -686,8 +734,9 @@ function circleBounce(p1, p2) {
686
734
  {
687
735
  dx: xDist,
688
736
  dy: yDist
689
- } = getDistances(pos2, pos1);
690
- if (xVelocityDiff * xDist + yVelocityDiff * yDist < 0) {
737
+ } = getDistances(pos2, pos1),
738
+ minimumDistance = 0;
739
+ if (xVelocityDiff * xDist + yVelocityDiff * yDist < minimumDistance) {
691
740
  return;
692
741
  }
693
742
  const angle = -Math.atan2(yDist, xDist),
@@ -767,19 +816,24 @@ function rectBounce(particle, divBounds) {
767
816
  }
768
817
  }
769
818
  function executeOnSingleOrMultiple(obj, callback) {
770
- return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, 0);
819
+ const defaultIndex = 0;
820
+ return isArray(obj) ? obj.map((item, index) => callback(item, index)) : callback(obj, defaultIndex);
771
821
  }
772
822
  function itemFromSingleOrMultiple(obj, index, useIndex) {
773
823
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
774
824
  }
775
825
  function findItemFromSingleOrMultiple(obj, callback) {
776
- return isArray(obj) ? obj.find((t, index) => callback(t, index)) : callback(obj, 0) ? obj : undefined;
826
+ if (isArray(obj)) {
827
+ return obj.find((t, index) => callback(t, index));
828
+ }
829
+ const defaultIndex = 0;
830
+ return callback(obj, defaultIndex) ? obj : undefined;
777
831
  }
778
832
  function initParticleNumericAnimationValue(options, pxRatio) {
779
833
  const valueRange = options.value,
780
834
  animationOptions = options.animation,
781
835
  res = {
782
- delayTime: getRangeValue(animationOptions.delay) * 1000,
836
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
783
837
  enable: animationOptions.enable,
784
838
  value: getRangeValue(options.value) * pxRatio,
785
839
  max: getRangeMax(valueRange) * pxRatio,
@@ -787,9 +841,10 @@ function initParticleNumericAnimationValue(options, pxRatio) {
787
841
  loops: 0,
788
842
  maxLoops: getRangeValue(animationOptions.count),
789
843
  time: 0
790
- };
844
+ },
845
+ decayOffset = 1;
791
846
  if (animationOptions.enable) {
792
- res.decay = 1 - getRangeValue(animationOptions.decay);
847
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
793
848
  switch (animationOptions.mode) {
794
849
  case "increase":
795
850
  res.status = "increasing";
@@ -798,7 +853,7 @@ function initParticleNumericAnimationValue(options, pxRatio) {
798
853
  res.status = "decreasing";
799
854
  break;
800
855
  case "random":
801
- res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
856
+ res.status = getRandom() >= halfRandom ? "increasing" : "decreasing";
802
857
  break;
803
858
  }
804
859
  const autoStatus = animationOptions.mode === "auto";
@@ -819,7 +874,7 @@ function initParticleNumericAnimationValue(options, pxRatio) {
819
874
  default:
820
875
  res.value = randomInRange(res);
821
876
  if (autoStatus) {
822
- res.status = getRandom() >= 0.5 ? "increasing" : "decreasing";
877
+ res.status = getRandom() >= halfRandom ? "increasing" : "decreasing";
823
878
  }
824
879
  break;
825
880
  }
@@ -839,13 +894,13 @@ function getPositionOrSize(positionOrSize, canvasSize) {
839
894
  const isPosition = ("x" in positionOrSize);
840
895
  if (isPosition) {
841
896
  return {
842
- x: positionOrSize.x / 100 * canvasSize.width,
843
- y: positionOrSize.y / 100 * canvasSize.height
897
+ x: positionOrSize.x / percentDenominator * canvasSize.width,
898
+ y: positionOrSize.y / percentDenominator * canvasSize.height
844
899
  };
845
900
  } else {
846
901
  return {
847
- width: positionOrSize.width / 100 * canvasSize.width,
848
- height: positionOrSize.height / 100 * canvasSize.height
902
+ width: positionOrSize.width / percentDenominator * canvasSize.width,
903
+ height: positionOrSize.height / percentDenominator * canvasSize.height
849
904
  };
850
905
  }
851
906
  }
@@ -873,9 +928,85 @@ function isObject(arg) {
873
928
  function isArray(arg) {
874
929
  return Array.isArray(arg);
875
930
  }
931
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
932
+ switch (destroyType) {
933
+ case "max":
934
+ if (value >= maxValue) {
935
+ particle.destroy();
936
+ }
937
+ break;
938
+ case "min":
939
+ if (value <= minValue) {
940
+ particle.destroy();
941
+ }
942
+ break;
943
+ }
944
+ }
945
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
946
+ const minLoops = 0,
947
+ minDelay = 0,
948
+ identity = 1,
949
+ minVelocity = 0,
950
+ minDecay = 1;
951
+ if (particle.destroyed || !data || !data.enable || (data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops)) {
952
+ return;
953
+ }
954
+ const velocity = (data.velocity ?? minVelocity) * delta.factor,
955
+ minValue = data.min,
956
+ maxValue = data.max,
957
+ decay = data.decay ?? minDecay;
958
+ if (!data.time) {
959
+ data.time = 0;
960
+ }
961
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
962
+ data.time += delta.value;
963
+ }
964
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
965
+ return;
966
+ }
967
+ switch (data.status) {
968
+ case "increasing":
969
+ if (data.value >= maxValue) {
970
+ if (changeDirection) {
971
+ data.status = "decreasing";
972
+ } else {
973
+ data.value -= maxValue;
974
+ }
975
+ if (!data.loops) {
976
+ data.loops = minLoops;
977
+ }
978
+ data.loops++;
979
+ } else {
980
+ data.value += velocity;
981
+ }
982
+ break;
983
+ case "decreasing":
984
+ if (data.value <= minValue) {
985
+ if (changeDirection) {
986
+ data.status = "increasing";
987
+ } else {
988
+ data.value += maxValue;
989
+ }
990
+ if (!data.loops) {
991
+ data.loops = minLoops;
992
+ }
993
+ data.loops++;
994
+ } else {
995
+ data.value -= velocity;
996
+ }
997
+ }
998
+ if (data.velocity && decay !== identity) {
999
+ data.velocity *= decay;
1000
+ }
1001
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
1002
+ if (!particle.destroyed) {
1003
+ data.value = clamp(data.value, minValue, maxValue);
1004
+ }
1005
+ }
876
1006
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/ColorUtils.js
877
1007
 
878
1008
 
1009
+
879
1010
  const randomColorValue = "random",
880
1011
  midColorValue = "mid",
881
1012
  colorManagers = new Map();
@@ -893,12 +1024,15 @@ function stringToRgba(input) {
893
1024
  return r + r + g + g + b + b + (a !== undefined ? a + a : "");
894
1025
  }),
895
1026
  regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i,
896
- result = regex.exec(hexFixed);
1027
+ result = regex.exec(hexFixed),
1028
+ radix = 16,
1029
+ defaultAlpha = 1,
1030
+ alphaFactor = 0xff;
897
1031
  return result ? {
898
- a: result[4] !== undefined ? parseInt(result[4], 16) / 0xff : 1,
899
- b: parseInt(result[3], 16),
900
- g: parseInt(result[2], 16),
901
- r: parseInt(result[1], 16)
1032
+ a: result[4] !== undefined ? parseInt(result[4], radix) / alphaFactor : defaultAlpha,
1033
+ b: parseInt(result[3], radix),
1034
+ g: parseInt(result[2], radix),
1035
+ r: parseInt(result[1], radix)
902
1036
  } : undefined;
903
1037
  }
904
1038
  function rangeColorToRgb(input, index, useIndex = true) {
@@ -954,28 +1088,37 @@ function rangeColorToHsl(color, index, useIndex = true) {
954
1088
  return rgb ? rgbToHsl(rgb) : undefined;
955
1089
  }
956
1090
  function rgbToHsl(color) {
957
- const r1 = color.r / 255,
958
- g1 = color.g / 255,
959
- b1 = color.b / 255,
1091
+ const rgbMax = 255,
1092
+ hMax = 360,
1093
+ sMax = 100,
1094
+ lMax = 100,
1095
+ hMin = 0,
1096
+ sMin = 0,
1097
+ hPhase = 60,
1098
+ half = 0.5,
1099
+ double = 2,
1100
+ r1 = color.r / rgbMax,
1101
+ g1 = color.g / rgbMax,
1102
+ b1 = color.b / rgbMax,
960
1103
  max = Math.max(r1, g1, b1),
961
1104
  min = Math.min(r1, g1, b1),
962
1105
  res = {
963
- h: 0,
964
- l: (max + min) * 0.5,
965
- s: 0
1106
+ h: hMin,
1107
+ l: (max + min) * half,
1108
+ s: sMin
966
1109
  };
967
1110
  if (max !== min) {
968
- res.s = res.l < 0.5 ? (max - min) / (max + min) : (max - min) / (2.0 - max - min);
969
- res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? 2.0 + (b1 - r1) / (max - min) : 4.0 + (r1 - g1) / (max - min);
1111
+ res.s = res.l < half ? (max - min) / (max + min) : (max - min) / (double - max - min);
1112
+ res.h = r1 === max ? (g1 - b1) / (max - min) : res.h = g1 === max ? double + (b1 - r1) / (max - min) : double * double + (r1 - g1) / (max - min);
970
1113
  }
971
- res.l *= 100;
972
- res.s *= 100;
973
- res.h *= 60;
974
- if (res.h < 0) {
975
- res.h += 360;
1114
+ res.l *= lMax;
1115
+ res.s *= sMax;
1116
+ res.h *= hPhase;
1117
+ if (res.h < hMin) {
1118
+ res.h += hMax;
976
1119
  }
977
- if (res.h >= 360) {
978
- res.h -= 360;
1120
+ if (res.h >= hMax) {
1121
+ res.h -= hMax;
979
1122
  }
980
1123
  return res;
981
1124
  }
@@ -986,43 +1129,59 @@ function stringToRgb(input) {
986
1129
  return stringToRgba(input);
987
1130
  }
988
1131
  function hslToRgb(hsl) {
989
- const h = (hsl.h % 360 + 360) % 360,
990
- s = Math.max(0, Math.min(100, hsl.s)),
991
- l = Math.max(0, Math.min(100, hsl.l)),
992
- hNormalized = h / 360,
993
- sNormalized = s / 100,
994
- lNormalized = l / 100;
995
- if (s === 0) {
996
- const grayscaleValue = Math.round(lNormalized * 255);
1132
+ const hMax = 360,
1133
+ sMax = 100,
1134
+ lMax = 100,
1135
+ sMin = 0,
1136
+ lMin = 0,
1137
+ h = (hsl.h % hMax + hMax) % hMax,
1138
+ s = Math.max(sMin, Math.min(sMax, hsl.s)),
1139
+ l = Math.max(lMin, Math.min(lMax, hsl.l)),
1140
+ hNormalized = h / hMax,
1141
+ sNormalized = s / sMax,
1142
+ lNormalized = l / lMax,
1143
+ rgbFactor = 255,
1144
+ triple = 3;
1145
+ if (s === sMin) {
1146
+ const grayscaleValue = Math.round(lNormalized * rgbFactor);
997
1147
  return {
998
1148
  r: grayscaleValue,
999
1149
  g: grayscaleValue,
1000
1150
  b: grayscaleValue
1001
1151
  };
1002
1152
  }
1003
- const channel = (temp1, temp2, temp3) => {
1004
- if (temp3 < 0) {
1005
- temp3 += 1;
1153
+ const half = 0.5,
1154
+ double = 2,
1155
+ channel = (temp1, temp2, temp3) => {
1156
+ const temp3Min = 0,
1157
+ temp3Max = 1,
1158
+ sextuple = 6;
1159
+ if (temp3 < temp3Min) {
1160
+ temp3++;
1006
1161
  }
1007
- if (temp3 > 1) {
1008
- temp3 -= 1;
1162
+ if (temp3 > temp3Max) {
1163
+ temp3--;
1009
1164
  }
1010
- if (temp3 * 6 < 1) {
1011
- return temp1 + (temp2 - temp1) * 6 * temp3;
1165
+ if (temp3 * sextuple < temp3Max) {
1166
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1012
1167
  }
1013
- if (temp3 * 2 < 1) {
1168
+ if (temp3 * double < temp3Max) {
1014
1169
  return temp2;
1015
1170
  }
1016
- if (temp3 * 3 < 2) {
1017
- return temp1 + (temp2 - temp1) * (2 / 3 - temp3) * 6;
1171
+ if (temp3 * triple < temp3Max * double) {
1172
+ const temp3Offset = double / triple;
1173
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1018
1174
  }
1019
1175
  return temp1;
1020
1176
  },
1021
- temp1 = lNormalized < 0.5 ? lNormalized * (1 + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1022
- temp2 = 2 * lNormalized - temp1,
1023
- red = Math.min(255, 255 * channel(temp2, temp1, hNormalized + 1 / 3)),
1024
- green = Math.min(255, 255 * channel(temp2, temp1, hNormalized)),
1025
- blue = Math.min(255, 255 * channel(temp2, temp1, hNormalized - 1 / 3));
1177
+ sNormalizedOffset = 1,
1178
+ temp1 = lNormalized < half ? lNormalized * (sNormalizedOffset + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized,
1179
+ temp2 = double * lNormalized - temp1,
1180
+ phaseNumerator = 1,
1181
+ phaseThird = phaseNumerator / triple,
1182
+ red = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized + phaseThird)),
1183
+ green = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized)),
1184
+ blue = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized - phaseThird));
1026
1185
  return {
1027
1186
  r: Math.round(red),
1028
1187
  g: Math.round(green),
@@ -1039,18 +1198,22 @@ function hslaToRgba(hsla) {
1039
1198
  };
1040
1199
  }
1041
1200
  function getRandomRgbColor(min) {
1042
- const fixedMin = min ?? 0;
1201
+ const defaultMin = 0,
1202
+ fixedMin = min ?? defaultMin,
1203
+ rgbMax = 256;
1043
1204
  return {
1044
- b: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1045
- g: Math.floor(randomInRange(setRangeValue(fixedMin, 256))),
1046
- r: Math.floor(randomInRange(setRangeValue(fixedMin, 256)))
1205
+ b: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
1206
+ g: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
1207
+ r: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax)))
1047
1208
  };
1048
1209
  }
1049
1210
  function getStyleFromRgb(color, opacity) {
1050
- return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? 1})`;
1211
+ const defaultOpacity = 1;
1212
+ return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? defaultOpacity})`;
1051
1213
  }
1052
1214
  function getStyleFromHsl(color, opacity) {
1053
- return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? 1})`;
1215
+ const defaultOpacity = 1;
1216
+ return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? defaultOpacity})`;
1054
1217
  }
1055
1218
  function colorMix(color1, color2, size1, size2) {
1056
1219
  let rgb1 = color1,
@@ -1136,25 +1299,120 @@ function getHslAnimationFromHsl(hsl, animationOptions, reduceFactor) {
1136
1299
  }
1137
1300
  function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
1138
1301
  colorValue.enable = colorAnimation.enable;
1302
+ const defaultVelocity = 0,
1303
+ decayOffset = 1,
1304
+ defaultLoops = 0,
1305
+ defaultTime = 0;
1139
1306
  if (colorValue.enable) {
1140
- colorValue.velocity = getRangeValue(colorAnimation.speed) / 100 * reduceFactor;
1141
- colorValue.decay = 1 - getRangeValue(colorAnimation.decay);
1307
+ colorValue.velocity = getRangeValue(colorAnimation.speed) / percentDenominator * reduceFactor;
1308
+ colorValue.decay = decayOffset - getRangeValue(colorAnimation.decay);
1142
1309
  colorValue.status = "increasing";
1143
- colorValue.loops = 0;
1310
+ colorValue.loops = defaultLoops;
1144
1311
  colorValue.maxLoops = getRangeValue(colorAnimation.count);
1145
- colorValue.time = 0;
1146
- colorValue.delayTime = getRangeValue(colorAnimation.delay) * 1000;
1312
+ colorValue.time = defaultTime;
1313
+ colorValue.delayTime = getRangeValue(colorAnimation.delay) * millisecondsToSeconds;
1147
1314
  if (!colorAnimation.sync) {
1148
1315
  colorValue.velocity *= getRandom();
1149
1316
  colorValue.value *= getRandom();
1150
1317
  }
1151
1318
  colorValue.initialValue = colorValue.value;
1319
+ colorValue.offset = setRangeValue(colorAnimation.offset);
1152
1320
  } else {
1153
- colorValue.velocity = 0;
1321
+ colorValue.velocity = defaultVelocity;
1322
+ }
1323
+ }
1324
+ function updateColorValue(data, range, decrease, delta) {
1325
+ const minLoops = 0,
1326
+ minDelay = 0,
1327
+ identity = 1,
1328
+ minVelocity = 0,
1329
+ minOffset = 0,
1330
+ velocityFactor = 3.6;
1331
+ if (!data || !data.enable || (data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops)) {
1332
+ return;
1333
+ }
1334
+ if (!data.time) {
1335
+ data.time = 0;
1336
+ }
1337
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1338
+ data.time += delta.value;
1339
+ }
1340
+ if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1341
+ return;
1342
+ }
1343
+ const offset = data.offset ? randomInRange(data.offset) : minOffset,
1344
+ velocity = (data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor,
1345
+ decay = data.decay ?? identity,
1346
+ max = getRangeMax(range),
1347
+ min = getRangeMin(range);
1348
+ if (!decrease || data.status === "increasing") {
1349
+ data.value += velocity;
1350
+ if (data.value > max) {
1351
+ if (!data.loops) {
1352
+ data.loops = 0;
1353
+ }
1354
+ data.loops++;
1355
+ if (decrease) {
1356
+ data.status = "decreasing";
1357
+ } else {
1358
+ data.value -= max;
1359
+ }
1360
+ }
1361
+ } else {
1362
+ data.value -= velocity;
1363
+ const minValue = 0;
1364
+ if (data.value < minValue) {
1365
+ if (!data.loops) {
1366
+ data.loops = 0;
1367
+ }
1368
+ data.loops++;
1369
+ data.status = "increasing";
1370
+ }
1371
+ }
1372
+ if (data.velocity && decay !== identity) {
1373
+ data.velocity *= decay;
1374
+ }
1375
+ data.value = clamp(data.value, min, max);
1376
+ }
1377
+ function updateColor(color, delta) {
1378
+ if (!color) {
1379
+ return;
1380
+ }
1381
+ const {
1382
+ h,
1383
+ s,
1384
+ l
1385
+ } = color;
1386
+ const ranges = {
1387
+ h: {
1388
+ min: 0,
1389
+ max: 360
1390
+ },
1391
+ s: {
1392
+ min: 0,
1393
+ max: 100
1394
+ },
1395
+ l: {
1396
+ min: 0,
1397
+ max: 100
1398
+ }
1399
+ };
1400
+ if (h) {
1401
+ updateColorValue(h, ranges.h, false, delta);
1402
+ }
1403
+ if (s) {
1404
+ updateColorValue(s, ranges.s, true, delta);
1405
+ }
1406
+ if (l) {
1407
+ updateColorValue(l, ranges.l, true, delta);
1154
1408
  }
1155
1409
  }
1156
1410
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Utils/CanvasUtils.js
1157
1411
 
1412
+ const CanvasUtils_origin = {
1413
+ x: 0,
1414
+ y: 0
1415
+ };
1158
1416
  function drawLine(context, begin, end) {
1159
1417
  context.beginPath();
1160
1418
  context.moveTo(begin.x, begin.y);
@@ -1163,44 +1421,46 @@ function drawLine(context, begin, end) {
1163
1421
  }
1164
1422
  function paintBase(context, dimension, baseColor) {
1165
1423
  context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
1166
- context.fillRect(0, 0, dimension.width, dimension.height);
1424
+ context.fillRect(CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1167
1425
  }
1168
1426
  function paintImage(context, dimension, image, opacity) {
1169
1427
  if (!image) {
1170
1428
  return;
1171
1429
  }
1172
1430
  context.globalAlpha = opacity;
1173
- context.drawImage(image, 0, 0, dimension.width, dimension.height);
1431
+ context.drawImage(image, CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1174
1432
  context.globalAlpha = 1;
1175
1433
  }
1176
1434
  function clear(context, dimension) {
1177
- context.clearRect(0, 0, dimension.width, dimension.height);
1435
+ context.clearRect(CanvasUtils_origin.x, CanvasUtils_origin.y, dimension.width, dimension.height);
1178
1436
  }
1179
1437
  function drawParticle(data) {
1180
1438
  const {
1181
- container,
1182
- context,
1183
- particle,
1184
- delta,
1185
- colorStyles,
1186
- backgroundMask,
1187
- composite,
1188
- radius,
1189
- opacity,
1190
- shadow,
1191
- transform
1192
- } = data;
1193
- const pos = particle.getPosition(),
1194
- angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : 0),
1439
+ container,
1440
+ context,
1441
+ particle,
1442
+ delta,
1443
+ colorStyles,
1444
+ backgroundMask,
1445
+ composite,
1446
+ radius,
1447
+ opacity,
1448
+ shadow,
1449
+ transform
1450
+ } = data,
1451
+ pos = particle.getPosition(),
1452
+ defaultAngle = 0,
1453
+ angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : defaultAngle),
1195
1454
  rotateData = {
1196
1455
  sin: Math.sin(angle),
1197
1456
  cos: Math.cos(angle)
1198
1457
  },
1458
+ defaultTransformFactor = 1,
1199
1459
  transformData = {
1200
- a: rotateData.cos * (transform.a ?? 1),
1201
- b: rotateData.sin * (transform.b ?? 1),
1202
- c: -rotateData.sin * (transform.c ?? 1),
1203
- d: rotateData.cos * (transform.d ?? 1)
1460
+ a: rotateData.cos * (transform.a ?? defaultTransformFactor),
1461
+ b: rotateData.sin * (transform.b ?? defaultTransformFactor),
1462
+ c: -rotateData.sin * (transform.c ?? defaultTransformFactor),
1463
+ d: rotateData.cos * (transform.d ?? defaultTransformFactor)
1204
1464
  };
1205
1465
  context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
1206
1466
  if (backgroundMask) {
@@ -1216,7 +1476,8 @@ function drawParticle(data) {
1216
1476
  if (colorStyles.fill) {
1217
1477
  context.fillStyle = colorStyles.fill;
1218
1478
  }
1219
- const strokeWidth = particle.strokeWidth ?? 0;
1479
+ const minStrokeWidth = 0,
1480
+ strokeWidth = particle.strokeWidth ?? minStrokeWidth;
1220
1481
  context.lineWidth = strokeWidth;
1221
1482
  if (colorStyles.stroke) {
1222
1483
  context.strokeStyle = colorStyles.stroke;
@@ -1228,23 +1489,14 @@ function drawParticle(data) {
1228
1489
  radius,
1229
1490
  opacity,
1230
1491
  delta,
1231
- transformData
1492
+ transformData,
1493
+ strokeWidth
1232
1494
  };
1233
- context.beginPath();
1234
1495
  drawShape(drawData);
1235
- if (particle.shapeClose) {
1236
- context.closePath();
1237
- }
1238
- if (strokeWidth > 0) {
1239
- context.stroke();
1240
- }
1241
- if (particle.shapeFill) {
1242
- context.fill();
1243
- }
1244
1496
  drawShapeAfterDraw(drawData);
1245
1497
  drawEffect(drawData);
1246
1498
  context.globalCompositeOperation = "source-over";
1247
- context.setTransform(1, 0, 0, 1, 0, 0);
1499
+ context.resetTransform();
1248
1500
  }
1249
1501
  function drawEffect(data) {
1250
1502
  const {
@@ -1277,14 +1529,16 @@ function drawEffect(data) {
1277
1529
  }
1278
1530
  function drawShape(data) {
1279
1531
  const {
1280
- container,
1281
- context,
1282
- particle,
1283
- radius,
1284
- opacity,
1285
- delta,
1286
- transformData
1287
- } = data;
1532
+ container,
1533
+ context,
1534
+ particle,
1535
+ radius,
1536
+ opacity,
1537
+ delta,
1538
+ strokeWidth,
1539
+ transformData
1540
+ } = data,
1541
+ minStrokeWidth = 0;
1288
1542
  if (!particle.shape) {
1289
1543
  return;
1290
1544
  }
@@ -1292,6 +1546,7 @@ function drawShape(data) {
1292
1546
  if (!drawer) {
1293
1547
  return;
1294
1548
  }
1549
+ context.beginPath();
1295
1550
  drawer.draw({
1296
1551
  context,
1297
1552
  particle,
@@ -1303,6 +1558,15 @@ function drawShape(data) {
1303
1558
  ...transformData
1304
1559
  }
1305
1560
  });
1561
+ if (particle.shapeClose) {
1562
+ context.closePath();
1563
+ }
1564
+ if (strokeWidth > minStrokeWidth) {
1565
+ context.stroke();
1566
+ }
1567
+ if (particle.shapeFill) {
1568
+ context.fill();
1569
+ }
1306
1570
  }
1307
1571
  function drawShapeAfterDraw(data) {
1308
1572
  const {
@@ -1318,7 +1582,7 @@ function drawShapeAfterDraw(data) {
1318
1582
  return;
1319
1583
  }
1320
1584
  const drawer = container.shapeDrawers.get(particle.shape);
1321
- if (!drawer || !drawer.afterDraw) {
1585
+ if (!drawer?.afterDraw) {
1322
1586
  return;
1323
1587
  }
1324
1588
  drawer.afterDraw({
@@ -1346,10 +1610,11 @@ function drawParticlePlugin(context, plugin, particle, delta) {
1346
1610
  plugin.drawParticle(context, particle, delta);
1347
1611
  }
1348
1612
  function alterHsl(color, type, value) {
1613
+ const lFactor = 1;
1349
1614
  return {
1350
1615
  h: color.h,
1351
1616
  s: color.s,
1352
- l: color.l + (type === "darken" ? -1 : 1) * value
1617
+ l: color.l + (type === "darken" ? -lFactor : lFactor) * value
1353
1618
  };
1354
1619
  }
1355
1620
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Canvas.js
@@ -1358,9 +1623,10 @@ function alterHsl(color, type, value) {
1358
1623
 
1359
1624
 
1360
1625
  function setTransformValue(factor, newFactor, key) {
1361
- const newValue = newFactor[key];
1626
+ const newValue = newFactor[key],
1627
+ defaultValue = 1;
1362
1628
  if (newValue !== undefined) {
1363
- factor[key] = (factor[key] ?? 1) * newValue;
1629
+ factor[key] = (factor[key] ?? defaultValue) * newValue;
1364
1630
  }
1365
1631
  }
1366
1632
  class Canvas {
@@ -1368,7 +1634,7 @@ class Canvas {
1368
1634
  this.container = container;
1369
1635
  this._applyPostDrawUpdaters = particle => {
1370
1636
  for (const updater of this._postDrawUpdaters) {
1371
- updater.afterDraw && updater.afterDraw(particle);
1637
+ updater.afterDraw?.(particle);
1372
1638
  }
1373
1639
  };
1374
1640
  this._applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
@@ -1391,12 +1657,12 @@ class Canvas {
1391
1657
  setTransformValue(transform, updaterTransform, key);
1392
1658
  }
1393
1659
  }
1394
- updater.beforeDraw && updater.beforeDraw(particle);
1660
+ updater.beforeDraw?.(particle);
1395
1661
  }
1396
1662
  };
1397
1663
  this._applyResizePlugins = () => {
1398
1664
  for (const plugin of this._resizePlugins) {
1399
- plugin.resize && plugin.resize();
1665
+ plugin.resize?.();
1400
1666
  }
1401
1667
  };
1402
1668
  this._getPluginParticleColors = particle => {
@@ -1457,17 +1723,18 @@ class Canvas {
1457
1723
  if (!trail.enable) {
1458
1724
  return;
1459
1725
  }
1726
+ const factorNumerator = 1,
1727
+ opacity = factorNumerator / trail.length;
1460
1728
  if (trailFill.color) {
1461
1729
  const fillColor = rangeColorToRgb(trailFill.color);
1462
1730
  if (!fillColor) {
1463
1731
  return;
1464
1732
  }
1465
- const trail = options.particles.move.trail;
1466
1733
  this._trailFill = {
1467
1734
  color: {
1468
1735
  ...fillColor
1469
1736
  },
1470
- opacity: 1 / trail.length
1737
+ opacity
1471
1738
  };
1472
1739
  } else {
1473
1740
  await new Promise((resolve, reject) => {
@@ -1478,7 +1745,7 @@ class Canvas {
1478
1745
  img.addEventListener("load", () => {
1479
1746
  this._trailFill = {
1480
1747
  image: img,
1481
- opacity: 1 / trail.length
1748
+ opacity
1482
1749
  };
1483
1750
  resolve();
1484
1751
  });
@@ -1533,9 +1800,10 @@ class Canvas {
1533
1800
  return;
1534
1801
  }
1535
1802
  const priority = "important",
1536
- style = element.style;
1803
+ style = element.style,
1804
+ radix = 10;
1537
1805
  style.setProperty("position", "fixed", priority);
1538
- style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(10), priority);
1806
+ style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(radix), priority);
1539
1807
  style.setProperty("top", "0", priority);
1540
1808
  style.setProperty("left", "0", priority);
1541
1809
  style.setProperty("width", "100%", priority);
@@ -1558,10 +1826,11 @@ class Canvas {
1558
1826
  clear() {
1559
1827
  const options = this.container.actualOptions,
1560
1828
  trail = options.particles.move.trail,
1561
- trailFill = this._trailFill;
1829
+ trailFill = this._trailFill,
1830
+ minimumLength = 0;
1562
1831
  if (options.backgroundMask.enable) {
1563
1832
  this.paint();
1564
- } else if (trail.enable && trail.length > 0 && trailFill) {
1833
+ } else if (trail.enable && trail.length > minimumLength && trailFill) {
1565
1834
  if (trailFill.color) {
1566
1835
  this._paintBase(getStyleFromRgb(trailFill.color, trailFill.opacity));
1567
1836
  } else if (trailFill.image) {
@@ -1577,7 +1846,7 @@ class Canvas {
1577
1846
  this.stop();
1578
1847
  if (this._generated) {
1579
1848
  const element = this.element;
1580
- element && element.remove();
1849
+ element?.remove();
1581
1850
  } else {
1582
1851
  this._resetOriginalStyle();
1583
1852
  }
@@ -1597,8 +1866,9 @@ class Canvas {
1597
1866
  if (particle.spawning || particle.destroyed) {
1598
1867
  return;
1599
1868
  }
1600
- const radius = particle.getRadius();
1601
- if (radius <= 0) {
1869
+ const radius = particle.getRadius(),
1870
+ minimumSize = 0;
1871
+ if (radius <= minimumSize) {
1602
1872
  return;
1603
1873
  }
1604
1874
  const pfColor = particle.getFillColor(),
@@ -1617,8 +1887,11 @@ class Canvas {
1617
1887
  const container = this.container,
1618
1888
  options = container.actualOptions,
1619
1889
  zIndexOptions = particle.options.zIndex,
1620
- zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate,
1621
- opacity = particle.bubble.opacity ?? particle.opacity?.value ?? 1,
1890
+ zIndexFactorOffset = 1,
1891
+ zIndexFactor = zIndexFactorOffset - particle.zIndexFactor,
1892
+ zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate,
1893
+ defaultOpacity = 1,
1894
+ opacity = particle.bubble.opacity ?? particle.opacity?.value ?? defaultOpacity,
1622
1895
  strokeOpacity = particle.strokeOpacity ?? opacity,
1623
1896
  zOpacity = opacity * zOpacityFactor,
1624
1897
  zStrokeOpacity = strokeOpacity * zOpacityFactor,
@@ -1636,7 +1909,7 @@ class Canvas {
1636
1909
  colorStyles,
1637
1910
  backgroundMask: options.backgroundMask.enable,
1638
1911
  composite: options.backgroundMask.composite,
1639
- radius: radius * (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate,
1912
+ radius: radius * zIndexFactor ** zIndexOptions.sizeRate,
1640
1913
  opacity: zOpacity,
1641
1914
  shadow: particle.options.shadow,
1642
1915
  transform
@@ -1708,7 +1981,7 @@ class Canvas {
1708
1981
  if (plugin.resize) {
1709
1982
  this._resizePlugins.push(plugin);
1710
1983
  }
1711
- if (plugin.particleFillColor || plugin.particleStrokeColor) {
1984
+ if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
1712
1985
  this._colorPlugins.push(plugin);
1713
1986
  }
1714
1987
  }
@@ -1720,7 +1993,7 @@ class Canvas {
1720
1993
  if (updater.afterDraw) {
1721
1994
  this._postDrawUpdaters.push(updater);
1722
1995
  }
1723
- if (updater.getColorStyles || updater.getTransformValues || updater.beforeDraw) {
1996
+ if (updater.getColorStyles ?? updater.getTransformValues ?? updater.beforeDraw) {
1724
1997
  this._preDrawUpdaters.push(updater);
1725
1998
  }
1726
1999
  }
@@ -1806,6 +2079,7 @@ class Canvas {
1806
2079
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/EventListeners.js
1807
2080
 
1808
2081
 
2082
+ const EventListeners_double = 2;
1809
2083
  function manageListener(element, event, handler, add, options) {
1810
2084
  if (add) {
1811
2085
  let addOptions = {
@@ -1842,7 +2116,8 @@ class EventListeners {
1842
2116
  executeOnSingleOrMultiple(onClick.mode, mode => this.container.handleClickMode(mode));
1843
2117
  }
1844
2118
  if (e.type === "touchend") {
1845
- setTimeout(() => this._mouseTouchFinish(), 500);
2119
+ const touchDelay = 500;
2120
+ setTimeout(() => this._mouseTouchFinish(), touchDelay);
1846
2121
  }
1847
2122
  };
1848
2123
  this._handleThemeChange = e => {
@@ -1853,7 +2128,7 @@ class EventListeners {
1853
2128
  themeName = mediaEvent.matches ? defaultThemes.dark : defaultThemes.light,
1854
2129
  theme = options.themes.find(theme => theme.name === themeName);
1855
2130
  if (theme && theme.default.auto) {
1856
- container.loadTheme(themeName);
2131
+ void container.loadTheme(themeName);
1857
2132
  }
1858
2133
  };
1859
2134
  this._handleVisibilityChange = () => {
@@ -1875,15 +2150,16 @@ class EventListeners {
1875
2150
  }
1876
2151
  }
1877
2152
  };
1878
- this._handleWindowResize = async () => {
2153
+ this._handleWindowResize = () => {
1879
2154
  if (this._resizeTimeout) {
1880
2155
  clearTimeout(this._resizeTimeout);
1881
2156
  delete this._resizeTimeout;
1882
2157
  }
1883
- this._resizeTimeout = setTimeout(async () => {
2158
+ const handleResize = async () => {
1884
2159
  const canvas = this.container.canvas;
1885
- canvas && (await canvas.windowResize());
1886
- }, this.container.actualOptions.interactivity.events.resize.delay * 1000);
2160
+ await canvas?.windowResize();
2161
+ };
2162
+ this._resizeTimeout = setTimeout(() => void handleResize(), this.container.actualOptions.interactivity.events.resize.delay * millisecondsToSeconds);
1887
2163
  };
1888
2164
  this._manageInteractivityListeners = (mouseLeaveTmpEvent, add) => {
1889
2165
  const handlers = this._handlers,
@@ -1974,12 +2250,12 @@ class EventListeners {
1974
2250
  this._resizeObserver.disconnect();
1975
2251
  delete this._resizeObserver;
1976
2252
  } else if (!this._resizeObserver && add && canvasEl) {
1977
- this._resizeObserver = new ResizeObserver(async entries => {
2253
+ this._resizeObserver = new ResizeObserver(entries => {
1978
2254
  const entry = entries.find(e => e.target === canvasEl);
1979
2255
  if (!entry) {
1980
2256
  return;
1981
2257
  }
1982
- await this._handleWindowResize();
2258
+ this._handleWindowResize();
1983
2259
  });
1984
2260
  this._resizeObserver.observe(canvasEl);
1985
2261
  }
@@ -2041,7 +2317,7 @@ class EventListeners {
2041
2317
  options = container.actualOptions,
2042
2318
  interactivity = container.interactivity,
2043
2319
  canvasEl = container.canvas.element;
2044
- if (!interactivity || !interactivity.element) {
2320
+ if (!interactivity?.element) {
2045
2321
  return;
2046
2322
  }
2047
2323
  interactivity.mouse.inside = true;
@@ -2065,8 +2341,8 @@ class EventListeners {
2065
2341
  targetRect = target.getBoundingClientRect(),
2066
2342
  canvasRect = canvasEl.getBoundingClientRect();
2067
2343
  pos = {
2068
- x: mouseEvent.offsetX + 2 * sourceRect.left - (targetRect.left + canvasRect.left),
2069
- y: mouseEvent.offsetY + 2 * sourceRect.top - (targetRect.top + canvasRect.top)
2344
+ x: mouseEvent.offsetX + EventListeners_double * sourceRect.left - (targetRect.left + canvasRect.left),
2345
+ y: mouseEvent.offsetY + EventListeners_double * sourceRect.top - (targetRect.top + canvasRect.top)
2070
2346
  };
2071
2347
  } else {
2072
2348
  pos = {
@@ -2084,11 +2360,13 @@ class EventListeners {
2084
2360
  this._canPush = e.type !== "touchmove";
2085
2361
  if (canvasEl) {
2086
2362
  const touchEvent = e,
2087
- lastTouch = touchEvent.touches[touchEvent.touches.length - 1],
2088
- canvasRect = canvasEl.getBoundingClientRect();
2363
+ lengthOffset = 1,
2364
+ lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset],
2365
+ canvasRect = canvasEl.getBoundingClientRect(),
2366
+ defaultCoordinate = 0;
2089
2367
  pos = {
2090
- x: lastTouch.clientX - (canvasRect.left ?? 0),
2091
- y: lastTouch.clientY - (canvasRect.top ?? 0)
2368
+ x: lastTouch.clientX - (canvasRect.left ?? defaultCoordinate),
2369
+ y: lastTouch.clientY - (canvasRect.top ?? defaultCoordinate)
2092
2370
  };
2093
2371
  }
2094
2372
  }
@@ -2465,6 +2743,7 @@ class Interactivity {
2465
2743
  }
2466
2744
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Options/Classes/ManualParticle.js
2467
2745
 
2746
+ const defaultPosition = 50;
2468
2747
  class ManualParticle {
2469
2748
  load(data) {
2470
2749
  if (!data) {
@@ -2472,8 +2751,8 @@ class ManualParticle {
2472
2751
  }
2473
2752
  if (data.position) {
2474
2753
  this.position = {
2475
- x: data.position.x ?? 50,
2476
- y: data.position.y ?? 50,
2754
+ x: data.position.x ?? defaultPosition,
2755
+ y: data.position.y ?? defaultPosition,
2477
2756
  mode: data.position.mode ?? "percent"
2478
2757
  };
2479
2758
  }
@@ -3562,6 +3841,9 @@ class Options {
3562
3841
  if (data.clear !== undefined) {
3563
3842
  this.clear = data.clear;
3564
3843
  }
3844
+ if (data.key !== undefined) {
3845
+ this.key = data.key;
3846
+ }
3565
3847
  if (data.name !== undefined) {
3566
3848
  this.name = data.name;
3567
3849
  }
@@ -3674,12 +3956,14 @@ class InteractionManager {
3674
3956
  }
3675
3957
  async externalInteract(delta) {
3676
3958
  for (const interactor of this._externalInteractors) {
3677
- interactor.isEnabled() && (await interactor.interact(delta));
3959
+ if (interactor.isEnabled()) {
3960
+ await interactor.interact(delta);
3961
+ }
3678
3962
  }
3679
3963
  }
3680
3964
  handleClickMode(mode) {
3681
3965
  for (const interactor of this._externalInteractors) {
3682
- interactor.handleClickMode && interactor.handleClickMode(mode);
3966
+ interactor.handleClickMode?.(mode);
3683
3967
  }
3684
3968
  }
3685
3969
  init() {
@@ -3702,15 +3986,21 @@ class InteractionManager {
3702
3986
  interactor.clear(particle, delta);
3703
3987
  }
3704
3988
  for (const interactor of this._particleInteractors) {
3705
- interactor.isEnabled(particle) && (await interactor.interact(particle, delta));
3989
+ if (interactor.isEnabled(particle)) {
3990
+ await interactor.interact(particle, delta);
3991
+ }
3706
3992
  }
3707
3993
  }
3708
- async reset(particle) {
3994
+ reset(particle) {
3709
3995
  for (const interactor of this._externalInteractors) {
3710
- interactor.isEnabled() && interactor.reset(particle);
3996
+ if (interactor.isEnabled()) {
3997
+ interactor.reset(particle);
3998
+ }
3711
3999
  }
3712
4000
  for (const interactor of this._particleInteractors) {
3713
- interactor.isEnabled(particle) && interactor.reset(particle);
4001
+ if (interactor.isEnabled(particle)) {
4002
+ interactor.reset(particle);
4003
+ }
3714
4004
  }
3715
4005
  }
3716
4006
  }
@@ -3724,6 +4014,10 @@ class InteractionManager {
3724
4014
 
3725
4015
 
3726
4016
 
4017
+ const defaultRetryCount = 0,
4018
+ Particle_double = 2,
4019
+ half = 0.5,
4020
+ Particle_squareExp = 2;
3727
4021
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
3728
4022
  const effectData = effectOptions.options[effect];
3729
4023
  if (!effectData) {
@@ -3748,7 +4042,7 @@ function fixOutMode(data) {
3748
4042
  if (!isInArray(data.outMode, data.checkModes)) {
3749
4043
  return;
3750
4044
  }
3751
- const diameter = data.radius * 2;
4045
+ const diameter = data.radius * Particle_double;
3752
4046
  if (data.coord > data.maxCoord - diameter) {
3753
4047
  data.setCb(-data.radius);
3754
4048
  } else if (data.coord < diameter) {
@@ -3758,7 +4052,7 @@ function fixOutMode(data) {
3758
4052
  class Particle {
3759
4053
  constructor(engine, id, container, position, overrideOptions, group) {
3760
4054
  this.container = container;
3761
- this._calcPosition = (container, position, zIndex, tryCount = 0) => {
4055
+ this._calcPosition = (container, position, zIndex, tryCount = defaultRetryCount) => {
3762
4056
  for (const [, plugin] of container.plugins) {
3763
4057
  const pluginPos = plugin.particlePosition !== undefined ? plugin.particlePosition(position, this) : undefined;
3764
4058
  if (pluginPos) {
@@ -3798,7 +4092,8 @@ class Particle {
3798
4092
  fixVertical(outModes.top ?? outModes.default);
3799
4093
  fixVertical(outModes.bottom ?? outModes.default);
3800
4094
  if (this._checkOverlap(pos, tryCount)) {
3801
- return this._calcPosition(container, undefined, zIndex, tryCount + 1);
4095
+ const increment = 1;
4096
+ return this._calcPosition(container, undefined, zIndex, tryCount + increment);
3802
4097
  }
3803
4098
  return pos;
3804
4099
  };
@@ -3809,11 +4104,11 @@ class Particle {
3809
4104
  if (moveOptions.direction === "inside" || moveOptions.direction === "outside") {
3810
4105
  return res;
3811
4106
  }
3812
- const rad = Math.PI / 180 * getRangeValue(moveOptions.angle.value),
3813
- radOffset = Math.PI / 180 * getRangeValue(moveOptions.angle.offset),
4107
+ const rad = degToRad(getRangeValue(moveOptions.angle.value)),
4108
+ radOffset = degToRad(getRangeValue(moveOptions.angle.offset)),
3814
4109
  range = {
3815
- left: radOffset - rad * 0.5,
3816
- right: radOffset + rad * 0.5
4110
+ left: radOffset - rad * half,
4111
+ right: radOffset + rad * half
3817
4112
  };
3818
4113
  if (!moveOptions.straight) {
3819
4114
  res.angle += randomInRange(setRangeValue(range.left, range.right));
@@ -3823,7 +4118,7 @@ class Particle {
3823
4118
  }
3824
4119
  return res;
3825
4120
  };
3826
- this._checkOverlap = (pos, tryCount = 0) => {
4121
+ this._checkOverlap = (pos, tryCount = defaultRetryCount) => {
3827
4122
  const collisionsOptions = this.options.collisions,
3828
4123
  radius = this.getRadius();
3829
4124
  if (!collisionsOptions.enable) {
@@ -3833,8 +4128,9 @@ class Particle {
3833
4128
  if (overlapOptions.enable) {
3834
4129
  return false;
3835
4130
  }
3836
- const retries = overlapOptions.retries;
3837
- if (retries >= 0 && tryCount > retries) {
4131
+ const retries = overlapOptions.retries,
4132
+ minRetries = 0;
4133
+ if (retries >= minRetries && tryCount > retries) {
3838
4134
  throw new Error(`${errorPrefix} particle is overlapping and can't be placed`);
3839
4135
  }
3840
4136
  return !!this.container.particles.find(particle => getDistance(pos, particle.position) < radius + particle.getRadius());
@@ -3843,9 +4139,11 @@ class Particle {
3843
4139
  if (!color || !this.roll || !this.backColor && !this.roll.alter) {
3844
4140
  return color;
3845
4141
  }
3846
- const backFactor = this.roll.horizontal && this.roll.vertical ? 2 : 1,
3847
- backSum = this.roll.horizontal ? Math.PI * 0.5 : 0,
3848
- rolled = Math.floor(((this.roll.angle ?? 0) + backSum) / (Math.PI / backFactor)) % 2;
4142
+ const rollFactor = 1,
4143
+ none = 0,
4144
+ backFactor = this.roll.horizontal && this.roll.vertical ? Particle_double * rollFactor : rollFactor,
4145
+ backSum = this.roll.horizontal ? Math.PI * half : none,
4146
+ rolled = Math.floor(((this.roll.angle ?? none) + backSum) / (Math.PI / backFactor)) % Particle_double;
3849
4147
  if (!rolled) {
3850
4148
  return color;
3851
4149
  }
@@ -3859,13 +4157,15 @@ class Particle {
3859
4157
  };
3860
4158
  this._initPosition = position => {
3861
4159
  const container = this.container,
3862
- zIndexValue = getRangeValue(this.options.zIndex.value);
3863
- this.position = this._calcPosition(container, position, clamp(zIndexValue, 0, container.zLayers));
4160
+ zIndexValue = getRangeValue(this.options.zIndex.value),
4161
+ minZ = 0;
4162
+ this.position = this._calcPosition(container, position, clamp(zIndexValue, minZ, container.zLayers));
3864
4163
  this.initialPosition = this.position.copy();
3865
- const canvasSize = container.canvas.size;
4164
+ const canvasSize = container.canvas.size,
4165
+ defaultRadius = 0;
3866
4166
  this.moveCenter = {
3867
4167
  ...getPosition(this.options.move.center, canvasSize),
3868
- radius: this.options.move.center.radius ?? 0,
4168
+ radius: this.options.move.center.radius ?? defaultRadius,
3869
4169
  mode: this.options.move.center.mode ?? "percent"
3870
4170
  };
3871
4171
  this.direction = getParticleDirectionAngle(this.options.move.direction, this.position, this.moveCenter);
@@ -3892,14 +4192,14 @@ class Particle {
3892
4192
  const container = this.container,
3893
4193
  pathGenerator = this.pathGenerator,
3894
4194
  shapeDrawer = container.shapeDrawers.get(this.shape);
3895
- shapeDrawer && shapeDrawer.particleDestroy && shapeDrawer.particleDestroy(this);
4195
+ shapeDrawer?.particleDestroy?.(this);
3896
4196
  for (const [, plugin] of container.plugins) {
3897
- plugin.particleDestroyed && plugin.particleDestroyed(this, override);
4197
+ plugin.particleDestroyed?.(this, override);
3898
4198
  }
3899
4199
  for (const updater of container.particles.updaters) {
3900
- updater.particleDestroyed && updater.particleDestroyed(this, override);
4200
+ updater.particleDestroyed?.(this, override);
3901
4201
  }
3902
- pathGenerator && pathGenerator.reset(this);
4202
+ pathGenerator?.reset(this);
3903
4203
  this._engine.dispatchEvent("particleDestroyed", {
3904
4204
  container: this.container,
3905
4205
  data: {
@@ -3919,7 +4219,7 @@ class Particle {
3919
4219
  return this._getRollColor(this.bubble.color ?? getHslFromAnimation(this.color));
3920
4220
  }
3921
4221
  getMass() {
3922
- return this.getRadius() ** 2 * Math.PI * 0.5;
4222
+ return this.getRadius() ** Particle_squareExp * Math.PI * half;
3923
4223
  }
3924
4224
  getPosition() {
3925
4225
  return {
@@ -3967,7 +4267,7 @@ class Particle {
3967
4267
  const effectOptions = particlesOptions.effect,
3968
4268
  shapeOptions = particlesOptions.shape;
3969
4269
  if (overrideOptions) {
3970
- if (overrideOptions.effect && overrideOptions.effect.type) {
4270
+ if (overrideOptions.effect?.type) {
3971
4271
  const overrideEffectType = overrideOptions.effect.type,
3972
4272
  effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
3973
4273
  if (effect) {
@@ -3975,7 +4275,7 @@ class Particle {
3975
4275
  effectOptions.load(overrideOptions.effect);
3976
4276
  }
3977
4277
  }
3978
- if (overrideOptions.shape && overrideOptions.shape.type) {
4278
+ if (overrideOptions.shape?.type) {
3979
4279
  const overrideShapeType = overrideOptions.shape.type,
3980
4280
  shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
3981
4281
  if (shape) {
@@ -4005,7 +4305,7 @@ class Particle {
4005
4305
  this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4006
4306
  this.options = particlesOptions;
4007
4307
  const pathOptions = this.options.move.path;
4008
- this.pathDelay = getRangeValue(pathOptions.delay.value) * 1000;
4308
+ this.pathDelay = getRangeValue(pathOptions.delay.value) * millisecondsToSeconds;
4009
4309
  if (pathOptions.generator) {
4010
4310
  this.pathGenerator = this._engine.getPathGenerator(pathOptions.generator);
4011
4311
  if (this.pathGenerator && container.addPath(pathOptions.generator, this.pathGenerator)) {
@@ -4024,7 +4324,8 @@ class Particle {
4024
4324
  this._initPosition(position);
4025
4325
  this.initialVelocity = this._calculateVelocity();
4026
4326
  this.velocity = this.initialVelocity.copy();
4027
- this.moveDecay = 1 - getRangeValue(this.options.move.decay);
4327
+ const decayOffset = 1;
4328
+ this.moveDecay = decayOffset - getRangeValue(this.options.move.decay);
4028
4329
  const particles = container.particles;
4029
4330
  particles.setLastZIndex(this.position.z);
4030
4331
  this.zIndexFactor = this.position.z / container.zLayers;
@@ -4036,7 +4337,7 @@ class Particle {
4036
4337
  container.effectDrawers.set(this.effect, effectDrawer);
4037
4338
  }
4038
4339
  }
4039
- if (effectDrawer && effectDrawer.loadEffect) {
4340
+ if (effectDrawer?.loadEffect) {
4040
4341
  effectDrawer.loadEffect(this);
4041
4342
  }
4042
4343
  let shapeDrawer = container.shapeDrawers.get(this.shape);
@@ -4046,7 +4347,7 @@ class Particle {
4046
4347
  container.shapeDrawers.set(this.shape, shapeDrawer);
4047
4348
  }
4048
4349
  }
4049
- if (shapeDrawer && shapeDrawer.loadShape) {
4350
+ if (shapeDrawer?.loadShape) {
4050
4351
  shapeDrawer.loadShape(this);
4051
4352
  }
4052
4353
  const sideCountFunc = shapeDrawer?.getSidesCount;
@@ -4059,16 +4360,12 @@ class Particle {
4059
4360
  updater.init(this);
4060
4361
  }
4061
4362
  for (const mover of particles.movers) {
4062
- mover.init && mover.init(this);
4063
- }
4064
- if (effectDrawer && effectDrawer.particleInit) {
4065
- effectDrawer.particleInit(container, this);
4066
- }
4067
- if (shapeDrawer && shapeDrawer.particleInit) {
4068
- shapeDrawer.particleInit(container, this);
4363
+ mover.init?.(this);
4069
4364
  }
4365
+ effectDrawer?.particleInit?.(container, this);
4366
+ shapeDrawer?.particleInit?.(container, this);
4070
4367
  for (const [, plugin] of container.plugins) {
4071
- plugin.particleCreated && plugin.particleCreated(this);
4368
+ plugin.particleCreated?.(this);
4072
4369
  }
4073
4370
  }
4074
4371
  isInsideCanvas() {
@@ -4082,7 +4379,7 @@ class Particle {
4082
4379
  }
4083
4380
  reset() {
4084
4381
  for (const updater of this.container.particles.updaters) {
4085
- updater.reset && updater.reset(this);
4382
+ updater.reset?.(this);
4086
4383
  }
4087
4384
  }
4088
4385
  }
@@ -4140,6 +4437,7 @@ class Rectangle extends Range {
4140
4437
 
4141
4438
 
4142
4439
 
4440
+ const Circle_squareExp = 2;
4143
4441
  class Circle extends Range {
4144
4442
  constructor(x, y, radius) {
4145
4443
  super(x, y);
@@ -4158,15 +4456,15 @@ class Circle extends Range {
4158
4456
  r = this.radius;
4159
4457
  if (range instanceof Circle) {
4160
4458
  const rSum = r + range.radius,
4161
- dist = Math.sqrt(distPos.x ** 2 + distPos.y ** 2);
4459
+ dist = Math.sqrt(distPos.x ** Circle_squareExp + distPos.y ** Circle_squareExp);
4162
4460
  return rSum > dist;
4163
4461
  } else if (range instanceof Rectangle) {
4164
4462
  const {
4165
4463
  width,
4166
4464
  height
4167
4465
  } = range.size,
4168
- edges = Math.pow(distPos.x - width, 2) + Math.pow(distPos.y - height, 2);
4169
- return edges <= r ** 2 || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
4466
+ edges = Math.pow(distPos.x - width, Circle_squareExp) + Math.pow(distPos.y - height, Circle_squareExp);
4467
+ return edges <= r ** Circle_squareExp || distPos.x <= r + width && distPos.y <= r + height || distPos.x <= width || distPos.y <= height;
4170
4468
  }
4171
4469
  return false;
4172
4470
  }
@@ -4175,6 +4473,9 @@ class Circle extends Range {
4175
4473
 
4176
4474
 
4177
4475
 
4476
+ const QuadTree_half = 0.5,
4477
+ QuadTree_double = 2,
4478
+ subdivideCount = 4;
4178
4479
  class QuadTree {
4179
4480
  constructor(rectangle, capacity) {
4180
4481
  this.rectangle = rectangle;
@@ -4191,8 +4492,9 @@ class QuadTree {
4191
4492
  {
4192
4493
  capacity
4193
4494
  } = this;
4194
- for (let i = 0; i < 4; i++) {
4195
- 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));
4495
+ for (let i = 0; i < subdivideCount; i++) {
4496
+ const fixedIndex = i % QuadTree_double;
4497
+ 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));
4196
4498
  }
4197
4499
  this._divided = true;
4198
4500
  };
@@ -4214,7 +4516,7 @@ class QuadTree {
4214
4516
  return this._subs.some(sub => sub.insert(point));
4215
4517
  }
4216
4518
  query(range, check, found) {
4217
- const res = found || [];
4519
+ const res = found ?? [];
4218
4520
  if (!range.intersects(this.rectangle)) {
4219
4521
  return [];
4220
4522
  }
@@ -4246,7 +4548,9 @@ class QuadTree {
4246
4548
 
4247
4549
 
4248
4550
 
4249
- const qTreeCapacity = 4;
4551
+ const qTreeCapacity = 4,
4552
+ Particles_squareExp = 2,
4553
+ defaultRemoveQuantity = 1;
4250
4554
  const qTreeRectangle = canvasSize => {
4251
4555
  const {
4252
4556
  height,
@@ -4275,7 +4579,8 @@ class Particles {
4275
4579
  }
4276
4580
  const densityFactor = this._initDensityFactor(numberOptions.density),
4277
4581
  optParticlesNumber = numberOptions.value,
4278
- optParticlesLimit = numberOptions.limit.value > 0 ? numberOptions.limit.value : optParticlesNumber,
4582
+ minLimit = 0,
4583
+ optParticlesLimit = numberOptions.limit.value > minLimit ? numberOptions.limit.value : optParticlesNumber,
4279
4584
  particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount,
4280
4585
  particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
4281
4586
  if (group === undefined) {
@@ -4290,13 +4595,14 @@ class Particles {
4290
4595
  }
4291
4596
  };
4292
4597
  this._initDensityFactor = densityOptions => {
4293
- const container = this._container;
4598
+ const container = this._container,
4599
+ defaultFactor = 1;
4294
4600
  if (!container.canvas.element || !densityOptions.enable) {
4295
- return 1;
4601
+ return defaultFactor;
4296
4602
  }
4297
4603
  const canvas = container.canvas.element,
4298
4604
  pxRatio = container.retina.pixelRatio;
4299
- return canvas.width * canvas.height / (densityOptions.height * densityOptions.width * pxRatio ** 2);
4605
+ return canvas.width * canvas.height / (densityOptions.height * densityOptions.width * pxRatio ** Particles_squareExp);
4300
4606
  };
4301
4607
  this._pushParticle = (position, overrideOptions, group, initializer) => {
4302
4608
  try {
@@ -4325,7 +4631,6 @@ class Particles {
4325
4631
  return particle;
4326
4632
  } catch (e) {
4327
4633
  getLogger().warning(`${errorPrefix} adding particle: ${e}`);
4328
- return;
4329
4634
  }
4330
4635
  };
4331
4636
  this._removeParticle = (index, group, override) => {
@@ -4333,9 +4638,10 @@ class Particles {
4333
4638
  if (!particle || particle.group !== group) {
4334
4639
  return false;
4335
4640
  }
4336
- const zIdx = this._zArray.indexOf(particle);
4337
- this._array.splice(index, 1);
4338
- this._zArray.splice(zIdx, 1);
4641
+ const zIdx = this._zArray.indexOf(particle),
4642
+ deleteCount = 1;
4643
+ this._array.splice(index, deleteCount);
4644
+ this._zArray.splice(zIdx, deleteCount);
4339
4645
  particle.destroy(override);
4340
4646
  this._engine.dispatchEvent("particleRemoved", {
4341
4647
  container: this._container,
@@ -4375,11 +4681,14 @@ class Particles {
4375
4681
  addParticle(position, overrideOptions, group, initializer) {
4376
4682
  const limitOptions = this._container.actualOptions.particles.number.limit,
4377
4683
  limit = group === undefined ? this._limit : this._groupLimits.get(group) ?? this._limit,
4378
- currentCount = this.count;
4379
- if (limit > 0) {
4684
+ currentCount = this.count,
4685
+ minLimit = 0;
4686
+ if (limit > minLimit) {
4380
4687
  if (limitOptions.mode === "delete") {
4381
- const countToRemove = currentCount + 1 - limit;
4382
- if (countToRemove > 0) {
4688
+ const countOffset = 1,
4689
+ minCount = 0,
4690
+ countToRemove = currentCount + countOffset - limit;
4691
+ if (countToRemove > minCount) {
4383
4692
  this.removeQuantity(countToRemove);
4384
4693
  }
4385
4694
  } else if (limitOptions.mode === "wait") {
@@ -4475,23 +4784,28 @@ class Particles {
4475
4784
  remove(particle, group, override) {
4476
4785
  this.removeAt(this._array.indexOf(particle), undefined, group, override);
4477
4786
  }
4478
- removeAt(index, quantity = 1, group, override) {
4479
- if (index < 0 || index > this.count) {
4787
+ removeAt(index, quantity = defaultRemoveQuantity, group, override) {
4788
+ const minIndex = 0;
4789
+ if (index < minIndex || index > this.count) {
4480
4790
  return;
4481
4791
  }
4482
4792
  let deleted = 0;
4483
4793
  for (let i = index; deleted < quantity && i < this.count; i++) {
4484
- this._removeParticle(i--, group, override) && deleted++;
4794
+ if (this._removeParticle(i--, group, override)) {
4795
+ deleted++;
4796
+ }
4485
4797
  }
4486
4798
  }
4487
4799
  removeQuantity(quantity, group) {
4488
- this.removeAt(0, quantity, group);
4800
+ const defaultIndex = 0;
4801
+ this.removeAt(defaultIndex, quantity, group);
4489
4802
  }
4490
4803
  setDensity() {
4491
4804
  const options = this._container.actualOptions,
4492
- groups = options.particles.groups;
4805
+ groups = options.particles.groups,
4806
+ manualCount = 0;
4493
4807
  for (const group in groups) {
4494
- this._applyDensity(groups[group], 0, group);
4808
+ this._applyDensity(groups[group], manualCount, group);
4495
4809
  }
4496
4810
  this._applyDensity(options.particles, options.manualParticles.length);
4497
4811
  }
@@ -4510,7 +4824,7 @@ class Particles {
4510
4824
  pathGenerator.update();
4511
4825
  }
4512
4826
  for (const [, plugin] of container.plugins) {
4513
- plugin.update && (await plugin.update(delta));
4827
+ await plugin.update?.(delta);
4514
4828
  }
4515
4829
  const resizeFactor = this._resizeFactor;
4516
4830
  for (const particle of this._array) {
@@ -4521,15 +4835,17 @@ class Particles {
4521
4835
  particle.initialPosition.y *= resizeFactor.height;
4522
4836
  }
4523
4837
  particle.ignoresResizeRatio = false;
4524
- await this._interactionManager.reset(particle);
4838
+ this._interactionManager.reset(particle);
4525
4839
  for (const [, plugin] of this._container.plugins) {
4526
4840
  if (particle.destroyed) {
4527
4841
  break;
4528
4842
  }
4529
- plugin.particleUpdate && plugin.particleUpdate(particle, delta);
4843
+ plugin.particleUpdate?.(particle, delta);
4530
4844
  }
4531
4845
  for (const mover of this.movers) {
4532
- mover.isEnabled(particle) && mover.move(particle, delta);
4846
+ if (mover.isEnabled(particle)) {
4847
+ mover.move(particle, delta);
4848
+ }
4533
4849
  }
4534
4850
  if (particle.destroyed) {
4535
4851
  particlesToDelete.add(particle);
@@ -4564,7 +4880,8 @@ class Particles {
4564
4880
  if (this._needsSort) {
4565
4881
  const zArray = this._zArray;
4566
4882
  zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
4567
- this._lastZIndex = zArray[zArray.length - 1].position.z;
4883
+ const lengthOffset = 1;
4884
+ this._lastZIndex = zArray[zArray.length - lengthOffset].position.z;
4568
4885
  this._needsSort = false;
4569
4886
  }
4570
4887
  }
@@ -4572,17 +4889,19 @@ class Particles {
4572
4889
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Retina.js
4573
4890
 
4574
4891
 
4892
+ const defaultRatio = 1,
4893
+ defaultReduceFactor = 1;
4575
4894
  class Retina {
4576
4895
  constructor(container) {
4577
4896
  this.container = container;
4578
- this.pixelRatio = 1;
4579
- this.reduceFactor = 1;
4897
+ this.pixelRatio = defaultRatio;
4898
+ this.reduceFactor = defaultReduceFactor;
4580
4899
  }
4581
4900
  init() {
4582
4901
  const container = this.container,
4583
4902
  options = container.actualOptions;
4584
- this.pixelRatio = !options.detectRetina || isSsr() ? 1 : window.devicePixelRatio;
4585
- this.reduceFactor = 1;
4903
+ this.pixelRatio = !options.detectRetina || isSsr() ? defaultRatio : window.devicePixelRatio;
4904
+ this.reduceFactor = defaultReduceFactor;
4586
4905
  const ratio = this.pixelRatio,
4587
4906
  canvas = container.canvas;
4588
4907
  if (canvas.element) {
@@ -4623,10 +4942,11 @@ class Retina {
4623
4942
  function guardCheck(container) {
4624
4943
  return container && !container.destroyed;
4625
4944
  }
4626
- function initDelta(value, fpsLimit = 60, smooth = false) {
4945
+ const defaultFps = 60;
4946
+ function initDelta(value, fpsLimit = defaultFps, smooth = false) {
4627
4947
  return {
4628
4948
  value,
4629
- factor: smooth ? 60 / fpsLimit : 60 * value / 1000
4949
+ factor: smooth ? defaultFps / fpsLimit : defaultFps * value / millisecondsToSeconds
4630
4950
  };
4631
4951
  }
4632
4952
  function loadContainerOptions(engine, container, ...sourceOptionsArr) {
@@ -4644,12 +4964,16 @@ class Container {
4644
4964
  if (entry.target !== this.interactivity.element) {
4645
4965
  continue;
4646
4966
  }
4647
- (entry.isIntersecting ? this.play : this.pause)();
4967
+ if (entry.isIntersecting) {
4968
+ this.play();
4969
+ } else {
4970
+ this.pause();
4971
+ }
4648
4972
  }
4649
4973
  };
4650
4974
  this._nextFrame = async timestamp => {
4651
4975
  try {
4652
- if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + 1000 / this.fpsLimit) {
4976
+ if (!this._smooth && this._lastFrameTime !== undefined && timestamp < this._lastFrameTime + millisecondsToSeconds / this.fpsLimit) {
4653
4977
  this.draw(false);
4654
4978
  return;
4655
4979
  }
@@ -4657,7 +4981,7 @@ class Container {
4657
4981
  const delta = initDelta(timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
4658
4982
  this.addLifeTime(delta.value);
4659
4983
  this._lastFrameTime = timestamp;
4660
- if (delta.value > 1000) {
4984
+ if (delta.value > millisecondsToSeconds) {
4661
4985
  this.draw(false);
4662
4986
  return;
4663
4987
  }
@@ -4744,8 +5068,9 @@ class Container {
4744
5068
  pos = {
4745
5069
  x: mouseEvent.offsetX || mouseEvent.clientX,
4746
5070
  y: mouseEvent.offsetY || mouseEvent.clientY
4747
- };
4748
- clickOrTouchHandler(e, pos, 1);
5071
+ },
5072
+ radius = 1;
5073
+ clickOrTouchHandler(e, pos, radius);
4749
5074
  };
4750
5075
  const touchStartHandler = () => {
4751
5076
  if (!guardCheck(this)) {
@@ -4766,18 +5091,20 @@ class Container {
4766
5091
  }
4767
5092
  if (touched && !touchMoved) {
4768
5093
  const touchEvent = e;
4769
- let lastTouch = touchEvent.touches[touchEvent.touches.length - 1];
5094
+ const lengthOffset = 1;
5095
+ let lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset];
4770
5096
  if (!lastTouch) {
4771
- lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - 1];
5097
+ lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - lengthOffset];
4772
5098
  if (!lastTouch) {
4773
5099
  return;
4774
5100
  }
4775
5101
  }
4776
5102
  const element = this.canvas.element,
4777
5103
  canvasRect = element ? element.getBoundingClientRect() : undefined,
5104
+ minCoordinate = 0,
4778
5105
  pos = {
4779
- x: lastTouch.clientX - (canvasRect ? canvasRect.left : 0),
4780
- y: lastTouch.clientY - (canvasRect ? canvasRect.top : 0)
5106
+ x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
5107
+ y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate)
4781
5108
  };
4782
5109
  clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
4783
5110
  }
@@ -4820,10 +5147,10 @@ class Container {
4820
5147
  this.particles.destroy();
4821
5148
  this.canvas.destroy();
4822
5149
  for (const [, effectDrawer] of this.effectDrawers) {
4823
- effectDrawer.destroy && effectDrawer.destroy(this);
5150
+ effectDrawer.destroy?.(this);
4824
5151
  }
4825
5152
  for (const [, shapeDrawer] of this.shapeDrawers) {
4826
- shapeDrawer.destroy && shapeDrawer.destroy(this);
5153
+ shapeDrawer.destroy?.(this);
4827
5154
  }
4828
5155
  for (const key of this.effectDrawers.keys()) {
4829
5156
  this.effectDrawers.delete(key);
@@ -4834,9 +5161,11 @@ class Container {
4834
5161
  this._engine.clearPlugins(this);
4835
5162
  this.destroyed = true;
4836
5163
  const mainArr = this._engine.dom(),
4837
- idx = mainArr.findIndex(t => t === this);
4838
- if (idx >= 0) {
4839
- mainArr.splice(idx, 1);
5164
+ idx = mainArr.findIndex(t => t === this),
5165
+ minIndex = 0;
5166
+ if (idx >= minIndex) {
5167
+ const deleteCount = 1;
5168
+ mainArr.splice(idx, deleteCount);
4840
5169
  }
4841
5170
  this._engine.dispatchEvent("containerDestroyed", {
4842
5171
  container: this
@@ -4847,13 +5176,14 @@ class Container {
4847
5176
  return;
4848
5177
  }
4849
5178
  let refreshTime = force;
4850
- this._drawAnimationFrame = requestAnimationFrame(async timestamp => {
5179
+ const frame = async timestamp => {
4851
5180
  if (refreshTime) {
4852
5181
  this._lastFrameTime = undefined;
4853
5182
  refreshTime = false;
4854
5183
  }
4855
5184
  await this._nextFrame(timestamp);
4856
- });
5185
+ };
5186
+ this._drawAnimationFrame = requestAnimationFrame(timestamp => void frame(timestamp));
4857
5187
  }
4858
5188
  async export(type, options = {}) {
4859
5189
  for (const [, plugin] of this.plugins) {
@@ -4877,7 +5207,7 @@ class Container {
4877
5207
  }
4878
5208
  this.particles.handleClickMode(mode);
4879
5209
  for (const [, plugin] of this.plugins) {
4880
- plugin.handleClickMode && plugin.handleClickMode(mode);
5210
+ plugin.handleClickMode?.(mode);
4881
5211
  }
4882
5212
  }
4883
5213
  async init() {
@@ -4910,19 +5240,21 @@ class Container {
4910
5240
  this.canvas.initBackground();
4911
5241
  this.canvas.resize();
4912
5242
  this.zLayers = this.actualOptions.zLayers;
4913
- this._duration = getRangeValue(this.actualOptions.duration) * 1000;
4914
- this._delay = getRangeValue(this.actualOptions.delay) * 1000;
5243
+ this._duration = getRangeValue(this.actualOptions.duration) * millisecondsToSeconds;
5244
+ this._delay = getRangeValue(this.actualOptions.delay) * millisecondsToSeconds;
4915
5245
  this._lifeTime = 0;
4916
- this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 120;
5246
+ const defaultFpsLimit = 120,
5247
+ minFpsLimit = 0;
5248
+ this.fpsLimit = this.actualOptions.fpsLimit > minFpsLimit ? this.actualOptions.fpsLimit : defaultFpsLimit;
4917
5249
  this._smooth = this.actualOptions.smooth;
4918
5250
  for (const [, drawer] of this.effectDrawers) {
4919
- drawer.init && (await drawer.init(this));
5251
+ await drawer.init?.(this);
4920
5252
  }
4921
5253
  for (const [, drawer] of this.shapeDrawers) {
4922
- drawer.init && (await drawer.init(this));
5254
+ await drawer.init?.(this);
4923
5255
  }
4924
5256
  for (const [, plugin] of this.plugins) {
4925
- plugin.init && (await plugin.init());
5257
+ await plugin.init?.();
4926
5258
  }
4927
5259
  this._engine.dispatchEvent("containerInit", {
4928
5260
  container: this
@@ -4930,7 +5262,7 @@ class Container {
4930
5262
  this.particles.init();
4931
5263
  this.particles.setDensity();
4932
5264
  for (const [, plugin] of this.plugins) {
4933
- plugin.particlesSetup && plugin.particlesSetup();
5265
+ plugin.particlesSetup?.();
4934
5266
  }
4935
5267
  this._engine.dispatchEvent("particlesSetup", {
4936
5268
  container: this
@@ -4955,7 +5287,7 @@ class Container {
4955
5287
  return;
4956
5288
  }
4957
5289
  for (const [, plugin] of this.plugins) {
4958
- plugin.pause && plugin.pause();
5290
+ plugin.pause?.();
4959
5291
  }
4960
5292
  if (!this.pageHidden) {
4961
5293
  this._paused = true;
@@ -4986,7 +5318,7 @@ class Container {
4986
5318
  this._engine.dispatchEvent("containerPlay", {
4987
5319
  container: this
4988
5320
  });
4989
- this.draw(needsUpdate || false);
5321
+ this.draw(needsUpdate ?? false);
4990
5322
  }
4991
5323
  async refresh() {
4992
5324
  if (!guardCheck(this)) {
@@ -5011,20 +5343,21 @@ class Container {
5011
5343
  await this.init();
5012
5344
  this.started = true;
5013
5345
  await new Promise(resolve => {
5014
- this._delayTimeout = setTimeout(async () => {
5346
+ const start = async () => {
5015
5347
  this._eventListeners.addListeners();
5016
5348
  if (this.interactivity.element instanceof HTMLElement && this._intersectionObserver) {
5017
5349
  this._intersectionObserver.observe(this.interactivity.element);
5018
5350
  }
5019
5351
  for (const [, plugin] of this.plugins) {
5020
- plugin.start && (await plugin.start());
5352
+ await plugin.start?.();
5021
5353
  }
5022
5354
  this._engine.dispatchEvent("containerStarted", {
5023
5355
  container: this
5024
5356
  });
5025
5357
  this.play();
5026
5358
  resolve();
5027
- }, this._delay);
5359
+ };
5360
+ this._delayTimeout = setTimeout(() => void start(), this._delay);
5028
5361
  });
5029
5362
  }
5030
5363
  stop() {
@@ -5045,7 +5378,7 @@ class Container {
5045
5378
  this._intersectionObserver.unobserve(this.interactivity.element);
5046
5379
  }
5047
5380
  for (const [, plugin] of this.plugins) {
5048
- plugin.stop && plugin.stop();
5381
+ plugin.stop?.();
5049
5382
  }
5050
5383
  for (const key of this.plugins.keys()) {
5051
5384
  this.plugins.delete(key);
@@ -5082,7 +5415,7 @@ class EventDispatcher {
5082
5415
  }
5083
5416
  dispatchEvent(type, args) {
5084
5417
  const listeners = this._listeners.get(type);
5085
- listeners && listeners.forEach(handler => handler(args));
5418
+ listeners?.forEach(handler => handler(args));
5086
5419
  }
5087
5420
  hasEventListener(type) {
5088
5421
  return !!this._listeners.get(type);
@@ -5100,14 +5433,16 @@ class EventDispatcher {
5100
5433
  return;
5101
5434
  }
5102
5435
  const length = arr.length,
5103
- idx = arr.indexOf(listener);
5104
- if (idx < 0) {
5436
+ idx = arr.indexOf(listener),
5437
+ minIndex = 0;
5438
+ if (idx < minIndex) {
5105
5439
  return;
5106
5440
  }
5107
- if (length === 1) {
5441
+ const deleteCount = 1;
5442
+ if (length === deleteCount) {
5108
5443
  this._listeners.delete(type);
5109
5444
  } else {
5110
- arr.splice(idx, 1);
5445
+ arr.splice(idx, deleteCount);
5111
5446
  }
5112
5447
  }
5113
5448
  }
@@ -5165,21 +5500,23 @@ class Engine {
5165
5500
  return res;
5166
5501
  }
5167
5502
  get version() {
5168
- return "3.0.3";
5503
+ return "3.1.0";
5169
5504
  }
5170
5505
  addConfig(config) {
5171
- const name = config.name ?? "default";
5172
- this._configs.set(name, config);
5506
+ const key = config.key ?? config.name ?? "default";
5507
+ this._configs.set(key, config);
5173
5508
  this._eventDispatcher.dispatchEvent("configAdded", {
5174
5509
  data: {
5175
- name,
5510
+ name: key,
5176
5511
  config
5177
5512
  }
5178
5513
  });
5179
5514
  }
5180
5515
  async addEffect(effect, drawer, refresh = true) {
5181
5516
  executeOnSingleOrMultiple(effect, type => {
5182
- !this.getEffectDrawer(type) && this.effectDrawers.set(type, drawer);
5517
+ if (!this.getEffectDrawer(type)) {
5518
+ this.effectDrawers.set(type, drawer);
5519
+ }
5183
5520
  });
5184
5521
  await this.refresh(refresh);
5185
5522
  }
@@ -5199,20 +5536,28 @@ class Engine {
5199
5536
  await this.refresh(refresh);
5200
5537
  }
5201
5538
  async addPathGenerator(name, generator, refresh = true) {
5202
- !this.getPathGenerator(name) && this.pathGenerators.set(name, generator);
5539
+ if (!this.getPathGenerator(name)) {
5540
+ this.pathGenerators.set(name, generator);
5541
+ }
5203
5542
  await this.refresh(refresh);
5204
5543
  }
5205
5544
  async addPlugin(plugin, refresh = true) {
5206
- !this.getPlugin(plugin.id) && this.plugins.push(plugin);
5545
+ if (!this.getPlugin(plugin.id)) {
5546
+ this.plugins.push(plugin);
5547
+ }
5207
5548
  await this.refresh(refresh);
5208
5549
  }
5209
5550
  async addPreset(preset, options, override = false, refresh = true) {
5210
- (override || !this.getPreset(preset)) && this.presets.set(preset, options);
5551
+ if (override || !this.getPreset(preset)) {
5552
+ this.presets.set(preset, options);
5553
+ }
5211
5554
  await this.refresh(refresh);
5212
5555
  }
5213
5556
  async addShape(shape, drawer, refresh = true) {
5214
5557
  executeOnSingleOrMultiple(shape, type => {
5215
- !this.getShapeDrawer(type) && this.shapeDrawers.set(type, drawer);
5558
+ if (!this.getShapeDrawer(type)) {
5559
+ this.shapeDrawers.set(type, drawer);
5560
+ }
5216
5561
  });
5217
5562
  await this.refresh(refresh);
5218
5563
  }
@@ -5231,7 +5576,8 @@ class Engine {
5231
5576
  const dom = this.dom(),
5232
5577
  item = dom[index];
5233
5578
  if (!item || item.destroyed) {
5234
- dom.splice(index, 1);
5579
+ const deleteCount = 1;
5580
+ dom.splice(index, deleteCount);
5235
5581
  return;
5236
5582
  }
5237
5583
  return item;
@@ -5239,7 +5585,9 @@ class Engine {
5239
5585
  getAvailablePlugins(container) {
5240
5586
  const res = new Map();
5241
5587
  for (const plugin of this.plugins) {
5242
- plugin.needsPlugin(container.actualOptions) && res.set(plugin.id, plugin.getPlugin(container));
5588
+ if (plugin.needsPlugin(container.actualOptions)) {
5589
+ res.set(plugin.id, plugin.getPlugin(container));
5590
+ }
5243
5591
  }
5244
5592
  return res;
5245
5593
  }
@@ -5280,7 +5628,8 @@ class Engine {
5280
5628
  this._initialized = true;
5281
5629
  }
5282
5630
  async load(params) {
5283
- const id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * 10000)}`,
5631
+ const randomFactor = 10000,
5632
+ id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * randomFactor)}`,
5284
5633
  {
5285
5634
  index,
5286
5635
  url
@@ -5298,12 +5647,14 @@ class Engine {
5298
5647
  }
5299
5648
  const currentOptions = itemFromSingleOrMultiple(options, index),
5300
5649
  dom = this.dom(),
5301
- oldIndex = dom.findIndex(v => v.id.description === id);
5302
- if (oldIndex >= 0) {
5650
+ oldIndex = dom.findIndex(v => v.id.description === id),
5651
+ minIndex = 0;
5652
+ if (oldIndex >= minIndex) {
5303
5653
  const old = this.domItem(oldIndex);
5304
5654
  if (old && !old.destroyed) {
5305
5655
  old.destroy();
5306
- dom.splice(oldIndex, 1);
5656
+ const deleteCount = 1;
5657
+ dom.splice(oldIndex, deleteCount);
5307
5658
  }
5308
5659
  }
5309
5660
  let canvasEl;
@@ -5313,7 +5664,8 @@ class Engine {
5313
5664
  } else {
5314
5665
  const existingCanvases = domContainer.getElementsByTagName("canvas");
5315
5666
  if (existingCanvases.length) {
5316
- canvasEl = existingCanvases[0];
5667
+ const firstIndex = 0;
5668
+ canvasEl = existingCanvases[firstIndex];
5317
5669
  canvasEl.dataset[generatedAttribute] = "false";
5318
5670
  } else {
5319
5671
  canvasEl = document.createElement("canvas");
@@ -5328,8 +5680,9 @@ class Engine {
5328
5680
  canvasEl.style.height = "100%";
5329
5681
  }
5330
5682
  const newItem = new Container(this, id, currentOptions);
5331
- if (oldIndex >= 0) {
5332
- dom.splice(oldIndex, 0, newItem);
5683
+ if (oldIndex >= minIndex) {
5684
+ const deleteCount = 0;
5685
+ dom.splice(oldIndex, deleteCount, newItem);
5333
5686
  } else {
5334
5687
  dom.push(newItem);
5335
5688
  }
@@ -5348,14 +5701,14 @@ class Engine {
5348
5701
  return;
5349
5702
  }
5350
5703
  for (const updater of updaters) {
5351
- updater.loadOptions && updater.loadOptions(options, ...sourceOptions);
5704
+ updater.loadOptions?.(options, ...sourceOptions);
5352
5705
  }
5353
5706
  }
5354
5707
  async refresh(refresh = true) {
5355
5708
  if (!refresh) {
5356
5709
  return;
5357
5710
  }
5358
- this.dom().forEach(t => t.refresh());
5711
+ await Promise.allSettled(this.dom().map(t => t.refresh()));
5359
5712
  }
5360
5713
  removeEventListener(type, listener) {
5361
5714
  this._eventDispatcher.removeEventListener(type, listener);
@@ -5401,12 +5754,15 @@ class HslColorManager {
5401
5754
  return;
5402
5755
  }
5403
5756
  const regex = /hsla?\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*(,\s*([\d.%]+)\s*)?\)/i,
5404
- result = regex.exec(input);
5757
+ result = regex.exec(input),
5758
+ minLength = 4,
5759
+ defaultAlpha = 1,
5760
+ radix = 10;
5405
5761
  return result ? hslaToRgba({
5406
- a: result.length > 4 ? parseAlpha(result[5]) : 1,
5407
- h: parseInt(result[1], 10),
5408
- l: parseInt(result[3], 10),
5409
- s: parseInt(result[2], 10)
5762
+ a: result.length > minLength ? parseAlpha(result[5]) : defaultAlpha,
5763
+ h: parseInt(result[1], radix),
5764
+ l: parseInt(result[3], radix),
5765
+ s: parseInt(result[2], radix)
5410
5766
  }) : undefined;
5411
5767
  }
5412
5768
  }
@@ -5440,12 +5796,15 @@ class RgbColorManager {
5440
5796
  return;
5441
5797
  }
5442
5798
  const regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d.%]+)\s*)?\)/i,
5443
- result = regex.exec(input);
5799
+ result = regex.exec(input),
5800
+ radix = 10,
5801
+ minLength = 4,
5802
+ defaultAlpha = 1;
5444
5803
  return result ? {
5445
- a: result.length > 4 ? parseAlpha(result[5]) : 1,
5446
- b: parseInt(result[3], 10),
5447
- g: parseInt(result[2], 10),
5448
- r: parseInt(result[1], 10)
5804
+ a: result.length > minLength ? parseAlpha(result[5]) : defaultAlpha,
5805
+ b: parseInt(result[3], radix),
5806
+ g: parseInt(result[2], radix),
5807
+ r: parseInt(result[1], radix)
5449
5808
  } : undefined;
5450
5809
  }
5451
5810
  }
@@ -5466,15 +5825,15 @@ function init() {
5466
5825
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/ExternalInteractorBase.js
5467
5826
  class ExternalInteractorBase {
5468
5827
  constructor(container) {
5469
- this.container = container;
5470
5828
  this.type = "external";
5829
+ this.container = container;
5471
5830
  }
5472
5831
  }
5473
5832
  ;// CONCATENATED MODULE: ../../engine/dist/browser/Core/Utils/ParticlesInteractorBase.js
5474
5833
  class ParticlesInteractorBase {
5475
5834
  constructor(container) {
5476
- this.container = container;
5477
5835
  this.type = "particles";
5836
+ this.container = container;
5478
5837
  }
5479
5838
  }
5480
5839
  ;// CONCATENATED MODULE: ../../engine/dist/browser/exports.js
@@ -5578,6 +5937,12 @@ if (!isSsr()) {
5578
5937
 
5579
5938
  ;// CONCATENATED MODULE: ../../move/base/dist/browser/Utils.js
5580
5939
 
5940
+ const Utils_half = 0.5,
5941
+ minVelocity = 0,
5942
+ identity = 1,
5943
+ moveSpeedFactor = 60,
5944
+ minSpinRadius = 0,
5945
+ spinFactor = 0.01;
5581
5946
  function applyDistance(particle) {
5582
5947
  const initialPosition = particle.initialPosition,
5583
5948
  {
@@ -5594,23 +5959,25 @@ function applyDistance(particle) {
5594
5959
  if (!hDistance && !vDistance) {
5595
5960
  return;
5596
5961
  }
5597
- if ((hDistance && dxFixed >= hDistance || vDistance && dyFixed >= vDistance) && !particle.misplaced) {
5962
+ const hasHDistance = (hDistance && dxFixed >= hDistance) ?? false,
5963
+ hasVDistance = (vDistance && dyFixed >= vDistance) ?? false;
5964
+ if ((hasHDistance || hasVDistance) && !particle.misplaced) {
5598
5965
  particle.misplaced = !!hDistance && dxFixed > hDistance || !!vDistance && dyFixed > vDistance;
5599
5966
  if (hDistance) {
5600
- particle.velocity.x = particle.velocity.y * 0.5 - particle.velocity.x;
5967
+ particle.velocity.x = particle.velocity.y * Utils_half - particle.velocity.x;
5601
5968
  }
5602
5969
  if (vDistance) {
5603
- particle.velocity.y = particle.velocity.x * 0.5 - particle.velocity.y;
5970
+ particle.velocity.y = particle.velocity.x * Utils_half - particle.velocity.y;
5604
5971
  }
5605
5972
  } else if ((!hDistance || dxFixed < hDistance) && (!vDistance || dyFixed < vDistance) && particle.misplaced) {
5606
5973
  particle.misplaced = false;
5607
5974
  } else if (particle.misplaced) {
5608
5975
  const pos = particle.position,
5609
5976
  vel = particle.velocity;
5610
- if (hDistance && (pos.x < initialPosition.x && vel.x < 0 || pos.x > initialPosition.x && vel.x > 0)) {
5977
+ if (hDistance && (pos.x < initialPosition.x && vel.x < minVelocity || pos.x > initialPosition.x && vel.x > minVelocity)) {
5611
5978
  vel.x *= -getRandom();
5612
5979
  }
5613
- if (vDistance && (pos.y < initialPosition.y && vel.y < 0 || pos.y > initialPosition.y && vel.y > 0)) {
5980
+ if (vDistance && (pos.y < initialPosition.y && vel.y < minVelocity || pos.y > initialPosition.y && vel.y > minVelocity)) {
5614
5981
  vel.y *= -getRandom();
5615
5982
  }
5616
5983
  }
@@ -5618,24 +5985,24 @@ function applyDistance(particle) {
5618
5985
  function move(particle, moveOptions, moveSpeed, maxSpeed, moveDrift, delta) {
5619
5986
  applyPath(particle, delta);
5620
5987
  const gravityOptions = particle.gravity,
5621
- gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -1 : 1;
5988
+ gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity : identity;
5622
5989
  if (moveDrift && moveSpeed) {
5623
- particle.velocity.x += moveDrift * delta.factor / (60 * moveSpeed);
5990
+ particle.velocity.x += moveDrift * delta.factor / (moveSpeedFactor * moveSpeed);
5624
5991
  }
5625
5992
  if (gravityOptions?.enable && moveSpeed) {
5626
- particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (60 * moveSpeed);
5993
+ particle.velocity.y += gravityFactor * (gravityOptions.acceleration * delta.factor) / (moveSpeedFactor * moveSpeed);
5627
5994
  }
5628
5995
  const decay = particle.moveDecay;
5629
5996
  particle.velocity.multTo(decay);
5630
5997
  const velocity = particle.velocity.mult(moveSpeed);
5631
- if (gravityOptions?.enable && maxSpeed > 0 && (!gravityOptions.inverse && velocity.y >= 0 && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= 0 && velocity.y <= -maxSpeed)) {
5998
+ if (gravityOptions?.enable && maxSpeed > minVelocity && (!gravityOptions.inverse && velocity.y >= minVelocity && velocity.y >= maxSpeed || gravityOptions.inverse && velocity.y <= minVelocity && velocity.y <= -maxSpeed)) {
5632
5999
  velocity.y = gravityFactor * maxSpeed;
5633
6000
  if (moveSpeed) {
5634
6001
  particle.velocity.y = velocity.y / moveSpeed;
5635
6002
  }
5636
6003
  }
5637
6004
  const zIndexOptions = particle.options.zIndex,
5638
- zVelocityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
6005
+ zVelocityFactor = (identity - particle.zIndexFactor) ** zIndexOptions.velocityRate;
5639
6006
  velocity.multTo(zVelocityFactor);
5640
6007
  const {
5641
6008
  position
@@ -5659,15 +6026,15 @@ function spin(particle, moveSpeed) {
5659
6026
  particle.position.y = particle.spin.center.y + particle.spin.radius * updateFunc.y(particle.spin.angle);
5660
6027
  particle.spin.radius += particle.spin.acceleration;
5661
6028
  const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height),
5662
- halfMaxSize = maxCanvasSize * 0.5;
6029
+ halfMaxSize = maxCanvasSize * Utils_half;
5663
6030
  if (particle.spin.radius > halfMaxSize) {
5664
6031
  particle.spin.radius = halfMaxSize;
5665
- particle.spin.acceleration *= -1;
5666
- } else if (particle.spin.radius < 0) {
5667
- particle.spin.radius = 0;
5668
- particle.spin.acceleration *= -1;
6032
+ particle.spin.acceleration *= -identity;
6033
+ } else if (particle.spin.radius < minSpinRadius) {
6034
+ particle.spin.radius = minSpinRadius;
6035
+ particle.spin.acceleration *= -identity;
5669
6036
  }
5670
- particle.spin.angle += moveSpeed * 0.01 * (1 - particle.spin.radius / maxCanvasSize);
6037
+ particle.spin.angle += moveSpeed * spinFactor * (identity - particle.spin.radius / maxCanvasSize);
5671
6038
  }
5672
6039
  function applyPath(particle, delta) {
5673
6040
  const particlesOptions = particle.options,
@@ -5685,18 +6052,20 @@ function applyPath(particle, delta) {
5685
6052
  particle.velocity.addTo(path);
5686
6053
  }
5687
6054
  if (pathOptions.clamp) {
5688
- particle.velocity.x = clamp(particle.velocity.x, -1, 1);
5689
- particle.velocity.y = clamp(particle.velocity.y, -1, 1);
6055
+ particle.velocity.x = clamp(particle.velocity.x, -identity, identity);
6056
+ particle.velocity.y = clamp(particle.velocity.y, -identity, identity);
5690
6057
  }
5691
6058
  particle.lastPathTime -= particle.pathDelay;
5692
6059
  }
5693
6060
  function getProximitySpeedFactor(particle) {
5694
- return particle.slow.inRange ? particle.slow.factor : 1;
6061
+ return particle.slow.inRange ? particle.slow.factor : identity;
5695
6062
  }
5696
6063
  ;// CONCATENATED MODULE: ../../move/base/dist/browser/BaseMover.js
5697
6064
 
5698
6065
 
5699
- const diffFactor = 2;
6066
+ const diffFactor = 2,
6067
+ defaultSizeFactor = 1,
6068
+ defaultDeltaFactor = 1;
5700
6069
  class BaseMover {
5701
6070
  constructor() {
5702
6071
  this._initSpin = particle => {
@@ -5710,17 +6079,19 @@ class BaseMover {
5710
6079
  x: 50,
5711
6080
  y: 50
5712
6081
  },
6082
+ spinFactor = 0.01,
5713
6083
  spinCenter = {
5714
- x: spinPos.x * 0.01 * container.canvas.size.width,
5715
- y: spinPos.y * 0.01 * container.canvas.size.height
6084
+ x: spinPos.x * spinFactor * container.canvas.size.width,
6085
+ y: spinPos.y * spinFactor * container.canvas.size.height
5716
6086
  },
5717
6087
  pos = particle.getPosition(),
5718
6088
  distance = getDistance(pos, spinCenter),
5719
6089
  spinAcceleration = getRangeValue(spinOptions.acceleration);
5720
6090
  particle.retina.spinAcceleration = spinAcceleration * container.retina.pixelRatio;
6091
+ const minVelocity = 0;
5721
6092
  particle.spin = {
5722
6093
  center: spinCenter,
5723
- direction: particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise",
6094
+ direction: particle.velocity.x >= minVelocity ? "clockwise" : "counter-clockwise",
5724
6095
  angle: particle.velocity.angle,
5725
6096
  radius: distance,
5726
6097
  acceleration: particle.retina.spinAcceleration
@@ -5747,13 +6118,16 @@ class BaseMover {
5747
6118
  return;
5748
6119
  }
5749
6120
  const container = particle.container,
5750
- pxRatio = container.retina.pixelRatio,
5751
- slowFactor = getProximitySpeedFactor(particle),
5752
- baseSpeed = (particle.retina.moveSpeed ??= getRangeValue(moveOptions.speed) * pxRatio) * container.retina.reduceFactor,
5753
- moveDrift = particle.retina.moveDrift ??= getRangeValue(particle.options.move.drift) * pxRatio,
6121
+ pxRatio = container.retina.pixelRatio;
6122
+ particle.retina.moveSpeed ??= getRangeValue(moveOptions.speed) * pxRatio;
6123
+ particle.retina.moveDrift ??= getRangeValue(particle.options.move.drift) * pxRatio;
6124
+ const slowFactor = getProximitySpeedFactor(particle),
6125
+ baseSpeed = particle.retina.moveSpeed * container.retina.reduceFactor,
6126
+ moveDrift = particle.retina.moveDrift,
5754
6127
  maxSize = getRangeMax(particleOptions.size.value) * pxRatio,
5755
- sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : 1,
5756
- moveSpeed = baseSpeed * sizeFactor * slowFactor * (delta.factor || 1) / diffFactor,
6128
+ sizeFactor = moveOptions.size ? particle.getRadius() / maxSize : defaultSizeFactor,
6129
+ deltaFactor = delta.factor || defaultDeltaFactor,
6130
+ moveSpeed = baseSpeed * sizeFactor * slowFactor * deltaFactor / diffFactor,
5757
6131
  maxSpeed = particle.retina.maxSpeed ?? container.retina.maxSpeed;
5758
6132
  if (moveOptions.spin.enable) {
5759
6133
  spin(particle, moveSpeed);
@@ -5770,6 +6144,15 @@ async function loadBaseMover(engine, refresh = true) {
5770
6144
  }
5771
6145
  ;// CONCATENATED MODULE: ../../shapes/circle/dist/browser/CircleDrawer.js
5772
6146
 
6147
+ const CircleDrawer_double = 2,
6148
+ CircleDrawer_doublePI = Math.PI * CircleDrawer_double,
6149
+ sides = 12,
6150
+ maxAngle = 360,
6151
+ minAngle = 0,
6152
+ CircleDrawer_origin = {
6153
+ x: 0,
6154
+ y: 0
6155
+ };
5773
6156
  class CircleDrawer {
5774
6157
  draw(data) {
5775
6158
  const {
@@ -5779,28 +6162,28 @@ class CircleDrawer {
5779
6162
  } = data;
5780
6163
  if (!particle.circleRange) {
5781
6164
  particle.circleRange = {
5782
- min: 0,
5783
- max: Math.PI * 2
6165
+ min: minAngle,
6166
+ max: CircleDrawer_doublePI
5784
6167
  };
5785
6168
  }
5786
6169
  const circleRange = particle.circleRange;
5787
- context.arc(0, 0, radius, circleRange.min, circleRange.max, false);
6170
+ context.arc(CircleDrawer_origin.x, CircleDrawer_origin.y, radius, circleRange.min, circleRange.max, false);
5788
6171
  }
5789
6172
  getSidesCount() {
5790
- return 12;
6173
+ return sides;
5791
6174
  }
5792
6175
  particleInit(container, particle) {
5793
6176
  const shapeData = particle.shapeData,
5794
6177
  angle = shapeData?.angle ?? {
5795
- max: 360,
5796
- min: 0
6178
+ max: maxAngle,
6179
+ min: minAngle
5797
6180
  };
5798
6181
  particle.circleRange = !isObject(angle) ? {
5799
- min: 0,
5800
- max: angle * Math.PI / 180
6182
+ min: minAngle,
6183
+ max: degToRad(angle)
5801
6184
  } : {
5802
- min: angle.min * Math.PI / 180,
5803
- max: angle.max * Math.PI / 180
6185
+ min: degToRad(angle.min),
6186
+ max: degToRad(angle.max)
5804
6187
  };
5805
6188
  }
5806
6189
  }
@@ -5809,84 +6192,8 @@ class CircleDrawer {
5809
6192
  async function loadCircleShape(engine, refresh = true) {
5810
6193
  await engine.addShape("circle", new CircleDrawer(), refresh);
5811
6194
  }
5812
- ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/Utils.js
5813
-
5814
- function updateColorValue(delta, colorValue, valueAnimation, max, decrease) {
5815
- if (!colorValue || !valueAnimation.enable || (colorValue.maxLoops ?? 0) > 0 && (colorValue.loops ?? 0) > (colorValue.maxLoops ?? 0)) {
5816
- return;
5817
- }
5818
- if (!colorValue.time) {
5819
- colorValue.time = 0;
5820
- }
5821
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
5822
- colorValue.time += delta.value;
5823
- }
5824
- if ((colorValue.delayTime ?? 0) > 0 && colorValue.time < (colorValue.delayTime ?? 0)) {
5825
- return;
5826
- }
5827
- const offset = randomInRange(valueAnimation.offset),
5828
- velocity = (colorValue.velocity ?? 0) * delta.factor + offset * 3.6,
5829
- decay = colorValue.decay ?? 1;
5830
- if (!decrease || colorValue.status === "increasing") {
5831
- colorValue.value += velocity;
5832
- if (colorValue.value > max) {
5833
- if (!colorValue.loops) {
5834
- colorValue.loops = 0;
5835
- }
5836
- colorValue.loops++;
5837
- if (decrease) {
5838
- colorValue.status = "decreasing";
5839
- colorValue.value -= colorValue.value % max;
5840
- }
5841
- }
5842
- } else {
5843
- colorValue.value -= velocity;
5844
- if (colorValue.value < 0) {
5845
- if (!colorValue.loops) {
5846
- colorValue.loops = 0;
5847
- }
5848
- colorValue.loops++;
5849
- colorValue.status = "increasing";
5850
- colorValue.value += colorValue.value;
5851
- }
5852
- }
5853
- if (colorValue.velocity && decay !== 1) {
5854
- colorValue.velocity *= decay;
5855
- }
5856
- if (colorValue.value > max) {
5857
- colorValue.value %= max;
5858
- }
5859
- }
5860
- function updateColor(particle, delta) {
5861
- const {
5862
- h: hAnimation,
5863
- s: sAnimation,
5864
- l: lAnimation
5865
- } = particle.options.color.animation,
5866
- {
5867
- color
5868
- } = particle;
5869
- if (!color) {
5870
- return;
5871
- }
5872
- const {
5873
- h,
5874
- s,
5875
- l
5876
- } = color;
5877
- if (h) {
5878
- updateColorValue(delta, h, hAnimation, 360, false);
5879
- }
5880
- if (s) {
5881
- updateColorValue(delta, s, sAnimation, 100, true);
5882
- }
5883
- if (l) {
5884
- updateColorValue(delta, l, lAnimation, 100, true);
5885
- }
5886
- }
5887
6195
  ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/ColorUpdater.js
5888
6196
 
5889
-
5890
6197
  class ColorUpdater {
5891
6198
  constructor(container) {
5892
6199
  this.container = container;
@@ -5909,7 +6216,7 @@ class ColorUpdater {
5909
6216
  return !particle.destroyed && !particle.spawning && (color?.h.value !== undefined && hAnimation.enable || color?.s.value !== undefined && sAnimation.enable || color?.l.value !== undefined && lAnimation.enable);
5910
6217
  }
5911
6218
  update(particle, delta) {
5912
- updateColor(particle, delta);
6219
+ updateColor(particle.color, delta);
5913
6220
  }
5914
6221
  }
5915
6222
  ;// CONCATENATED MODULE: ../../updaters/color/dist/browser/index.js
@@ -5917,91 +6224,27 @@ class ColorUpdater {
5917
6224
  async function loadColorUpdater(engine, refresh = true) {
5918
6225
  await engine.addParticleUpdater("color", container => new ColorUpdater(container), refresh);
5919
6226
  }
5920
- ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/Utils.js
5921
-
5922
- function checkDestroy(particle, value, minValue, maxValue) {
5923
- switch (particle.options.opacity.animation.destroy) {
5924
- case "max":
5925
- if (value >= maxValue) {
5926
- particle.destroy();
5927
- }
5928
- break;
5929
- case "min":
5930
- if (value <= minValue) {
5931
- particle.destroy();
5932
- }
5933
- break;
5934
- }
5935
- }
5936
- function updateOpacity(particle, delta) {
5937
- const data = particle.opacity;
5938
- if (particle.destroyed || !data?.enable || (data.maxLoops ?? 0) > 0 && (data.loops ?? 0) > (data.maxLoops ?? 0)) {
5939
- return;
5940
- }
5941
- const minValue = data.min,
5942
- maxValue = data.max,
5943
- decay = data.decay ?? 1;
5944
- if (!data.time) {
5945
- data.time = 0;
5946
- }
5947
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
5948
- data.time += delta.value;
5949
- }
5950
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
5951
- return;
5952
- }
5953
- switch (data.status) {
5954
- case "increasing":
5955
- if (data.value >= maxValue) {
5956
- data.status = "decreasing";
5957
- if (!data.loops) {
5958
- data.loops = 0;
5959
- }
5960
- data.loops++;
5961
- } else {
5962
- data.value += (data.velocity ?? 0) * delta.factor;
5963
- }
5964
- break;
5965
- case "decreasing":
5966
- if (data.value <= minValue) {
5967
- data.status = "increasing";
5968
- if (!data.loops) {
5969
- data.loops = 0;
5970
- }
5971
- data.loops++;
5972
- } else {
5973
- data.value -= (data.velocity ?? 0) * delta.factor;
5974
- }
5975
- break;
5976
- }
5977
- if (data.velocity && data.decay !== 1) {
5978
- data.velocity *= decay;
5979
- }
5980
- checkDestroy(particle, data.value, minValue, maxValue);
5981
- if (!particle.destroyed) {
5982
- data.value = clamp(data.value, minValue, maxValue);
5983
- }
5984
- }
5985
6227
  ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/OpacityUpdater.js
5986
6228
 
5987
-
5988
6229
  class OpacityUpdater {
5989
6230
  constructor(container) {
5990
6231
  this.container = container;
5991
6232
  }
5992
6233
  init(particle) {
5993
- const opacityOptions = particle.options.opacity;
5994
- particle.opacity = initParticleNumericAnimationValue(opacityOptions, 1);
6234
+ const opacityOptions = particle.options.opacity,
6235
+ pxRatio = 1;
6236
+ particle.opacity = initParticleNumericAnimationValue(opacityOptions, pxRatio);
5995
6237
  const opacityAnimation = opacityOptions.animation;
5996
6238
  if (opacityAnimation.enable) {
5997
- particle.opacity.velocity = getRangeValue(opacityAnimation.speed) / 100 * this.container.retina.reduceFactor;
6239
+ particle.opacity.velocity = getRangeValue(opacityAnimation.speed) / percentDenominator * this.container.retina.reduceFactor;
5998
6240
  if (!opacityAnimation.sync) {
5999
6241
  particle.opacity.velocity *= getRandom();
6000
6242
  }
6001
6243
  }
6002
6244
  }
6003
6245
  isEnabled(particle) {
6004
- return !particle.destroyed && !particle.spawning && !!particle.opacity && particle.opacity.enable && ((particle.opacity.maxLoops ?? 0) <= 0 || (particle.opacity.maxLoops ?? 0) > 0 && (particle.opacity.loops ?? 0) < (particle.opacity.maxLoops ?? 0));
6246
+ const none = 0;
6247
+ return !particle.destroyed && !particle.spawning && !!particle.opacity && particle.opacity.enable && ((particle.opacity.maxLoops ?? none) <= none || (particle.opacity.maxLoops ?? none) > none && (particle.opacity.loops ?? none) < (particle.opacity.maxLoops ?? none));
6005
6248
  }
6006
6249
  reset(particle) {
6007
6250
  if (particle.opacity) {
@@ -6010,10 +6253,10 @@ class OpacityUpdater {
6010
6253
  }
6011
6254
  }
6012
6255
  update(particle, delta) {
6013
- if (!this.isEnabled(particle)) {
6256
+ if (!this.isEnabled(particle) || !particle.opacity) {
6014
6257
  return;
6015
6258
  }
6016
- updateOpacity(particle, delta);
6259
+ updateAnimation(particle, particle.opacity, true, particle.options.opacity.animation.destroy, delta);
6017
6260
  }
6018
6261
  }
6019
6262
  ;// CONCATENATED MODULE: ../../updaters/opacity/dist/browser/index.js
@@ -6023,18 +6266,20 @@ async function loadOpacityUpdater(engine, refresh = true) {
6023
6266
  }
6024
6267
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/Utils.js
6025
6268
 
6269
+ const Utils_minVelocity = 0,
6270
+ boundsMin = 0;
6026
6271
  function bounceHorizontal(data) {
6027
6272
  if (data.outMode !== "bounce" && data.outMode !== "bounce-horizontal" && data.outMode !== "bounceHorizontal" && data.outMode !== "split" || data.direction !== "left" && data.direction !== "right") {
6028
6273
  return;
6029
6274
  }
6030
- if (data.bounds.right < 0 && data.direction === "left") {
6275
+ if (data.bounds.right < boundsMin && data.direction === "left") {
6031
6276
  data.particle.position.x = data.size + data.offset.x;
6032
6277
  } else if (data.bounds.left > data.canvasSize.width && data.direction === "right") {
6033
6278
  data.particle.position.x = data.canvasSize.width - data.size - data.offset.x;
6034
6279
  }
6035
6280
  const velocity = data.particle.velocity.x;
6036
6281
  let bounced = false;
6037
- if (data.direction === "right" && data.bounds.right >= data.canvasSize.width && velocity > 0 || data.direction === "left" && data.bounds.left <= 0 && velocity < 0) {
6282
+ if (data.direction === "right" && data.bounds.right >= data.canvasSize.width && velocity > Utils_minVelocity || data.direction === "left" && data.bounds.left <= boundsMin && velocity < Utils_minVelocity) {
6038
6283
  const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
6039
6284
  data.particle.velocity.x *= -newVelocity;
6040
6285
  bounced = true;
@@ -6045,7 +6290,7 @@ function bounceHorizontal(data) {
6045
6290
  const minPos = data.offset.x + data.size;
6046
6291
  if (data.bounds.right >= data.canvasSize.width && data.direction === "right") {
6047
6292
  data.particle.position.x = data.canvasSize.width - minPos;
6048
- } else if (data.bounds.left <= 0 && data.direction === "left") {
6293
+ } else if (data.bounds.left <= boundsMin && data.direction === "left") {
6049
6294
  data.particle.position.x = minPos;
6050
6295
  }
6051
6296
  if (data.outMode === "split") {
@@ -6056,14 +6301,14 @@ function bounceVertical(data) {
6056
6301
  if (data.outMode !== "bounce" && data.outMode !== "bounce-vertical" && data.outMode !== "bounceVertical" && data.outMode !== "split" || data.direction !== "bottom" && data.direction !== "top") {
6057
6302
  return;
6058
6303
  }
6059
- if (data.bounds.bottom < 0 && data.direction === "top") {
6304
+ if (data.bounds.bottom < boundsMin && data.direction === "top") {
6060
6305
  data.particle.position.y = data.size + data.offset.y;
6061
6306
  } else if (data.bounds.top > data.canvasSize.height && data.direction === "bottom") {
6062
6307
  data.particle.position.y = data.canvasSize.height - data.size - data.offset.y;
6063
6308
  }
6064
6309
  const velocity = data.particle.velocity.y;
6065
6310
  let bounced = false;
6066
- if (data.direction === "bottom" && data.bounds.bottom >= data.canvasSize.height && velocity > 0 || data.direction === "top" && data.bounds.top <= 0 && velocity < 0) {
6311
+ if (data.direction === "bottom" && data.bounds.bottom >= data.canvasSize.height && velocity > Utils_minVelocity || data.direction === "top" && data.bounds.top <= boundsMin && velocity < Utils_minVelocity) {
6067
6312
  const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
6068
6313
  data.particle.velocity.y *= -newVelocity;
6069
6314
  bounced = true;
@@ -6074,7 +6319,7 @@ function bounceVertical(data) {
6074
6319
  const minPos = data.offset.y + data.size;
6075
6320
  if (data.bounds.bottom >= data.canvasSize.height && data.direction === "bottom") {
6076
6321
  data.particle.position.y = data.canvasSize.height - minPos;
6077
- } else if (data.bounds.top <= 0 && data.direction === "top") {
6322
+ } else if (data.bounds.top <= boundsMin && data.direction === "top") {
6078
6323
  data.particle.position.y = minPos;
6079
6324
  }
6080
6325
  if (data.outMode === "split") {
@@ -6133,6 +6378,7 @@ class BounceOutMode {
6133
6378
  }
6134
6379
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/DestroyOutMode.js
6135
6380
 
6381
+ const DestroyOutMode_minVelocity = 0;
6136
6382
  class DestroyOutMode {
6137
6383
  constructor(container) {
6138
6384
  this.container = container;
@@ -6160,7 +6406,7 @@ class DestroyOutMode {
6160
6406
  x: vx,
6161
6407
  y: vy
6162
6408
  } = particle.velocity;
6163
- if (vx < 0 && dx > particle.moveCenter.radius || vy < 0 && dy > particle.moveCenter.radius || vx >= 0 && dx < -particle.moveCenter.radius || vy >= 0 && dy < -particle.moveCenter.radius) {
6409
+ if (vx < DestroyOutMode_minVelocity && dx > particle.moveCenter.radius || vy < DestroyOutMode_minVelocity && dy > particle.moveCenter.radius || vx >= DestroyOutMode_minVelocity && dx < -particle.moveCenter.radius || vy >= DestroyOutMode_minVelocity && dy < -particle.moveCenter.radius) {
6164
6410
  return;
6165
6411
  }
6166
6412
  break;
@@ -6171,6 +6417,7 @@ class DestroyOutMode {
6171
6417
  }
6172
6418
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/NoneOutMode.js
6173
6419
 
6420
+ const NoneOutMode_minVelocity = 0;
6174
6421
  class NoneOutMode {
6175
6422
  constructor(container) {
6176
6423
  this.container = container;
@@ -6180,7 +6427,7 @@ class NoneOutMode {
6180
6427
  if (!this.modes.includes(outMode)) {
6181
6428
  return;
6182
6429
  }
6183
- if (particle.options.move.distance.horizontal && (direction === "left" || direction === "right") || particle.options.move.distance.vertical && (direction === "top" || direction === "bottom")) {
6430
+ if ((particle.options.move.distance.horizontal && (direction === "left" || direction === "right")) ?? (particle.options.move.distance.vertical && (direction === "top" || direction === "bottom"))) {
6184
6431
  return;
6185
6432
  }
6186
6433
  const gravityOptions = particle.options.move.gravity,
@@ -6188,7 +6435,7 @@ class NoneOutMode {
6188
6435
  const canvasSize = container.canvas.size;
6189
6436
  const pRadius = particle.getRadius();
6190
6437
  if (!gravityOptions.enable) {
6191
- if (particle.velocity.y > 0 && particle.position.y <= canvasSize.height + pRadius || particle.velocity.y < 0 && particle.position.y >= -pRadius || particle.velocity.x > 0 && particle.position.x <= canvasSize.width + pRadius || particle.velocity.x < 0 && particle.position.x >= -pRadius) {
6438
+ if (particle.velocity.y > NoneOutMode_minVelocity && particle.position.y <= canvasSize.height + pRadius || particle.velocity.y < NoneOutMode_minVelocity && particle.position.y >= -pRadius || particle.velocity.x > NoneOutMode_minVelocity && particle.position.x <= canvasSize.width + pRadius || particle.velocity.x < NoneOutMode_minVelocity && particle.position.x >= -pRadius) {
6192
6439
  return;
6193
6440
  }
6194
6441
  if (!isPointInside(particle.position, container.canvas.size, Vector.origin, pRadius, direction)) {
@@ -6204,6 +6451,8 @@ class NoneOutMode {
6204
6451
  }
6205
6452
  ;// CONCATENATED MODULE: ../../updaters/outModes/dist/browser/OutOutMode.js
6206
6453
 
6454
+ const OutOutMode_minVelocity = 0,
6455
+ minDistance = 0;
6207
6456
  class OutOutMode {
6208
6457
  constructor(container) {
6209
6458
  this.container = container;
@@ -6229,7 +6478,7 @@ class OutOutMode {
6229
6478
  dx,
6230
6479
  dy
6231
6480
  } = getDistances(particle.position, circVec);
6232
- if (vx <= 0 && dx >= 0 || vy <= 0 && dy >= 0 || vx >= 0 && dx <= 0 || vy >= 0 && dy <= 0) {
6481
+ if (vx <= OutOutMode_minVelocity && dx >= minDistance || vy <= OutOutMode_minVelocity && dy >= minDistance || vx >= OutOutMode_minVelocity && dx <= minDistance || vy >= OutOutMode_minVelocity && dy <= minDistance) {
6233
6482
  return;
6234
6483
  }
6235
6484
  particle.position.x = Math.floor(randomInRange({
@@ -6331,12 +6580,12 @@ class OutOutMode {
6331
6580
 
6332
6581
  class OutOfCanvasUpdater {
6333
6582
  constructor(container) {
6334
- this.container = container;
6335
6583
  this._updateOutMode = (particle, delta, outMode, direction) => {
6336
6584
  for (const updater of this.updaters) {
6337
6585
  updater.update(particle, direction, delta, outMode);
6338
6586
  }
6339
6587
  };
6588
+ this.container = container;
6340
6589
  this.updaters = [new BounceOutMode(container), new DestroyOutMode(container), new OutOutMode(container), new NoneOutMode(container)];
6341
6590
  }
6342
6591
  init() {}
@@ -6356,97 +6605,32 @@ class OutOfCanvasUpdater {
6356
6605
  async function loadOutModesUpdater(engine, refresh = true) {
6357
6606
  await engine.addParticleUpdater("outModes", container => new OutOfCanvasUpdater(container), refresh);
6358
6607
  }
6359
- ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/Utils.js
6360
-
6361
- function Utils_checkDestroy(particle, value, minValue, maxValue) {
6362
- switch (particle.options.size.animation.destroy) {
6363
- case "max":
6364
- if (value >= maxValue) {
6365
- particle.destroy();
6366
- }
6367
- break;
6368
- case "min":
6369
- if (value <= minValue) {
6370
- particle.destroy();
6371
- }
6372
- break;
6373
- }
6374
- }
6375
- function updateSize(particle, delta) {
6376
- const data = particle.size;
6377
- if (particle.destroyed || !data || !data.enable || (data.maxLoops ?? 0) > 0 && (data.loops ?? 0) > (data.maxLoops ?? 0)) {
6378
- return;
6379
- }
6380
- const sizeVelocity = (data.velocity ?? 0) * delta.factor,
6381
- minValue = data.min,
6382
- maxValue = data.max,
6383
- decay = data.decay ?? 1;
6384
- if (!data.time) {
6385
- data.time = 0;
6386
- }
6387
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
6388
- data.time += delta.value;
6389
- }
6390
- if ((data.delayTime ?? 0) > 0 && data.time < (data.delayTime ?? 0)) {
6391
- return;
6392
- }
6393
- switch (data.status) {
6394
- case "increasing":
6395
- if (data.value >= maxValue) {
6396
- data.status = "decreasing";
6397
- if (!data.loops) {
6398
- data.loops = 0;
6399
- }
6400
- data.loops++;
6401
- } else {
6402
- data.value += sizeVelocity;
6403
- }
6404
- break;
6405
- case "decreasing":
6406
- if (data.value <= minValue) {
6407
- data.status = "increasing";
6408
- if (!data.loops) {
6409
- data.loops = 0;
6410
- }
6411
- data.loops++;
6412
- } else {
6413
- data.value -= sizeVelocity;
6414
- }
6415
- }
6416
- if (data.velocity && decay !== 1) {
6417
- data.velocity *= decay;
6418
- }
6419
- Utils_checkDestroy(particle, data.value, minValue, maxValue);
6420
- if (!particle.destroyed) {
6421
- data.value = clamp(data.value, minValue, maxValue);
6422
- }
6423
- }
6424
6608
  ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/SizeUpdater.js
6425
6609
 
6426
-
6610
+ const minLoops = 0;
6427
6611
  class SizeUpdater {
6428
6612
  init(particle) {
6429
6613
  const container = particle.container,
6430
6614
  sizeOptions = particle.options.size,
6431
6615
  sizeAnimation = sizeOptions.animation;
6432
6616
  if (sizeAnimation.enable) {
6433
- particle.size.velocity = (particle.retina.sizeAnimationSpeed ?? container.retina.sizeAnimationSpeed) / 100 * container.retina.reduceFactor;
6617
+ particle.size.velocity = (particle.retina.sizeAnimationSpeed ?? container.retina.sizeAnimationSpeed) / percentDenominator * container.retina.reduceFactor;
6434
6618
  if (!sizeAnimation.sync) {
6435
6619
  particle.size.velocity *= getRandom();
6436
6620
  }
6437
6621
  }
6438
6622
  }
6439
6623
  isEnabled(particle) {
6440
- return !particle.destroyed && !particle.spawning && particle.size.enable && ((particle.size.maxLoops ?? 0) <= 0 || (particle.size.maxLoops ?? 0) > 0 && (particle.size.loops ?? 0) < (particle.size.maxLoops ?? 0));
6624
+ return !particle.destroyed && !particle.spawning && particle.size.enable && ((particle.size.maxLoops ?? minLoops) <= minLoops || (particle.size.maxLoops ?? minLoops) > minLoops && (particle.size.loops ?? minLoops) < (particle.size.maxLoops ?? minLoops));
6441
6625
  }
6442
6626
  reset(particle) {
6443
- particle.size.loops = 0;
6627
+ particle.size.loops = minLoops;
6444
6628
  }
6445
6629
  update(particle, delta) {
6446
6630
  if (!this.isEnabled(particle)) {
6447
6631
  return;
6448
6632
  }
6449
- updateSize(particle, delta);
6633
+ updateAnimation(particle, particle.size, true, particle.options.size.animation.destroy, delta);
6450
6634
  }
6451
6635
  }
6452
6636
  ;// CONCATENATED MODULE: ../../updaters/size/dist/browser/index.js
@@ -6473,7 +6657,7 @@ async function loadBasic(engine, refresh = true) {
6473
6657
  ;// CONCATENATED MODULE: ./dist/browser/bundle.js
6474
6658
 
6475
6659
 
6476
- loadBasic(tsParticles);
6660
+ void loadBasic(tsParticles);
6477
6661
 
6478
6662
 
6479
6663
  /******/ return __webpack_exports__;