@tsparticles/preset-firefly 4.1.2 → 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.2 */
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$2 = 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 = 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.2";
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
- }
1480
+ loadProperty(this, "value", data.value);
1985
1481
  }
1986
1482
  }
1987
1483
 
1988
- class Shape {
1989
- close;
1990
- options;
1991
- type;
1992
- constructor() {
1993
- this.close = true;
1994
- this.options = {};
1995
- this.type = "circle";
1996
- }
1997
- load(data) {
1998
- if (isNull(data)) {
1999
- return;
2000
- }
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
- }
2016
- }
2017
- }
2018
-
2019
- 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
- }
1498
+ loadProperty(this, "close", data.close);
1499
+ loadProperty(this, "type", data.type);
2043
1500
  }
2044
1501
  }
2045
1502
 
2046
- class ParticlesOptions {
2047
- bounce;
2048
- effect;
2049
- groups;
2050
- move;
2051
- number;
1503
+ class ZIndex extends ValueWithRandom {
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
1738
  }
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
- }
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$2, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1894
+ const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$1, 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.2");
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.2");
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.2");
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.2");
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.2");
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.2");
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.2");
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.2");
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.2");
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.2");
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.2");
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
3034
  return;
3675
3035
  }
3676
- if (data.enable !== undefined) {
3677
- this.enable = data.enable;
3678
- }
3679
- if (data.mode !== undefined) {
3680
- this.mode = data.mode;
3681
- }
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.2");
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,31 +3244,20 @@
3917
3244
  }
3918
3245
 
3919
3246
  class TrailColorWeight {
3920
- x;
3921
- y;
3922
- constructor() {
3923
- this.x = 0;
3924
- this.y = 0;
3925
- }
3247
+ x = 0;
3248
+ y = 0;
3926
3249
  load(data) {
3927
3250
  if (!data) {
3928
3251
  return;
3929
3252
  }
3930
- if (data.x !== undefined) {
3931
- this.x = data.x;
3932
- }
3933
- if (data.y !== undefined) {
3934
- this.y = data.y;
3935
- }
3253
+ loadProperty(this, "x", data.x);
3254
+ loadProperty(this, "y", data.y);
3936
3255
  }
3937
3256
  }
3938
3257
 
