@tsparticles/preset-fire 4.1.3 → 4.2.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.
@@ -1,5 +1,5 @@
1
1
  (function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
- /* Preset v4.1.3 */
2
+ /* Preset v4.2.0 */
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
5
5
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -15,7 +15,7 @@
15
15
  b: 0,
16
16
  c: 0,
17
17
  d: 1,
18
- }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
18
+ }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, minVelocity = 0, minDistance = 0, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, maxNits = 400, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
19
19
 
20
20
  var MoveDirection;
21
21
  (function (MoveDirection) {
@@ -82,11 +82,6 @@
82
82
  div(n) {
83
83
  return Vector3d.create(this.x / n, this.y / n, this.z / n);
84
84
  }
85
- divTo(n) {
86
- this.x /= n;
87
- this.y /= n;
88
- this.z /= n;
89
- }
90
85
  getLengthSq() {
91
86
  return this.x ** squareExp + this.y ** squareExp;
92
87
  }
@@ -282,27 +277,6 @@
282
277
  return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
283
278
  }
284
279
 
285
- var AnimationMode;
286
- (function (AnimationMode) {
287
- AnimationMode["auto"] = "auto";
288
- AnimationMode["increase"] = "increase";
289
- AnimationMode["decrease"] = "decrease";
290
- AnimationMode["random"] = "random";
291
- })(AnimationMode || (AnimationMode = {}));
292
-
293
- var AnimationStatus;
294
- (function (AnimationStatus) {
295
- AnimationStatus["increasing"] = "increasing";
296
- AnimationStatus["decreasing"] = "decreasing";
297
- })(AnimationStatus || (AnimationStatus = {}));
298
-
299
- var DestroyType;
300
- (function (DestroyType) {
301
- DestroyType["none"] = "none";
302
- DestroyType["max"] = "max";
303
- DestroyType["min"] = "min";
304
- })(DestroyType || (DestroyType = {}));
305
-
306
280
  var OutModeDirection;
307
281
  (function (OutModeDirection) {
308
282
  OutModeDirection["bottom"] = "bottom";
@@ -317,67 +291,7 @@
317
291
  PixelMode["percent"] = "percent";
318
292
  })(PixelMode || (PixelMode = {}));
319
293
 
320
- var StartValueType;
321
- (function (StartValueType) {
322
- StartValueType["max"] = "max";
323
- StartValueType["min"] = "min";
324
- StartValueType["random"] = "random";
325
- })(StartValueType || (StartValueType = {}));
326
-
327
294
  const minRadius = 0;
328
- function memoize(fn, options) {
329
- const cache = new Map(), stableStringify = (obj, seen = new WeakSet()) => {
330
- if (obj === null) {
331
- return "null";
332
- }
333
- const t = typeof obj;
334
- if (t === "undefined") {
335
- return "undefined";
336
- }
337
- if (t === "number" || t === "boolean" || t === "string") {
338
- return JSON.stringify(obj);
339
- }
340
- if (t === "function") {
341
- try {
342
- const fn = obj;
343
- return fn.toString();
344
- }
345
- catch {
346
- return '"[Function]"';
347
- }
348
- }
349
- if (t === "symbol") {
350
- try {
351
- return obj.toString();
352
- }
353
- catch {
354
- return '"[Symbol]"';
355
- }
356
- }
357
- if (Array.isArray(obj)) {
358
- return `[${obj.map(i => stableStringify(i, seen)).join(",")}]`;
359
- }
360
- if (seen.has(obj)) {
361
- return '"[Circular]"';
362
- }
363
- seen.add(obj);
364
- const keys = Object.keys(obj).sort();
365
- return `{${keys.map(k => `${JSON.stringify(k)}:${stableStringify(obj[k], seen)}`).join(",")}}`;
366
- }, defaultKeyer = (args) => stableStringify(args), makeKey = (args) => (defaultKeyer(args));
367
- return (...args) => {
368
- const key = makeKey(args), now = Date.now(), entry = cache.get(key);
369
- if (entry !== undefined) {
370
- {
371
- cache.delete(key);
372
- cache.set(key, { value: entry.value, ts: entry.ts });
373
- return entry.value;
374
- }
375
- }
376
- const result = fn(...args);
377
- cache.set(key, { value: result, ts: now });
378
- return result;
379
- };
380
- }
381
295
  function hasMatchMedia() {
382
296
  return typeof matchMedia !== "undefined";
383
297
  }
@@ -390,12 +304,6 @@
390
304
  }
391
305
  return matchMedia(query);
392
306
  }