3939
3258
  class TrailColorComponent {
3940
3259
  value;
3941
- weights;
3942
- constructor() {
3943
- this.weights = new TrailColorWeight();
3944
- }
3260
+ weights = new TrailColorWeight();
3945
3261
  load(data) {
3946
3262
  if (!data) {
3947
3263
  return;
@@ -3957,14 +3273,9 @@
3957
3273
  }
3958
3274
 
3959
3275
  class TrailColorCoords {
3960
- h;
3961
- l;
3962
- s;
3963
- constructor() {
3964
- this.h = new TrailColorComponent();
3965
- this.s = new TrailColorComponent();
3966
- this.l = new TrailColorComponent();
3967
- }
3276
+ h = new TrailColorComponent();
3277
+ l = new TrailColorComponent();
3278
+ s = new TrailColorComponent();
3968
3279
  load(data) {
3969
3280
  if (!data) {
3970
3281
  return;
@@ -3985,29 +3296,17 @@
3985
3296
  }
3986
3297
 
3987
3298
  class Trail {
3988
- colorCoords;
3989
- delay;
3299
+ colorCoords = new TrailColorCoords();
3300
+ delay = 1;
3990
3301
  particles;
3991
- pauseOnStop;
3992
- quantity;
3993
- constructor() {
3994
- this.delay = 1;
3995
- this.pauseOnStop = false;
3996
- this.quantity = 1;
3997
- this.colorCoords = new TrailColorCoords();
3998
- }
3302
+ pauseOnStop = false;
3303
+ quantity = 1;
3999
3304
  load(data) {
4000
3305
  if (isNull(data))
4001
3306
  return;
4002
- if (data.delay !== undefined) {
4003
- this.delay = data.delay;
4004
- }
4005
- if (data.quantity !== undefined) {
4006
- this.quantity = data.quantity;
4007
- }
4008
- if (data.pauseOnStop !== undefined) {
4009
- this.pauseOnStop = data.pauseOnStop;
4010
- }
3307
+ loadProperty(this, "delay", data.delay);
3308
+ loadProperty(this, "quantity", data.quantity);
3309
+ loadProperty(this, "pauseOnStop", data.pauseOnStop);
4011
3310
  if (data.particles !== undefined) {
4012
3311
  this.particles = deepExtend({}, data.particles);
4013
3312
  }
@@ -4101,17 +3400,14 @@
4101
3400
  (mouse.inside && !!mouse.position && isInArray(trailMode, events.onHover.mode))));
4102
3401
  }
4103
3402
  loadModeOptions(options, ...sources) {
4104
- options.trail ??= new Trail();
4105
- for (const source of sources) {
4106
- options.trail.load(source?.trail);
4107
- }
3403
+ loadOptionProperty(options, "trail", Trail, ...sources);
4108
3404
  }
4109
3405
  reset() {
4110
3406
  }
4111
3407
  }
4112
3408
 
4113
3409
  async function loadExternalTrailInteraction(engine) {
4114
- engine.checkVersion("4.1.2");
3410
+ engine.checkVersion("4.2.0");
4115
3411
  await engine.pluginManager.register((e) => {
4116
3412
  ensureInteractivityPluginLoaded(e);
4117
3413
  e.pluginManager.addInteractor?.("externalTrail", container => {
@@ -4121,55 +3417,36 @@
4121
3417
  }
4122
3418
 
4123
3419
  class LifeDelay extends ValueWithRandom {
4124
- sync;
4125
- constructor() {
4126
- super();
4127
- this.sync = false;
4128
- }
3420
+ sync = false;
4129
3421
  load(data) {
4130
3422
  if (isNull(data)) {
4131
3423
  return;
4132
3424
  }
4133
3425
  super.load(data);
4134
- if (data.sync !== undefined) {
4135
- this.sync = data.sync;
4136
- }
3426
+ loadProperty(this, "sync", data.sync);
4137
3427
  }
4138
3428
  }
4139
3429
 
4140
3430
  class LifeDuration extends ValueWithRandom {
4141
- sync;
4142
- constructor() {
4143
- super();
4144
- this.sync = false;
4145
- }
3431
+ sync = false;
4146
3432
  load(data) {
4147
3433
  if (isNull(data)) {
4148
3434
  return;
4149
3435
  }
4150
3436
  super.load(data);
4151
- if (data.sync !== undefined) {
4152
- this.sync = data.sync;
4153
- }
3437
+ loadProperty(this, "sync", data.sync);
4154
3438
  }
4155
3439
  }
4156
3440
 
4157
3441
  class Life {
4158
- count;
4159
- delay;
4160
- duration;
4161
- constructor() {
4162
- this.count = 0;
4163
- this.delay = new LifeDelay();
4164
- this.duration = new LifeDuration();
4165
- }
3442
+ count = 0;
3443
+ delay = new LifeDelay();
3444
+ duration = new LifeDuration();
4166
3445
  load(data) {
4167
3446
  if (isNull(data)) {
4168
3447
  return;
4169
3448
  }
4170
- if (data.count !== undefined) {
4171
- this.count = data.count;
4172
- }
3449
+ loadProperty(this, "count", data.count);
4173
3450
  this.delay.load(data.delay);
4174
3451
  this.duration.load(data.duration);
4175
3452
  }
@@ -4228,7 +3505,7 @@
4228
3505
  }
4229
3506
  }
4230
3507
 
4231
- const noTime = 0, identity$1 = 1, infiniteValue = -1;
3508
+ const noTime = 0, identity = 1, infiniteValue = -1;
4232
3509
  class LifeUpdater {
4233
3510
  #container;
4234
3511
  constructor(container) {
@@ -4239,7 +3516,7 @@
4239
3516
  if (!lifeOptions) {
4240
3517
  return;
4241
3518
  }
4242
- const delayFactor = lifeOptions.delay.sync ? identity$1 : getRandom(), durationFactor = lifeOptions.duration.sync ? identity$1 : getRandom();
3519
+ const delayFactor = lifeOptions.delay.sync ? identity : getRandom(), durationFactor = lifeOptions.duration.sync ? identity : getRandom();
4243
3520
  particle.life = {
4244
3521
  delay: container.retina.reduceFactor
4245
3522
  ? ((getRangeValue(lifeOptions.delay.value) * delayFactor) / container.retina.reduceFactor) *
@@ -4265,10 +3542,7 @@
4265
3542
  return !particle.destroyed;
4266
3543
  }
4267
3544
  loadOptions(options, ...sources) {
4268
- options.life ??= new Life();
4269
- for (const source of sources) {
4270
- options.life.load(source?.life);
4271
- }
3545
+ loadOptionProperty(options, "life", Life, ...sources);
4272
3546
  }
4273
3547
  update(particle, delta) {
4274
3548
  if (!this.isEnabled(particle) || !particle.life) {
@@ -4279,7 +3553,7 @@
4279
3553
  }
4280
3554
 
4281
3555
  async function loadLifeUpdater(engine) {
4282
- engine.checkVersion("4.1.2");
3556
+ engine.checkVersion("4.2.0");
4283
3557
  await engine.pluginManager.register(e => {
4284
3558
  e.pluginManager.addParticleUpdater("life", container => {
4285
3559
  return Promise.resolve(new LifeUpdater(container));
@@ -4424,7 +3698,7 @@
4424
3698
  return;
4425
3699
  }
4426
3700
  this.draw(ctx => {
4427
- clear(ctx, this.#canvasManager.size);
3701
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4428
3702
  });
4429
3703
  }
4430
3704
  clear() {
@@ -4486,7 +3760,7 @@
4486
3760
  plugin.drawParticleSetup?.(context, particle, delta);
4487
3761
  }
4488
3762
  this.#applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
4489
- drawParticle({
3763
+ this.#drawParticle({
4490
3764
  container,
4491
3765
  context,
4492
3766
  particle,
@@ -4505,7 +3779,7 @@
4505
3779
  drawParticlePlugins(particle, delta) {
4506
3780
  this.draw(ctx => {
4507
3781
  for (const plugin of this.#drawParticlePlugins) {
4508
- drawParticlePlugin(ctx, plugin, particle, delta);
3782
+ this.#drawParticlePlugin(ctx, plugin, particle, delta);
4509
3783
  }
4510
3784
  });
4511
3785
  }
@@ -4605,12 +3879,19 @@
4605
3879
  }
4606
3880
  paintBase(baseColor) {
4607
3881
  this.draw(ctx => {
4608
- paintBase(ctx, this.#canvasManager.size, baseColor);
3882
+ ctx.fillStyle = baseColor ?? "rgba(0,0,0,0)";
3883
+ ctx.fillRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4609
3884
  });
4610
3885
  }
4611
3886
  paintImage(image, opacity) {
4612
3887
  this.draw(ctx => {
4613
- paintImage(ctx, this.#canvasManager.size, image, opacity);
3888
+ if (!image) {
3889
+ return;
3890
+ }
3891
+ const prevAlpha = ctx.globalAlpha;
3892
+ ctx.globalAlpha = opacity;
3893
+ ctx.drawImage(image, originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
3894
+ ctx.globalAlpha = prevAlpha;
4614
3895
  });
4615
3896
  }
4616
3897
  setContext(context) {
@@ -4624,15 +3905,15 @@
4624
3905
  }
4625
3906
  stop() {
4626
3907
  this.draw(ctx => {
4627
- clear(ctx, this.#canvasManager.size);
3908
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4628
3909
  });
4629
3910
  }
4630
- #applyPostDrawUpdaters = particle => {
3911
+ #applyPostDrawUpdaters(particle) {
4631
3912
  for (const updater of this.#postDrawUpdaters) {
4632
3913
  updater.afterDraw?.(particle);
4633
3914
  }
4634
- };
4635
- #applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
3915
+ }
3916
+ #applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
4636
3917
  for (const updater of this.#preDrawUpdaters) {
4637
3918
  if (updater.getColorStyles) {
4638
3919
  const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
@@ -4651,8 +3932,114 @@
4651
3932
  }
4652
3933
  updater.beforeDraw?.(particle);
4653
3934
  }
4654
- };
4655
- #getPluginParticleColors = particle => {
3935
+ }
3936
+ #drawAfterEffect(drawer, data) {
3937
+ if (!drawer?.drawAfter) {
3938
+ return;
3939
+ }
3940
+ const { particle } = data;
3941
+ if (!particle.effect) {
3942
+ return;
3943
+ }
3944
+ drawer.drawAfter(data);
3945
+ }
3946
+ #drawBeforeEffect(drawer, data) {
3947
+ if (!drawer?.drawBefore) {
3948
+ return;
3949
+ }
3950
+ const { particle } = data;
3951
+ if (!particle.effect) {
3952
+ return;
3953
+ }
3954
+ drawer.drawBefore(data);
3955
+ }
3956
+ #drawParticle(data) {
3957
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
3958
+ x: pos.x,
3959
+ y: pos.y,
3960
+ };
3961
+ context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
3962
+ if (colorStyles.fill) {
3963
+ context.fillStyle = colorStyles.fill;
3964
+ }
3965
+ const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
3966
+ context.lineWidth = strokeWidth;
3967
+ if (colorStyles.stroke) {
3968
+ context.strokeStyle = colorStyles.stroke;
3969
+ }
3970
+ const drawData = {
3971
+ context,
3972
+ particle,
3973
+ radius,
3974
+ drawRadius: radius * drawScale,
3975
+ opacity,
3976
+ delta,
3977
+ pixelRatio: container.retina.pixelRatio,
3978
+ fill: fillEnabled,
3979
+ stroke: strokeWidth > minStrokeWidth,
3980
+ transformData,
3981
+ position: { ...pos },
3982
+ drawPosition,
3983
+ drawScale,
3984
+ };
3985
+ for (const plugin of container.plugins) {
3986
+ plugin.drawParticleTransform?.(drawData);
3987
+ }
3988
+ const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
3989
+ this.#drawBeforeEffect(effect, drawData);
3990
+ this.#drawShapeBeforeDraw(shape, drawData);
3991
+ this.#drawShape(shape, drawData);
3992
+ this.#drawShapeAfterDraw(shape, drawData);
3993
+ this.#drawAfterEffect(effect, drawData);
3994
+ context.resetTransform();
3995
+ }
3996
+ #drawParticlePlugin(context, plugin, particle, delta) {
3997
+ if (!plugin.drawParticle) {
3998
+ return;
3999
+ }
4000
+ plugin.drawParticle(context, particle, delta);
4001
+ }
4002
+ #drawShape(drawer, data) {
4003
+ if (!drawer) {
4004
+ return;
4005
+ }
4006
+ const { context, fill, particle, stroke } = data;
4007
+ if (!particle.shape) {
4008
+ return;
4009
+ }
4010
+ context.beginPath();
4011
+ drawer.draw(data);
4012
+ if (particle.shapeClose) {
4013
+ context.closePath();
4014
+ }
4015
+ if (fill) {
4016
+ context.fill();
4017
+ }
4018
+ if (stroke) {
4019
+ context.stroke();
4020
+ }
4021
+ }
4022
+ #drawShapeAfterDraw(drawer, data) {
4023
+ if (!drawer?.afterDraw) {
4024
+ return;
4025
+ }
4026
+ const { particle } = data;
4027
+ if (!particle.shape) {
4028
+ return;
4029
+ }
4030
+ drawer.afterDraw(data);
4031
+ }
4032
+ #drawShapeBeforeDraw(drawer, data) {
4033
+ if (!drawer?.beforeDraw) {
4034
+ return;
4035
+ }
4036
+ const { particle } = data;
4037
+ if (!particle.shape) {
4038
+ return;
4039
+ }
4040
+ drawer.beforeDraw(data);
4041
+ }
4042
+ #getPluginParticleColors(particle) {
4656
4043
  let fColor, sColor;
4657
4044
  for (const plugin of this.#colorPlugins) {
4658
4045
  if (!fColor && plugin.particleFillColor) {
@@ -4668,7 +4055,7 @@
4668
4055
  this.#reusablePluginColors[fColorIndex] = fColor;
4669
4056
  this.#reusablePluginColors[sColorIndex] = sColor;
4670
4057
  return this.#reusablePluginColors;
4671
- };
4058
+ }
4672
4059
  }
4673
4060
 
4674
4061
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -4800,6 +4187,7 @@
4800
4187
  obs.observe(element, { attributes: true });
4801
4188
  });
4802
4189
  this.initPlugins();
4190
+ this.#initContext();
4803
4191
  this.render.init();
4804
4192
  }
4805
4193
  initBackground() {
@@ -4809,7 +4197,7 @@
4809
4197
  }
4810
4198
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4811
4199
  if (color) {
4812
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity);
4200
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
4813
4201
  }
4814
4202
  else {
4815
4203
  elementStyle.backgroundColor = "";
@@ -4831,7 +4219,7 @@
4831
4219
  if (this.#generated && this.domElement) {
4832
4220
  this.domElement.remove();
4833
4221
  }
4834
- const container = this.#container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4222
+ const domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4835
4223
  this.domElement = domCanvas;
4836
4224
  this.#generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4837
4225
  this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
@@ -4852,26 +4240,6 @@
4852
4240
  const pxRatio = this.#container.retina.pixelRatio, retinaSize = this.size;
4853
4241
  renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4854
4242
  renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4855
- const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4856
- this.render.setContextSettings({
4857
- alpha: true,
4858
- colorSpace: canSupportHdrQuery?.matches && container.hdr ? "display-p3" : "srgb",
4859
- desynchronized: true,
4860
- willReadFrequently: false,
4861
- });
4862
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4863
- this.#safeMutationObserver(obs => {
4864
- obs.disconnect();
4865
- });
4866
- container.retina.init();
4867
- this.initBackground();
4868
- this.#safeMutationObserver(obs => {
4869
- const element = this.domElement;
4870
- if (!element || !(element instanceof Node)) {
4871
- return;
4872
- }
4873
- obs.observe(element, { attributes: true });
4874
- });
4875
4243
  }
4876
4244
  resize() {
4877
4245
  const element = this.domElement;
@@ -4939,12 +4307,30 @@
4939
4307
  await container.refresh();
4940
4308
  }
4941
4309
  }
4942
- #applyResizePlugins = () => {
4310
+ #applyResizePlugins() {
4943
4311
  for (const plugin of this.#resizePlugins) {
4944
4312
  plugin.resize?.();
4945
4313
  }
4946
- };
4947
- #initStyle = () => {
4314
+ }
4315
+ #initContext() {
4316
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4317
+ safeMatchMedia("(color-gamut: p3)")?.matches &&
4318
+ safeMatchMedia("(dynamic-range: high)")?.matches;
4319
+ this.render.setContextSettings({
4320
+ alpha: true,
4321
+ desynchronized: true,
4322
+ willReadFrequently: false,
4323
+ ...(canSupportHdr
4324
+ ? { colorSpace: "display-p3", colorType: "float16" }
4325
+ : { colorSpace: "srgb" }),
4326
+ });
4327
+ const renderCanvas = this.renderCanvas;
4328
+ if (!renderCanvas) {
4329
+ return;
4330
+ }
4331
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4332
+ }
4333
+ #initStyle() {
4948
4334
  const element = this.domElement, options = this.#container.actualOptions;
4949
4335
  if (!element) {
4950
4336
  return;
@@ -4965,8 +4351,8 @@
4965
4351
  }
4966
4352
  element.style.setProperty(key, value, "important");
4967
4353
  }
4968
- };
4969
- #repairStyle = () => {
4354
+ }
4355
+ #repairStyle() {
4970
4356
  const element = this.domElement;
4971
4357
  if (!element) {
4972
4358
  return;
@@ -4985,27 +4371,27 @@
4985
4371
  }
4986
4372
  observer.observe(element, { attributes: true });
4987
4373
  });
4988
- };
4989
- #resetOriginalStyle = () => {
4374
+ }
4375
+ #resetOriginalStyle() {
4990
4376
  const element = this.domElement, originalStyle = this.#originalStyle;
4991
4377
  if (!element || !originalStyle) {
4992
4378
  return;
4993
4379
  }
4994
4380
  setStyle(element, originalStyle, true);
4995
- };
4996
- #safeMutationObserver = callback => {
4381
+ }
4382
+ #safeMutationObserver(callback) {
4997
4383
  if (!this.#mutationObserver) {
4998
4384
  return;
4999
4385
  }
5000
4386
  callback(this.#mutationObserver);
5001
- };
5002
- #setFullScreenStyle = () => {
4387
+ }
4388
+ #setFullScreenStyle() {
5003
4389
  const element = this.domElement;
5004
4390
  if (!element) {
5005
4391
  return;
5006
4392
  }
5007
4393
  setStyle(element, getFullScreenStyle(this.#container.actualOptions.fullScreen.zIndex), true);
5008
- };
4394
+ }
5009
4395
  }
5010
4396
 