393
- function safeIntersectionObserver(callback) {
394
- if (typeof IntersectionObserver === "undefined") {
395
- return;
396
- }
397
- return new IntersectionObserver(callback);
398
- }
399
307
  function safeMutationObserver(callback) {
400
308
  if (typeof MutationObserver === "undefined") {
401
309
  return;
@@ -405,11 +313,8 @@
405
313
  function isInArray(value, array) {
406
314
  return value === array || (isArray(array) && array.includes(value));
407
315
  }
408
- function arrayRandomIndex(array) {
409
- return Math.floor(getRandom() * array.length);
410
- }
411
316
  function itemFromArray(array, index, useIndex = true) {
412
- return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
317
+ return array[index !== undefined && useIndex ? index % array.length : Math.floor(getRandom() * array.length)];
413
318
  }
414
319
  function isPointInside(point, size, offset, radius, direction) {
415
320
  return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
@@ -493,56 +398,6 @@
493
398
  function itemFromSingleOrMultiple(obj, index, useIndex) {
494
399
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
495
400
  }
496
- function initParticleNumericAnimationValue(options, pxRatio) {
497
- const valueRange = options.value, animationOptions = options.animation, res = {
498
- delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
499
- enable: animationOptions.enable,
500
- value: getRangeValue(options.value) * pxRatio,
501
- max: getRangeMax(valueRange) * pxRatio,
502
- min: getRangeMin(valueRange) * pxRatio,
503
- loops: 0,
504
- maxLoops: getRangeValue(animationOptions.count),
505
- time: 0,
506
- }, decayOffset = 1;
507
- if (animationOptions.enable) {
508
- res.decay = decayOffset - getRangeValue(animationOptions.decay);
509
- switch (animationOptions.mode) {
510
- case AnimationMode.increase:
511
- res.status = AnimationStatus.increasing;
512
- break;
513
- case AnimationMode.decrease:
514
- res.status = AnimationStatus.decreasing;
515
- break;
516
- case AnimationMode.random:
517
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
518
- break;
519
- }
520
- const autoStatus = animationOptions.mode === AnimationMode.auto;
521
- switch (animationOptions.startValue) {
522
- case StartValueType.min:
523
- res.value = res.min;
524
- if (autoStatus) {
525
- res.status = AnimationStatus.increasing;
526
- }
527
- break;
528
- case StartValueType.max:
529
- res.value = res.max;
530
- if (autoStatus) {
531
- res.status = AnimationStatus.decreasing;
532
- }
533
- break;
534
- case StartValueType.random:
535
- default:
536
- res.value = randomInRangeValue(res);
537
- if (autoStatus) {
538
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
539
- }
540
- break;
541
- }
542
- }
543
- res.initialValue = res.value;
544
- return res;
545
- }
546
401
  function getPositionOrSize(positionOrSize, canvasSize) {
547
402
  const isPercent = positionOrSize.mode === PixelMode.percent;
548
403
  if (!isPercent) {
@@ -566,71 +421,6 @@
566
421
  function getPosition(position, canvasSize) {
567
422
  return getPositionOrSize(position, canvasSize);
568
423
  }
569
- function checkDestroy(particle, destroyType, value, minValue, maxValue) {
570
- switch (destroyType) {
571
- case DestroyType.max:
572
- if (value >= maxValue) {
573
- particle.destroy();
574
- }
575
- break;
576
- case DestroyType.min:
577
- if (value <= minValue) {
578
- particle.destroy();
579
- }
580
- break;
581
- }
582
- }
583
- function updateAnimation(particle, data, changeDirection, destroyType, delta) {
584
- const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
585
- if (particle.destroyed ||
586
- !data.enable ||
587
- ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
588
- return;
589
- }
590
- const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
591
- data.time ??= 0;
592
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
593
- data.time += delta.value;
594
- }
595
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
596
- return;
597
- }
598
- switch (data.status) {
599
- case AnimationStatus.increasing:
600
- data.value += velocity;
601
- break;
602
- case AnimationStatus.decreasing:
603
- data.value -= velocity;
604
- break;
605
- }
606
- if (data.velocity && decay !== identity) {
607
- data.velocity *= decay;
608
- }
609
- switch (data.status) {
610
- case AnimationStatus.increasing:
611
- if (data.value >= maxValue) {
612
- {
613
- data.status = AnimationStatus.decreasing;
614
- }
615
- data.loops ??= minLoops;
616
- data.loops++;
617
- }
618
- break;
619
- case AnimationStatus.decreasing:
620
- if (data.value <= minValue) {
621
- {
622
- data.status = AnimationStatus.increasing;
623
- }
624
- data.loops ??= minLoops;
625
- data.loops++;
626
- }
627
- break;
628
- }
629
- checkDestroy(particle, destroyType, data.value, minValue, maxValue);
630
- if (!particle.destroyed) {
631
- data.value = clamp(data.value, minValue, maxValue);
632
- }
633
- }
634
424
  function cloneStyle(style) {
635
425
  const clonedStyle = safeDocument().createElement("div").style;
636
426
  for (const key in style) {
@@ -652,30 +442,34 @@
652
442
  }
653
443
  return clonedStyle;
654
444
  }
655
- function computeFullScreenStyle(zIndex) {
656
- const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
657
- width: "100%",
658
- height: "100%",
659
- margin: "0",
660
- padding: "0",
661
- borderWidth: "0",
662
- position: "fixed",
663
- zIndex: zIndex.toString(radix),
664
- "z-index": zIndex.toString(radix),
665
- top: "0",
666
- left: "0",
667
- "pointer-events": "none",
668
- };
669
- for (const key in style) {
670
- const value = style[key];
671
- if (value === undefined) {
672
- continue;
445
+ let _cachedZIndex, _cachedStyle;
446
+ function getFullScreenStyle(zIndex) {
447
+ if (_cachedZIndex !== zIndex || !_cachedStyle) {
448
+ _cachedZIndex = zIndex;
449
+ const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
450
+ width: "100%",
451
+ height: "100%",
452
+ margin: "0",
453
+ padding: "0",
454
+ borderWidth: "0",
455
+ position: "fixed",
456
+ zIndex: zIndex.toString(radix),
457
+ "z-index": zIndex.toString(radix),
458
+ top: "0",
459
+ left: "0",
460
+ "pointer-events": "none",
461
+ };
462
+ for (const key in style) {
463
+ const value = style[key];
464
+ if (value === undefined) {
465
+ continue;
466
+ }
467
+ fullScreenStyle.setProperty(key, value);
673
468
  }
674
- fullScreenStyle.setProperty(key, value);
469
+ _cachedStyle = fullScreenStyle;
675
470
  }
676
- return fullScreenStyle;
471
+ return _cachedStyle;
677
472
  }
678
- const getFullScreenStyle = memoize(computeFullScreenStyle);
679
473
  function manageListener(element, event, handler, add, options) {
680
474
  if (add) {
681
475
  let addOptions = { passive: true };
@@ -1002,7 +796,7 @@
1002
796
  return this.#domArray;
1003
797
  }
1004
798
  get version() {
1005
- return "4.1.3";
799
+ return "4.2.0";
1006
800
  }
1007
801
  addEventListener(type, listener) {
1008
802
  this.#eventDispatcher.addEventListener(type, listener);
@@ -1172,6 +966,14 @@
1172
966
  RotateDirection["random"] = "random";
1173
967
  })(RotateDirection || (RotateDirection = {}));
1174
968
 
969
+ var AnimationMode;
970
+ (function (AnimationMode) {
971
+ AnimationMode["auto"] = "auto";
972
+ AnimationMode["increase"] = "increase";
973
+ AnimationMode["decrease"] = "decrease";
974
+ AnimationMode["random"] = "random";
975
+ })(AnimationMode || (AnimationMode = {}));
976
+
1175
977
  var LimitMode;
1176
978
  (function (LimitMode) {
1177
979
  LimitMode["delete"] = "delete";
@@ -1193,6 +995,13 @@
1193
995
  AlterType["enlighten"] = "enlighten";
1194
996
  })(AlterType || (AlterType = {}));
1195
997
 
998
+ var DestroyType;
999
+ (function (DestroyType) {
1000
+ DestroyType["none"] = "none";
1001
+ DestroyType["max"] = "max";
1002
+ DestroyType["min"] = "min";
1003
+ })(DestroyType || (DestroyType = {}));
1004
+
1196
1005
  var GradientType;
1197
1006
  (function (GradientType) {
1198
1007
  GradientType["linear"] = "linear";
@@ -1207,160 +1016,121 @@
1207
1016
  ParticleOutType["outside"] = "outside";
1208
1017
  })(ParticleOutType || (ParticleOutType = {}));
1209
1018
 
1210
- var EasingType;
1211
- (function (EasingType) {
1212
- EasingType["easeInBack"] = "ease-in-back";
1213
- EasingType["easeInBounce"] = "ease-in-bounce";
1214
- EasingType["easeInCirc"] = "ease-in-circ";
1215
- EasingType["easeInCubic"] = "ease-in-cubic";
1216
- EasingType["easeInElastic"] = "ease-in-elastic";
1217
- EasingType["easeInExpo"] = "ease-in-expo";
1218
- EasingType["easeInGaussian"] = "ease-in-gaussian";
1219
- EasingType["easeInLinear"] = "ease-in-linear";
1220
- EasingType["easeInQuad"] = "ease-in-quad";
1221
- EasingType["easeInQuart"] = "ease-in-quart";
1222
- EasingType["easeInQuint"] = "ease-in-quint";
1223
- EasingType["easeInSigmoid"] = "ease-in-sigmoid";
1224
- EasingType["easeInSine"] = "ease-in-sine";
1225
- EasingType["easeInSmoothstep"] = "ease-in-smoothstep";
1226
- EasingType["easeOutBack"] = "ease-out-back";
1227
- EasingType["easeOutBounce"] = "ease-out-bounce";
1228
- EasingType["easeOutCirc"] = "ease-out-circ";
1229
- EasingType["easeOutCubic"] = "ease-out-cubic";
1230
- EasingType["easeOutElastic"] = "ease-out-elastic";
1231
- EasingType["easeOutExpo"] = "ease-out-expo";
1232
- EasingType["easeOutGaussian"] = "ease-out-gaussian";
1233
- EasingType["easeOutLinear"] = "ease-out-linear";
1234
- EasingType["easeOutQuad"] = "ease-out-quad";
1235
- EasingType["easeOutQuart"] = "ease-out-quart";
1236
- EasingType["easeOutQuint"] = "ease-out-quint";
1237
- EasingType["easeOutSigmoid"] = "ease-out-sigmoid";
1238
- EasingType["easeOutSine"] = "ease-out-sine";
1239
- EasingType["easeOutSmoothstep"] = "ease-out-smoothstep";
1240
- EasingType["easeInOutBack"] = "ease-in-out-back";
1241
- EasingType["easeInOutBounce"] = "ease-in-out-bounce";
1242
- EasingType["easeInOutCirc"] = "ease-in-out-circ";
1243
- EasingType["easeInOutCubic"] = "ease-in-out-cubic";
1244
- EasingType["easeInOutElastic"] = "ease-in-out-elastic";
1245
- EasingType["easeInOutExpo"] = "ease-in-out-expo";
1246
- EasingType["easeInOutGaussian"] = "ease-in-out-gaussian";
1247
- EasingType["easeInOutLinear"] = "ease-in-out-linear";
1248
- EasingType["easeInOutQuad"] = "ease-in-out-quad";
1249
- EasingType["easeInOutQuart"] = "ease-in-out-quart";
1250
- EasingType["easeInOutQuint"] = "ease-in-out-quint";
1251
- EasingType["easeInOutSigmoid"] = "ease-in-out-sigmoid";
1252
- EasingType["easeInOutSine"] = "ease-in-out-sine";
1253
- EasingType["easeInOutSmoothstep"] = "ease-in-out-smoothstep";
1254
- })(EasingType || (EasingType = {}));
1255
-
1256
- class AnimationOptions {
1257
- count;
1258
- decay;
1259
- delay;
1260
- enable;
1261
- speed;
1262
- sync;
1263
- constructor() {
1264
- this.count = 0;
1265
- this.enable = false;
1266
- this.speed = 1;
1267
- this.decay = 0;
1268
- this.delay = 0;
1269
- this.sync = false;
1270
- }
1019
+ var StartValueType;
1020
+ (function (StartValueType) {
1021
+ StartValueType["max"] = "max";
1022
+ StartValueType["min"] = "min";
1023
+ StartValueType["random"] = "random";
1024
+ })(StartValueType || (StartValueType = {}));
1025
+
1026
+ var AnimationStatus;
1027
+ (function (AnimationStatus) {
1028
+ AnimationStatus["increasing"] = "increasing";
1029
+ AnimationStatus["decreasing"] = "decreasing";
1030
+ })(AnimationStatus || (AnimationStatus = {}));
1031
+
1032
+ class OptionLoader {
1271
1033
  load(data) {
1272
1034
  if (isNull(data)) {
1273
1035
  return;
1274
1036
  }
1275
- if (data.count !== undefined) {
1276
- this.count = setRangeValue(data.count);
1277
- }
1278
- if (data.enable !== undefined) {
1279
- this.enable = data.enable;
1280
- }
1281
- if (data.speed !== undefined) {
1282
- this.speed = setRangeValue(data.speed);
1283
- }
1284
- if (data.decay !== undefined) {
1285
- this.decay = setRangeValue(data.decay);
1286
- }
1287
- if (data.delay !== undefined) {
1288
- this.delay = setRangeValue(data.delay);
1289
- }
1290
- if (data.sync !== undefined) {
1291
- this.sync = data.sync;
1292
- }
1037
+ this.doLoad(data);
1293
1038
  }
1294
1039
  }
1295
- class RangedAnimationOptions extends AnimationOptions {
1296
- mode;
1297
- startValue;
1298
- constructor() {
1299
- super();
1300
- this.mode = AnimationMode.auto;
1301
- this.startValue = StartValueType.random;
1040
+ function loadOptions(options, ...sourceOptionsArr) {
1041
+ for (const sourceOptions of sourceOptionsArr) {
1042
+ options.load(sourceOptions);
1302
1043
  }
1303
- load(data) {
1304
- super.load(data);
1305
- if (isNull(data)) {
1306
- return;
1307
- }
1308
- if (data.mode !== undefined) {
1309
- this.mode = data.mode;
1310
- }
1311
- if (data.startValue !== undefined) {
1312
- this.startValue = data.startValue;
1313
- }
1044
+ }
1045
+
1046
+ function loadProperty(obj, key, value) {
1047
+ if (value !== undefined) {
1048
+ obj[key] = value;
1049
+ }
1050
+ }
1051
+ function loadRangeProperty(obj, key, value) {
1052
+ if (value !== undefined) {
1053
+ obj[key] = setRangeValue(value);
1054
+ }
1055
+ }
1056
+ function loadNestedProperty(obj, key, value) {
1057
+ if (value !== undefined) {
1058
+ obj[key].load(value);
1059
+ }
1060
+ }
1061
+ function loadLazyProperty(obj, key, value, factory) {
1062
+ if (value !== undefined) {
1063
+ const objRecord = obj;
1064
+ objRecord[key] ??= factory();
1065
+ objRecord[key].load(value);
1066
+ }
1067
+ }
1068
+ function loadOptionProperty(obj, key, optionClass, ...sources) {
1069
+ const objRecord = obj;
1070
+ objRecord[key] ??= new optionClass();
1071
+ const target = objRecord[key];
1072
+ for (const source of sources) {
1073
+ target.load(source?.[key]);
1074
+ }
1075
+ }
1076
+
1077
+ class AnimationOptions extends OptionLoader {
1078
+ count = 0;
1079
+ decay = 0;
1080
+ delay = 0;
1081
+ enable = false;
1082
+ speed = 1;
1083
+ sync = false;
1084
+ doLoad(data) {
1085
+ loadRangeProperty(this, "count", data.count);
1086
+ loadProperty(this, "enable", data.enable);
1087
+ loadRangeProperty(this, "speed", data.speed);
1088
+ loadRangeProperty(this, "decay", data.decay);
1089
+ loadRangeProperty(this, "delay", data.delay);
1090
+ loadProperty(this, "sync", data.sync);
1091
+ }
1092
+ }
1093
+ class RangedAnimationOptions extends AnimationOptions {
1094
+ mode = AnimationMode.auto;
1095
+ startValue = StartValueType.random;
1096
+ doLoad(data) {
1097
+ super.doLoad(data);
1098
+ loadProperty(this, "mode", data.mode);
1099
+ loadProperty(this, "startValue", data.startValue);
1314
1100
  }
1315
1101
  }
1316
1102
 
1317
1103
  class ColorAnimation extends AnimationOptions {
1318
1104
  max;
1319
1105
  min;
1320
- offset;
1106
+ offset = 0;
1107
+ sync = true;
1321
1108
  constructor(min, max) {
1322
1109
  super();
1323
1110
  this.min = min;
1324
1111
  this.max = max;
1325
- this.offset = 0;
1326
- this.sync = true;
1327
1112
  }
1328
- load(data) {
1329
- super.load(data);
1330
- if (isNull(data)) {
1331
- return;
1332
- }
1333
- if (data.max !== undefined) {
1334
- this.max = data.max;
1335
- }
1336
- if (data.min !== undefined) {
1337
- this.min = data.min;
1338
- }
1339
- if (data.offset !== undefined) {
1340
- this.offset = setRangeValue(data.offset);
1341
- }
1113
+ doLoad(data) {
1114
+ super.doLoad(data);
1115
+ loadProperty(this, "max", data.max);
1116
+ loadProperty(this, "min", data.min);
1117
+ loadRangeProperty(this, "offset", data.offset);
1342
1118
  }
1343
1119
  }
1344
1120
 
1345
- class HslAnimation {
1121
+ class HslAnimation extends OptionLoader {
1346
1122
  h = new ColorAnimation(hMin, hMax);
1347
1123
  l = new ColorAnimation(lMin, lMax);
1348
1124
  s = new ColorAnimation(sMin, sMax);
1349
- load(data) {
1350
- if (isNull(data)) {
1351
- return;
1352
- }
1125
+ doLoad(data) {
1353
1126
  this.h.load(data.h);
1354
1127
  this.s.load(data.s);
1355
1128
  this.l.load(data.l);
1356
1129
  }
1357
1130
  }
1358
1131
 
1359
- class OptionsColor {
1360
- value;
1361
- constructor() {
1362
- this.value = "";
1363
- }
1132
+ class OptionsColor extends OptionLoader {
1133
+ value = "";
1364
1134
  static create(source, data) {
1365
1135
  const color = new OptionsColor();
1366
1136
  color.load(source);
@@ -1374,10 +1144,7 @@
1374
1144
  }
1375
1145
  return color;
1376
1146
  }
1377
- load(data) {
1378
- if (isNull(data)) {
1379
- return;
1380
- }
1147
+ doLoad(data) {
1381
1148
  if (!isNull(data.value)) {
1382
1149
  this.value = data.value;
1383
1150
  }
@@ -1385,11 +1152,7 @@
1385
1152
  }
1386
1153
 
1387
1154
  class AnimatableColor extends OptionsColor {
1388
- animation;
1389
- constructor() {
1390
- super();
1391
- this.animation = new HslAnimation();
1392
- }
1155
+ animation = new HslAnimation();
1393
1156
  static create(source, data) {
1394
1157
  const color = new AnimatableColor();
1395
1158
  color.load(source);
@@ -1403,11 +1166,8 @@
1403
1166
  }
1404
1167
  return color;
1405
1168
  }
1406
- load(data) {
1407
- super.load(data);
1408
- if (isNull(data)) {
1409
- return;
1410
- }
1169
+ doLoad(data) {
1170
+ super.doLoad(data);
1411
1171
  const colorAnimation = data.animation;
1412
1172
  if (colorAnimation !== undefined) {
1413
1173
  if (colorAnimation.enable === undefined) {
@@ -1420,100 +1180,53 @@
1420
1180
  }
1421
1181
  }
1422
1182
 
1423
- class Background {
1183
+ class Background extends OptionLoader {
1424
1184
  color;
1425
- image;
1426
- opacity;
1427
- position;
1428
- repeat;
1429
- size;
1185
+ image = "";
1186
+ opacity = 1;
1187
+ position = "";
1188
+ repeat = "";
1189
+ size = "";
1430
1190
  constructor() {
1191
+ super();
1431
1192
  this.color = new OptionsColor();
1432
1193
  this.color.value = "";
1433
- this.image = "";
1434
- this.position = "";
1435
- this.repeat = "";
1436
- this.size = "";
1437
- this.opacity = 1;
1438
1194
  }
1439
- load(data) {
1440
- if (isNull(data)) {
1441
- return;
1442
- }
1195
+ doLoad(data) {
1443
1196
  if (data.color !== undefined) {
1444
1197
  this.color = OptionsColor.create(this.color, data.color);
1445
1198
  }
1446
- if (data.image !== undefined) {
1447
- this.image = data.image;
1448
- }
1449
- if (data.position !== undefined) {
1450
- this.position = data.position;
1451
- }
1452
- if (data.repeat !== undefined) {
1453
- this.repeat = data.repeat;
1454
- }
1455
- if (data.size !== undefined) {
1456
- this.size = data.size;
1457
- }
1458
- if (data.opacity !== undefined) {
1459
- this.opacity = data.opacity;
1460
- }
1199
+ loadProperty(this, "image", data.image);
1200
+ loadProperty(this, "position", data.position);
1201
+ loadProperty(this, "repeat", data.repeat);
1202
+ loadProperty(this, "size", data.size);
1203
+ loadProperty(this, "opacity", data.opacity);
1461
1204
  }
1462
1205
  }
1463
1206
 
1464
- class FullScreen {
1465
- enable;
1466
- zIndex;
1467
- constructor() {
1468
- this.enable = true;
1469
- this.zIndex = 0;
1470
- }
1471
- load(data) {
1472
- if (isNull(data)) {
1473
- return;
1474
- }
1475
- if (data.enable !== undefined) {
1476
- this.enable = data.enable;
1477
- }
1478
- if (data.zIndex !== undefined) {
1479
- this.zIndex = data.zIndex;
1480
- }
1207
+ class FullScreen extends OptionLoader {
1208
+ enable = true;
1209
+ zIndex = 0;
1210
+ doLoad(data) {
1211
+ loadProperty(this, "enable", data.enable);
1212
+ loadProperty(this, "zIndex", data.zIndex);
1481
1213
  }
1482
1214
  }
1483
1215
 
1484
- class ResizeEvent {
1485
- delay;
1486
- enable;
1487
- constructor() {
1488
- this.delay = 0.5;
1489
- this.enable = true;
1490
- }
1491
- load(data) {
1492
- if (isNull(data)) {
1493
- return;
1494
- }
1495
- if (data.delay !== undefined) {
1496
- this.delay = data.delay;
1497
- }
1498
- if (data.enable !== undefined) {
1499
- this.enable = data.enable;
1500
- }
1216
+ class ResizeEvent extends OptionLoader {
1217
+ delay = 0.5;
1218
+ enable = true;
1219
+ doLoad(data) {
1220
+ loadProperty(this, "delay", data.delay);
1221
+ loadProperty(this, "enable", data.enable);
1501
1222
  }
1502
1223
  }
1503
1224
 
1504
- class Effect {
1505
- close;
1506
- options;
1507
- type;
1508
- constructor() {
1509
- this.close = true;
1510
- this.options = {};
1511
- this.type = [];
1512
- }
1513
- load(data) {
1514
- if (isNull(data)) {
1515
- return;
1516
- }
1225
+ class Effect extends OptionLoader {
1226
+ close = true;
1227
+ options = {};
1228
+ type = [];
1229
+ doLoad(data) {
1517
1230
  const options = data.options;
1518
1231
  if (options !== undefined) {
1519
1232
  for (const effect in options) {
@@ -1523,128 +1236,62 @@
1523
1236
  }
1524
1237
  }
1525
1238
  }
1526
- if (data.close !== undefined) {
1527
- this.close = data.close;
1528
- }
1529
- if (data.type !== undefined) {
1530
- this.type = data.type;
1531
- }
1239
+ loadProperty(this, "close", data.close);
1240
+ loadProperty(this, "type", data.type);
1532
1241
  }
1533
1242
  }
1534
1243
 
1535
- class Fill {
1244
+ class Fill extends OptionLoader {
1536
1245
  color;
1537
- enable;
1538
- opacity;
1539
- constructor() {
1540
- this.enable = true;
1541
- this.opacity = 1;
1542
- }
1543
- load(data) {
1544
- if (isNull(data)) {
1545
- return;
1546
- }
1246
+ enable = true;
1247
+ opacity = 1;
1248
+ doLoad(data) {
1547
1249
  if (data.color !== undefined) {
1548
1250
  this.color = AnimatableColor.create(this.color, data.color);
1549
1251
  }
1550
- if (data.enable !== undefined) {
1551
- this.enable = data.enable;
1552
- }
1553
- if (data.opacity !== undefined) {
1554
- this.opacity = setRangeValue(data.opacity);
1555
- }
1252
+ loadProperty(this, "enable", data.enable);
1253
+ loadRangeProperty(this, "opacity", data.opacity);
1556
1254
  }
1557
1255
  }
1558
1256
 
1559
- class MoveAngle {
1560
- offset;
1561
- value;
1562
- constructor() {
1563
- this.offset = 0;
1564
- this.value = 90;
1565
- }
1566
- load(data) {
1567
- if (isNull(data)) {
1568
- return;
1569
- }
1570
- if (data.offset !== undefined) {
1571
- this.offset = setRangeValue(data.offset);
1572
- }
1573
- if (data.value !== undefined) {
1574
- this.value = setRangeValue(data.value);
1575
- }
1257
+ class MoveAngle extends OptionLoader {
1258
+ offset = 0;
1259
+ value = 90;
1260
+ doLoad(data) {
1261
+ loadRangeProperty(this, "offset", data.offset);
1262
+ loadRangeProperty(this, "value", data.value);
1576
1263
  }
1577
1264
  }
1578
1265
 
1579
- class MoveCenter {
1580
- mode;
1581
- radius;
1582
- x;
1583
- y;
1584
- constructor() {
1585
- this.x = 50;
1586
- this.y = 50;
1587
- this.mode = PixelMode.percent;
1588
- this.radius = 0;
1589
- }
1590
- load(data) {
1591
- if (isNull(data)) {
1592
- return;
1593
- }
1594
- if (data.x !== undefined) {
1595
- this.x = data.x;
1596
- }
1597
- if (data.y !== undefined) {
1598
- this.y = data.y;
1599
- }
1600
- if (data.mode !== undefined) {
1601
- this.mode = data.mode;
1602
- }
1603
- if (data.radius !== undefined) {
1604
- this.radius = data.radius;
1605
- }
1266
+ class MoveCenter extends OptionLoader {
1267
+ mode = PixelMode.percent;
1268
+ radius = 0;
1269
+ x = 50;
1270
+ y = 50;
1271
+ doLoad(data) {
1272
+ loadProperty(this, "x", data.x);
1273
+ loadProperty(this, "y", data.y);
1274
+ loadProperty(this, "mode", data.mode);
1275
+ loadProperty(this, "radius", data.radius);
1606
1276
  }
1607
1277
  }
1608
1278
 
1609
- class MoveGravity {
1610
- acceleration;
1611
- enable;
1612
- inverse;
1613
- maxSpeed;
1614
- constructor() {
1615
- this.acceleration = 9.81;
1616
- this.enable = false;
1617
- this.inverse = false;
1618
- this.maxSpeed = 50;
1619
- }
1620
- load(data) {
1621
- if (isNull(data)) {
1622
- return;
1623
- }
1624
- if (data.acceleration !== undefined) {
1625
- this.acceleration = setRangeValue(data.acceleration);
1626
- }
1627
- if (data.enable !== undefined) {
1628
- this.enable = data.enable;
1629
- }
1630
- if (data.inverse !== undefined) {
1631
- this.inverse = data.inverse;
1632
- }
1633
- if (data.maxSpeed !== undefined) {
1634
- this.maxSpeed = setRangeValue(data.maxSpeed);
1635
- }
1279
+ class MoveGravity extends OptionLoader {
1280
+ acceleration = 9.81;
1281
+ enable = false;
1282
+ inverse = false;
1283
+ maxSpeed = 50;
1284
+ doLoad(data) {
1285
+ loadRangeProperty(this, "acceleration", data.acceleration);
1286
+ loadProperty(this, "enable", data.enable);
1287
+ loadProperty(this, "inverse", data.inverse);
1288
+ loadRangeProperty(this, "maxSpeed", data.maxSpeed);
1636
1289
  }
1637
1290
  }
1638
1291
 
1639
- class ValueWithRandom {
1640
- value;
1641
- constructor() {
1642
- this.value = 0;
1643
- }
1644
- load(data) {
1645
- if (isNull(data)) {
1646
- return;
1647
- }
1292
+ class ValueWithRandom extends OptionLoader {
1293
+ value = 0;
1294
+ doLoad(data) {
1648
1295
  if (!isNull(data.value)) {
1649
1296
  this.value = setRangeValue(data.value);
1650
1297
  }
@@ -1652,51 +1299,25 @@
1652
1299
  }
1653
1300
  class AnimationValueWithRandom extends ValueWithRandom {
1654
1301
  animation = new AnimationOptions();
1655
- load(data) {
1656
- super.load(data);
1657
- if (isNull(data)) {
1658
- return;
1659
- }
1660
- const animation = data.animation;
1661
- if (animation !== undefined) {
1662
- this.animation.load(animation);
1663
- }
1302
+ doLoad(data) {
1303
+ super.doLoad(data);
1304
+ loadNestedProperty(this, "animation", data.animation);
1664
1305
  }
1665
1306
  }
1666
1307
  class RangedAnimationValueWithRandom extends AnimationValueWithRandom {
1667
- animation;
1668
- constructor() {
1669
- super();
1670
- this.animation = new RangedAnimationOptions();
1671
- }
1672
- load(data) {
1673
- super.load(data);
1674
- }
1308
+ animation = new RangedAnimationOptions();
1675
1309
  }
1676
1310
 
1677
- class MovePath {
1678
- clamp;
1679
- delay;
1680
- enable;
1311
+ class MovePath extends OptionLoader {
1312
+ clamp = true;
1313
+ delay = new ValueWithRandom();
1314
+ enable = false;
1681
1315
  generator;
1682
- options;
1683
- constructor() {
1684
- this.clamp = true;
1685
- this.delay = new ValueWithRandom();
1686
- this.enable = false;
1687
- this.options = {};
1688
- }
1689
- load(data) {
1690
- if (isNull(data)) {
1691
- return;
1692
- }
1693
- if (data.clamp !== undefined) {
1694
- this.clamp = data.clamp;
1695
- }
1316
+ options = {};
1317
+ doLoad(data) {
1318
+ loadProperty(this, "clamp", data.clamp);
1696
1319
  this.delay.load(data.delay);
1697
- if (data.enable !== undefined) {
1698
- this.enable = data.enable;
1699
- }
1320
+ loadProperty(this, "enable", data.enable);
1700
1321
  this.generator = data.generator;
1701
1322
  if (data.options) {
1702
1323
  this.options = deepExtend(this.options, data.options);
@@ -1704,19 +1325,13 @@
1704
1325
  }
1705
1326
  }
1706
1327
 
1707
- class OutModes {
1328
+ class OutModes extends OptionLoader {
1708
1329
  bottom;
1709
- default;
1330
+ default = OutMode.out;
1710
1331
  left;
1711
1332
  right;
1712
1333
  top;
1713
- constructor() {
1714
- this.default = OutMode.out;
1715
- }
1716
- load(data) {
1717
- if (isNull(data)) {
1718
- return;
1719
- }
1334
+ doLoad(data) {
1720
1335
  if (data.default !== undefined) {
1721
1336
  this.default = data.default;
1722
1337
  }
@@ -1727,79 +1342,42 @@
1727
1342
  }
1728
1343
  }
1729
1344
 
1730
- class Spin {
1731
- acceleration;
1732
- enable;
1345
+ class Spin extends OptionLoader {
1346
+ acceleration = 0;
1347
+ enable = false;
1733
1348
  position;
1734
- constructor() {
1735
- this.acceleration = 0;
1736
- this.enable = false;
1737
- }
1738
- load(data) {
1739
- if (isNull(data)) {
1740
- return;
1741
- }
1742
- if (data.acceleration !== undefined) {
1743
- this.acceleration = setRangeValue(data.acceleration);
1744
- }
1745
- if (data.enable !== undefined) {
1746
- this.enable = data.enable;
1747
- }
1349
+ doLoad(data) {
1350
+ loadRangeProperty(this, "acceleration", data.acceleration);
1351
+ loadProperty(this, "enable", data.enable);
1748
1352
  if (data.position) {
1749
1353
  this.position = deepExtend({}, data.position);
1750
1354
  }
1751
1355
  }
1752
1356
  }
1753
1357
 
1754
- class Move {
1755
- angle;
1756
- center;
1757
- decay;
1758
- direction;
1759
- distance;
1760
- drift;
1761
- enable;
1762
- gravity;
1763
- outModes;
1764
- path;
1765
- random;
1766
- size;
1767
- speed;
1768
- spin;
1769
- straight;
1770
- vibrate;
1771
- warp;
1772
- constructor() {
1773
- this.angle = new MoveAngle();
1774
- this.center = new MoveCenter();
1775
- this.decay = 0;
1776
- this.distance = {};
1777
- this.direction = MoveDirection.none;
1778
- this.drift = 0;
1779
- this.enable = false;
1780
- this.gravity = new MoveGravity();
1781
- this.path = new MovePath();
1782
- this.outModes = new OutModes();
1783
- this.random = false;
1784
- this.size = false;
1785
- this.speed = 2;
1786
- this.spin = new Spin();
1787
- this.straight = false;
1788
- this.vibrate = false;
1789
- this.warp = false;
1790
- }
1791
- load(data) {
1792
- if (isNull(data)) {
1793
- return;
1794
- }
1358
+ class Move extends OptionLoader {
1359
+ angle = new MoveAngle();
1360
+ center = new MoveCenter();
1361
+ decay = 0;
1362
+ direction = MoveDirection.none;
1363
+ distance = {};
1364
+ drift = 0;
1365
+ enable = false;
1366
+ gravity = new MoveGravity();
1367
+ outModes = new OutModes();
1368
+ path = new MovePath();
1369
+ random = false;
1370
+ size = false;
1371
+ speed = 2;
1372
+ spin = new Spin();
1373
+ straight = false;
1374
+ vibrate = false;
1375
+ warp = false;
1376
+ doLoad(data) {
1795
1377
  this.angle.load(isNumber(data.angle) ? { value: data.angle } : data.angle);
1796
1378
  this.center.load(data.center);
1797
- if (data.decay !== undefined) {
1798
- this.decay = setRangeValue(data.decay);
1799
- }
1800
- if (data.direction !== undefined) {
1801
- this.direction = data.direction;
1802
- }
1379
+ loadRangeProperty(this, "decay", data.decay);
1380
+ loadProperty(this, "direction", data.direction);
1803
1381
  if (data.distance !== undefined) {
1804
1382
  this.distance = isNumber(data.distance)
1805
1383
  ? {
@@ -1808,12 +1386,8 @@
1808
1386
  }
1809
1387
  : { ...data.distance };
1810
1388
  }
1811
- if (data.drift !== undefined) {
1812
- this.drift = setRangeValue(data.drift);
1813
- }
1814
- if (data.enable !== undefined) {
1815
- this.enable = data.enable;
1816
- }
1389
+ loadRangeProperty(this, "drift", data.drift);
1390
+ loadProperty(this, "enable", data.enable);
1817
1391
  this.gravity.load(data.gravity);
1818
1392
  const outModes = data.outModes;
1819
1393
  if (outModes !== undefined) {
@@ -1827,177 +1401,91 @@
1827
1401
  }
1828
1402
  }
1829
1403
  this.path.load(data.path);
1830
- if (data.random !== undefined) {
1831
- this.random = data.random;
1832
- }
1833
- if (data.size !== undefined) {
1834
- this.size = data.size;
1835
- }
1836
- if (data.speed !== undefined) {
1837
- this.speed = setRangeValue(data.speed);
1838
- }
1404
+ loadProperty(this, "random", data.random);
1405
+ loadProperty(this, "size", data.size);
1406
+ loadRangeProperty(this, "speed", data.speed);
1839
1407
  this.spin.load(data.spin);
1840
- if (data.straight !== undefined) {
1841
- this.straight = data.straight;
1842
- }
1843
- if (data.vibrate !== undefined) {
1844
- this.vibrate = data.vibrate;
1845
- }
1846
- if (data.warp !== undefined) {
1847
- this.warp = data.warp;
1848
- }
1408
+ loadProperty(this, "straight", data.straight);
1409
+ loadProperty(this, "vibrate", data.vibrate);
1410
+ loadProperty(this, "warp", data.warp);
1849
1411
  }
1850
1412
  }
1851
1413
 
1852
- class Stroke {
1414
+ class Stroke extends OptionLoader {
1853
1415
  color;
1854
1416
  opacity;
1855
- width;
1856
- constructor() {
1857
- this.width = 0;
1858
- }
1859
- load(data) {
1860
- if (isNull(data)) {
1861
- return;
1862
- }
1417
+ width = 0;
1418
+ doLoad(data) {
1863
1419
  if (data.color !== undefined) {
1864
1420
  this.color = AnimatableColor.create(this.color, data.color);
1865
1421
  }
1866
- if (data.width !== undefined) {
1867
- this.width = setRangeValue(data.width);
1868
- }
1869
- if (data.opacity !== undefined) {
1870
- this.opacity = setRangeValue(data.opacity);
1871
- }
1422
+ loadRangeProperty(this, "width", data.width);
1423
+ loadRangeProperty(this, "opacity", data.opacity);
1872
1424
  }
1873
1425
  }
1874
1426
 
1875
- class Paint {
1427
+ class Paint extends OptionLoader {
1876
1428
  color;
1877
1429
  fill;
1878
1430
  stroke;
1879
- load(data) {
1880
- if (isNull(data)) {
1881
- return;
1882
- }
1431
+ doLoad(data) {
1883
1432
  if (data.color !== undefined) {
1884
1433
  this.color = AnimatableColor.create(this.color, data.color);
1885
1434
  }
1886
- if (data.fill !== undefined) {
1887
- this.fill ??= new Fill();
1888
- this.fill.load(data.fill);
1889
- }
1890
- if (data.stroke !== undefined) {
1891
- this.stroke ??= new Stroke();
1892
- this.stroke.load(data.stroke);
1893
- }
1435
+ loadLazyProperty(this, "fill", data.fill, () => new Fill());
1436
+ loadLazyProperty(this, "stroke", data.stroke, () => new Stroke());
1894
1437
  }
1895
1438
  }
1896
1439
 
1897
1440
  class ParticlesBounceFactor extends ValueWithRandom {
1898
- constructor() {
1899
- super();
1900
- this.value = 1;
1901
- }
1441
+ value = 1;
1902
1442
  }
1903
1443
 
1904
- class ParticlesBounce {
1905
- horizontal;
1906
- vertical;
1907
- constructor() {
1908
- this.horizontal = new ParticlesBounceFactor();
1909
- this.vertical = new ParticlesBounceFactor();
1910
- }
1911
- load(data) {
1912
- if (isNull(data)) {
1913
- return;
1914
- }
1444
+ class ParticlesBounce extends OptionLoader {
1445
+ horizontal = new ParticlesBounceFactor();
1446
+ vertical = new ParticlesBounceFactor();
1447
+ doLoad(data) {
1915
1448
  this.horizontal.load(data.horizontal);
1916
1449
  this.vertical.load(data.vertical);
1917
1450
  }
1918
1451
  }
1919
1452
 
1920
- class ParticlesDensity {
1921
- enable;
1922
- height;
1923
- width;
1924
- constructor() {
1925
- this.enable = false;
1926
- this.width = 1920;
1927
- this.height = 1080;
1928
- }
1929
- load(data) {
1930
- if (isNull(data)) {
1931
- return;
1932
- }
1933
- if (data.enable !== undefined) {
1934
- this.enable = data.enable;
1935
- }
1936
- const width = data.width;
1937
- if (width !== undefined) {
1938
- this.width = width;
1939
- }
1940
- const height = data.height;
1941
- if (height !== undefined) {
1942
- this.height = height;
1943
- }
1453
+ class ParticlesDensity extends OptionLoader {
1454
+ enable = false;
1455
+ height = 1080;
1456
+ width = 1920;
1457
+ doLoad(data) {
1458
+ loadProperty(this, "enable", data.enable);
1459
+ loadProperty(this, "width", data.width);
1460
+ loadProperty(this, "height", data.height);
1944
1461
  }
1945
1462
  }
1946
1463
 
1947
- class ParticlesNumberLimit {
1948
- mode;
1949
- value;
1950
- constructor() {
1951
- this.mode = LimitMode.delete;
1952
- this.value = 0;
1953
- }
1954
- load(data) {
1955
- if (isNull(data)) {
1956
- return;
1957
- }
1958
- if (data.mode !== undefined) {
1959
- this.mode = data.mode;
1960
- }
1961
- if (data.value !== undefined) {
1962
- this.value = data.value;
1963
- }
1464
+ class ParticlesNumberLimit extends OptionLoader {
1465
+ mode = LimitMode.delete;
1466
+ value = 0;
1467
+ doLoad(data) {
1468
+ loadProperty(this, "mode", data.mode);
1469
+ loadProperty(this, "value", data.value);
1964
1470
  }
1965
1471
  }
1966
1472
 
1967
- class ParticlesNumber {
1968
- density;
1969
- limit;
1970
- value;
1971
- constructor() {
1972
- this.density = new ParticlesDensity();
1973
- this.limit = new ParticlesNumberLimit();
1974
- this.value = 0;
1975
- }
1976
- load(data) {
1977
- if (isNull(data)) {
1978
- return;
1979
- }
1473
+ class ParticlesNumber extends OptionLoader {
1474
+ density = new ParticlesDensity();
1475
+ limit = new ParticlesNumberLimit();
1476
+ value = 0;
1477
+ doLoad(data) {
1980
1478
  this.density.load(data.density);
1981
1479
  this.limit.load(data.limit);
1982
- if (data.value !== undefined) {
1983
- this.value = data.value;
1984
- }
1985
- }
1986
- }
1987
-
1988
- class Shape {
1989
- close;
1990
- options;
1991
- type;
1992
- constructor() {
1993
- this.close = true;
1994
- this.options = {};
1995
- this.type = "circle";
1480
+ loadProperty(this, "value", data.value);
1996
1481
  }
1997
- load(data) {
1998
- if (isNull(data)) {
1999
- return;
2000
- }
1482
+ }
1483
+
1484
+ class Shape extends OptionLoader {
1485
+ close = true;
1486
+ options = {};
1487
+ type = "circle";
1488
+ doLoad(data) {
2001
1489
  const options = data.options;
2002
1490
  if (options !== undefined) {
2003
1491
  for (const shape in options) {
@@ -2007,76 +1495,47 @@
2007
1495
  }
2008
1496
  }
2009
1497
  }
2010
- if (data.close !== undefined) {
2011
- this.close = data.close;
2012
- }
2013
- if (data.type !== undefined) {
2014
- this.type = data.type;
2015
- }
1498
+ loadProperty(this, "close", data.close);
1499
+ loadProperty(this, "type", data.type);
2016
1500
  }
2017
1501
  }
2018
1502
 
2019
1503
  class ZIndex extends ValueWithRandom {
2020
- opacityRate;
2021
- sizeRate;
2022
- velocityRate;
2023
- constructor() {
2024
- super();
2025
- this.opacityRate = 1;
2026
- this.sizeRate = 1;
2027
- this.velocityRate = 1;
2028
- }
2029
- load(data) {
2030
- super.load(data);
2031
- if (isNull(data)) {
2032
- return;
2033
- }
2034
- if (data.opacityRate !== undefined) {
2035
- this.opacityRate = data.opacityRate;
2036
- }
2037
- if (data.sizeRate !== undefined) {
2038
- this.sizeRate = data.sizeRate;
2039
- }
2040
- if (data.velocityRate !== undefined) {
2041
- this.velocityRate = data.velocityRate;
2042
- }
2043
- }
2044
- }
2045
-
2046
- class ParticlesOptions {
2047
- bounce;
2048
- effect;
2049
- groups;
2050
- move;
2051
- number;
1504
+ opacityRate = 1;
1505
+ sizeRate = 1;
1506
+ velocityRate = 1;
1507
+ doLoad(data) {
1508
+ super.doLoad(data);
1509
+ loadProperty(this, "opacityRate", data.opacityRate);
1510
+ loadProperty(this, "sizeRate", data.sizeRate);
1511
+ loadProperty(this, "velocityRate", data.velocityRate);
1512
+ }
1513
+ }
1514
+
1515
+ class ParticlesOptions extends OptionLoader {
1516
+ bounce = new ParticlesBounce();
1517
+ effect = new Effect();
1518
+ groups = {};
1519
+ move = new Move();
1520
+ number = new ParticlesNumber();
2052
1521
  paint;
2053
1522
  palette;
2054
- reduceDuplicates;
2055
- shape;
2056
- zIndex;
1523
+ reduceDuplicates = false;
1524
+ shape = new Shape();
1525
+ zIndex = new ZIndex();
2057
1526
  #container;
2058
1527
  #pluginManager;
2059
1528
  constructor(pluginManager, container) {
1529
+ super();
2060
1530
  this.#pluginManager = pluginManager;
2061
1531
  this.#container = container;
2062
- this.bounce = new ParticlesBounce();
2063
- this.effect = new Effect();
2064
- this.groups = {};
2065
- this.move = new Move();
2066
- this.number = new ParticlesNumber();
2067
1532
  this.paint = new Paint();
2068
1533
  this.paint.color = new AnimatableColor();
2069
1534
  this.paint.color.value = "#fff";
2070
1535
  this.paint.fill = new Fill();
2071
1536
  this.paint.fill.enable = true;
2072
- this.reduceDuplicates = false;
2073
- this.shape = new Shape();
2074
- this.zIndex = new ZIndex();
2075
1537
  }
2076
- load(data) {
2077
- if (isNull(data)) {
2078
- return;
2079
- }
1538
+ doLoad(data) {
2080
1539
  if (data.palette) {
2081
1540
  this.palette = data.palette;
2082
1541
  this.#importPalette(this.palette);
@@ -2134,7 +1593,7 @@
2134
1593
  }
2135
1594
  }
2136
1595
  }
2137
- #importPalette = (palette) => {
1596
+ #importPalette(palette) {
2138
1597
  const paletteData = this.#pluginManager.getPalette(palette);
2139
1598
  if (!paletteData) {
2140
1599
  return;
@@ -2178,69 +1637,49 @@
2178
1637
  mode: paletteData.blendMode,
2179
1638
  },
2180
1639
  });
2181
- };
2182
- }
2183
-
2184
- function loadOptions(options, ...sourceOptionsArr) {
2185
- for (const sourceOptions of sourceOptionsArr) {
2186
- options.load(sourceOptions);
2187
1640
  }
2188
1641
  }
1642
+
2189
1643
  function loadParticlesOptions(pluginManager, container, ...sourceOptionsArr) {
2190
1644
  const options = new ParticlesOptions(pluginManager, container);
2191
1645
  loadOptions(options, ...sourceOptionsArr);
2192
1646
  return options;
2193
1647
  }
2194
1648
 
2195
- class Options {
2196
- autoPlay;
1649
+ class Options extends OptionLoader {
1650
+ autoPlay = true;
2197
1651
  background;
2198
- clear;
2199
- defaultThemes;
2200
- delay;
2201
- detectRetina;
2202
- duration;
2203
- fpsLimit;
1652
+ clear = true;
1653
+ defaultThemes = {};
1654
+ delay = 0;
1655
+ detectRetina = true;
1656
+ duration = 0;
1657
+ fpsLimit = 120;
2204
1658
  fullScreen;
2205
- hdr;
1659
+ hdr = true;
2206
1660
  key;
2207
1661
  name;
2208
1662
  palette;
2209
1663
  particles;
2210
- pauseOnBlur;
2211
- pauseOnOutsideViewport;
1664
+ pauseOnBlur = true;
1665
+ pauseOnOutsideViewport = true;
2212
1666
  preset;
2213
1667
  resize;
2214
- smooth;
2215
- style;
2216
- zLayers;
1668
+ smooth = false;
1669
+ style = {};
1670
+ zLayers = 100;
2217
1671
  #container;
2218
1672
  #pluginManager;
2219
1673
  constructor(pluginManager, container) {
1674
+ super();
2220
1675
  this.#pluginManager = pluginManager;
2221
1676
  this.#container = container;
2222
- this.autoPlay = true;
2223
1677
  this.background = new Background();
2224
- this.clear = true;
2225
- this.defaultThemes = {};
2226
- this.delay = 0;
2227
1678
  this.fullScreen = new FullScreen();
2228
- this.detectRetina = true;
2229
- this.duration = 0;
2230
- this.fpsLimit = 120;
2231
- this.hdr = true;
2232
1679
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
2233
- this.pauseOnBlur = true;
2234
- this.pauseOnOutsideViewport = true;
2235
1680
  this.resize = new ResizeEvent();
2236
- this.smooth = false;
2237
- this.style = {};
2238
- this.zLayers = 100;
2239
1681
  }
2240
- load(data) {
2241
- if (isNull(data)) {
2242
- return;
2243
- }
1682
+ doLoad(data) {
2244
1683
  if (data.preset !== undefined) {
2245
1684
  this.preset = data.preset;
2246
1685
  executeOnSingleOrMultiple(this.preset, preset => {
@@ -2251,44 +1690,18 @@
2251
1690
  this.palette = data.palette;
2252
1691
  this.#importPalette(this.palette);
2253
1692
  }
2254
- if (data.autoPlay !== undefined) {
2255
- this.autoPlay = data.autoPlay;
2256
- }
2257
- if (data.clear !== undefined) {
2258
- this.clear = data.clear;
2259
- }
2260
- if (data.key !== undefined) {
2261
- this.key = data.key;
2262
- }
2263
- if (data.name !== undefined) {
2264
- this.name = data.name;
2265
- }
2266
- if (data.delay !== undefined) {
2267
- this.delay = setRangeValue(data.delay);
2268
- }
2269
- const detectRetina = data.detectRetina;
2270
- if (detectRetina !== undefined) {
2271
- this.detectRetina = detectRetina;
2272
- }
2273
- if (data.duration !== undefined) {
2274
- this.duration = setRangeValue(data.duration);
2275
- }
2276
- const fpsLimit = data.fpsLimit;
2277
- if (fpsLimit !== undefined) {
2278
- this.fpsLimit = fpsLimit;
2279
- }
2280
- if (data.hdr !== undefined) {
2281
- this.hdr = data.hdr;
2282
- }
2283
- if (data.pauseOnBlur !== undefined) {
2284
- this.pauseOnBlur = data.pauseOnBlur;
2285
- }
2286
- if (data.pauseOnOutsideViewport !== undefined) {
2287
- this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
2288
- }
2289
- if (data.zLayers !== undefined) {
2290
- this.zLayers = data.zLayers;
2291
- }
1693
+ loadProperty(this, "autoPlay", data.autoPlay);
1694
+ loadProperty(this, "clear", data.clear);
1695
+ loadProperty(this, "key", data.key);
1696
+ loadProperty(this, "name", data.name);
1697
+ loadRangeProperty(this, "delay", data.delay);
1698
+ loadProperty(this, "detectRetina", data.detectRetina);
1699
+ loadRangeProperty(this, "duration", data.duration);
1700
+ loadProperty(this, "fpsLimit", data.fpsLimit);
1701
+ loadProperty(this, "hdr", data.hdr);
1702
+ loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1703
+ loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1704
+ loadProperty(this, "zLayers", data.zLayers);
2292
1705
  this.background.load(data.background);
2293
1706
  const fullScreen = data.fullScreen;
2294
1707
  if (isBoolean(fullScreen)) {
@@ -2300,14 +1713,12 @@
2300
1713
  this.particles.load(data.particles);
2301
1714
  this.resize.load(data.resize);
2302
1715
  this.style = deepExtend(this.style, data.style);
2303
- if (data.smooth !== undefined) {
2304
- this.smooth = data.smooth;
2305
- }
1716
+ loadProperty(this, "smooth", data.smooth);
2306
1717
  this.#pluginManager.plugins.forEach(plugin => {
2307
1718
  plugin.loadOptions(this.#container, this, data);
2308
1719
  });
2309
1720
  }
2310
- #importPalette = palette => {
1721
+ #importPalette(palette) {
2311
1722
  const paletteData = this.#pluginManager.getPalette(palette);
2312
1723
  if (!paletteData) {
2313
1724
  return;
@@ -2324,143 +1735,19 @@
2324
1735
  palette,
2325
1736
  },
2326
1737
  });
2327
- };
2328
- #importPreset = preset => {
2329
- this.load(this.#pluginManager.getPreset(preset));
2330
- };
2331
- }
2332
-
2333
- function paintBase(context, dimension, baseColor) {
2334
- context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
2335
- context.fillRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2336
- }
2337
- function paintImage(context, dimension, image, opacity) {
2338
- if (!image) {
2339
- return;
2340
- }
2341
- const prevAlpha = context.globalAlpha;
2342
- context.globalAlpha = opacity;
2343
- context.drawImage(image, originPoint.x, originPoint.y, dimension.width, dimension.height);
2344
- context.globalAlpha = prevAlpha;
2345
- }
2346
- function clear(context, dimension) {
2347
- context.clearRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2348
- }
2349
- function drawParticle(data) {
2350
- const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
2351
- x: pos.x,
2352
- y: pos.y,
2353
- };
2354
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
2355
- if (colorStyles.fill) {
2356
- context.fillStyle = colorStyles.fill;
2357
- }
2358
- const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
2359
- context.lineWidth = strokeWidth;
2360
- if (colorStyles.stroke) {
2361
- context.strokeStyle = colorStyles.stroke;
2362
- }
2363
- const drawData = {
2364
- context,
2365
- particle,
2366
- radius,
2367
- drawRadius: radius * drawScale,
2368
- opacity,
2369
- delta,
2370
- pixelRatio: container.retina.pixelRatio,
2371
- fill: fillEnabled,
2372
- stroke: strokeWidth > minStrokeWidth,
2373
- transformData,
2374
- position: { ...pos },
2375
- drawPosition,
2376
- drawScale,
2377
- };
2378
- for (const plugin of container.plugins) {
2379
- plugin.drawParticleTransform?.(drawData);
2380
- }
2381
- const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
2382
- drawBeforeEffect(effect, drawData);
2383
- drawShapeBeforeDraw(shape, drawData);
2384
- drawShape(shape, drawData);
2385
- drawShapeAfterDraw(shape, drawData);
2386
- drawAfterEffect(effect, drawData);
2387
- context.resetTransform();
2388
- }
2389
- function drawAfterEffect(drawer, data) {
2390
- if (!drawer?.drawAfter) {
2391
- return;
2392
- }
2393
- const { particle } = data;
2394
- if (!particle.effect) {
2395
- return;
2396
- }
2397
- drawer.drawAfter(data);
2398
- }
2399
- function drawBeforeEffect(drawer, data) {
2400
- if (!drawer?.drawBefore) {
2401
- return;
2402
- }
2403
- const { particle } = data;
2404
- if (!particle.effect) {
2405
- return;
2406
- }
2407
- drawer.drawBefore(data);
2408
- }
2409
- function drawShape(drawer, data) {
2410
- if (!drawer) {
2411
- return;
2412
- }
2413
- const { context, fill, particle, stroke } = data;
2414
- if (!particle.shape) {
2415
- return;
2416
- }
2417
- context.beginPath();
2418
- drawer.draw(data);
2419
- if (particle.shapeClose) {
2420
- context.closePath();
2421
- }
2422
- if (fill) {
2423
- context.fill();
2424
- }
2425
- if (stroke) {
2426
- context.stroke();
2427
- }
2428
- }
2429
- function drawShapeAfterDraw(drawer, data) {
2430
- if (!drawer?.afterDraw) {
2431
- return;
2432
- }
2433
- const { particle } = data;
2434
- if (!particle.shape) {
2435
- return;
2436
- }
2437
- drawer.afterDraw(data);
2438
- }
2439
- function drawShapeBeforeDraw(drawer, data) {
2440
- if (!drawer?.beforeDraw) {
2441
- return;
2442
- }
2443
- const { particle } = data;
2444
- if (!particle.shape) {
2445
- return;
2446
1738
  }
2447
- drawer.beforeDraw(data);
2448
- }
2449
- function drawParticlePlugin(context, plugin, particle, delta) {
2450
- if (!plugin.drawParticle) {
2451
- return;
1739
+ #importPreset(preset) {
1740
+ this.load(this.#pluginManager.getPreset(preset));
2452
1741
  }
2453
- plugin.drawParticle(context, particle, delta);
2454
1742
  }
2455
1743
 
2456
- const styleCache = new Map(), maxCacheSize = 1000, firstIndex = 0, rgbFixedPrecision = 2, hslFixedPrecision = 2;
1744
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
2457
1745
  function getCachedStyle(key, generator) {
2458
1746
  let cached = styleCache.get(key);
2459
1747
  if (!cached) {
2460
1748
  cached = generator();
2461
- if (styleCache.size >= maxCacheSize) {
2462
- const keysToDelete = [...styleCache.keys()].slice(firstIndex, maxCacheSize * half);
2463
- keysToDelete.forEach(k => styleCache.delete(k));
1749
+ if (styleCache.size > maxStyleCacheSize) {
1750
+ styleCache.clear();
2464
1751
  }
2465
1752
  styleCache.set(key, cached);
2466
1753
  }
@@ -2563,34 +1850,35 @@
2563
1850
  function stringToRgb(pluginManager, input) {
2564
1851
  return stringToRgba(pluginManager, input);
2565
1852
  }
1853
+ function hslChannel(temp1, temp2, temp3) {
1854
+ const temp3Min = 0, temp3Max = 1;
1855
+ if (temp3 < temp3Min) {
1856
+ temp3++;
1857
+ }
1858
+ if (temp3 > temp3Max) {
1859
+ temp3--;
1860
+ }
1861
+ if (temp3 * sextuple < temp3Max) {
1862
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1863
+ }
1864
+ if (temp3 * double < temp3Max) {
1865
+ return temp2;
1866
+ }
1867
+ if (temp3 * triple < temp3Max * double) {
1868
+ const temp3Offset = double / triple;
1869
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1870
+ }
1871
+ return temp1;
1872
+ }
2566
1873
  function hslToRgb(hsl) {
2567
1874
  const h = ((hsl.h % hMax) + hMax) % hMax, s = Math.max(sMin, Math.min(sMax, hsl.s)), l = Math.max(lMin, Math.min(lMax, hsl.l)), hNormalized = h / hMax, sNormalized = s / sMax, lNormalized = l / lMax;
2568
1875
  if (s === sMin) {
2569
1876
  const grayscaleValue = Math.round(lNormalized * rgbMax);
2570
1877
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
2571
1878
  }
2572
- const channel = (temp1, temp2, temp3) => {
2573
- const temp3Min = 0, temp3Max = 1;
2574
- if (temp3 < temp3Min) {
2575
- temp3++;
2576
- }
2577
- if (temp3 > temp3Max) {
2578
- temp3--;
2579
- }
2580
- if (temp3 * sextuple < temp3Max) {
2581
- return temp1 + (temp2 - temp1) * sextuple * temp3;
2582
- }
2583
- if (temp3 * double < temp3Max) {
2584
- return temp2;
2585
- }
2586
- if (temp3 * triple < temp3Max * double) {
2587
- const temp3Offset = double / triple;
2588
- return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
2589
- }
2590
- return temp1;
2591
- }, temp1 = lNormalized < half
1879
+ const temp1 = lNormalized < half
2592
1880
  ? lNormalized * (sNormalizedOffset + sNormalized)
2593
- : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized - phaseThird));
1881
+ : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized - phaseThird));
2594
1882
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
2595
1883
  }
2596
1884
  function hslaToRgba(hsla) {
@@ -2603,7 +1891,7 @@
2603
1891
  };
2604
1892
  }
2605
1893
  function getRandomRgbColor(min) {
2606
- const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$1, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1894
+ const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
2607
1895
  return {
2608
1896
  b: getRgbInRangeValue(),
2609
1897
  g: getRgbInRangeValue(),
@@ -2614,21 +1902,18 @@
2614
1902
  const op = opacity ?? defaultOpacity$1, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2615
1903
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2616
1904
  }
2617
- function getHdrStyleFromRgb(color, opacity) {
2618
- return `color(display-p3 ${(color.r / rgbMax).toString()} ${(color.g / rgbMax).toString()} ${(color.b / rgbMax).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1905
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1906
+ const headroom = peakNits / sdrReferenceWhiteNits;
1907
+ return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2619
1908
  }
2620
1909
  function getSdrStyleFromRgb(color, opacity) {
2621
1910
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
2622
1911
  }
2623
1912
  function getStyleFromHsl(color, hdr, opacity) {
2624
1913
  const op = opacity ?? defaultOpacity$1, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2625
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromHsl(color, opacity) : getSdrStyleFromHsl(color, opacity)));
2626
- }
2627
- function getHdrStyleFromHsl(color, opacity) {
2628
- return getHdrStyleFromRgb(hslToRgb(color), opacity);
2629
- }
2630
- function getSdrStyleFromHsl(color, opacity) {
2631
- return `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${(opacity ?? defaultOpacity$1).toString()})`;
1914
+ return getCachedStyle(key, () => hdr
1915
+ ? getStyleFromRgb(hslToRgb(color), true, opacity)
1916
+ : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
2632
1917
  }
2633
1918
  function getHslFromAnimation(animation) {
2634
1919
  return animation === undefined
@@ -2750,22 +2035,14 @@
2750
2035
  const tsParticles = initEngine();
2751
2036
 
2752
2037
  class Blend {
2753
- enable;
2754
- mode;
2755
- constructor() {
2756
- this.mode = "destination-out";
2757
- this.enable = false;
2758
- }
2038
+ enable = false;
2039
+ mode = "destination-out";
2759
2040
  load(data) {
2760
2041
  if (isNull(data)) {
2761
2042
  return;
2762
2043
  }
2763
- if (data.mode !== undefined) {
2764
- this.mode = data.mode;
2765
- }
2766
- if (data.enable !== undefined) {
2767
- this.enable = data.enable;
2768
- }
2044
+ loadProperty(this, "mode", data.mode);
2045
+ loadProperty(this, "enable", data.enable);
2769
2046
  }
2770
2047
  }
2771
2048
 
@@ -2795,7 +2072,7 @@
2795
2072
  }
2796
2073
 
2797
2074
  async function loadBlendPlugin(engine) {
2798
- engine.checkVersion("4.1.3");
2075
+ engine.checkVersion("4.2.0");
2799
2076
  await engine.pluginManager.register(e => {
2800
2077
  e.pluginManager.addPlugin(new BlendPlugin());
2801
2078
  });
@@ -2832,7 +2109,7 @@
2832
2109
  }
2833
2110
 
2834
2111
  async function loadCircleShape(engine) {
2835
- engine.checkVersion("4.1.3");
2112
+ engine.checkVersion("4.2.0");
2836
2113
  await engine.pluginManager.register(e => {
2837
2114
  e.pluginManager.addShape(["circle"], () => {
2838
2115
  return Promise.resolve(new CircleDrawer());
@@ -2880,7 +2157,7 @@
2880
2157
  }
2881
2158
 
2882
2159
  async function loadHexColorPlugin(engine) {
2883
- engine.checkVersion("4.1.3");
2160
+ engine.checkVersion("4.2.0");
2884
2161
  await engine.pluginManager.register(e => {
2885
2162
  e.pluginManager.addColorManager("hex", new HexColorManager());
2886
2163
  });
@@ -2933,7 +2210,7 @@
2933
2210
  }
2934
2211
 
2935
2212
  async function loadHslColorPlugin(engine) {
2936
- engine.checkVersion("4.1.3");
2213
+ engine.checkVersion("4.2.0");
2937
2214
  await engine.pluginManager.register(e => {
2938
2215
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2939
2216
  });
@@ -2957,7 +2234,7 @@
2957
2234
  }
2958
2235
 
2959
2236
  async function loadMovePlugin(engine) {
2960
- engine.checkVersion("4.1.3");
2237
+ engine.checkVersion("4.2.0");
2961
2238
  await engine.pluginManager.register(e => {
2962
2239
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2963
2240
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2975,31 +2252,137 @@
2975
2252
  });
2976
2253
  }
2977
2254
 
2978
- class OpacityAnimation extends RangedAnimationOptions {
2979
- destroy;
2980
- constructor() {
2981
- super();
2982
- this.destroy = DestroyType.none;
2983
- this.speed = 2;
2255
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
2256
+ switch (destroyType) {
2257
+ case DestroyType.max:
2258
+ if (value >= maxValue) {
2259
+ particle.destroy();
2260
+ }
2261
+ break;
2262
+ case DestroyType.min:
2263
+ if (value <= minValue) {
2264
+ particle.destroy();
2265
+ }
2266
+ break;
2267
+ }
2268
+ }
2269
+ function initParticleNumericAnimationValue(options, pxRatio) {
2270
+ const valueRange = options.value, animationOptions = options.animation, res = {
2271
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
2272
+ enable: animationOptions.enable,
2273
+ value: getRangeValue(options.value) * pxRatio,
2274
+ max: getRangeMax(valueRange) * pxRatio,
2275
+ min: getRangeMin(valueRange) * pxRatio,
2276
+ loops: 0,
2277
+ maxLoops: getRangeValue(animationOptions.count),
2278
+ time: 0,
2279
+ }, decayOffset = 1;
2280
+ if (animationOptions.enable) {
2281
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
2282
+ switch (animationOptions.mode) {
2283
+ case AnimationMode.increase:
2284
+ res.status = AnimationStatus.increasing;
2285
+ break;
2286
+ case AnimationMode.decrease:
2287
+ res.status = AnimationStatus.decreasing;
2288
+ break;
2289
+ case AnimationMode.random:
2290
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2291
+ break;
2292
+ }
2293
+ const autoStatus = animationOptions.mode === AnimationMode.auto;
2294
+ switch (animationOptions.startValue) {
2295
+ case StartValueType.min:
2296
+ res.value = res.min;
2297
+ if (autoStatus) {
2298
+ res.status = AnimationStatus.increasing;
2299
+ }
2300
+ break;
2301
+ case StartValueType.max:
2302
+ res.value = res.max;
2303
+ if (autoStatus) {
2304
+ res.status = AnimationStatus.decreasing;
2305
+ }
2306
+ break;
2307
+ case StartValueType.random:
2308
+ default:
2309
+ res.value = randomInRangeValue(res);
2310
+ if (autoStatus) {
2311
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2312
+ }
2313
+ break;
2314
+ }
2315
+ }
2316
+ res.initialValue = res.value;
2317
+ return res;
2318
+ }
2319
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
2320
+ const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
2321
+ if (particle.destroyed ||
2322
+ !data.enable ||
2323
+ ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
2324
+ return;
2325
+ }
2326
+ const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
2327
+ data.time ??= 0;
2328
+ const delayTime = data.delayTime ?? minDelay;
2329
+ if (delayTime > minDelay && data.time < delayTime) {
2330
+ data.time += delta.value;
2331
+ if (data.time < delayTime) {
2332
+ return;
2333
+ }
2334
+ }
2335
+ switch (data.status) {
2336
+ case AnimationStatus.increasing:
2337
+ data.value += velocity;
2338
+ break;
2339
+ case AnimationStatus.decreasing:
2340
+ data.value -= velocity;
2341
+ break;
2342
+ }
2343
+ if (data.velocity && decay !== identity) {
2344
+ data.velocity *= decay;
2345
+ }
2346
+ switch (data.status) {
2347
+ case AnimationStatus.increasing:
2348
+ if (data.value >= maxValue) {
2349
+ {
2350
+ data.status = AnimationStatus.decreasing;
2351
+ }
2352
+ data.loops ??= minLoops;
2353
+ data.loops++;
2354
+ }
2355
+ break;
2356
+ case AnimationStatus.decreasing:
2357
+ if (data.value <= minValue) {
2358
+ {
2359
+ data.status = AnimationStatus.increasing;
2360
+ }
2361
+ data.loops ??= minLoops;
2362
+ data.loops++;
2363
+ }
2364
+ break;
2365
+ }
2366
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
2367
+ if (!particle.destroyed) {
2368
+ data.value = clamp(data.value, minValue, maxValue);
2984
2369
  }
2370
+ }
2371
+
2372
+ class OpacityAnimation extends RangedAnimationOptions {
2373
+ destroy = DestroyType.none;
2985
2374
  load(data) {
2986
2375
  super.load(data);
2987
2376
  if (isNull(data)) {
2988
2377
  return;
2989
2378
  }
2990
- if (data.destroy !== undefined) {
2991
- this.destroy = data.destroy;
2992
- }
2379
+ loadProperty(this, "destroy", data.destroy);
2993
2380
  }
2994
2381
  }
2995
2382
 
2996
2383
  class Opacity extends RangedAnimationValueWithRandom {
2997
- animation;
2998
- constructor() {
2999
- super();
3000
- this.animation = new OpacityAnimation();
3001
- this.value = 1;
3002
- }
2384
+ animation = new OpacityAnimation();
2385
+ value = 1;
3003
2386
  load(data) {
3004
2387
  if (isNull(data)) {
3005
2388
  return;
@@ -3043,10 +2426,7 @@
3043
2426
  (particle.opacity.loops ?? none) < (particle.opacity.maxLoops ?? none))));
3044
2427
  }
3045
2428
  loadOptions(options, ...sources) {
3046
- options.opacity ??= new Opacity();
3047
- for (const source of sources) {
3048
- options.opacity.load(source?.opacity);
3049
- }
2429
+ loadOptionProperty(options, "opacity", Opacity, ...sources);
3050
2430
  }
3051
2431
  reset(particle) {
3052
2432
  if (!particle.opacity) {
@@ -3064,7 +2444,7 @@
3064
2444
  }
3065
2445
 
3066
2446
  async function loadOpacityUpdater(engine) {
3067
- engine.checkVersion("4.1.3");
2447
+ engine.checkVersion("4.2.0");
3068
2448
  await engine.pluginManager.register(e => {
3069
2449
  e.pluginManager.addParticleUpdater("opacity", container => {
3070
2450
  return Promise.resolve(new OpacityUpdater(container));
@@ -3072,7 +2452,7 @@
3072
2452
  });
3073
2453
  }
3074
2454
 
3075
- const minVelocity$4 = 0, boundsMin = 0;
2455
+ const boundsMin = 0;
3076
2456
  function bounceHorizontal(data) {
3077
2457
  if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
3078
2458
  (data.direction !== OutModeDirection.left && data.direction !== OutModeDirection.right)) {
@@ -3087,8 +2467,8 @@
3087
2467
  const velocity = data.particle.velocity.x;
3088
2468
  let bounced = false;
3089
2469
  if (data.outOfCanvas &&
3090
- ((data.direction === OutModeDirection.right && velocity > minVelocity$4) ||
3091
- (data.direction === OutModeDirection.left && velocity < minVelocity$4))) {
2470
+ ((data.direction === OutModeDirection.right && velocity > minVelocity) ||
2471
+ (data.direction === OutModeDirection.left && velocity < minVelocity))) {
3092
2472
  const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
3093
2473
  data.particle.velocity.x *= -newVelocity;
3094
2474
  bounced = true;
@@ -3121,8 +2501,8 @@
3121
2501
  const velocity = data.particle.velocity.y;
3122
2502
  let bounced = false;
3123
2503
  if (data.outOfCanvas &&
3124
- ((data.direction === OutModeDirection.bottom && velocity > minVelocity$4) ||
3125
- (data.direction === OutModeDirection.top && velocity < minVelocity$4))) {
2504
+ ((data.direction === OutModeDirection.bottom && velocity > minVelocity) ||
2505
+ (data.direction === OutModeDirection.top && velocity < minVelocity))) {
3126
2506
  const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
3127
2507
  data.particle.velocity.y *= -newVelocity;
3128
2508
  bounced = true;
@@ -3175,7 +2555,6 @@
3175
2555
  }
3176
2556
  }
3177
2557
 
3178
- const minVelocity$3 = 0;
3179
2558
  class DestroyOutMode {
3180
2559
  modes;
3181
2560
  constructor(_container) {
@@ -3194,10 +2573,10 @@
3194
2573
  break;
3195
2574
  case ParticleOutType.inside: {
3196
2575
  const { dx, dy } = getDistances(particle.position, particle.moveCenter), { x: vx, y: vy } = particle.velocity;
3197
- if ((vx < minVelocity$3 && dx > particle.moveCenter.radius) ||
3198
- (vy < minVelocity$3 && dy > particle.moveCenter.radius) ||
3199
- (vx >= minVelocity$3 && dx < -particle.moveCenter.radius) ||
3200
- (vy >= minVelocity$3 && dy < -particle.moveCenter.radius)) {
2576
+ if ((vx < minVelocity && dx > particle.moveCenter.radius) ||
2577
+ (vy < minVelocity && dy > particle.moveCenter.radius) ||
2578
+ (vx >= minVelocity && dx < -particle.moveCenter.radius) ||
2579
+ (vy >= minVelocity && dy < -particle.moveCenter.radius)) {
3201
2580
  return;
3202
2581
  }
3203
2582
  break;
@@ -3207,7 +2586,6 @@
3207
2586
  }
3208
2587
  }
3209
2588
 
3210
- const minVelocity$2 = 0;
3211
2589
  class NoneOutMode {
3212
2590
  modes;
3213
2591
  #container;
@@ -3227,10 +2605,10 @@
3227
2605
  }
3228
2606
  const gravityOptions = particle.options.move.gravity, container = this.#container, canvasSize = container.canvas.size, pRadius = particle.getRadius();
3229
2607
  if (!gravityOptions.enable) {
3230
- if ((particle.velocity.y > minVelocity$2 && particle.position.y <= canvasSize.height + pRadius) ||
3231
- (particle.velocity.y < minVelocity$2 && particle.position.y >= -pRadius) ||
3232
- (particle.velocity.x > minVelocity$2 && particle.position.x <= canvasSize.width + pRadius) ||
3233
- (particle.velocity.x < minVelocity$2 && particle.position.x >= -pRadius)) {
2608
+ if ((particle.velocity.y > minVelocity && particle.position.y <= canvasSize.height + pRadius) ||
2609
+ (particle.velocity.y < minVelocity && particle.position.y >= -pRadius) ||
2610
+ (particle.velocity.x > minVelocity && particle.position.x <= canvasSize.width + pRadius) ||
2611
+ (particle.velocity.x < minVelocity && particle.position.x >= -pRadius)) {
3234
2612
  return;
3235
2613
  }
3236
2614
  if (!isPointInside(particle.position, container.canvas.size, originPoint, pRadius, direction)) {
@@ -3249,7 +2627,7 @@
3249
2627
  }
3250
2628
  }
3251
2629
 
3252
- const minVelocity$1 = 0, minDistance = 0, updateVector = Vector.origin;
2630
+ const updateVector = Vector.origin;
3253
2631
  class OutOutMode {
3254
2632
  modes;
3255
2633
  #container;
@@ -3270,10 +2648,10 @@
3270
2648
  updateVector.angle = particle.velocity.angle + Math.PI;
3271
2649
  updateVector.addTo(particle.moveCenter);
3272
2650
  const { dx, dy } = getDistances(particle.position, updateVector);
3273
- if ((vx <= minVelocity$1 && dx >= minDistance) ||
3274
- (vy <= minVelocity$1 && dy >= minDistance) ||
3275
- (vx >= minVelocity$1 && dx <= minDistance) ||
3276
- (vy >= minVelocity$1 && dy <= minDistance)) {
2651
+ if ((vx <= minVelocity && dx >= minDistance) ||
2652
+ (vy <= minVelocity && dy >= minDistance) ||
2653
+ (vx >= minVelocity && dx <= minDistance) ||
2654
+ (vy >= minVelocity && dy <= minDistance)) {
3277
2655
  return;
3278
2656
  }
3279
2657
  particle.position.x = Math.floor(randomInRangeValue({
@@ -3397,21 +2775,21 @@
3397
2775
  this.#updateOutMode(particle, delta, outModes.right ?? outModes.default, OutModeDirection.right);
3398
2776
  this.#updateOutMode(particle, delta, outModes.top ?? outModes.default, OutModeDirection.top);
3399
2777
  }
3400
- #addUpdaterIfMissing = (particle, outMode, getUpdater) => {
2778
+ #addUpdaterIfMissing(particle, outMode, getUpdater) {
3401
2779
  const outModes = particle.options.move.outModes;
3402
2780
  if (!this.updaters.has(outMode) && checkOutMode(outModes, outMode)) {
3403
2781
  this.updaters.set(outMode, getUpdater(this.#container));
3404
2782
  }
3405
- };
3406
- #updateOutMode = (particle, delta, outMode, direction) => {
2783
+ }
2784
+ #updateOutMode(particle, delta, outMode, direction) {
3407
2785
  for (const updater of this.updaters.values()) {
3408
2786
  updater.update(particle, direction, delta, outMode);
3409
2787
  }
3410
- };
2788
+ }
3411
2789
  }
3412
2790
 
3413
2791
  async function loadOutModesUpdater(engine) {
3414
- engine.checkVersion("4.1.3");
2792
+ engine.checkVersion("4.2.0");
3415
2793
  await engine.pluginManager.register(e => {
3416
2794
  e.pluginManager.addParticleUpdater("outModes", container => {
3417
2795
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3482,7 +2860,7 @@
3482
2860
  }
3483
2861
 
3484
2862
  async function loadPaintUpdater(engine) {
3485
- engine.checkVersion("4.1.3");
2863
+ engine.checkVersion("4.2.0");
3486
2864
  await engine.pluginManager.register(e => {
3487
2865
  e.pluginManager.addParticleUpdater("paint", container => {
3488
2866
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3537,37 +2915,26 @@
3537
2915
  }
3538
2916
 
3539
2917
  async function loadRgbColorPlugin(engine) {
3540
- engine.checkVersion("4.1.3");
2918
+ engine.checkVersion("4.2.0");
3541
2919
  await engine.pluginManager.register(e => {
3542
2920
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3543
2921
  });
3544
2922
  }
3545
2923
 
3546
2924
  class SizeAnimation extends RangedAnimationOptions {
3547
- destroy;
3548
- constructor() {
3549
- super();
3550
- this.destroy = DestroyType.none;
3551
- this.speed = 5;
3552
- }
2925
+ destroy = DestroyType.none;
3553
2926
  load(data) {
3554
2927
  super.load(data);
3555
2928
  if (isNull(data)) {
3556
2929
  return;
3557
2930
  }
3558
- if (data.destroy !== undefined) {
3559
- this.destroy = data.destroy;
3560
- }
2931
+ loadProperty(this, "destroy", data.destroy);
3561
2932
  }
3562
2933
  }
3563
2934
 
3564
2935
  class Size extends RangedAnimationValueWithRandom {
3565
- animation;
3566
- constructor() {
3567
- super();
3568
- this.animation = new SizeAnimation();
3569
- this.value = 3;
3570
- }
2936
+ animation = new SizeAnimation();
2937
+ value = 3;
3571
2938
  load(data) {
3572
2939
  super.load(data);
3573
2940
  if (isNull(data)) {
@@ -3610,10 +2977,7 @@
3610
2977
  (particle.size.loops ?? minLoops) < (particle.size.maxLoops ?? minLoops))));
3611
2978
  }
3612
2979
  loadOptions(options, ...sources) {
3613
- options.size ??= new Size();
3614
- for (const source of sources) {
3615
- options.size.load(source?.size);
3616
- }
2980
+ loadOptionProperty(options, "size", Size, ...sources);
3617
2981
  }
3618
2982
  preInit(particle) {
3619
2983
  const pxRatio = this.#container.retina.pixelRatio, options = particle.options, sizeOptions = options.size;
@@ -3636,7 +3000,7 @@
3636
3000
  }
3637
3001
 
3638
3002
  async function loadSizeUpdater(engine) {
3639
- engine.checkVersion("4.1.3");
3003
+ engine.checkVersion("4.2.0");
3640
3004
  await engine.pluginManager.register(e => {
3641
3005
  e.pluginManager.addParticleUpdater("size", container => {
3642
3006
  return Promise.resolve(new SizeUpdater(container));
@@ -3645,7 +3009,7 @@
3645
3009
  }
3646
3010
 
3647
3011
  async function loadBasic(engine) {
3648
- engine.checkVersion("4.1.3");
3012
+ engine.checkVersion("4.2.0");
3649
3013
  await engine.pluginManager.register(async (e) => {
3650
3014
  await Promise.all([
3651
3015
  loadBlendPlugin(e),
@@ -3663,22 +3027,14 @@
3663
3027
  }
3664
3028
 
3665
3029
  class ClickEvent {
3666
- enable;
3667
- mode;
3668
- constructor() {
3669
- this.enable = false;
3670
- this.mode = [];
3671
- }
3030
+ enable = false;
3031
+ mode = [];
3672
3032
  load(data) {
3673
3033
  if (isNull(data)) {
3674
- return;
3675
- }
3676
- if (data.enable !== undefined) {
3677
- this.enable = data.enable;
3678
- }
3679
- if (data.mode !== undefined) {
3680
- this.mode = data.mode;
3034
+ return;
3681
3035
  }
3036
+ loadProperty(this, "enable", data.enable);
3037
+ loadProperty(this, "mode", data.mode);
3682
3038
  }
3683
3039
  }
3684
3040
 
@@ -3689,64 +3045,37 @@
3689
3045
  })(DivType || (DivType = {}));
3690
3046
 
3691
3047
  class DivEvent {
3692
- enable;
3693
- mode;
3694
- selectors;
3695
- type;
3696
- constructor() {
3697
- this.selectors = [];
3698
- this.enable = false;
3699
- this.mode = [];
3700
- this.type = DivType.circle;
3701
- }
3048
+ enable = false;
3049
+ mode = [];
3050
+ selectors = [];
3051
+ type = DivType.circle;
3702
3052
  load(data) {
3703
3053
  if (isNull(data)) {
3704
3054
  return;
3705
3055
  }
3706
- if (data.selectors !== undefined) {
3707
- this.selectors = data.selectors;
3708
- }
3709
- if (data.enable !== undefined) {
3710
- this.enable = data.enable;
3711
- }
3712
- if (data.mode !== undefined) {
3713
- this.mode = data.mode;
3714
- }
3715
- if (data.type !== undefined) {
3716
- this.type = data.type;
3717
- }
3056
+ loadProperty(this, "selectors", data.selectors);
3057
+ loadProperty(this, "enable", data.enable);
3058
+ loadProperty(this, "mode", data.mode);
3059
+ loadProperty(this, "type", data.type);
3718
3060
  }
3719
3061
  }
3720
3062
 
3721
3063
  class HoverEvent {
3722
- enable;
3723
- mode;
3724
- constructor() {
3725
- this.enable = false;
3726
- this.mode = [];
3727
- }
3064
+ enable = false;
3065
+ mode = [];
3728
3066
  load(data) {
3729
3067
  if (isNull(data)) {
3730
3068
  return;
3731
3069
  }
3732
- if (data.enable !== undefined) {
3733
- this.enable = data.enable;
3734
- }
3735
- if (data.mode !== undefined) {
3736
- this.mode = data.mode;
3737
- }
3070
+ loadProperty(this, "enable", data.enable);
3071
+ loadProperty(this, "mode", data.mode);
3738
3072
  }
3739
3073
  }
3740
3074
 
3741
3075
  class Events {
3742
- onClick;
3743
- onDiv;
3744
- onHover;
3745
- constructor() {
3746
- this.onClick = new ClickEvent();
3747
- this.onDiv = new DivEvent();
3748
- this.onHover = new HoverEvent();
3749
- }
3076
+ onClick = new ClickEvent();
3077
+ onDiv = new DivEvent();
3078
+ onHover = new HoverEvent();
3750
3079
  load(data) {
3751
3080
  if (isNull(data)) {
3752
3081
  return;
@@ -3799,12 +3128,10 @@
3799
3128
  }
3800
3129
 
3801
3130
  class Interactivity {
3802
- detectsOn;
3803
- events;
3131
+ detectsOn = InteractivityDetect.window;
3132
+ events = new Events();
3804
3133
  modes;
3805
3134
  constructor(pluginManager, container) {
3806
- this.detectsOn = InteractivityDetect.window;
3807
- this.events = new Events();
3808
3135
  this.modes = new Modes(pluginManager, container);
3809
3136
  }
3810
3137
  load(data) {
@@ -3883,7 +3210,7 @@
3883
3210
  const clickEvent = "click", mouseDownEvent = "pointerdown", mouseUpEvent = "pointerup", mouseLeaveEvent = "pointerleave", mouseMoveEvent = "pointermove", touchStartEvent = "touchstart", touchEndEvent = "touchend", touchMoveEvent = "touchmove", touchCancelEvent = "touchcancel";
3884
3211
 
3885
3212
  async function loadInteractivityPlugin(engine) {
3886
- engine.checkVersion("4.1.3");
3213
+ engine.checkVersion("4.2.0");
3887
3214
  await engine.pluginManager.register(e => {
3888
3215
  const interactivityEngine = e, interactivityPluginManager = interactivityEngine.pluginManager;
3889
3216
  interactivityPluginManager.addPlugin(new InteractivityPlugin(interactivityPluginManager));
@@ -3917,32 +3244,22 @@
3917
3244
  }
3918
3245
 
3919
3246
  class Push {
3920
- default;
3921
- groups;
3247
+ default = true;
3248
+ groups = [];
3922
3249
  particles;
3923
- quantity;
3924
- constructor() {
3925
- this.default = true;
3926
- this.groups = [];
3927
- this.quantity = 4;
3928
- }
3250
+ quantity = 4;
3929
3251
  load(data) {
3930
3252
  if (isNull(data)) {
3931
3253
  return;
3932
3254
  }
3933
- if (data.default !== undefined) {
3934
- this.default = data.default;
3935
- }
3255
+ loadProperty(this, "default", data.default);
3936
3256
  if (data.groups !== undefined) {
3937
3257
  this.groups = data.groups.map(t => t);
3938
3258
  }
3939
3259
  if (!this.groups.length) {
3940
3260
  this.default = true;
3941
3261
  }
3942
- const quantity = data.quantity;
3943
- if (quantity !== undefined) {
3944
- this.quantity = setRangeValue(quantity);
3945
- }
3262
+ loadRangeProperty(this, "quantity", data.quantity);
3946
3263
  this.particles = executeOnSingleOrMultiple(data.particles, particles => {
3947
3264
  return deepExtend({}, particles);
3948
3265
  });
@@ -3982,17 +3299,14 @@
3982
3299
  return !!events && mouse.clicking && mouse.inside && !!mouse.position && isInArray(pushMode, events.onClick.mode);
3983
3300
  }
3984
3301
  loadModeOptions(options, ...sources) {
3985
- options.push ??= new Push();
3986
- for (const source of sources) {
3987
- options.push.load(source?.push);
3988
- }
3302
+ loadOptionProperty(options, "push", Push, ...sources);
3989
3303
  }
3990
3304
  reset() {
3991
3305
  }
3992
3306
  }
3993
3307
 
3994
3308
  async function loadExternalPushInteraction(engine) {
3995
- engine.checkVersion("4.1.3");
3309
+ engine.checkVersion("4.2.0");
3996
3310
  await engine.pluginManager.register((e) => {
3997
3311
  ensureInteractivityPluginLoaded(e);
3998
3312
  e.pluginManager.addInteractor?.("externalPush", container => {
@@ -4116,7 +3430,7 @@
4116
3430
  return;
4117
3431
  }
4118
3432
  this.draw(ctx => {
4119
- clear(ctx, this.#canvasManager.size);
3433
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4120
3434
  });
4121
3435
  }
4122
3436
  clear() {
@@ -4178,7 +3492,7 @@
4178
3492
  plugin.drawParticleSetup?.(context, particle, delta);
4179
3493
  }
4180
3494
  this.#applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
4181
- drawParticle({
3495
+ this.#drawParticle({
4182
3496
  container,
4183
3497
  context,
4184
3498
  particle,
@@ -4197,7 +3511,7 @@
4197
3511
  drawParticlePlugins(particle, delta) {
4198
3512
  this.draw(ctx => {
4199
3513
  for (const plugin of this.#drawParticlePlugins) {
4200
- drawParticlePlugin(ctx, plugin, particle, delta);
3514
+ this.#drawParticlePlugin(ctx, plugin, particle, delta);
4201
3515
  }
4202
3516
  });
4203
3517
  }
@@ -4297,12 +3611,19 @@
4297
3611
  }
4298
3612
  paintBase(baseColor) {
4299
3613
  this.draw(ctx => {
4300
- paintBase(ctx, this.#canvasManager.size, baseColor);
3614
+ ctx.fillStyle = baseColor ?? "rgba(0,0,0,0)";
3615
+ ctx.fillRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4301
3616
  });
4302
3617
  }
4303
3618
  paintImage(image, opacity) {
4304
3619
  this.draw(ctx => {
4305
- paintImage(ctx, this.#canvasManager.size, image, opacity);
3620
+ if (!image) {
3621
+ return;
3622
+ }
3623
+ const prevAlpha = ctx.globalAlpha;
3624
+ ctx.globalAlpha = opacity;
3625
+ ctx.drawImage(image, originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
3626
+ ctx.globalAlpha = prevAlpha;
4306
3627
  });
4307
3628
  }
4308
3629
  setContext(context) {
@@ -4316,15 +3637,15 @@
4316
3637
  }
4317
3638
  stop() {
4318
3639
  this.draw(ctx => {
4319
- clear(ctx, this.#canvasManager.size);
3640
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4320
3641
  });
4321
3642
  }
4322
- #applyPostDrawUpdaters = particle => {
3643
+ #applyPostDrawUpdaters(particle) {
4323
3644
  for (const updater of this.#postDrawUpdaters) {
4324
3645
  updater.afterDraw?.(particle);
4325
3646
  }
4326
- };
4327
- #applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
3647
+ }
3648
+ #applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
4328
3649
  for (const updater of this.#preDrawUpdaters) {
4329
3650
  if (updater.getColorStyles) {
4330
3651
  const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
@@ -4343,8 +3664,114 @@
4343
3664
  }
4344
3665
  updater.beforeDraw?.(particle);
4345
3666
  }
4346
- };
4347
- #getPluginParticleColors = particle => {
3667
+ }
3668
+ #drawAfterEffect(drawer, data) {
3669
+ if (!drawer?.drawAfter) {
3670
+ return;
3671
+ }
3672
+ const { particle } = data;
3673
+ if (!particle.effect) {
3674
+ return;
3675
+ }
3676
+ drawer.drawAfter(data);
3677
+ }
3678
+ #drawBeforeEffect(drawer, data) {
3679
+ if (!drawer?.drawBefore) {
3680
+ return;
3681
+ }
3682
+ const { particle } = data;
3683
+ if (!particle.effect) {
3684
+ return;
3685
+ }
3686
+ drawer.drawBefore(data);
3687
+ }
3688
+ #drawParticle(data) {
3689
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
3690
+ x: pos.x,
3691
+ y: pos.y,
3692
+ };
3693
+ context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
3694
+ if (colorStyles.fill) {
3695
+ context.fillStyle = colorStyles.fill;
3696
+ }
3697
+ const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
3698
+ context.lineWidth = strokeWidth;
3699
+ if (colorStyles.stroke) {
3700
+ context.strokeStyle = colorStyles.stroke;
3701
+ }
3702
+ const drawData = {
3703
+ context,
3704
+ particle,
3705
+ radius,
3706
+ drawRadius: radius * drawScale,
3707
+ opacity,
3708
+ delta,
3709
+ pixelRatio: container.retina.pixelRatio,
3710
+ fill: fillEnabled,
3711
+ stroke: strokeWidth > minStrokeWidth,
3712
+ transformData,
3713
+ position: { ...pos },
3714
+ drawPosition,
3715
+ drawScale,
3716
+ };
3717
+ for (const plugin of container.plugins) {
3718
+ plugin.drawParticleTransform?.(drawData);
3719
+ }
3720
+ const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
3721
+ this.#drawBeforeEffect(effect, drawData);
3722
+ this.#drawShapeBeforeDraw(shape, drawData);
3723
+ this.#drawShape(shape, drawData);
3724
+ this.#drawShapeAfterDraw(shape, drawData);
3725
+ this.#drawAfterEffect(effect, drawData);
3726
+ context.resetTransform();
3727
+ }
3728
+ #drawParticlePlugin(context, plugin, particle, delta) {
3729
+ if (!plugin.drawParticle) {
3730
+ return;
3731
+ }
3732
+ plugin.drawParticle(context, particle, delta);
3733
+ }
3734
+ #drawShape(drawer, data) {
3735
+ if (!drawer) {
3736
+ return;
3737
+ }
3738
+ const { context, fill, particle, stroke } = data;
3739
+ if (!particle.shape) {
3740
+ return;
3741
+ }
3742
+ context.beginPath();
3743
+ drawer.draw(data);
3744
+ if (particle.shapeClose) {
3745
+ context.closePath();
3746
+ }
3747
+ if (fill) {
3748
+ context.fill();
3749
+ }
3750
+ if (stroke) {
3751
+ context.stroke();
3752
+ }
3753
+ }
3754
+ #drawShapeAfterDraw(drawer, data) {
3755
+ if (!drawer?.afterDraw) {
3756
+ return;
3757
+ }
3758
+ const { particle } = data;
3759
+ if (!particle.shape) {
3760
+ return;
3761
+ }
3762
+ drawer.afterDraw(data);
3763
+ }
3764
+ #drawShapeBeforeDraw(drawer, data) {
3765
+ if (!drawer?.beforeDraw) {
3766
+ return;
3767
+ }
3768
+ const { particle } = data;
3769
+ if (!particle.shape) {
3770
+ return;
3771
+ }
3772
+ drawer.beforeDraw(data);
3773
+ }
3774
+ #getPluginParticleColors(particle) {
4348
3775
  let fColor, sColor;
4349
3776
  for (const plugin of this.#colorPlugins) {
4350
3777
  if (!fColor && plugin.particleFillColor) {
@@ -4360,7 +3787,7 @@
4360
3787
  this.#reusablePluginColors[fColorIndex] = fColor;
4361
3788
  this.#reusablePluginColors[sColorIndex] = sColor;
4362
3789
  return this.#reusablePluginColors;
4363
- };
3790
+ }
4364
3791
  }
4365
3792
 
4366
3793
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -4492,6 +3919,7 @@
4492
3919
  obs.observe(element, { attributes: true });
4493
3920
  });
4494
3921
  this.initPlugins();
3922
+ this.#initContext();
4495
3923
  this.render.init();
4496
3924
  }
4497
3925
  initBackground() {
@@ -4501,7 +3929,7 @@
4501
3929
  }
4502
3930
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4503
3931
  if (color) {
4504
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity);
3932
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
4505
3933
  }
4506
3934
  else {
4507
3935
  elementStyle.backgroundColor = "";
@@ -4523,7 +3951,7 @@
4523
3951
  if (this.#generated && this.domElement) {
4524
3952
  this.domElement.remove();
4525
3953
  }
4526
- const container = this.#container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
3954
+ const domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4527
3955
  this.domElement = domCanvas;
4528
3956
  this.#generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4529
3957
  this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
@@ -4544,26 +3972,6 @@
4544
3972
  const pxRatio = this.#container.retina.pixelRatio, retinaSize = this.size;
4545
3973
  renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4546
3974
  renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4547
- const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4548
- this.render.setContextSettings({
4549
- alpha: true,
4550
- colorSpace: canSupportHdrQuery?.matches && container.hdr ? "display-p3" : "srgb",
4551
- desynchronized: true,
4552
- willReadFrequently: false,
4553
- });
4554
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4555
- this.#safeMutationObserver(obs => {
4556
- obs.disconnect();
4557
- });
4558
- container.retina.init();
4559
- this.initBackground();
4560
- this.#safeMutationObserver(obs => {
4561
- const element = this.domElement;
4562
- if (!element || !(element instanceof Node)) {
4563
- return;
4564
- }
4565
- obs.observe(element, { attributes: true });
4566
- });
4567
3975
  }
4568
3976
  resize() {
4569
3977
  const element = this.domElement;
@@ -4631,12 +4039,30 @@
4631
4039
  await container.refresh();
4632
4040
  }
4633
4041
  }
4634
- #applyResizePlugins = () => {
4042
+ #applyResizePlugins() {
4635
4043
  for (const plugin of this.#resizePlugins) {
4636
4044
  plugin.resize?.();
4637
4045
  }
4638
- };
4639
- #initStyle = () => {
4046
+ }
4047
+ #initContext() {
4048
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4049
+ safeMatchMedia("(color-gamut: p3)")?.matches &&
4050
+ safeMatchMedia("(dynamic-range: high)")?.matches;
4051
+ this.render.setContextSettings({
4052
+ alpha: true,
4053
+ desynchronized: true,
4054
+ willReadFrequently: false,
4055
+ ...(canSupportHdr
4056
+ ? { colorSpace: "display-p3", colorType: "float16" }
4057
+ : { colorSpace: "srgb" }),
4058
+ });
4059
+ const renderCanvas = this.renderCanvas;
4060
+ if (!renderCanvas) {
4061
+ return;
4062
+ }
4063
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4064
+ }
4065
+ #initStyle() {
4640
4066
  const element = this.domElement, options = this.#container.actualOptions;
4641
4067
  if (!element) {
4642
4068
  return;
@@ -4657,8 +4083,8 @@
4657
4083
  }
4658
4084
  element.style.setProperty(key, value, "important");
4659
4085
  }
4660
- };
4661
- #repairStyle = () => {
4086
+ }
4087
+ #repairStyle() {
4662
4088
  const element = this.domElement;
4663
4089
  if (!element) {
4664
4090
  return;
@@ -4677,27 +4103,27 @@
4677
4103
  }
4678
4104
  observer.observe(element, { attributes: true });
4679
4105
  });
4680
- };
4681
- #resetOriginalStyle = () => {
4106
+ }
4107
+ #resetOriginalStyle() {
4682
4108
  const element = this.domElement, originalStyle = this.#originalStyle;
4683
4109
  if (!element || !originalStyle) {
4684
4110
  return;
4685
4111
  }
4686
4112
  setStyle(element, originalStyle, true);
4687
- };
4688
- #safeMutationObserver = callback => {
4113
+ }
4114
+ #safeMutationObserver(callback) {
4689
4115
  if (!this.#mutationObserver) {
4690
4116
  return;
4691
4117
  }
4692
4118
  callback(this.#mutationObserver);
4693
- };
4694
- #setFullScreenStyle = () => {
4119
+ }
4120
+ #setFullScreenStyle() {
4695
4121
  const element = this.domElement;
4696
4122
  if (!element) {
4697
4123
  return;
4698
4124
  }
4699
4125
  setStyle(element, getFullScreenStyle(this.#container.actualOptions.fullScreen.zIndex), true);
4700
- };
4126
+ }
4701
4127
  }
4702
4128
 
4703
4129
  class EventListeners {
@@ -4722,7 +4148,7 @@
4722
4148
  removeListeners() {
4723
4149
  this.#manageListeners(false);
4724
4150
  }
4725
- #handleVisibilityChange = () => {
4151
+ #handleVisibilityChange() {
4726
4152
  const container = this.#container, options = container.actualOptions;
4727
4153
  if (!options.pauseOnBlur) {
4728
4154
  return;
@@ -4740,8 +4166,8 @@
4740
4166
  container.draw(true);
4741
4167
  }
4742
4168
  }
4743
- };
4744
- #handleWindowResize = () => {
4169
+ }
4170
+ #handleWindowResize() {
4745
4171
  if (this.#resizeTimeout) {
4746
4172
  clearTimeout(this.#resizeTimeout);
4747
4173
  this.#resizeTimeout = undefined;
@@ -4751,13 +4177,13 @@
4751
4177
  await canvas.windowResize();
4752
4178
  };
4753
4179
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
4754
- };
4755
- #manageListeners = add => {
4180
+ }
4181
+ #manageListeners(add) {
4756
4182
  const handlers = this.#handlers;
4757
4183
  this.#manageResize(add);
4758
4184
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
4759
- };
4760
- #manageResize = add => {
4185
+ }
4186
+ #manageResize(add) {
4761
4187
  const handlers = this.#handlers, container = this.#container, options = container.actualOptions;
4762
4188
  if (!options.resize.enable) {
4763
4189
  return;
@@ -4784,7 +4210,7 @@
4784
4210
  });
4785
4211
  this.#resizeObserver.observe(canvasEl);
4786
4212
  }
4787
- };
4213
+ }
4788
4214
  }
4789
4215
 
4790
4216
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
@@ -4811,6 +4237,131 @@
4811
4237
  data.setCb(data.radius);
4812
4238
  }
4813
4239
  }
4240
+ function normalizeAngle(angle, modulus) {
4241
+ const normalized = angle % modulus;
4242
+ return normalized < defaultAngle ? normalized + modulus : normalized;
4243
+ }
4244
+ function initParticleState(particle, id, group) {
4245
+ particle.id = id;
4246
+ particle.group = group;
4247
+ particle.justWarped = false;
4248
+ particle.effectClose = true;
4249
+ particle.shapeClose = true;
4250
+ particle.pathRotation = false;
4251
+ particle.lastPathTime = 0;
4252
+ particle.destroyed = false;
4253
+ particle.unbreakable = false;
4254
+ particle.isRotating = false;
4255
+ particle.rotation = 0;
4256
+ particle.misplaced = false;
4257
+ particle.retina = {
4258
+ maxDistance: {},
4259
+ maxSpeed: 0,
4260
+ moveDrift: 0,
4261
+ moveSpeed: 0,
4262
+ sizeAnimationSpeed: 0,
4263
+ };
4264
+ particle.size = {
4265
+ value: 1,
4266
+ max: 1,
4267
+ min: 1,
4268
+ enable: false,
4269
+ };
4270
+ particle.outType = ParticleOutType.normal;
4271
+ particle.ignoresResizeRatio = true;
4272
+ }
4273
+ function resolveParticleOptions(particle, container, pluginManager, overrideOptions) {
4274
+ const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates;
4275
+ particle.effect = itemFromSingleOrMultiple(particlesOptions.effect.type, particle.id, reduceDuplicates);
4276
+ particle.shape = itemFromSingleOrMultiple(particlesOptions.shape.type, particle.id, reduceDuplicates);
4277
+ const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
4278
+ if (overrideOptions) {
4279
+ if (overrideOptions.effect) {
4280
+ const overrideEffectType = overrideOptions.effect.type;
4281
+ if (overrideEffectType && overrideEffectType !== particle.effect) {
4282
+ const effect = itemFromSingleOrMultiple(overrideEffectType, particle.id, reduceDuplicates);
4283
+ if (effect) {
4284
+ particle.effect = effect;
4285
+ }
4286
+ }
4287
+ effectOptions.load(overrideOptions.effect);
4288
+ }
4289
+ if (overrideOptions.shape) {
4290
+ const overrideShapeType = overrideOptions.shape.type;
4291
+ if (overrideShapeType && overrideShapeType !== particle.shape) {
4292
+ const shape = itemFromSingleOrMultiple(overrideShapeType, particle.id, reduceDuplicates);
4293
+ if (shape) {
4294
+ particle.shape = shape;
4295
+ }
4296
+ }
4297
+ shapeOptions.load(overrideOptions.shape);
4298
+ }
4299
+ }
4300
+ if (particle.effect === randomColorValue) {
4301
+ const availableEffects = [...container.effectDrawers.keys()];
4302
+ particle.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
4303
+ }
4304
+ if (particle.shape === randomColorValue) {
4305
+ const availableShapes = [...container.shapeDrawers.keys()];
4306
+ particle.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
4307
+ }
4308
+ particle.effectData = particle.effect
4309
+ ? loadEffectData(particle.effect, effectOptions, particle.id, reduceDuplicates)
4310
+ : undefined;
4311
+ particle.shapeData = particle.shape
4312
+ ? loadShapeData(particle.shape, shapeOptions, particle.id, reduceDuplicates)
4313
+ : undefined;
4314
+ particlesOptions.load(overrideOptions);
4315
+ const effectData = particle.effectData, shapeData = particle.shapeData;
4316
+ if (effectData) {
4317
+ particlesOptions.load(effectData.particles);
4318
+ }
4319
+ if (shapeData) {
4320
+ particlesOptions.load(shapeData.particles);
4321
+ }
4322
+ particle.effectClose = effectData?.close ?? particlesOptions.effect.close;
4323
+ particle.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4324
+ return particlesOptions;
4325
+ }
4326
+ function initParticleDrawers(particle, container) {
4327
+ let effectDrawer, shapeDrawer;
4328
+ if (particle.effect) {
4329
+ effectDrawer = container.effectDrawers.get(particle.effect);
4330
+ }
4331
+ if (effectDrawer?.loadEffect) {
4332
+ effectDrawer.loadEffect(particle);
4333
+ }
4334
+ if (particle.shape) {
4335
+ shapeDrawer = container.shapeDrawers.get(particle.shape);
4336
+ }
4337
+ if (shapeDrawer?.loadShape) {
4338
+ shapeDrawer.loadShape(particle);
4339
+ }
4340
+ const sideCountFunc = shapeDrawer?.getSidesCount;
4341
+ if (sideCountFunc) {
4342
+ particle.sides = sideCountFunc(particle);
4343
+ }
4344
+ }
4345
+ function runUpdaterPreInit(updaters, particle) {
4346
+ for (const updater of updaters) {
4347
+ updater.preInit?.(particle);
4348
+ }
4349
+ }
4350
+ function runUpdaterInit(updaters, particle) {
4351
+ for (const updater of updaters) {
4352
+ updater.init(particle);
4353
+ }
4354
+ }
4355
+ function runDrawerInit(container, particle) {
4356
+ const shapeDrawer = particle.shape ? container.shapeDrawers.get(particle.shape) : undefined, effectDrawer = particle.effect ? container.effectDrawers.get(particle.effect) : undefined;
4357
+ effectDrawer?.particleInit?.(container, particle);
4358
+ shapeDrawer?.particleInit?.(container, particle);
4359
+ }
4360
+ function runParticleCreatedPlugins(container, particle) {
4361
+ for (const plugin of container.particleCreatedPlugins) {
4362
+ plugin.particleCreated?.(particle);
4363
+ }
4364
+ }
4814
4365
  class Particle {
4815
4366
  backColor;
4816
4367
  bubble;
@@ -4936,94 +4487,20 @@
4936
4487
  const rotateData = this.getRotateData(), rotating = this.isRotating;
4937
4488
  this.#cachedTransform.a = rotateData.cos * (externalTransform.a ?? defaultTransform.a);
4938
4489
  this.#cachedTransform.b = rotating
4939
- ? rotateData.sin * (externalTransform.b ?? identity$1)
4490
+ ? rotateData.sin * (externalTransform.b ?? identity)
4940
4491
  : (externalTransform.b ?? defaultTransform.b);
4941
4492
  this.#cachedTransform.c = rotating
4942
- ? -rotateData.sin * (externalTransform.c ?? identity$1)
4493
+ ? -rotateData.sin * (externalTransform.c ?? identity)
4943
4494
  : (externalTransform.c ?? defaultTransform.c);
4944
4495
  this.#cachedTransform.d = rotateData.cos * (externalTransform.d ?? defaultTransform.d);
4945
4496
  return this.#cachedTransform;
4946
4497
  }
4947
4498
  init(id, position, overrideOptions, group) {
4948
4499
  const container = this.#container;
4949
- this.id = id;
4950
- this.group = group;
4951
- this.justWarped = false;
4952
- this.effectClose = true;
4953
- this.shapeClose = true;
4954
- this.pathRotation = false;
4955
- this.lastPathTime = 0;
4956
- this.destroyed = false;
4957
- this.unbreakable = false;
4958
- this.isRotating = false;
4959
- this.rotation = 0;
4960
- this.misplaced = false;
4961
- this.retina = {
4962
- maxDistance: {},
4963
- maxSpeed: 0,
4964
- moveDrift: 0,
4965
- moveSpeed: 0,
4966
- sizeAnimationSpeed: 0,
4967
- };
4968
- this.size = {
4969
- value: 1,
4970
- max: 1,
4971
- min: 1,
4972
- enable: false,
4973
- };
4974
- this.outType = ParticleOutType.normal;
4975
- this.ignoresResizeRatio = true;
4976
- const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
4977
- this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
4978
- this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
4979
- const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
4980
- if (overrideOptions) {
4981
- if (overrideOptions.effect) {
4982
- const overrideEffectType = overrideOptions.effect.type;
4983
- if (overrideEffectType && overrideEffectType !== this.effect) {
4984
- const effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
4985
- if (effect) {
4986
- this.effect = effect;
4987
- }
4988
- }
4989
- effectOptions.load(overrideOptions.effect);
4990
- }
4991
- if (overrideOptions.shape) {
4992
- const overrideShapeType = overrideOptions.shape.type;
4993
- if (overrideShapeType && overrideShapeType !== this.shape) {
4994
- const shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
4995
- if (shape) {
4996
- this.shape = shape;
4997
- }
4998
- }
4999
- shapeOptions.load(overrideOptions.shape);
5000
- }
5001
- }
5002
- if (this.effect === randomColorValue) {
5003
- const availableEffects = [...this.#container.effectDrawers.keys()];
5004
- this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
5005
- }
5006
- if (this.shape === randomColorValue) {
5007
- const availableShapes = [...this.#container.shapeDrawers.keys()];
5008
- this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
5009
- }
5010
- this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
5011
- this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
5012
- particlesOptions.load(overrideOptions);
5013
- const effectData = this.effectData, shapeData = this.shapeData;
5014
- if (effectData) {
5015
- particlesOptions.load(effectData.particles);
5016
- }
5017
- if (shapeData) {
5018
- particlesOptions.load(shapeData.particles);
5019
- }
5020
- this.effectClose = effectData?.close ?? particlesOptions.effect.close;
5021
- this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
5022
- this.options = particlesOptions;
4500
+ initParticleState(this, id, group);
4501
+ this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
5023
4502
  container.retina.initParticle(this);
5024
- for (const updater of container.particleUpdaters) {
5025
- updater.preInit?.(this);
5026
- }
4503
+ runUpdaterPreInit(container.particleUpdaters, this);
5027
4504
  this.bubble = {
5028
4505
  inRange: false,
5029
4506
  };
@@ -5036,32 +4513,11 @@
5036
4513
  this.velocity = this.initialVelocity.copy();
5037
4514
  this.zIndexFactor = this.position.z / container.zLayers;
5038
4515
  this.sides = 24;
5039
- let effectDrawer, shapeDrawer;
5040
- if (this.effect) {
5041
- effectDrawer = container.effectDrawers.get(this.effect);
5042
- }
5043
- if (effectDrawer?.loadEffect) {
5044
- effectDrawer.loadEffect(this);
5045
- }
5046
- if (this.shape) {
5047
- shapeDrawer = container.shapeDrawers.get(this.shape);
5048
- }
5049
- if (shapeDrawer?.loadShape) {
5050
- shapeDrawer.loadShape(this);
5051
- }
5052
- const sideCountFunc = shapeDrawer?.getSidesCount;
5053
- if (sideCountFunc) {
5054
- this.sides = sideCountFunc(this);
5055
- }
4516
+ initParticleDrawers(this, container);
5056
4517
  this.spawning = false;
5057
- for (const updater of container.particleUpdaters) {
5058
- updater.init(this);
5059
- }
5060
- effectDrawer?.particleInit?.(container, this);
5061
- shapeDrawer?.particleInit?.(container, this);
5062
- for (const plugin of container.particleCreatedPlugins) {
5063
- plugin.particleCreated?.(this);
5064
- }
4518
+ runUpdaterInit(container.particleUpdaters, this);
4519
+ runDrawerInit(container, this);
4520
+ runParticleCreatedPlugins(container, this);
5065
4521
  }
5066
4522
  isInsideCanvas(direction) {
5067
4523
  return this.#getInsideCanvasResult({ direction }).inside;
@@ -5075,15 +4531,15 @@
5075
4531
  }
5076
4532
  const angle = this.roll.angle;
5077
4533
  if (this.roll.horizontal && this.roll.vertical) {
5078
- const normalizedAngle = angle % doublePI, adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + doublePI : normalizedAngle;
4534
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5079
4535
  return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
5080
4536
  }
5081
4537
  if (this.roll.horizontal) {
5082
- const normalizedAngle = (angle + Math.PI * half) % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4538
+ const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
5083
4539
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5084
4540
  }
5085
4541
  if (this.roll.vertical) {
5086
- const normalizedAngle = angle % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4542
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5087
4543
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5088
4544
  }
5089
4545
  return false;
@@ -5096,10 +4552,10 @@
5096
4552
  updater.reset?.(this);
5097
4553
  }
5098
4554
  }
5099
- #calcPosition = (position, zIndex) => {
4555
+ #calcPosition(position, zIndex) {
5100
4556
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
5101
- const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
5102
- while (!signal.aborted) {
4557
+ const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
4558
+ for (;;) {
5103
4559
  for (const plugin of plugins) {
5104
4560
  const pluginPos = plugin.particlePosition?.(posVec, this);
5105
4561
  if (pluginPos) {
@@ -5127,9 +4583,8 @@
5127
4583
  tryCount += tryCountIncrement;
5128
4584
  posVec = undefined;
5129
4585
  }
5130
- return posVec;
5131
- };
5132
- #calculateVelocity = () => {
4586
+ }
4587
+ #calculateVelocity() {
5133
4588
  const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
5134
4589
  if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
5135
4590
  return res;
@@ -5145,8 +4600,8 @@
5145
4600
  res.length *= getRandom();
5146
4601
  }
5147
4602
  return res;
5148
- };
5149
- #fixHorizontal = (pos, radius, outMode) => {
4603
+ }
4604
+ #fixHorizontal(pos, radius, outMode) {
5150
4605
  fixOutMode({
5151
4606
  outMode,
5152
4607
  checkModes: [OutMode.bounce],
@@ -5155,8 +4610,8 @@
5155
4610
  setCb: (value) => (pos.x += value),
5156
4611
  radius,
5157
4612
  });
5158
- };
5159
- #fixVertical = (pos, radius, outMode) => {
4613
+ }
4614
+ #fixVertical(pos, radius, outMode) {
5160
4615
  fixOutMode({
5161
4616
  outMode,
5162
4617
  checkModes: [OutMode.bounce],
@@ -5165,8 +4620,8 @@
5165
4620
  setCb: (value) => (pos.y += value),
5166
4621
  radius,
5167
4622
  });
5168
- };
5169
- #getDefaultInsideCanvasResult = (direction, outMode) => {
4623
+ }
4624
+ #getDefaultInsideCanvasResult(direction, outMode) {
5170
4625
  const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
5171
4626
  if (direction === OutModeDirection.bottom) {
5172
4627
  return {
@@ -5199,8 +4654,8 @@
5199
4654
  position.x <= canvasSize.width + radius,
5200
4655
  reason: "default",
5201
4656
  };
5202
- };
5203
- #getInsideCanvasCallbackData = (direction, outMode) => {
4657
+ }
4658
+ #getInsideCanvasCallbackData(direction, outMode) {
5204
4659
  return {
5205
4660
  canvasSize: this.#container.canvas.size,
5206
4661
  direction,
@@ -5208,8 +4663,8 @@
5208
4663
  particle: this,
5209
4664
  radius: this.getRadius(),
5210
4665
  };
5211
- };
5212
- #getInsideCanvasResult = (data) => {
4666
+ }
4667
+ #getInsideCanvasResult(data) {
5213
4668
  const defaultResult = this.#getDefaultInsideCanvasResult(data.direction, data.outMode), container = this.#container, shapeDrawer = this.shape ? container.shapeDrawers.get(this.shape) : undefined, effectDrawer = this.effect ? container.effectDrawers.get(this.effect) : undefined, shapeCheck = shapeDrawer?.isInsideCanvas, effectCheck = effectDrawer?.isInsideCanvas;
5214
4669
  if (!shapeCheck && !effectCheck) {
5215
4670
  return defaultResult;
@@ -5224,8 +4679,8 @@
5224
4679
  };
5225
4680
  }
5226
4681
  return shapeResult ?? effectResult ?? defaultResult;
5227
- };
5228
- #getRollColor = color => {
4682
+ }
4683
+ #getRollColor(color) {
5229
4684
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
5230
4685
  return color;
5231
4686
  }
@@ -5239,8 +4694,8 @@
5239
4694
  return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
5240
4695
  }
5241
4696
  return color;
5242
- };
5243
- #initPosition = position => {
4697
+ }
4698
+ #initPosition(position) {
5244
4699
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5245
4700
  if (!initialPosition) {
5246
4701
  throw new Error("a valid position cannot be found for particle");
@@ -5263,8 +4718,8 @@
5263
4718
  break;
5264
4719
  }
5265
4720
  this.offset = Vector.origin;
5266
- };
5267
- #normalizeInsideCanvasResult = (result, reason) => {
4721
+ }
4722
+ #normalizeInsideCanvasResult(result, reason) {
5268
4723
  if (typeof result === "boolean") {
5269
4724
  return {
5270
4725
  inside: result,
@@ -5276,7 +4731,7 @@
5276
4731
  margin: result.margin,
5277
4732
  reason: result.reason ?? reason,
5278
4733
  };
5279
- };
4734
+ }
5280
4735
  }
5281
4736
 
5282
4737
  class SpatialHashGrid {
@@ -5629,10 +5084,10 @@
5629
5084
  }
5630
5085
  this.#resizeFactor = undefined;
5631
5086
  }
5632
- #addToPool = (...particles) => {
5087
+ #addToPool(...particles) {
5633
5088
  this.#pool.push(...particles);
5634
- };
5635
- #applyDensity = (options, pluginsCount, group, groupOptions) => {
5089
+ }
5090
+ #applyDensity(options, pluginsCount, group, groupOptions) {
5636
5091
  const numberOptions = options.number;
5637
5092
  if (!numberOptions.density.enable) {
5638
5093
  if (group === undefined) {
@@ -5656,36 +5111,19 @@
5656
5111
  else if (particlesCount > particlesNumber) {
5657
5112
  this.removeQuantity(particlesCount - particlesNumber, group);
5658
5113
  }
5659
- };
5660
- #createBuckets = (zLayers) => {
5114
+ }
5115
+ #createBuckets(zLayers) {
5661
5116
  const bucketCount = Math.max(Math.floor(zLayers), one);
5662
5117
  return Array.from({ length: bucketCount }, () => []);
5663
- };
5664
- #getBucketIndex = (zIndex) => {
5118
+ }
5119
+ #getBucketIndex(zIndex) {
5665
5120
  const maxBucketIndex = this.#zBuckets.length - one;
5666
5121
  if (maxBucketIndex <= minIndex) {
5667
5122
  return minIndex;
5668
5123
  }
5669
5124
  return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
5670
- };
5671
- #getParticleInsertIndex = (bucket, particleId) => {
5672
- let start = minIndex, end = bucket.length;
5673
- while (start < end) {
5674
- const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
5675
- if (!middleParticle) {
5676
- end = middle;
5677
- continue;
5678
- }
5679
- if (middleParticle.id < particleId) {
5680
- start = middle + one;
5681
- }
5682
- else {
5683
- end = middle;
5684
- }
5685
- }
5686
- return start;
5687
- };
5688
- #initDensityFactor = densityOptions => {
5125
+ }
5126
+ #initDensityFactor(densityOptions) {
5689
5127
  const container = this.#container;
5690
5128
  if (!densityOptions.enable) {
5691
5129
  return defaultDensityFactor;
@@ -5695,16 +5133,16 @@
5695
5133
  return defaultDensityFactor;
5696
5134
  }
5697
5135
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5698
- };
5699
- #insertParticleIntoBucket = (particle) => {
5136
+ }
5137
+ #insertParticleIntoBucket(particle) {
5700
5138
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
5701
5139
  if (!bucket) {
5702
5140
  return;
5703
5141
  }
5704
- bucket.splice(this.#getParticleInsertIndex(bucket, particle.id), empty, particle);
5142
+ bucket.push(particle);
5705
5143
  this.#particleBuckets.set(particle.id, bucketIndex);
5706
- };
5707
- #removeParticle = (index, group, override) => {
5144
+ }
5145
+ #removeParticle(index, group, override) {
5708
5146
  const particle = this.#array[index];
5709
5147
  if (!particle) {
5710
5148
  return false;
@@ -5720,22 +5158,20 @@
5720
5158
  });
5721
5159
  this.#addToPool(particle);
5722
5160
  return true;
5723
- };
5724
- #removeParticleFromBucket = (particle) => {
5161
+ }
5162
+ #removeParticleFromBucket(particle) {
5725
5163
  const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
5726
5164
  if (!bucket) {
5727
5165
  this.#particleBuckets.delete(particle.id);
5728
5166
  return;
5729
5167
  }
5730
- const particleIndex = this.#getParticleInsertIndex(bucket, particle.id);
5731
- if (bucket[particleIndex]?.id !== particle.id) {
5732
- this.#particleBuckets.delete(particle.id);
5733
- return;
5168
+ const idx = bucket.findIndex(p => p.id === particle.id);
5169
+ if (idx >= minIndex) {
5170
+ bucket.splice(idx, deleteCount);
5734
5171
  }
5735
- bucket.splice(particleIndex, deleteCount);
5736
5172
  this.#particleBuckets.delete(particle.id);
5737
- };
5738
- #resetBuckets = (zLayers) => {
5173
+ }
5174
+ #resetBuckets(zLayers) {
5739
5175
  const bucketCount = Math.max(Math.floor(zLayers), one);
5740
5176
  if (this.#zBuckets.length !== bucketCount) {
5741
5177
  this.#zBuckets = this.#createBuckets(bucketCount);
@@ -5744,8 +5180,8 @@
5744
5180
  for (const bucket of this.#zBuckets) {
5745
5181
  bucket.length = minIndex;
5746
5182
  }
5747
- };
5748
- #updateParticleBucket = (particle) => {
5183
+ }
5184
+ #updateParticleBucket(particle) {
5749
5185
  const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
5750
5186
  if (currentBucketIndex === undefined) {
5751
5187
  this.#insertParticleIntoBucket(particle);
@@ -5756,9 +5192,9 @@
5756
5192
  }
5757
5193
  const currentBucket = this.#zBuckets[currentBucketIndex];
5758
5194
  if (currentBucket) {
5759
- const particleIndex = this.#getParticleInsertIndex(currentBucket, particle.id);
5760
- if (currentBucket[particleIndex]?.id === particle.id) {
5761
- currentBucket.splice(particleIndex, deleteCount);
5195
+ const idx = currentBucket.findIndex(p => p.id === particle.id);
5196
+ if (idx >= minIndex) {
5197
+ currentBucket.splice(idx, deleteCount);
5762
5198
  }
5763
5199
  }
5764
5200
  const newBucket = this.#zBuckets[newBucketIndex];
@@ -5766,10 +5202,16 @@
5766
5202
  this.#particleBuckets.set(particle.id, newBucketIndex);
5767
5203
  return;
5768
5204
  }
5769
- newBucket.splice(this.#getParticleInsertIndex(newBucket, particle.id), empty, particle);
5205
+ newBucket.push(particle);
5206
+ if (newBucket.length >= double) {
5207
+ const prev = newBucket[newBucket.length - double];
5208
+ if (prev && particle.id < prev.id) {
5209
+ newBucket.sort((a, b) => a.id - b.id);
5210
+ }
5211
+ }
5770
5212
  this.#particleBuckets.set(particle.id, newBucketIndex);
5771
- };
5772
- #updateParticlesPhase1 = (delta) => {
5213
+ }
5214
+ #updateParticlesPhase1(delta) {
5773
5215
  const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
5774
5216
  for (const particle of this.#array) {
5775
5217
  if (resizeFactor && !particle.ignoresResizeRatio) {
@@ -5795,8 +5237,8 @@
5795
5237
  this.grid.insert(particle);
5796
5238
  }
5797
5239
  return particlesToDelete;
5798
- };
5799
- #updateParticlesPhase2 = (delta, particlesToDelete) => {
5240
+ }
5241
+ #updateParticlesPhase2(delta, particlesToDelete) {
5800
5242
  for (const particle of this.#array) {
5801
5243
  if (particle.destroyed) {
5802
5244
  particlesToDelete.add(particle);
@@ -5812,7 +5254,7 @@
5812
5254
  }
5813
5255
  this.#updateParticleBucket(particle);
5814
5256
  }
5815
- };
5257
+ }
5816
5258
  }
5817
5259
 
5818
5260
  class Retina {
@@ -6174,7 +5616,7 @@
6174
5616
  }
6175
5617
  return refresh;
6176
5618
  }
6177
- #nextFrame = (timestamp) => {
5619
+ #nextFrame(timestamp) {
6178
5620
  try {
6179
5621
  if (!this.#smooth &&
6180
5622
  this.#lastFrameTime !== undefined &&
@@ -6202,7 +5644,7 @@
6202
5644
  catch (e) {
6203
5645
  getLogger().error("error in animation loop", e);
6204
5646
  }
6205
- };
5647
+ }
6206
5648
  }
6207
5649
 
6208
5650
  var Container$1 = /*#__PURE__*/Object.freeze({
@@ -6248,7 +5690,7 @@
6248
5690
  BlendPluginInstance: BlendPluginInstance
6249
5691
  });
6250
5692
 
6251
- const minVelocity = 0, identity = 1, moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
5693
+ const moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
6252
5694
  function applyDistance(particle) {
6253
5695
  const initialPosition = particle.initialPosition, { dx, dy } = getDistances(initialPosition, particle.position), dxFixed = Math.abs(dx), dyFixed = Math.abs(dy), { maxDistance } = particle.retina, hDistance = maxDistance.horizontal, vDistance = maxDistance.vertical;
6254
5696
  if (!hDistance && !vDistance) {
@@ -6523,7 +5965,7 @@
6523
5965
  removeListeners() {
6524
5966
  this.#manageListeners(false);
6525
5967
  }
6526
- #doMouseTouchClick = e => {
5968
+ #doMouseTouchClick(e) {
6527
5969
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions;
6528
5970
  if (this.#canPush) {
6529
5971
  const mouseInteractivity = interactionManager.interactivityData.mouse, mousePos = mouseInteractivity.position;
@@ -6545,11 +5987,11 @@
6545
5987
  this.#mouseTouchFinish();
6546
5988
  }, touchDelay);
6547
5989
  }
6548
- };
6549
- #handleVisibilityChange = () => {
5990
+ }
5991
+ #handleVisibilityChange() {
6550
5992
  this.#mouseTouchFinish();
6551
- };
6552
- #manageInteractivityListeners = add => {
5993
+ }
5994
+ #manageInteractivityListeners(add) {
6553
5995
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivityEl = interactionManager.interactivityData.element;
6554
5996
  if (!interactivityEl) {
6555
5997
  return;
@@ -6580,8 +6022,8 @@
6580
6022
  }
6581
6023
  manageListener(interactivityEl, mouseLeaveEvent, handlers.mouseLeave, add);
6582
6024
  manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
6583
- };
6584
- #manageListeners = add => {
6025
+ }
6026
+ #manageListeners(add) {
6585
6027
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.domElement;
6586
6028
  if (detectType === InteractivityDetect.window) {
6587
6029
  interactionManager.interactivityData.element = safeDocument();
@@ -6594,13 +6036,13 @@
6594
6036
  }
6595
6037
  this.#manageInteractivityListeners(add);
6596
6038
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
6597
- };
6598
- #mouseDown = () => {
6039
+ }
6040
+ #mouseDown() {
6599
6041
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
6600
6042
  mouse.clicking = true;
6601
6043
  mouse.downPosition = mouse.position;
6602
- };
6603
- #mouseTouchClick = e => {
6044
+ }
6045
+ #mouseTouchClick(e) {
6604
6046
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, { mouse } = interactionManager.interactivityData;
6605
6047
  mouse.inside = true;
6606
6048
  let handled = false;
@@ -6618,8 +6060,8 @@
6618
6060
  this.#doMouseTouchClick(e);
6619
6061
  }
6620
6062
  mouse.clicking = false;
6621
- };
6622
- #mouseTouchFinish = () => {
6063
+ }
6064
+ #mouseTouchFinish() {
6623
6065
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
6624
6066
  delete mouse.position;
6625
6067
  delete mouse.clickPosition;
@@ -6627,8 +6069,8 @@
6627
6069
  interactivityData.status = mouseLeaveEvent;
6628
6070
  mouse.inside = false;
6629
6071
  mouse.clicking = false;
6630
- };
6631
- #mouseTouchMove = e => {
6072
+ }
6073
+ #mouseTouchMove(e) {
6632
6074
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.domElement;
6633
6075
  if (!interactivity.element) {
6634
6076
  return;
@@ -6690,31 +6132,37 @@
6690
6132
  }
6691
6133
  interactivity.mouse.position = pos;
6692
6134
  interactivity.status = mouseMoveEvent;
6693
- };
6694
- #touchEnd = e => {
6135
+ }
6136
+ #touchEnd(e) {
6695
6137
  const evt = e, touches = Array.from(evt.changedTouches);
6696
6138
  for (const touch of touches) {
6697
6139
  this.#touches.delete(touch.identifier);
6698
6140
  }
6699
6141
  this.#mouseTouchFinish();
6700
- };
6701
- #touchEndClick = e => {
6142
+ }
6143
+ #touchEndClick(e) {
6702
6144
  const evt = e, touches = Array.from(evt.changedTouches);
6703
6145
  for (const touch of touches) {
6704
6146
  this.#touches.delete(touch.identifier);
6705
6147
  }
6706
6148
  this.#mouseTouchClick(e);
6707
- };
6708
- #touchStart = e => {
6149
+ }
6150
+ #touchStart(e) {
6709
6151
  const evt = e, touches = Array.from(evt.changedTouches);
6710
6152
  for (const touch of touches) {
6711
6153
  this.#touches.set(touch.identifier, performance.now());
6712
6154
  }
6713
6155
  this.#mouseTouchMove(e);
6714
- };
6156
+ }
6715
6157
  }
6716
6158
 
6717
6159
  const clickRadius = 1, touchEndLengthOffset = 1, minCoordinate = 0;
6160
+ function safeIntersectionObserver(callback) {
6161
+ if (typeof IntersectionObserver === "undefined") {
6162
+ return;
6163
+ }
6164
+ return new IntersectionObserver(callback);
6165
+ }
6718
6166
  class InteractionManager {
6719
6167
  interactivityData;
6720
6168
  #clickHandlers;
@@ -6917,7 +6365,7 @@
6917
6365
  const container = this.#container;
6918
6366
  container.particles.grid.setCellSize(maxTotalDistance * container.retina.pixelRatio);
6919
6367
  }
6920
- #intersectionManager = entries => {
6368
+ #intersectionManager(entries) {
6921
6369
  const container = this.#container;
6922
6370
  if (container.destroyed || !container.actualOptions.pauseOnOutsideViewport) {
6923
6371
  return;
@@ -6933,7 +6381,7 @@
6933
6381
  container.pause();
6934
6382
  }
6935
6383
  }
6936
- };
6384
+ }
6937
6385
  }
6938
6386
 
6939
6387
  class InteractivityPluginInstance {