5011
4397
  class EventListeners {
@@ -5030,7 +4416,7 @@
5030
4416
  removeListeners() {
5031
4417
  this.#manageListeners(false);
5032
4418
  }
5033
- #handleVisibilityChange = () => {
4419
+ #handleVisibilityChange() {
5034
4420
  const container = this.#container, options = container.actualOptions;
5035
4421
  if (!options.pauseOnBlur) {
5036
4422
  return;
@@ -5048,8 +4434,8 @@
5048
4434
  container.draw(true);
5049
4435
  }
5050
4436
  }
5051
- };
5052
- #handleWindowResize = () => {
4437
+ }
4438
+ #handleWindowResize() {
5053
4439
  if (this.#resizeTimeout) {
5054
4440
  clearTimeout(this.#resizeTimeout);
5055
4441
  this.#resizeTimeout = undefined;
@@ -5059,13 +4445,13 @@
5059
4445
  await canvas.windowResize();
5060
4446
  };
5061
4447
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
5062
- };
5063
- #manageListeners = add => {
4448
+ }
4449
+ #manageListeners(add) {
5064
4450
  const handlers = this.#handlers;
5065
4451
  this.#manageResize(add);
5066
4452
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
5067
- };
5068
- #manageResize = add => {
4453
+ }
4454
+ #manageResize(add) {
5069
4455
  const handlers = this.#handlers, container = this.#container, options = container.actualOptions;
5070
4456
  if (!options.resize.enable) {
5071
4457
  return;
@@ -5092,7 +4478,7 @@
5092
4478
  });
5093
4479
  this.#resizeObserver.observe(canvasEl);
5094
4480
  }
5095
- };
4481
+ }
5096
4482
  }
5097
4483
 
5098
4484
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
@@ -5119,6 +4505,131 @@
5119
4505
  data.setCb(data.radius);
5120
4506
  }
5121
4507
  }
4508
+ function normalizeAngle(angle, modulus) {
4509
+ const normalized = angle % modulus;
4510
+ return normalized < defaultAngle ? normalized + modulus : normalized;
4511
+ }
4512
+ function initParticleState(particle, id, group) {
4513
+ particle.id = id;
4514
+ particle.group = group;
4515
+ particle.justWarped = false;
4516
+ particle.effectClose = true;
4517
+ particle.shapeClose = true;
4518
+ particle.pathRotation = false;
4519
+ particle.lastPathTime = 0;
4520
+ particle.destroyed = false;
4521
+ particle.unbreakable = false;
4522
+ particle.isRotating = false;
4523
+ particle.rotation = 0;
4524
+ particle.misplaced = false;
4525
+ particle.retina = {
4526
+ maxDistance: {},
4527
+ maxSpeed: 0,
4528
+ moveDrift: 0,
4529
+ moveSpeed: 0,
4530
+ sizeAnimationSpeed: 0,
4531
+ };
4532
+ particle.size = {
4533
+ value: 1,
4534
+ max: 1,
4535
+ min: 1,
4536
+ enable: false,
4537
+ };
4538
+ particle.outType = ParticleOutType.normal;
4539
+ particle.ignoresResizeRatio = true;
4540
+ }
4541
+ function resolveParticleOptions(particle, container, pluginManager, overrideOptions) {
4542
+ const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates;
4543
+ particle.effect = itemFromSingleOrMultiple(particlesOptions.effect.type, particle.id, reduceDuplicates);
4544
+ particle.shape = itemFromSingleOrMultiple(particlesOptions.shape.type, particle.id, reduceDuplicates);
4545
+ const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
4546
+ if (overrideOptions) {
4547
+ if (overrideOptions.effect) {
4548
+ const overrideEffectType = overrideOptions.effect.type;
4549
+ if (overrideEffectType && overrideEffectType !== particle.effect) {
4550
+ const effect = itemFromSingleOrMultiple(overrideEffectType, particle.id, reduceDuplicates);
4551
+ if (effect) {
4552
+ particle.effect = effect;
4553
+ }
4554
+ }
4555
+ effectOptions.load(overrideOptions.effect);
4556
+ }
4557
+ if (overrideOptions.shape) {
4558
+ const overrideShapeType = overrideOptions.shape.type;
4559
+ if (overrideShapeType && overrideShapeType !== particle.shape) {
4560
+ const shape = itemFromSingleOrMultiple(overrideShapeType, particle.id, reduceDuplicates);
4561
+ if (shape) {
4562
+ particle.shape = shape;
4563
+ }
4564
+ }
4565
+ shapeOptions.load(overrideOptions.shape);
4566
+ }
4567
+ }
4568
+ if (particle.effect === randomColorValue) {
4569
+ const availableEffects = [...container.effectDrawers.keys()];
4570
+ particle.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
4571
+ }
4572
+ if (particle.shape === randomColorValue) {
4573
+ const availableShapes = [...container.shapeDrawers.keys()];
4574
+ particle.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
4575
+ }
4576
+ particle.effectData = particle.effect
4577
+ ? loadEffectData(particle.effect, effectOptions, particle.id, reduceDuplicates)
4578
+ : undefined;
4579
+ particle.shapeData = particle.shape
4580
+ ? loadShapeData(particle.shape, shapeOptions, particle.id, reduceDuplicates)
4581
+ : undefined;
4582
+ particlesOptions.load(overrideOptions);
4583
+ const effectData = particle.effectData, shapeData = particle.shapeData;
4584
+ if (effectData) {
4585
+ particlesOptions.load(effectData.particles);
4586
+ }
4587
+ if (shapeData) {
4588
+ particlesOptions.load(shapeData.particles);
4589
+ }
4590
+ particle.effectClose = effectData?.close ?? particlesOptions.effect.close;
4591
+ particle.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4592
+ return particlesOptions;
4593
+ }
4594
+ function initParticleDrawers(particle, container) {
4595
+ let effectDrawer, shapeDrawer;
4596
+ if (particle.effect) {
4597
+ effectDrawer = container.effectDrawers.get(particle.effect);
4598
+ }
4599
+ if (effectDrawer?.loadEffect) {
4600
+ effectDrawer.loadEffect(particle);
4601
+ }
4602
+ if (particle.shape) {
4603
+ shapeDrawer = container.shapeDrawers.get(particle.shape);
4604
+ }
4605
+ if (shapeDrawer?.loadShape) {
4606
+ shapeDrawer.loadShape(particle);
4607
+ }
4608
+ const sideCountFunc = shapeDrawer?.getSidesCount;
4609
+ if (sideCountFunc) {
4610
+ particle.sides = sideCountFunc(particle);
4611
+ }
4612
+ }
4613
+ function runUpdaterPreInit(updaters, particle) {
4614
+ for (const updater of updaters) {
4615
+ updater.preInit?.(particle);
4616
+ }
4617
+ }
4618
+ function runUpdaterInit(updaters, particle) {
4619
+ for (const updater of updaters) {
4620
+ updater.init(particle);
4621
+ }
4622
+ }
4623
+ function runDrawerInit(container, particle) {
4624
+ const shapeDrawer = particle.shape ? container.shapeDrawers.get(particle.shape) : undefined, effectDrawer = particle.effect ? container.effectDrawers.get(particle.effect) : undefined;
4625
+ effectDrawer?.particleInit?.(container, particle);
4626
+ shapeDrawer?.particleInit?.(container, particle);
4627
+ }
4628
+ function runParticleCreatedPlugins(container, particle) {
4629
+ for (const plugin of container.particleCreatedPlugins) {
4630
+ plugin.particleCreated?.(particle);
4631
+ }
4632
+ }
5122
4633
  class Particle {
5123
4634
  backColor;
5124
4635
  bubble;
@@ -5244,88 +4755,20 @@
5244
4755
  const rotateData = this.getRotateData(), rotating = this.isRotating;
5245
4756
  this.#cachedTransform.a = rotateData.cos * (externalTransform.a ?? defaultTransform.a);
5246
4757
  this.#cachedTransform.b = rotating
5247
- ? rotateData.sin * (externalTransform.b ?? identity$2)
4758
+ ? rotateData.sin * (externalTransform.b ?? identity$1)
5248
4759
  : (externalTransform.b ?? defaultTransform.b);
5249
4760
  this.#cachedTransform.c = rotating
5250
- ? -rotateData.sin * (externalTransform.c ?? identity$2)
4761
+ ? -rotateData.sin * (externalTransform.c ?? identity$1)
5251
4762
  : (externalTransform.c ?? defaultTransform.c);
5252
4763
  this.#cachedTransform.d = rotateData.cos * (externalTransform.d ?? defaultTransform.d);
5253
4764
  return this.#cachedTransform;
5254
4765
  }
5255
4766
  init(id, position, overrideOptions, group) {
5256
4767
  const container = this.#container;
5257
- this.id = id;
5258
- this.group = group;
5259
- this.justWarped = false;
5260
- this.effectClose = true;
5261
- this.shapeClose = true;
5262
- this.pathRotation = false;
5263
- this.lastPathTime = 0;
5264
- this.destroyed = false;
5265
- this.unbreakable = false;
5266
- this.isRotating = false;
5267
- this.rotation = 0;
5268
- this.misplaced = false;
5269
- this.retina = {
5270
- maxDistance: {},
5271
- maxSpeed: 0,
5272
- moveDrift: 0,
5273
- moveSpeed: 0,
5274
- sizeAnimationSpeed: 0,
5275
- };
5276
- this.size = {
5277
- value: 1,
5278
- max: 1,
5279
- min: 1,
5280
- enable: false,
5281
- };
5282
- this.outType = ParticleOutType.normal;
5283
- this.ignoresResizeRatio = true;
5284
- const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
5285
- this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
5286
- this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
5287
- const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
5288
- if (overrideOptions) {
5289
- if (overrideOptions.effect?.type && overrideOptions.effect.type !== this.effect) {
5290
- const overrideEffectType = overrideOptions.effect.type, effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
5291
- if (effect) {
5292
- this.effect = effect;
5293
- effectOptions.load(overrideOptions.effect);
5294
- }
5295
- }
5296
- if (overrideOptions.shape?.type && overrideOptions.shape.type !== this.shape) {
5297
- const overrideShapeType = overrideOptions.shape.type, shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
5298
- if (shape) {
5299
- this.shape = shape;
5300
- shapeOptions.load(overrideOptions.shape);
5301
- }
5302
- }
5303
- }
5304
- if (this.effect === randomColorValue) {
5305
- const availableEffects = [...this.#container.effectDrawers.keys()];
5306
- this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
5307
- }
5308
- if (this.shape === randomColorValue) {
5309
- const availableShapes = [...this.#container.shapeDrawers.keys()];
5310
- this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
5311
- }
5312
- this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
5313
- this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
5314
- particlesOptions.load(overrideOptions);
5315
- const effectData = this.effectData, shapeData = this.shapeData;
5316
- if (effectData) {
5317
- particlesOptions.load(effectData.particles);
5318
- }
5319
- if (shapeData) {
5320
- particlesOptions.load(shapeData.particles);
5321
- }
5322
- this.effectClose = effectData?.close ?? particlesOptions.effect.close;
5323
- this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
5324
- this.options = particlesOptions;
4768
+ initParticleState(this, id, group);
4769
+ this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
5325
4770
  container.retina.initParticle(this);
5326
- for (const updater of container.particleUpdaters) {
5327
- updater.preInit?.(this);
5328
- }
4771
+ runUpdaterPreInit(container.particleUpdaters, this);
5329
4772
  this.bubble = {
5330
4773
  inRange: false,
5331
4774
  };
@@ -5338,32 +4781,11 @@
5338
4781
  this.velocity = this.initialVelocity.copy();
5339
4782
  this.zIndexFactor = this.position.z / container.zLayers;
5340
4783
  this.sides = 24;
5341
- let effectDrawer, shapeDrawer;
5342
- if (this.effect) {
5343
- effectDrawer = container.effectDrawers.get(this.effect);
5344
- }
5345
- if (effectDrawer?.loadEffect) {
5346
- effectDrawer.loadEffect(this);
5347
- }
5348
- if (this.shape) {
5349
- shapeDrawer = container.shapeDrawers.get(this.shape);
5350
- }
5351
- if (shapeDrawer?.loadShape) {
5352
- shapeDrawer.loadShape(this);
5353
- }
5354
- const sideCountFunc = shapeDrawer?.getSidesCount;
5355
- if (sideCountFunc) {
5356
- this.sides = sideCountFunc(this);
5357
- }
4784
+ initParticleDrawers(this, container);
5358
4785
  this.spawning = false;
5359
- for (const updater of container.particleUpdaters) {
5360
- updater.init(this);
5361
- }
5362
- effectDrawer?.particleInit?.(container, this);
5363
- shapeDrawer?.particleInit?.(container, this);
5364
- for (const plugin of container.particleCreatedPlugins) {
5365
- plugin.particleCreated?.(this);
5366
- }
4786
+ runUpdaterInit(container.particleUpdaters, this);
4787
+ runDrawerInit(container, this);
4788
+ runParticleCreatedPlugins(container, this);
5367
4789
  }
5368
4790
  isInsideCanvas(direction) {
5369
4791
  return this.#getInsideCanvasResult({ direction }).inside;
@@ -5377,15 +4799,15 @@
5377
4799
  }
5378
4800
  const angle = this.roll.angle;
5379
4801
  if (this.roll.horizontal && this.roll.vertical) {
5380
- const normalizedAngle = angle % doublePI, adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + doublePI : normalizedAngle;
4802
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5381
4803
  return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
5382
4804
  }
5383
4805
  if (this.roll.horizontal) {
5384
- const normalizedAngle = (angle + Math.PI * half) % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4806
+ const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
5385
4807
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5386
4808
  }
5387
4809
  if (this.roll.vertical) {
5388
- const normalizedAngle = angle % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4810
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5389
4811
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5390
4812
  }
5391
4813
  return false;
@@ -5398,10 +4820,10 @@
5398
4820
  updater.reset?.(this);
5399
4821
  }
5400
4822
  }
5401
- #calcPosition = (position, zIndex) => {
4823
+ #calcPosition(position, zIndex) {
5402
4824
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
5403
- const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
5404
- while (!signal.aborted) {
4825
+ const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
4826
+ for (;;) {
5405
4827
  for (const plugin of plugins) {
5406
4828
  const pluginPos = plugin.particlePosition?.(posVec, this);
5407
4829
  if (pluginPos) {
@@ -5429,9 +4851,8 @@
5429
4851
  tryCount += tryCountIncrement;
5430
4852
  posVec = undefined;
5431
4853
  }
5432
- return posVec;
5433
- };
5434
- #calculateVelocity = () => {
4854
+ }
4855
+ #calculateVelocity() {
5435
4856
  const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
5436
4857
  if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
5437
4858
  return res;
@@ -5447,8 +4868,8 @@
5447
4868
  res.length *= getRandom();
5448
4869
  }
5449
4870
  return res;
5450
- };
5451
- #fixHorizontal = (pos, radius, outMode) => {
4871
+ }
4872
+ #fixHorizontal(pos, radius, outMode) {
5452
4873
  fixOutMode({
5453
4874
  outMode,
5454
4875
  checkModes: [OutMode.bounce],
@@ -5457,8 +4878,8 @@
5457
4878
  setCb: (value) => (pos.x += value),
5458
4879
  radius,
5459
4880
  });
5460
- };
5461
- #fixVertical = (pos, radius, outMode) => {
4881
+ }
4882
+ #fixVertical(pos, radius, outMode) {
5462
4883
  fixOutMode({
5463
4884
  outMode,
5464
4885
  checkModes: [OutMode.bounce],
@@ -5467,8 +4888,8 @@
5467
4888
  setCb: (value) => (pos.y += value),
5468
4889
  radius,
5469
4890
  });
5470
- };
5471
- #getDefaultInsideCanvasResult = (direction, outMode) => {
4891
+ }
4892
+ #getDefaultInsideCanvasResult(direction, outMode) {
5472
4893
  const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
5473
4894
  if (direction === OutModeDirection.bottom) {
5474
4895
  return {
@@ -5501,8 +4922,8 @@
5501
4922
  position.x <= canvasSize.width + radius,
5502
4923
  reason: "default",
5503
4924
  };
5504
- };
5505
- #getInsideCanvasCallbackData = (direction, outMode) => {
4925
+ }
4926
+ #getInsideCanvasCallbackData(direction, outMode) {
5506
4927
  return {
5507
4928
  canvasSize: this.#container.canvas.size,
5508
4929
  direction,
@@ -5510,8 +4931,8 @@
5510
4931
  particle: this,
5511
4932
  radius: this.getRadius(),
5512
4933
  };
5513
- };
5514
- #getInsideCanvasResult = (data) => {
4934
+ }
4935
+ #getInsideCanvasResult(data) {
5515
4936
  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;
5516
4937
  if (!shapeCheck && !effectCheck) {
5517
4938
  return defaultResult;
@@ -5526,8 +4947,8 @@
5526
4947
  };
5527
4948
  }
5528
4949
  return shapeResult ?? effectResult ?? defaultResult;
5529
- };
5530
- #getRollColor = color => {
4950
+ }
4951
+ #getRollColor(color) {
5531
4952
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
5532
4953
  return color;
5533
4954
  }
@@ -5541,8 +4962,8 @@
5541
4962
  return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
5542
4963
  }
5543
4964
  return color;
5544
- };
5545
- #initPosition = position => {
4965
+ }
4966
+ #initPosition(position) {
5546
4967
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5547
4968
  if (!initialPosition) {
5548
4969
  throw new Error("a valid position cannot be found for particle");
@@ -5565,8 +4986,8 @@
5565
4986
  break;
5566
4987
  }
5567
4988
  this.offset = Vector.origin;
5568
- };
5569
- #normalizeInsideCanvasResult = (result, reason) => {
4989
+ }
4990
+ #normalizeInsideCanvasResult(result, reason) {
5570
4991
  if (typeof result === "boolean") {
5571
4992
  return {
5572
4993
  inside: result,
@@ -5578,7 +4999,7 @@
5578
4999
  margin: result.margin,
5579
5000
  reason: result.reason ?? reason,
5580
5001
  };
5581
- };
5002
+ }
5582
5003
  }
5583
5004
 
5584
5005
  class SpatialHashGrid {
@@ -5931,10 +5352,10 @@
5931
5352
  }
5932
5353
  this.#resizeFactor = undefined;
5933
5354
  }
5934
- #addToPool = (...particles) => {
5355
+ #addToPool(...particles) {
5935
5356
  this.#pool.push(...particles);
5936
- };
5937
- #applyDensity = (options, pluginsCount, group, groupOptions) => {
5357
+ }
5358
+ #applyDensity(options, pluginsCount, group, groupOptions) {
5938
5359
  const numberOptions = options.number;
5939
5360
  if (!numberOptions.density.enable) {
5940
5361
  if (group === undefined) {
@@ -5958,36 +5379,19 @@
5958
5379
  else if (particlesCount > particlesNumber) {
5959
5380
  this.removeQuantity(particlesCount - particlesNumber, group);
5960
5381
  }
5961
- };
5962
- #createBuckets = (zLayers) => {
5382
+ }
5383
+ #createBuckets(zLayers) {
5963
5384
  const bucketCount = Math.max(Math.floor(zLayers), one);
5964
5385
  return Array.from({ length: bucketCount }, () => []);
5965
- };
5966
- #getBucketIndex = (zIndex) => {
5386
+ }
5387
+ #getBucketIndex(zIndex) {
5967
5388
  const maxBucketIndex = this.#zBuckets.length - one;
5968
5389
  if (maxBucketIndex <= minIndex) {
5969
5390
  return minIndex;
5970
5391
  }
5971
5392
  return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
5972
- };
5973
- #getParticleInsertIndex = (bucket, particleId) => {
5974
- let start = minIndex, end = bucket.length;
5975
- while (start < end) {
5976
- const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
5977
- if (!middleParticle) {
5978
- end = middle;
5979
- continue;
5980
- }
5981
- if (middleParticle.id < particleId) {
5982
- start = middle + one;
5983
- }
5984
- else {
5985
- end = middle;
5986
- }
5987
- }
5988
- return start;
5989
- };
5990
- #initDensityFactor = densityOptions => {
5393
+ }
5394
+ #initDensityFactor(densityOptions) {
5991
5395
  const container = this.#container;
5992
5396
  if (!densityOptions.enable) {
5993
5397
  return defaultDensityFactor;
@@ -5997,16 +5401,16 @@
5997
5401
  return defaultDensityFactor;
5998
5402
  }
5999
5403
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
6000
- };
6001
- #insertParticleIntoBucket = (particle) => {
5404
+ }
5405
+ #insertParticleIntoBucket(particle) {
6002
5406
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6003
5407
  if (!bucket) {
6004
5408
  return;
6005
5409
  }
6006
- bucket.splice(this.#getParticleInsertIndex(bucket, particle.id), empty, particle);
5410
+ bucket.push(particle);
6007
5411
  this.#particleBuckets.set(particle.id, bucketIndex);
6008
- };
6009
- #removeParticle = (index, group, override) => {
5412
+ }
5413
+ #removeParticle(index, group, override) {
6010
5414
  const particle = this.#array[index];
6011
5415
  if (!particle) {
6012
5416
  return false;
@@ -6022,22 +5426,20 @@
6022
5426
  });
6023
5427
  this.#addToPool(particle);
6024
5428
  return true;
6025
- };
6026
- #removeParticleFromBucket = (particle) => {
5429
+ }
5430
+ #removeParticleFromBucket(particle) {
6027
5431
  const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6028
5432
  if (!bucket) {
6029
5433
  this.#particleBuckets.delete(particle.id);
6030
5434
  return;
6031
5435
  }
6032
- const particleIndex = this.#getParticleInsertIndex(bucket, particle.id);
6033
- if (bucket[particleIndex]?.id !== particle.id) {
6034
- this.#particleBuckets.delete(particle.id);
6035
- return;
5436
+ const idx = bucket.findIndex(p => p.id === particle.id);
5437
+ if (idx >= minIndex) {
5438
+ bucket.splice(idx, deleteCount);
6036
5439
  }
6037
- bucket.splice(particleIndex, deleteCount);
6038
5440
  this.#particleBuckets.delete(particle.id);
6039
- };
6040
- #resetBuckets = (zLayers) => {
5441
+ }
5442
+ #resetBuckets(zLayers) {
6041
5443
  const bucketCount = Math.max(Math.floor(zLayers), one);
6042
5444
  if (this.#zBuckets.length !== bucketCount) {
6043
5445
  this.#zBuckets = this.#createBuckets(bucketCount);
@@ -6046,8 +5448,8 @@
6046
5448
  for (const bucket of this.#zBuckets) {
6047
5449
  bucket.length = minIndex;
6048
5450
  }
6049
- };
6050
- #updateParticleBucket = (particle) => {
5451
+ }
5452
+ #updateParticleBucket(particle) {
6051
5453
  const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
6052
5454
  if (currentBucketIndex === undefined) {
6053
5455
  this.#insertParticleIntoBucket(particle);
@@ -6058,9 +5460,9 @@
6058
5460
  }
6059
5461
  const currentBucket = this.#zBuckets[currentBucketIndex];
6060
5462
  if (currentBucket) {
6061
- const particleIndex = this.#getParticleInsertIndex(currentBucket, particle.id);
6062
- if (currentBucket[particleIndex]?.id === particle.id) {
6063
- currentBucket.splice(particleIndex, deleteCount);
5463
+ const idx = currentBucket.findIndex(p => p.id === particle.id);
5464
+ if (idx >= minIndex) {
5465
+ currentBucket.splice(idx, deleteCount);
6064
5466
  }
6065
5467
  }
6066
5468
  const newBucket = this.#zBuckets[newBucketIndex];
@@ -6068,10 +5470,16 @@
6068
5470
  this.#particleBuckets.set(particle.id, newBucketIndex);
6069
5471
  return;
6070
5472
  }
6071
- newBucket.splice(this.#getParticleInsertIndex(newBucket, particle.id), empty, particle);
5473
+ newBucket.push(particle);
5474
+ if (newBucket.length >= double) {
5475
+ const prev = newBucket[newBucket.length - double];
5476
+ if (prev && particle.id < prev.id) {
5477
+ newBucket.sort((a, b) => a.id - b.id);
5478
+ }
5479
+ }
6072
5480
  this.#particleBuckets.set(particle.id, newBucketIndex);
6073
- };
6074
- #updateParticlesPhase1 = (delta) => {
5481
+ }
5482
+ #updateParticlesPhase1(delta) {
6075
5483
  const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
6076
5484
  for (const particle of this.#array) {
6077
5485
  if (resizeFactor && !particle.ignoresResizeRatio) {
@@ -6097,8 +5505,8 @@
6097
5505
  this.grid.insert(particle);
6098
5506
  }
6099
5507
  return particlesToDelete;
6100
- };
6101
- #updateParticlesPhase2 = (delta, particlesToDelete) => {
5508
+ }
5509
+ #updateParticlesPhase2(delta, particlesToDelete) {
6102
5510
  for (const particle of this.#array) {
6103
5511
  if (particle.destroyed) {
6104
5512
  particlesToDelete.add(particle);
@@ -6114,7 +5522,7 @@
6114
5522
  }
6115
5523
  this.#updateParticleBucket(particle);
6116
5524
  }
6117
- };
5525
+ }
6118
5526
  }
6119
5527
 
6120
5528
  class Retina {
@@ -6476,7 +5884,7 @@
6476
5884
  }
6477
5885
  return refresh;
6478
5886
  }
6479
- #nextFrame = (timestamp) => {
5887
+ #nextFrame(timestamp) {
6480
5888
  try {
6481
5889
  if (!this.#smooth &&
6482
5890
  this.#lastFrameTime !== undefined &&
@@ -6504,7 +5912,7 @@
6504
5912
  catch (e) {
6505
5913
  getLogger().error("error in animation loop", e);
6506
5914
  }
6507
- };
5915
+ }
6508
5916
  }
6509
5917
 
6510
5918
  var Container$1 = /*#__PURE__*/Object.freeze({
@@ -6550,7 +5958,7 @@
6550
5958
  BlendPluginInstance: BlendPluginInstance
6551
5959
  });
6552
5960
 
6553
- const minVelocity = 0, identity = 1, moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
5961
+ const moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
6554
5962
  function applyDistance(particle) {
6555
5963
  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;
6556
5964
  if (!hDistance && !vDistance) {
@@ -6583,7 +5991,7 @@
6583
5991
  }
6584
5992
  function move(particle, moveOptions, moveSpeed, maxSpeed, moveDrift, reduceFactor, delta) {
6585
5993
  applyPath(particle, delta);
6586
- const gravityOptions = particle.gravity, gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity : identity;
5994
+ const gravityOptions = particle.gravity, gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity$1 : identity$1;
6587
5995
  if (moveDrift && moveSpeed) {
6588
5996
  particle.velocity.x += (moveDrift * delta.factor) / (moveSpeedFactor * moveSpeed);
6589
5997
  }
@@ -6603,7 +6011,7 @@
6603
6011
  particle.velocity.y = velocity.y / moveSpeed;
6604
6012
  }
6605
6013
  }
6606
- const zIndexOptions = particle.options.zIndex, zVelocityFactor = (identity - particle.zIndexFactor) ** zIndexOptions.velocityRate;
6014
+ const zIndexOptions = particle.options.zIndex, zVelocityFactor = (identity$1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
6607
6015
  velocity.multTo(zVelocityFactor);
6608
6016
  velocity.multTo(reduceFactor);
6609
6017
  const { position } = particle;
@@ -6629,13 +6037,13 @@
6629
6037
  const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height), halfMaxSize = maxCanvasSize * half;
6630
6038
  if (particle.spin.radius > halfMaxSize) {
6631
6039
  particle.spin.radius = halfMaxSize;
6632
- particle.spin.acceleration *= -identity;
6040
+ particle.spin.acceleration *= -identity$1;
6633
6041
  }
6634
6042
  else if (particle.spin.radius < minSpinRadius) {
6635
6043
  particle.spin.radius = minSpinRadius;
6636
- particle.spin.acceleration *= -identity;
6044
+ particle.spin.acceleration *= -identity$1;
6637
6045
  }
6638
- particle.spin.angle += moveSpeed * spinFactor * (identity - particle.spin.radius / maxCanvasSize);
6046
+ particle.spin.angle += moveSpeed * spinFactor * (identity$1 - particle.spin.radius / maxCanvasSize);
6639
6047
  }
6640
6048
  function applyPath(particle, delta) {
6641
6049
  const particlesOptions = particle.options, pathOptions = particlesOptions.move.path, pathEnabled = pathOptions.enable;
@@ -6652,13 +6060,13 @@
6652
6060
  particle.velocity.addTo(path);
6653
6061
  }
6654
6062
  if (pathOptions.clamp) {
6655
- particle.velocity.x = clamp(particle.velocity.x, -identity, identity);
6656
- particle.velocity.y = clamp(particle.velocity.y, -identity, identity);
6063
+ particle.velocity.x = clamp(particle.velocity.x, -identity$1, identity$1);
6064
+ particle.velocity.y = clamp(particle.velocity.y, -identity$1, identity$1);
6657
6065
  }
6658
6066
  particle.lastPathTime -= pathDelay;
6659
6067
  }
6660
6068
  function getProximitySpeedFactor(particle) {
6661
- return particle.slow.inRange ? particle.slow.factor : identity;
6069
+ return particle.slow.inRange ? particle.slow.factor : identity$1;
6662
6070
  }
6663
6071
  function initSpin(container, particle) {
6664
6072
  const options = particle.options, spinOptions = options.move.spin;
@@ -6825,7 +6233,7 @@
6825
6233
  removeListeners() {
6826
6234
  this.#manageListeners(false);
6827
6235
  }
6828
- #doMouseTouchClick = e => {
6236
+ #doMouseTouchClick(e) {
6829
6237
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions;
6830
6238
  if (this.#canPush) {
6831
6239
  const mouseInteractivity = interactionManager.interactivityData.mouse, mousePos = mouseInteractivity.position;
@@ -6847,11 +6255,11 @@
6847
6255
  this.#mouseTouchFinish();
6848
6256
  }, touchDelay);
6849
6257
  }
6850
- };
6851
- #handleVisibilityChange = () => {
6258
+ }
6259
+ #handleVisibilityChange() {
6852
6260
  this.#mouseTouchFinish();
6853
- };
6854
- #manageInteractivityListeners = add => {
6261
+ }
6262
+ #manageInteractivityListeners(add) {
6855
6263
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivityEl = interactionManager.interactivityData.element;
6856
6264
  if (!interactivityEl) {
6857
6265
  return;
@@ -6882,8 +6290,8 @@
6882
6290
  }
6883
6291
  manageListener(interactivityEl, mouseLeaveEvent, handlers.mouseLeave, add);
6884
6292
  manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
6885
- };
6886
- #manageListeners = add => {
6293
+ }
6294
+ #manageListeners(add) {
6887
6295
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.domElement;
6888
6296
  if (detectType === InteractivityDetect.window) {
6889
6297
  interactionManager.interactivityData.element = safeDocument();
@@ -6896,13 +6304,13 @@
6896
6304
  }
6897
6305
  this.#manageInteractivityListeners(add);
6898
6306
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
6899
- };
6900
- #mouseDown = () => {
6307
+ }
6308
+ #mouseDown() {
6901
6309
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
6902
6310
  mouse.clicking = true;
6903
6311
  mouse.downPosition = mouse.position;
6904
- };
6905
- #mouseTouchClick = e => {
6312
+ }
6313
+ #mouseTouchClick(e) {
6906
6314
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, { mouse } = interactionManager.interactivityData;
6907
6315
  mouse.inside = true;
6908
6316
  let handled = false;
@@ -6920,8 +6328,8 @@
6920
6328
  this.#doMouseTouchClick(e);
6921
6329
  }
6922
6330
  mouse.clicking = false;
6923
- };
6924
- #mouseTouchFinish = () => {
6331
+ }
6332
+ #mouseTouchFinish() {
6925
6333
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
6926
6334
  delete mouse.position;
6927
6335
  delete mouse.clickPosition;
@@ -6929,8 +6337,8 @@
6929
6337
  interactivityData.status = mouseLeaveEvent;
6930
6338
  mouse.inside = false;
6931
6339
  mouse.clicking = false;
6932
- };
6933
- #mouseTouchMove = e => {
6340
+ }
6341
+ #mouseTouchMove(e) {
6934
6342
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.domElement;
6935
6343
  if (!interactivity.element) {
6936
6344
  return;
@@ -6992,31 +6400,37 @@
6992
6400
  }
6993
6401
  interactivity.mouse.position = pos;
6994
6402
  interactivity.status = mouseMoveEvent;
6995
- };
6996
- #touchEnd = e => {
6403
+ }
6404
+ #touchEnd(e) {
6997
6405
  const evt = e, touches = Array.from(evt.changedTouches);
6998
6406
  for (const touch of touches) {
6999
6407
  this.#touches.delete(touch.identifier);
7000
6408
  }
7001
6409
  this.#mouseTouchFinish();
7002
- };
7003
- #touchEndClick = e => {
6410
+ }
6411
+ #touchEndClick(e) {
7004
6412
  const evt = e, touches = Array.from(evt.changedTouches);
7005
6413
  for (const touch of touches) {
7006
6414
  this.#touches.delete(touch.identifier);
7007
6415
  }
7008
6416
  this.#mouseTouchClick(e);
7009
- };
7010
- #touchStart = e => {
6417
+ }
6418
+ #touchStart(e) {
7011
6419
  const evt = e, touches = Array.from(evt.changedTouches);
7012
6420
  for (const touch of touches) {
7013
6421
  this.#touches.set(touch.identifier, performance.now());
7014
6422
  }
7015
6423
  this.#mouseTouchMove(e);
7016
- };
6424
+ }
7017
6425
  }
7018
6426
 
7019
6427
  const clickRadius = 1, touchEndLengthOffset = 1, minCoordinate = 0;
6428
+ function safeIntersectionObserver(callback) {
6429
+ if (typeof IntersectionObserver === "undefined") {
6430
+ return;
6431
+ }
6432
+ return new IntersectionObserver(callback);
6433
+ }
7020
6434
  class InteractionManager {
7021
6435
  interactivityData;
7022
6436
  #clickHandlers;
@@ -7219,7 +6633,7 @@
7219
6633
  const container = this.#container;
7220
6634
  container.particles.grid.setCellSize(maxTotalDistance * container.retina.pixelRatio);
7221
6635
  }
7222
- #intersectionManager = entries => {
6636
+ #intersectionManager(entries) {
7223
6637
  const container = this.#container;
7224
6638
  if (container.destroyed || !container.actualOptions.pauseOnOutsideViewport) {
7225
6639
  return;
@@ -7235,7 +6649,7 @@
7235
6649
  container.pause();
7236
6650
  }
7237
6651
  }
7238
- };
6652
+ }
7239
6653
  }
7240
6654
 
7241
6655
  class InteractivityPluginInstance {