@tsparticles/preset-links 4.1.3 → 4.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  (function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
- /* Preset v4.1.3 */
2
+ /* Preset v4.2.1 */
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", midColorValue = "mid", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
18
+ }, randomColorValue = "random", midColorValue = "mid", 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$2 = 0, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, maxNits = 400, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
19
19
 
20
20
  var MoveDirection;
21
21
  (function (MoveDirection) {
@@ -82,11 +82,6 @@
82
82
  div(n) {
83
83
  return Vector3d.create(this.x / n, this.y / n, this.z / n);
84
84
  }
85
- divTo(n) {
86
- this.x /= n;
87
- this.y /= n;
88
- this.z /= n;
89
- }
90
85
  getLengthSq() {
91
86
  return this.x ** squareExp + this.y ** squareExp;
92
87
  }
@@ -285,27 +280,6 @@
285
280
  return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
286
281
  }
287
282
 
288
- var AnimationMode;
289
- (function (AnimationMode) {
290
- AnimationMode["auto"] = "auto";
291
- AnimationMode["increase"] = "increase";
292
- AnimationMode["decrease"] = "decrease";
293
- AnimationMode["random"] = "random";
294
- })(AnimationMode || (AnimationMode = {}));
295
-
296
- var AnimationStatus;
297
- (function (AnimationStatus) {
298
- AnimationStatus["increasing"] = "increasing";
299
- AnimationStatus["decreasing"] = "decreasing";
300
- })(AnimationStatus || (AnimationStatus = {}));
301
-
302
- var DestroyType;
303
- (function (DestroyType) {
304
- DestroyType["none"] = "none";
305
- DestroyType["max"] = "max";
306
- DestroyType["min"] = "min";
307
- })(DestroyType || (DestroyType = {}));
308
-
309
283
  var OutModeDirection;
310
284
  (function (OutModeDirection) {
311
285
  OutModeDirection["bottom"] = "bottom";
@@ -320,67 +294,7 @@
320
294
  PixelMode["percent"] = "percent";
321
295
  })(PixelMode || (PixelMode = {}));
322
296
 
323
- var StartValueType;
324
- (function (StartValueType) {
325
- StartValueType["max"] = "max";
326
- StartValueType["min"] = "min";
327
- StartValueType["random"] = "random";
328
- })(StartValueType || (StartValueType = {}));
329
-
330
297
  const minRadius = 0;
331
- function memoize(fn, options) {
332
- const cache = new Map(), stableStringify = (obj, seen = new WeakSet()) => {
333
- if (obj === null) {
334
- return "null";
335
- }
336
- const t = typeof obj;
337
- if (t === "undefined") {
338
- return "undefined";
339
- }
340
- if (t === "number" || t === "boolean" || t === "string") {
341
- return JSON.stringify(obj);
342
- }
343
- if (t === "function") {
344
- try {
345
- const fn = obj;
346
- return fn.toString();
347
- }
348
- catch {
349
- return '"[Function]"';
350
- }
351
- }
352
- if (t === "symbol") {
353
- try {
354
- return obj.toString();
355
- }
356
- catch {
357
- return '"[Symbol]"';
358
- }
359
- }
360
- if (Array.isArray(obj)) {
361
- return `[${obj.map(i => stableStringify(i, seen)).join(",")}]`;
362
- }
363
- if (seen.has(obj)) {
364
- return '"[Circular]"';
365
- }
366
- seen.add(obj);
367
- const keys = Object.keys(obj).sort();
368
- return `{${keys.map(k => `${JSON.stringify(k)}:${stableStringify(obj[k], seen)}`).join(",")}}`;
369
- }, defaultKeyer = (args) => stableStringify(args), makeKey = (args) => (defaultKeyer(args));
370
- return (...args) => {
371
- const key = makeKey(args), now = Date.now(), entry = cache.get(key);
372
- if (entry !== undefined) {
373
- {
374
- cache.delete(key);
375
- cache.set(key, { value: entry.value, ts: entry.ts });
376
- return entry.value;
377
- }
378
- }
379
- const result = fn(...args);
380
- cache.set(key, { value: result, ts: now });
381
- return result;
382
- };
383
- }
384
298
  function hasMatchMedia() {
385
299
  return typeof matchMedia !== "undefined";
386
300
  }
@@ -393,12 +307,6 @@
393
307
  }
394
308
  return matchMedia(query);
395
309
  }
396
- function safeIntersectionObserver(callback) {
397
- if (typeof IntersectionObserver === "undefined") {
398
- return;
399
- }
400
- return new IntersectionObserver(callback);
401
- }
402
310
  function safeMutationObserver(callback) {
403
311
  if (typeof MutationObserver === "undefined") {
404
312
  return;
@@ -408,11 +316,8 @@
408
316
  function isInArray(value, array) {
409
317
  return value === array || (isArray(array) && array.includes(value));
410
318
  }
411
- function arrayRandomIndex(array) {
412
- return Math.floor(getRandom() * array.length);
413
- }
414
319
  function itemFromArray(array, index, useIndex = true) {
415
- return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
320
+ return array[index !== undefined && useIndex ? index % array.length : Math.floor(getRandom() * array.length)];
416
321
  }
417
322
  function isPointInside(point, size, offset, radius, direction) {
418
323
  return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
@@ -496,56 +401,6 @@
496
401
  function itemFromSingleOrMultiple(obj, index, useIndex) {
497
402
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
498
403
  }
499
- function initParticleNumericAnimationValue(options, pxRatio) {
500
- const valueRange = options.value, animationOptions = options.animation, res = {
501
- delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
502
- enable: animationOptions.enable,
503
- value: getRangeValue(options.value) * pxRatio,
504
- max: getRangeMax(valueRange) * pxRatio,
505
- min: getRangeMin(valueRange) * pxRatio,
506
- loops: 0,
507
- maxLoops: getRangeValue(animationOptions.count),
508
- time: 0,
509
- }, decayOffset = 1;
510
- if (animationOptions.enable) {
511
- res.decay = decayOffset - getRangeValue(animationOptions.decay);
512
- switch (animationOptions.mode) {
513
- case AnimationMode.increase:
514
- res.status = AnimationStatus.increasing;
515
- break;
516
- case AnimationMode.decrease:
517
- res.status = AnimationStatus.decreasing;
518
- break;
519
- case AnimationMode.random:
520
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
521
- break;
522
- }
523
- const autoStatus = animationOptions.mode === AnimationMode.auto;
524
- switch (animationOptions.startValue) {
525
- case StartValueType.min:
526
- res.value = res.min;
527
- if (autoStatus) {
528
- res.status = AnimationStatus.increasing;
529
- }
530
- break;
531
- case StartValueType.max:
532
- res.value = res.max;
533
- if (autoStatus) {
534
- res.status = AnimationStatus.decreasing;
535
- }
536
- break;
537
- case StartValueType.random:
538
- default:
539
- res.value = randomInRangeValue(res);
540
- if (autoStatus) {
541
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
542
- }
543
- break;
544
- }
545
- }
546
- res.initialValue = res.value;
547
- return res;
548
- }
549
404
  function getPositionOrSize(positionOrSize, canvasSize) {
550
405
  const isPercent = positionOrSize.mode === PixelMode.percent;
551
406
  if (!isPercent) {
@@ -569,71 +424,6 @@
569
424
  function getPosition(position, canvasSize) {
570
425
  return getPositionOrSize(position, canvasSize);
571
426
  }
572
- function checkDestroy(particle, destroyType, value, minValue, maxValue) {
573
- switch (destroyType) {
574
- case DestroyType.max:
575
- if (value >= maxValue) {
576
- particle.destroy();
577
- }
578
- break;
579
- case DestroyType.min:
580
- if (value <= minValue) {
581
- particle.destroy();
582
- }
583
- break;
584
- }
585
- }
586
- function updateAnimation(particle, data, changeDirection, destroyType, delta) {
587
- const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
588
- if (particle.destroyed ||
589
- !data.enable ||
590
- ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
591
- return;
592
- }
593
- const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
594
- data.time ??= 0;
595
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
596
- data.time += delta.value;
597
- }
598
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
599
- return;
600
- }
601
- switch (data.status) {
602
- case AnimationStatus.increasing:
603
- data.value += velocity;
604
- break;
605
- case AnimationStatus.decreasing:
606
- data.value -= velocity;
607
- break;
608
- }
609
- if (data.velocity && decay !== identity) {
610
- data.velocity *= decay;
611
- }
612
- switch (data.status) {
613
- case AnimationStatus.increasing:
614
- if (data.value >= maxValue) {
615
- {
616
- data.status = AnimationStatus.decreasing;
617
- }
618
- data.loops ??= minLoops;
619
- data.loops++;
620
- }
621
- break;
622
- case AnimationStatus.decreasing:
623
- if (data.value <= minValue) {
624
- {
625
- data.status = AnimationStatus.increasing;
626
- }
627
- data.loops ??= minLoops;
628
- data.loops++;
629
- }
630
- break;
631
- }
632
- checkDestroy(particle, destroyType, data.value, minValue, maxValue);
633
- if (!particle.destroyed) {
634
- data.value = clamp(data.value, minValue, maxValue);
635
- }
636
- }
637
427
  function cloneStyle(style) {
638
428
  const clonedStyle = safeDocument().createElement("div").style;
639
429
  for (const key in style) {
@@ -655,30 +445,34 @@
655
445
  }
656
446
  return clonedStyle;
657
447
  }
658
- function computeFullScreenStyle(zIndex) {
659
- const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
660
- width: "100%",
661
- height: "100%",
662
- margin: "0",
663
- padding: "0",
664
- borderWidth: "0",
665
- position: "fixed",
666
- zIndex: zIndex.toString(radix),
667
- "z-index": zIndex.toString(radix),
668
- top: "0",
669
- left: "0",
670
- "pointer-events": "none",
671
- };
672
- for (const key in style) {
673
- const value = style[key];
674
- if (value === undefined) {
675
- continue;
448
+ let _cachedZIndex, _cachedStyle;
449
+ function getFullScreenStyle(zIndex) {
450
+ if (_cachedZIndex !== zIndex || !_cachedStyle) {
451
+ _cachedZIndex = zIndex;
452
+ const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
453
+ width: "100%",
454
+ height: "100%",
455
+ margin: "0",
456
+ padding: "0",
457
+ borderWidth: "0",
458
+ position: "fixed",
459
+ zIndex: zIndex.toString(radix),
460
+ "z-index": zIndex.toString(radix),
461
+ top: "0",
462
+ left: "0",
463
+ "pointer-events": "none",
464
+ };
465
+ for (const key in style) {
466
+ const value = style[key];
467
+ if (value === undefined) {
468
+ continue;
469
+ }
470
+ fullScreenStyle.setProperty(key, value);
676
471
  }
677
- fullScreenStyle.setProperty(key, value);
472
+ _cachedStyle = fullScreenStyle;
678
473
  }
679
- return fullScreenStyle;
474
+ return _cachedStyle;
680
475
  }
681
- const getFullScreenStyle = memoize(computeFullScreenStyle);
682
476
  function manageListener(element, event, handler, add, options) {
683
477
  if (add) {
684
478
  let addOptions = { passive: true };
@@ -1005,7 +799,7 @@
1005
799
  return this.#domArray;
1006
800
  }
1007
801
  get version() {
1008
- return "4.1.3";
802
+ return "4.2.1";
1009
803
  }
1010
804
  addEventListener(type, listener) {
1011
805
  this.#eventDispatcher.addEventListener(type, listener);
@@ -1175,6 +969,14 @@
1175
969
  RotateDirection["random"] = "random";
1176
970
  })(RotateDirection || (RotateDirection = {}));
1177
971
 
972
+ var AnimationMode;
973
+ (function (AnimationMode) {
974
+ AnimationMode["auto"] = "auto";
975
+ AnimationMode["increase"] = "increase";
976
+ AnimationMode["decrease"] = "decrease";
977
+ AnimationMode["random"] = "random";
978
+ })(AnimationMode || (AnimationMode = {}));
979
+
1178
980
  var LimitMode;
1179
981
  (function (LimitMode) {
1180
982
  LimitMode["delete"] = "delete";
@@ -1196,6 +998,13 @@
1196
998
  AlterType["enlighten"] = "enlighten";
1197
999
  })(AlterType || (AlterType = {}));
1198
1000
 
1001
+ var DestroyType;
1002
+ (function (DestroyType) {
1003
+ DestroyType["none"] = "none";
1004
+ DestroyType["max"] = "max";
1005
+ DestroyType["min"] = "min";
1006
+ })(DestroyType || (DestroyType = {}));
1007
+
1199
1008
  var GradientType;
1200
1009
  (function (GradientType) {
1201
1010
  GradientType["linear"] = "linear";
@@ -1210,160 +1019,121 @@
1210
1019
  ParticleOutType["outside"] = "outside";
1211
1020
  })(ParticleOutType || (ParticleOutType = {}));
1212
1021
 
1213
- var EasingType;
1214
- (function (EasingType) {
1215
- EasingType["easeInBack"] = "ease-in-back";
1216
- EasingType["easeInBounce"] = "ease-in-bounce";
1217
- EasingType["easeInCirc"] = "ease-in-circ";
1218
- EasingType["easeInCubic"] = "ease-in-cubic";
1219
- EasingType["easeInElastic"] = "ease-in-elastic";
1220
- EasingType["easeInExpo"] = "ease-in-expo";
1221
- EasingType["easeInGaussian"] = "ease-in-gaussian";
1222
- EasingType["easeInLinear"] = "ease-in-linear";
1223
- EasingType["easeInQuad"] = "ease-in-quad";
1224
- EasingType["easeInQuart"] = "ease-in-quart";
1225
- EasingType["easeInQuint"] = "ease-in-quint";
1226
- EasingType["easeInSigmoid"] = "ease-in-sigmoid";
1227
- EasingType["easeInSine"] = "ease-in-sine";
1228
- EasingType["easeInSmoothstep"] = "ease-in-smoothstep";
1229
- EasingType["easeOutBack"] = "ease-out-back";
1230
- EasingType["easeOutBounce"] = "ease-out-bounce";
1231
- EasingType["easeOutCirc"] = "ease-out-circ";
1232
- EasingType["easeOutCubic"] = "ease-out-cubic";
1233
- EasingType["easeOutElastic"] = "ease-out-elastic";
1234
- EasingType["easeOutExpo"] = "ease-out-expo";
1235
- EasingType["easeOutGaussian"] = "ease-out-gaussian";
1236
- EasingType["easeOutLinear"] = "ease-out-linear";
1237
- EasingType["easeOutQuad"] = "ease-out-quad";
1238
- EasingType["easeOutQuart"] = "ease-out-quart";
1239
- EasingType["easeOutQuint"] = "ease-out-quint";
1240
- EasingType["easeOutSigmoid"] = "ease-out-sigmoid";
1241
- EasingType["easeOutSine"] = "ease-out-sine";
1242
- EasingType["easeOutSmoothstep"] = "ease-out-smoothstep";
1243
- EasingType["easeInOutBack"] = "ease-in-out-back";
1244
- EasingType["easeInOutBounce"] = "ease-in-out-bounce";
1245
- EasingType["easeInOutCirc"] = "ease-in-out-circ";
1246
- EasingType["easeInOutCubic"] = "ease-in-out-cubic";
1247
- EasingType["easeInOutElastic"] = "ease-in-out-elastic";
1248
- EasingType["easeInOutExpo"] = "ease-in-out-expo";
1249
- EasingType["easeInOutGaussian"] = "ease-in-out-gaussian";
1250
- EasingType["easeInOutLinear"] = "ease-in-out-linear";
1251
- EasingType["easeInOutQuad"] = "ease-in-out-quad";
1252
- EasingType["easeInOutQuart"] = "ease-in-out-quart";
1253
- EasingType["easeInOutQuint"] = "ease-in-out-quint";
1254
- EasingType["easeInOutSigmoid"] = "ease-in-out-sigmoid";
1255
- EasingType["easeInOutSine"] = "ease-in-out-sine";
1256
- EasingType["easeInOutSmoothstep"] = "ease-in-out-smoothstep";
1257
- })(EasingType || (EasingType = {}));
1258
-
1259
- class AnimationOptions {
1260
- count;
1261
- decay;
1262
- delay;
1263
- enable;
1264
- speed;
1265
- sync;
1266
- constructor() {
1267
- this.count = 0;
1268
- this.enable = false;
1269
- this.speed = 1;
1270
- this.decay = 0;
1271
- this.delay = 0;
1272
- this.sync = false;
1273
- }
1022
+ var StartValueType;
1023
+ (function (StartValueType) {
1024
+ StartValueType["max"] = "max";
1025
+ StartValueType["min"] = "min";
1026
+ StartValueType["random"] = "random";
1027
+ })(StartValueType || (StartValueType = {}));
1028
+
1029
+ var AnimationStatus;
1030
+ (function (AnimationStatus) {
1031
+ AnimationStatus["increasing"] = "increasing";
1032
+ AnimationStatus["decreasing"] = "decreasing";
1033
+ })(AnimationStatus || (AnimationStatus = {}));
1034
+
1035
+ class OptionLoader {
1274
1036
  load(data) {
1275
1037
  if (isNull(data)) {
1276
1038
  return;
1277
1039
  }
1278
- if (data.count !== undefined) {
1279
- this.count = setRangeValue(data.count);
1280
- }
1281
- if (data.enable !== undefined) {
1282
- this.enable = data.enable;
1283
- }
1284
- if (data.speed !== undefined) {
1285
- this.speed = setRangeValue(data.speed);
1286
- }
1287
- if (data.decay !== undefined) {
1288
- this.decay = setRangeValue(data.decay);
1289
- }
1290
- if (data.delay !== undefined) {
1291
- this.delay = setRangeValue(data.delay);
1292
- }
1293
- if (data.sync !== undefined) {
1294
- this.sync = data.sync;
1295
- }
1040
+ this.doLoad(data);
1296
1041
  }
1297
1042
  }
1298
- class RangedAnimationOptions extends AnimationOptions {
1299
- mode;
1300
- startValue;
1301
- constructor() {
1302
- super();
1303
- this.mode = AnimationMode.auto;
1304
- this.startValue = StartValueType.random;
1043
+ function loadOptions(options, ...sourceOptionsArr) {
1044
+ for (const sourceOptions of sourceOptionsArr) {
1045
+ options.load(sourceOptions);
1305
1046
  }
1306
- load(data) {
1307
- super.load(data);
1308
- if (isNull(data)) {
1309
- return;
1310
- }
1311
- if (data.mode !== undefined) {
1312
- this.mode = data.mode;
1313
- }
1314
- if (data.startValue !== undefined) {
1315
- this.startValue = data.startValue;
1316
- }
1047
+ }
1048
+
1049
+ function loadProperty(obj, key, value) {
1050
+ if (value !== undefined) {
1051
+ obj[key] = value;
1052
+ }
1053
+ }
1054
+ function loadRangeProperty(obj, key, value) {
1055
+ if (value !== undefined) {
1056
+ obj[key] = setRangeValue(value);
1057
+ }
1058
+ }
1059
+ function loadNestedProperty(obj, key, value) {
1060
+ if (value !== undefined) {
1061
+ obj[key].load(value);
1062
+ }
1063
+ }
1064
+ function loadLazyProperty(obj, key, value, factory) {
1065
+ if (value !== undefined) {
1066
+ const objRecord = obj;
1067
+ objRecord[key] ??= factory();
1068
+ objRecord[key].load(value);
1069
+ }
1070
+ }
1071
+ function loadOptionProperty(obj, key, optionClass, ...sources) {
1072
+ const objRecord = obj;
1073
+ objRecord[key] ??= new optionClass();
1074
+ const target = objRecord[key];
1075
+ for (const source of sources) {
1076
+ target.load(source?.[key]);
1077
+ }
1078
+ }
1079
+
1080
+ class AnimationOptions extends OptionLoader {
1081
+ count = 0;
1082
+ decay = 0;
1083
+ delay = 0;
1084
+ enable = false;
1085
+ speed = 1;
1086
+ sync = false;
1087
+ doLoad(data) {
1088
+ loadRangeProperty(this, "count", data.count);
1089
+ loadProperty(this, "enable", data.enable);
1090
+ loadRangeProperty(this, "speed", data.speed);
1091
+ loadRangeProperty(this, "decay", data.decay);
1092
+ loadRangeProperty(this, "delay", data.delay);
1093
+ loadProperty(this, "sync", data.sync);
1094
+ }
1095
+ }
1096
+ class RangedAnimationOptions extends AnimationOptions {
1097
+ mode = AnimationMode.auto;
1098
+ startValue = StartValueType.random;
1099
+ doLoad(data) {
1100
+ super.doLoad(data);
1101
+ loadProperty(this, "mode", data.mode);
1102
+ loadProperty(this, "startValue", data.startValue);
1317
1103
  }
1318
1104
  }
1319
1105
 
1320
1106
  class ColorAnimation extends AnimationOptions {
1321
1107
  max;
1322
1108
  min;
1323
- offset;
1109
+ offset = 0;
1110
+ sync = true;
1324
1111
  constructor(min, max) {
1325
1112
  super();
1326
1113
  this.min = min;
1327
1114
  this.max = max;
1328
- this.offset = 0;
1329
- this.sync = true;
1330
1115
  }
1331
- load(data) {
1332
- super.load(data);
1333
- if (isNull(data)) {
1334
- return;
1335
- }
1336
- if (data.max !== undefined) {
1337
- this.max = data.max;
1338
- }
1339
- if (data.min !== undefined) {
1340
- this.min = data.min;
1341
- }
1342
- if (data.offset !== undefined) {
1343
- this.offset = setRangeValue(data.offset);
1344
- }
1116
+ doLoad(data) {
1117
+ super.doLoad(data);
1118
+ loadProperty(this, "max", data.max);
1119
+ loadProperty(this, "min", data.min);
1120
+ loadRangeProperty(this, "offset", data.offset);
1345
1121
  }
1346
1122
  }
1347
1123
 
1348
- class HslAnimation {
1124
+ class HslAnimation extends OptionLoader {
1349
1125
  h = new ColorAnimation(hMin, hMax);
1350
1126
  l = new ColorAnimation(lMin, lMax);
1351
1127
  s = new ColorAnimation(sMin, sMax);
1352
- load(data) {
1353
- if (isNull(data)) {
1354
- return;
1355
- }
1128
+ doLoad(data) {
1356
1129
  this.h.load(data.h);
1357
1130
  this.s.load(data.s);
1358
1131
  this.l.load(data.l);
1359
1132
  }
1360
1133
  }
1361
1134
 
1362
- class OptionsColor {
1363
- value;
1364
- constructor() {
1365
- this.value = "";
1366
- }
1135
+ class OptionsColor extends OptionLoader {
1136
+ value = "";
1367
1137
  static create(source, data) {
1368
1138
  const color = new OptionsColor();
1369
1139
  color.load(source);
@@ -1377,10 +1147,7 @@
1377
1147
  }
1378
1148
  return color;
1379
1149
  }
1380
- load(data) {
1381
- if (isNull(data)) {
1382
- return;
1383
- }
1150
+ doLoad(data) {
1384
1151
  if (!isNull(data.value)) {
1385
1152
  this.value = data.value;
1386
1153
  }
@@ -1388,11 +1155,7 @@
1388
1155
  }
1389
1156
 
1390
1157
  class AnimatableColor extends OptionsColor {
1391
- animation;
1392
- constructor() {
1393
- super();
1394
- this.animation = new HslAnimation();
1395
- }
1158
+ animation = new HslAnimation();
1396
1159
  static create(source, data) {
1397
1160
  const color = new AnimatableColor();
1398
1161
  color.load(source);
@@ -1406,11 +1169,8 @@
1406
1169
  }
1407
1170
  return color;
1408
1171
  }
1409
- load(data) {
1410
- super.load(data);
1411
- if (isNull(data)) {
1412
- return;
1413
- }
1172
+ doLoad(data) {
1173
+ super.doLoad(data);
1414
1174
  const colorAnimation = data.animation;
1415
1175
  if (colorAnimation !== undefined) {
1416
1176
  if (colorAnimation.enable === undefined) {
@@ -1423,100 +1183,53 @@
1423
1183
  }
1424
1184
  }
1425
1185
 
1426
- class Background {
1186
+ class Background extends OptionLoader {
1427
1187
  color;
1428
- image;
1429
- opacity;
1430
- position;
1431
- repeat;
1432
- size;
1188
+ image = "";
1189
+ opacity = 1;
1190
+ position = "";
1191
+ repeat = "";
1192
+ size = "";
1433
1193
  constructor() {
1194
+ super();
1434
1195
  this.color = new OptionsColor();
1435
1196
  this.color.value = "";
1436
- this.image = "";
1437
- this.position = "";
1438
- this.repeat = "";
1439
- this.size = "";
1440
- this.opacity = 1;
1441
1197
  }
1442
- load(data) {
1443
- if (isNull(data)) {
1444
- return;
1445
- }
1198
+ doLoad(data) {
1446
1199
  if (data.color !== undefined) {
1447
1200
  this.color = OptionsColor.create(this.color, data.color);
1448
1201
  }
1449
- if (data.image !== undefined) {
1450
- this.image = data.image;
1451
- }
1452
- if (data.position !== undefined) {
1453
- this.position = data.position;
1454
- }
1455
- if (data.repeat !== undefined) {
1456
- this.repeat = data.repeat;
1457
- }
1458
- if (data.size !== undefined) {
1459
- this.size = data.size;
1460
- }
1461
- if (data.opacity !== undefined) {
1462
- this.opacity = data.opacity;
1463
- }
1202
+ loadProperty(this, "image", data.image);
1203
+ loadProperty(this, "position", data.position);
1204
+ loadProperty(this, "repeat", data.repeat);
1205
+ loadProperty(this, "size", data.size);
1206
+ loadProperty(this, "opacity", data.opacity);
1464
1207
  }
1465
1208
  }
1466
1209
 
1467
- class FullScreen {
1468
- enable;
1469
- zIndex;
1470
- constructor() {
1471
- this.enable = true;
1472
- this.zIndex = 0;
1473
- }
1474
- load(data) {
1475
- if (isNull(data)) {
1476
- return;
1477
- }
1478
- if (data.enable !== undefined) {
1479
- this.enable = data.enable;
1480
- }
1481
- if (data.zIndex !== undefined) {
1482
- this.zIndex = data.zIndex;
1483
- }
1210
+ class FullScreen extends OptionLoader {
1211
+ enable = true;
1212
+ zIndex = 0;
1213
+ doLoad(data) {
1214
+ loadProperty(this, "enable", data.enable);
1215
+ loadProperty(this, "zIndex", data.zIndex);
1484
1216
  }
1485
1217
  }
1486
1218
 
1487
- class ResizeEvent {
1488
- delay;
1489
- enable;
1490
- constructor() {
1491
- this.delay = 0.5;
1492
- this.enable = true;
1493
- }
1494
- load(data) {
1495
- if (isNull(data)) {
1496
- return;
1497
- }
1498
- if (data.delay !== undefined) {
1499
- this.delay = data.delay;
1500
- }
1501
- if (data.enable !== undefined) {
1502
- this.enable = data.enable;
1503
- }
1219
+ class ResizeEvent extends OptionLoader {
1220
+ delay = 0.5;
1221
+ enable = true;
1222
+ doLoad(data) {
1223
+ loadProperty(this, "delay", data.delay);
1224
+ loadProperty(this, "enable", data.enable);
1504
1225
  }
1505
1226
  }
1506
1227
 
1507
- class Effect {
1508
- close;
1509
- options;
1510
- type;
1511
- constructor() {
1512
- this.close = true;
1513
- this.options = {};
1514
- this.type = [];
1515
- }
1516
- load(data) {
1517
- if (isNull(data)) {
1518
- return;
1519
- }
1228
+ class Effect extends OptionLoader {
1229
+ close = true;
1230
+ options = {};
1231
+ type = [];
1232
+ doLoad(data) {
1520
1233
  const options = data.options;
1521
1234
  if (options !== undefined) {
1522
1235
  for (const effect in options) {
@@ -1526,128 +1239,62 @@
1526
1239
  }
1527
1240
  }
1528
1241
  }
1529
- if (data.close !== undefined) {
1530
- this.close = data.close;
1531
- }
1532
- if (data.type !== undefined) {
1533
- this.type = data.type;
1534
- }
1242
+ loadProperty(this, "close", data.close);
1243
+ loadProperty(this, "type", data.type);
1535
1244
  }
1536
1245
  }
1537
1246
 
1538
- class Fill {
1247
+ class Fill extends OptionLoader {
1539
1248
  color;
1540
- enable;
1541
- opacity;
1542
- constructor() {
1543
- this.enable = true;
1544
- this.opacity = 1;
1545
- }
1546
- load(data) {
1547
- if (isNull(data)) {
1548
- return;
1549
- }
1249
+ enable = true;
1250
+ opacity = 1;
1251
+ doLoad(data) {
1550
1252
  if (data.color !== undefined) {
1551
1253
  this.color = AnimatableColor.create(this.color, data.color);
1552
1254
  }
1553
- if (data.enable !== undefined) {
1554
- this.enable = data.enable;
1555
- }
1556
- if (data.opacity !== undefined) {
1557
- this.opacity = setRangeValue(data.opacity);
1558
- }
1255
+ loadProperty(this, "enable", data.enable);
1256
+ loadRangeProperty(this, "opacity", data.opacity);
1559
1257
  }
1560
1258
  }
1561
1259
 
1562
- class MoveAngle {
1563
- offset;
1564
- value;
1565
- constructor() {
1566
- this.offset = 0;
1567
- this.value = 90;
1568
- }
1569
- load(data) {
1570
- if (isNull(data)) {
1571
- return;
1572
- }
1573
- if (data.offset !== undefined) {
1574
- this.offset = setRangeValue(data.offset);
1575
- }
1576
- if (data.value !== undefined) {
1577
- this.value = setRangeValue(data.value);
1578
- }
1260
+ class MoveAngle extends OptionLoader {
1261
+ offset = 0;
1262
+ value = 90;
1263
+ doLoad(data) {
1264
+ loadRangeProperty(this, "offset", data.offset);
1265
+ loadRangeProperty(this, "value", data.value);
1579
1266
  }
1580
1267
  }
1581
1268
 
1582
- class MoveCenter {
1583
- mode;
1584
- radius;
1585
- x;
1586
- y;
1587
- constructor() {
1588
- this.x = 50;
1589
- this.y = 50;
1590
- this.mode = PixelMode.percent;
1591
- this.radius = 0;
1592
- }
1593
- load(data) {
1594
- if (isNull(data)) {
1595
- return;
1596
- }
1597
- if (data.x !== undefined) {
1598
- this.x = data.x;
1599
- }
1600
- if (data.y !== undefined) {
1601
- this.y = data.y;
1602
- }
1603
- if (data.mode !== undefined) {
1604
- this.mode = data.mode;
1605
- }
1606
- if (data.radius !== undefined) {
1607
- this.radius = data.radius;
1608
- }
1269
+ class MoveCenter extends OptionLoader {
1270
+ mode = PixelMode.percent;
1271
+ radius = 0;
1272
+ x = 50;
1273
+ y = 50;
1274
+ doLoad(data) {
1275
+ loadProperty(this, "x", data.x);
1276
+ loadProperty(this, "y", data.y);
1277
+ loadProperty(this, "mode", data.mode);
1278
+ loadProperty(this, "radius", data.radius);
1609
1279
  }
1610
1280
  }
1611
1281
 
1612
- class MoveGravity {
1613
- acceleration;
1614
- enable;
1615
- inverse;
1616
- maxSpeed;
1617
- constructor() {
1618
- this.acceleration = 9.81;
1619
- this.enable = false;
1620
- this.inverse = false;
1621
- this.maxSpeed = 50;
1622
- }
1623
- load(data) {
1624
- if (isNull(data)) {
1625
- return;
1626
- }
1627
- if (data.acceleration !== undefined) {
1628
- this.acceleration = setRangeValue(data.acceleration);
1629
- }
1630
- if (data.enable !== undefined) {
1631
- this.enable = data.enable;
1632
- }
1633
- if (data.inverse !== undefined) {
1634
- this.inverse = data.inverse;
1635
- }
1636
- if (data.maxSpeed !== undefined) {
1637
- this.maxSpeed = setRangeValue(data.maxSpeed);
1638
- }
1282
+ class MoveGravity extends OptionLoader {
1283
+ acceleration = 9.81;
1284
+ enable = false;
1285
+ inverse = false;
1286
+ maxSpeed = 50;
1287
+ doLoad(data) {
1288
+ loadRangeProperty(this, "acceleration", data.acceleration);
1289
+ loadProperty(this, "enable", data.enable);
1290
+ loadProperty(this, "inverse", data.inverse);
1291
+ loadRangeProperty(this, "maxSpeed", data.maxSpeed);
1639
1292
  }
1640
1293
  }
1641
1294
 
1642
- class ValueWithRandom {
1643
- value;
1644
- constructor() {
1645
- this.value = 0;
1646
- }
1647
- load(data) {
1648
- if (isNull(data)) {
1649
- return;
1650
- }
1295
+ class ValueWithRandom extends OptionLoader {
1296
+ value = 0;
1297
+ doLoad(data) {
1651
1298
  if (!isNull(data.value)) {
1652
1299
  this.value = setRangeValue(data.value);
1653
1300
  }
@@ -1655,51 +1302,25 @@
1655
1302
  }
1656
1303
  class AnimationValueWithRandom extends ValueWithRandom {
1657
1304
  animation = new AnimationOptions();
1658
- load(data) {
1659
- super.load(data);
1660
- if (isNull(data)) {
1661
- return;
1662
- }
1663
- const animation = data.animation;
1664
- if (animation !== undefined) {
1665
- this.animation.load(animation);
1666
- }
1305
+ doLoad(data) {
1306
+ super.doLoad(data);
1307
+ loadNestedProperty(this, "animation", data.animation);
1667
1308
  }
1668
1309
  }
1669
1310
  class RangedAnimationValueWithRandom extends AnimationValueWithRandom {
1670
- animation;
1671
- constructor() {
1672
- super();
1673
- this.animation = new RangedAnimationOptions();
1674
- }
1675
- load(data) {
1676
- super.load(data);
1677
- }
1311
+ animation = new RangedAnimationOptions();
1678
1312
  }
1679
1313
 
1680
- class MovePath {
1681
- clamp;
1682
- delay;
1683
- enable;
1314
+ class MovePath extends OptionLoader {
1315
+ clamp = true;
1316
+ delay = new ValueWithRandom();
1317
+ enable = false;
1684
1318
  generator;
1685
- options;
1686
- constructor() {
1687
- this.clamp = true;
1688
- this.delay = new ValueWithRandom();
1689
- this.enable = false;
1690
- this.options = {};
1691
- }
1692
- load(data) {
1693
- if (isNull(data)) {
1694
- return;
1695
- }
1696
- if (data.clamp !== undefined) {
1697
- this.clamp = data.clamp;
1698
- }
1319
+ options = {};
1320
+ doLoad(data) {
1321
+ loadProperty(this, "clamp", data.clamp);
1699
1322
  this.delay.load(data.delay);
1700
- if (data.enable !== undefined) {
1701
- this.enable = data.enable;
1702
- }
1323
+ loadProperty(this, "enable", data.enable);
1703
1324
  this.generator = data.generator;
1704
1325
  if (data.options) {
1705
1326
  this.options = deepExtend(this.options, data.options);
@@ -1707,19 +1328,13 @@
1707
1328
  }
1708
1329
  }
1709
1330
 
1710
- class OutModes {
1331
+ class OutModes extends OptionLoader {
1711
1332
  bottom;
1712
- default;
1333
+ default = OutMode.out;
1713
1334
  left;
1714
1335
  right;
1715
1336
  top;
1716
- constructor() {
1717
- this.default = OutMode.out;
1718
- }
1719
- load(data) {
1720
- if (isNull(data)) {
1721
- return;
1722
- }
1337
+ doLoad(data) {
1723
1338
  if (data.default !== undefined) {
1724
1339
  this.default = data.default;
1725
1340
  }
@@ -1730,79 +1345,42 @@
1730
1345
  }
1731
1346
  }
1732
1347
 
1733
- class Spin {
1734
- acceleration;
1735
- enable;
1348
+ class Spin extends OptionLoader {
1349
+ acceleration = 0;
1350
+ enable = false;
1736
1351
  position;
1737
- constructor() {
1738
- this.acceleration = 0;
1739
- this.enable = false;
1740
- }
1741
- load(data) {
1742
- if (isNull(data)) {
1743
- return;
1744
- }
1745
- if (data.acceleration !== undefined) {
1746
- this.acceleration = setRangeValue(data.acceleration);
1747
- }
1748
- if (data.enable !== undefined) {
1749
- this.enable = data.enable;
1750
- }
1352
+ doLoad(data) {
1353
+ loadRangeProperty(this, "acceleration", data.acceleration);
1354
+ loadProperty(this, "enable", data.enable);
1751
1355
  if (data.position) {
1752
1356
  this.position = deepExtend({}, data.position);
1753
1357
  }
1754
1358
  }
1755
1359
  }
1756
1360
 
1757
- class Move {
1758
- angle;
1759
- center;
1760
- decay;
1761
- direction;
1762
- distance;
1763
- drift;
1764
- enable;
1765
- gravity;
1766
- outModes;
1767
- path;
1768
- random;
1769
- size;
1770
- speed;
1771
- spin;
1772
- straight;
1773
- vibrate;
1774
- warp;
1775
- constructor() {
1776
- this.angle = new MoveAngle();
1777
- this.center = new MoveCenter();
1778
- this.decay = 0;
1779
- this.distance = {};
1780
- this.direction = MoveDirection.none;
1781
- this.drift = 0;
1782
- this.enable = false;
1783
- this.gravity = new MoveGravity();
1784
- this.path = new MovePath();
1785
- this.outModes = new OutModes();
1786
- this.random = false;
1787
- this.size = false;
1788
- this.speed = 2;
1789
- this.spin = new Spin();
1790
- this.straight = false;
1791
- this.vibrate = false;
1792
- this.warp = false;
1793
- }
1794
- load(data) {
1795
- if (isNull(data)) {
1796
- return;
1797
- }
1361
+ class Move extends OptionLoader {
1362
+ angle = new MoveAngle();
1363
+ center = new MoveCenter();
1364
+ decay = 0;
1365
+ direction = MoveDirection.none;
1366
+ distance = {};
1367
+ drift = 0;
1368
+ enable = false;
1369
+ gravity = new MoveGravity();
1370
+ outModes = new OutModes();
1371
+ path = new MovePath();
1372
+ random = false;
1373
+ size = false;
1374
+ speed = 2;
1375
+ spin = new Spin();
1376
+ straight = false;
1377
+ vibrate = false;
1378
+ warp = false;
1379
+ doLoad(data) {
1798
1380
  this.angle.load(isNumber(data.angle) ? { value: data.angle } : data.angle);
1799
1381
  this.center.load(data.center);
1800
- if (data.decay !== undefined) {
1801
- this.decay = setRangeValue(data.decay);
1802
- }
1803
- if (data.direction !== undefined) {
1804
- this.direction = data.direction;
1805
- }
1382
+ loadRangeProperty(this, "decay", data.decay);
1383
+ loadProperty(this, "direction", data.direction);
1806
1384
  if (data.distance !== undefined) {
1807
1385
  this.distance = isNumber(data.distance)
1808
1386
  ? {
@@ -1811,12 +1389,8 @@
1811
1389
  }
1812
1390
  : { ...data.distance };
1813
1391
  }
1814
- if (data.drift !== undefined) {
1815
- this.drift = setRangeValue(data.drift);
1816
- }
1817
- if (data.enable !== undefined) {
1818
- this.enable = data.enable;
1819
- }
1392
+ loadRangeProperty(this, "drift", data.drift);
1393
+ loadProperty(this, "enable", data.enable);
1820
1394
  this.gravity.load(data.gravity);
1821
1395
  const outModes = data.outModes;
1822
1396
  if (outModes !== undefined) {
@@ -1830,256 +1404,141 @@
1830
1404
  }
1831
1405
  }
1832
1406
  this.path.load(data.path);
1833
- if (data.random !== undefined) {
1834
- this.random = data.random;
1835
- }
1836
- if (data.size !== undefined) {
1837
- this.size = data.size;
1838
- }
1839
- if (data.speed !== undefined) {
1840
- this.speed = setRangeValue(data.speed);
1841
- }
1407
+ loadProperty(this, "random", data.random);
1408
+ loadProperty(this, "size", data.size);
1409
+ loadRangeProperty(this, "speed", data.speed);
1842
1410
  this.spin.load(data.spin);
1843
- if (data.straight !== undefined) {
1844
- this.straight = data.straight;
1845
- }
1846
- if (data.vibrate !== undefined) {
1847
- this.vibrate = data.vibrate;
1848
- }
1849
- if (data.warp !== undefined) {
1850
- this.warp = data.warp;
1851
- }
1411
+ loadProperty(this, "straight", data.straight);
1412
+ loadProperty(this, "vibrate", data.vibrate);
1413
+ loadProperty(this, "warp", data.warp);
1852
1414
  }
1853
1415
  }
1854
1416
 
1855
- class Stroke {
1417
+ class Stroke extends OptionLoader {
1856
1418
  color;
1857
1419
  opacity;
1858
- width;
1859
- constructor() {
1860
- this.width = 0;
1861
- }
1862
- load(data) {
1863
- if (isNull(data)) {
1864
- return;
1865
- }
1420
+ width = 0;
1421
+ doLoad(data) {
1866
1422
  if (data.color !== undefined) {
1867
1423
  this.color = AnimatableColor.create(this.color, data.color);
1868
1424
  }
1869
- if (data.width !== undefined) {
1870
- this.width = setRangeValue(data.width);
1871
- }
1872
- if (data.opacity !== undefined) {
1873
- this.opacity = setRangeValue(data.opacity);
1874
- }
1425
+ loadRangeProperty(this, "width", data.width);
1426
+ loadRangeProperty(this, "opacity", data.opacity);
1875
1427
  }
1876
1428
  }
1877
1429
 
1878
- class Paint {
1430
+ class Paint extends OptionLoader {
1879
1431
  color;
1880
1432
  fill;
1881
1433
  stroke;
1882
- load(data) {
1883
- if (isNull(data)) {
1884
- return;
1885
- }
1434
+ doLoad(data) {
1886
1435
  if (data.color !== undefined) {
1887
1436
  this.color = AnimatableColor.create(this.color, data.color);
1888
1437
  }
1889
- if (data.fill !== undefined) {
1890
- this.fill ??= new Fill();
1891
- this.fill.load(data.fill);
1892
- }
1893
- if (data.stroke !== undefined) {
1894
- this.stroke ??= new Stroke();
1895
- this.stroke.load(data.stroke);
1896
- }
1438
+ loadLazyProperty(this, "fill", data.fill, () => new Fill());
1439
+ loadLazyProperty(this, "stroke", data.stroke, () => new Stroke());
1897
1440
  }
1898
1441
  }
1899
1442
 
1900
1443
  class ParticlesBounceFactor extends ValueWithRandom {
1901
- constructor() {
1902
- super();
1903
- this.value = 1;
1904
- }
1444
+ value = 1;
1905
1445
  }
1906
1446
 
1907
- class ParticlesBounce {
1908
- horizontal;
1909
- vertical;
1910
- constructor() {
1911
- this.horizontal = new ParticlesBounceFactor();
1912
- this.vertical = new ParticlesBounceFactor();
1913
- }
1914
- load(data) {
1915
- if (isNull(data)) {
1916
- return;
1917
- }
1447
+ class ParticlesBounce extends OptionLoader {
1448
+ horizontal = new ParticlesBounceFactor();
1449
+ vertical = new ParticlesBounceFactor();
1450
+ doLoad(data) {
1918
1451
  this.horizontal.load(data.horizontal);
1919
1452
  this.vertical.load(data.vertical);
1920
1453
  }
1921
1454
  }
1922
1455
 
1923
- class ParticlesDensity {
1924
- enable;
1925
- height;
1926
- width;
1927
- constructor() {
1928
- this.enable = false;
1929
- this.width = 1920;
1930
- this.height = 1080;
1931
- }
1932
- load(data) {
1933
- if (isNull(data)) {
1934
- return;
1935
- }
1936
- if (data.enable !== undefined) {
1937
- this.enable = data.enable;
1938
- }
1939
- const width = data.width;
1940
- if (width !== undefined) {
1941
- this.width = width;
1942
- }
1943
- const height = data.height;
1944
- if (height !== undefined) {
1945
- this.height = height;
1946
- }
1456
+ class ParticlesDensity extends OptionLoader {
1457
+ enable = false;
1458
+ height = 1080;
1459
+ width = 1920;
1460
+ doLoad(data) {
1461
+ loadProperty(this, "enable", data.enable);
1462
+ loadProperty(this, "width", data.width);
1463
+ loadProperty(this, "height", data.height);
1947
1464
  }
1948
1465
  }
1949
1466
 
1950
- class ParticlesNumberLimit {
1951
- mode;
1952
- value;
1953
- constructor() {
1954
- this.mode = LimitMode.delete;
1955
- this.value = 0;
1956
- }
1957
- load(data) {
1958
- if (isNull(data)) {
1959
- return;
1960
- }
1961
- if (data.mode !== undefined) {
1962
- this.mode = data.mode;
1963
- }
1964
- if (data.value !== undefined) {
1965
- this.value = data.value;
1966
- }
1467
+ class ParticlesNumberLimit extends OptionLoader {
1468
+ mode = LimitMode.delete;
1469
+ value = 0;
1470
+ doLoad(data) {
1471
+ loadProperty(this, "mode", data.mode);
1472
+ loadProperty(this, "value", data.value);
1967
1473
  }
1968
1474
  }
1969
1475
 
1970
- class ParticlesNumber {
1971
- density;
1972
- limit;
1973
- value;
1974
- constructor() {
1975
- this.density = new ParticlesDensity();
1976
- this.limit = new ParticlesNumberLimit();
1977
- this.value = 0;
1978
- }
1979
- load(data) {
1980
- if (isNull(data)) {
1981
- return;
1982
- }
1476
+ class ParticlesNumber extends OptionLoader {
1477
+ density = new ParticlesDensity();
1478
+ limit = new ParticlesNumberLimit();
1479
+ value = 0;
1480
+ doLoad(data) {
1983
1481
  this.density.load(data.density);
1984
1482
  this.limit.load(data.limit);
1985
- if (data.value !== undefined) {
1986
- this.value = data.value;
1987
- }
1483
+ loadProperty(this, "value", data.value);
1988
1484
  }
1989
1485
  }
1990
1486
 
1991
- class Shape {
1992
- close;
1993
- options;
1994
- type;
1995
- constructor() {
1996
- this.close = true;
1997
- this.options = {};
1998
- this.type = "circle";
1999
- }
2000
- load(data) {
2001
- if (isNull(data)) {
2002
- return;
2003
- }
1487
+ class Shape extends OptionLoader {
1488
+ close = true;
1489
+ options = {};
1490
+ type = "circle";
1491
+ doLoad(data) {
2004
1492
  const options = data.options;
2005
1493
  if (options !== undefined) {
2006
1494
  for (const shape in options) {
2007
1495
  const item = options[shape];
2008
1496
  if (item) {
2009
1497
  this.options[shape] = deepExtend(this.options[shape] ?? {}, item);
2010
- }
2011
- }
2012
- }
2013
- if (data.close !== undefined) {
2014
- this.close = data.close;
2015
- }
2016
- if (data.type !== undefined) {
2017
- this.type = data.type;
2018
- }
2019
- }
2020
- }
2021
-
2022
- class ZIndex extends ValueWithRandom {
2023
- opacityRate;
2024
- sizeRate;
2025
- velocityRate;
2026
- constructor() {
2027
- super();
2028
- this.opacityRate = 1;
2029
- this.sizeRate = 1;
2030
- this.velocityRate = 1;
2031
- }
2032
- load(data) {
2033
- super.load(data);
2034
- if (isNull(data)) {
2035
- return;
2036
- }
2037
- if (data.opacityRate !== undefined) {
2038
- this.opacityRate = data.opacityRate;
2039
- }
2040
- if (data.sizeRate !== undefined) {
2041
- this.sizeRate = data.sizeRate;
2042
- }
2043
- if (data.velocityRate !== undefined) {
2044
- this.velocityRate = data.velocityRate;
1498
+ }
1499
+ }
2045
1500
  }
1501
+ loadProperty(this, "close", data.close);
1502
+ loadProperty(this, "type", data.type);
2046
1503
  }
2047
1504
  }
2048
1505
 
2049
- class ParticlesOptions {
2050
- bounce;
2051
- effect;
2052
- groups;
2053
- move;
2054
- number;
1506
+ class ZIndex extends ValueWithRandom {
1507
+ opacityRate = 1;
1508
+ sizeRate = 1;
1509
+ velocityRate = 1;
1510
+ doLoad(data) {
1511
+ super.doLoad(data);
1512
+ loadProperty(this, "opacityRate", data.opacityRate);
1513
+ loadProperty(this, "sizeRate", data.sizeRate);
1514
+ loadProperty(this, "velocityRate", data.velocityRate);
1515
+ }
1516
+ }
1517
+
1518
+ class ParticlesOptions extends OptionLoader {
1519
+ bounce = new ParticlesBounce();
1520
+ effect = new Effect();
1521
+ groups = {};
1522
+ move = new Move();
1523
+ number = new ParticlesNumber();
2055
1524
  paint;
2056
1525
  palette;
2057
- reduceDuplicates;
2058
- shape;
2059
- zIndex;
1526
+ reduceDuplicates = false;
1527
+ shape = new Shape();
1528
+ zIndex = new ZIndex();
2060
1529
  #container;
2061
1530
  #pluginManager;
2062
1531
  constructor(pluginManager, container) {
1532
+ super();
2063
1533
  this.#pluginManager = pluginManager;
2064
1534
  this.#container = container;
2065
- this.bounce = new ParticlesBounce();
2066
- this.effect = new Effect();
2067
- this.groups = {};
2068
- this.move = new Move();
2069
- this.number = new ParticlesNumber();
2070
1535
  this.paint = new Paint();
2071
1536
  this.paint.color = new AnimatableColor();
2072
1537
  this.paint.color.value = "#fff";
2073
1538
  this.paint.fill = new Fill();
2074
1539
  this.paint.fill.enable = true;
2075
- this.reduceDuplicates = false;
2076
- this.shape = new Shape();
2077
- this.zIndex = new ZIndex();
2078
1540
  }
2079
- load(data) {
2080
- if (isNull(data)) {
2081
- return;
2082
- }
1541
+ doLoad(data) {
2083
1542
  if (data.palette) {
2084
1543
  this.palette = data.palette;
2085
1544
  this.#importPalette(this.palette);
@@ -2137,7 +1596,7 @@
2137
1596
  }
2138
1597
  }
2139
1598
  }
2140
- #importPalette = (palette) => {
1599
+ #importPalette(palette) {
2141
1600
  const paletteData = this.#pluginManager.getPalette(palette);
2142
1601
  if (!paletteData) {
2143
1602
  return;
@@ -2181,69 +1640,49 @@
2181
1640
  mode: paletteData.blendMode,
2182
1641
  },
2183
1642
  });
2184
- };
2185
- }
2186
-
2187
- function loadOptions(options, ...sourceOptionsArr) {
2188
- for (const sourceOptions of sourceOptionsArr) {
2189
- options.load(sourceOptions);
2190
1643
  }
2191
1644
  }
1645
+
2192
1646
  function loadParticlesOptions(pluginManager, container, ...sourceOptionsArr) {
2193
1647
  const options = new ParticlesOptions(pluginManager, container);
2194
1648
  loadOptions(options, ...sourceOptionsArr);
2195
1649
  return options;
2196
1650
  }
2197
1651
 
2198
- class Options {
2199
- autoPlay;
1652
+ class Options extends OptionLoader {
1653
+ autoPlay = true;
2200
1654
  background;
2201
- clear;
2202
- defaultThemes;
2203
- delay;
2204
- detectRetina;
2205
- duration;
2206
- fpsLimit;
1655
+ clear = true;
1656
+ defaultThemes = {};
1657
+ delay = 0;
1658
+ detectRetina = true;
1659
+ duration = 0;
1660
+ fpsLimit = 120;
2207
1661
  fullScreen;
2208
- hdr;
1662
+ hdr = true;
2209
1663
  key;
2210
1664
  name;
2211
1665
  palette;
2212
1666
  particles;
2213
- pauseOnBlur;
2214
- pauseOnOutsideViewport;
1667
+ pauseOnBlur = true;
1668
+ pauseOnOutsideViewport = true;
2215
1669
  preset;
2216
1670
  resize;
2217
- smooth;
2218
- style;
2219
- zLayers;
1671
+ smooth = false;
1672
+ style = {};
1673
+ zLayers = 100;
2220
1674
  #container;
2221
1675
  #pluginManager;
2222
1676
  constructor(pluginManager, container) {
1677
+ super();
2223
1678
  this.#pluginManager = pluginManager;
2224
1679
  this.#container = container;
2225
- this.autoPlay = true;
2226
1680
  this.background = new Background();
2227
- this.clear = true;
2228
- this.defaultThemes = {};
2229
- this.delay = 0;
2230
1681
  this.fullScreen = new FullScreen();
2231
- this.detectRetina = true;
2232
- this.duration = 0;
2233
- this.fpsLimit = 120;
2234
- this.hdr = true;
2235
1682
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
2236
- this.pauseOnBlur = true;
2237
- this.pauseOnOutsideViewport = true;
2238
1683
  this.resize = new ResizeEvent();
2239
- this.smooth = false;
2240
- this.style = {};
2241
- this.zLayers = 100;
2242
1684
  }
2243
- load(data) {
2244
- if (isNull(data)) {
2245
- return;
2246
- }
1685
+ doLoad(data) {
2247
1686
  if (data.preset !== undefined) {
2248
1687
  this.preset = data.preset;
2249
1688
  executeOnSingleOrMultiple(this.preset, preset => {
@@ -2254,44 +1693,18 @@
2254
1693
  this.palette = data.palette;
2255
1694
  this.#importPalette(this.palette);
2256
1695
  }
2257
- if (data.autoPlay !== undefined) {
2258
- this.autoPlay = data.autoPlay;
2259
- }
2260
- if (data.clear !== undefined) {
2261
- this.clear = data.clear;
2262
- }
2263
- if (data.key !== undefined) {
2264
- this.key = data.key;
2265
- }
2266
- if (data.name !== undefined) {
2267
- this.name = data.name;
2268
- }
2269
- if (data.delay !== undefined) {
2270
- this.delay = setRangeValue(data.delay);
2271
- }
2272
- const detectRetina = data.detectRetina;
2273
- if (detectRetina !== undefined) {
2274
- this.detectRetina = detectRetina;
2275
- }
2276
- if (data.duration !== undefined) {
2277
- this.duration = setRangeValue(data.duration);
2278
- }
2279
- const fpsLimit = data.fpsLimit;
2280
- if (fpsLimit !== undefined) {
2281
- this.fpsLimit = fpsLimit;
2282
- }
2283
- if (data.hdr !== undefined) {
2284
- this.hdr = data.hdr;
2285
- }
2286
- if (data.pauseOnBlur !== undefined) {
2287
- this.pauseOnBlur = data.pauseOnBlur;
2288
- }
2289
- if (data.pauseOnOutsideViewport !== undefined) {
2290
- this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
2291
- }
2292
- if (data.zLayers !== undefined) {
2293
- this.zLayers = data.zLayers;
2294
- }
1696
+ loadProperty(this, "autoPlay", data.autoPlay);
1697
+ loadProperty(this, "clear", data.clear);
1698
+ loadProperty(this, "key", data.key);
1699
+ loadProperty(this, "name", data.name);
1700
+ loadRangeProperty(this, "delay", data.delay);
1701
+ loadProperty(this, "detectRetina", data.detectRetina);
1702
+ loadRangeProperty(this, "duration", data.duration);
1703
+ loadProperty(this, "fpsLimit", data.fpsLimit);
1704
+ loadProperty(this, "hdr", data.hdr);
1705
+ loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1706
+ loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1707
+ loadProperty(this, "zLayers", data.zLayers);
2295
1708
  this.background.load(data.background);
2296
1709
  const fullScreen = data.fullScreen;
2297
1710
  if (isBoolean(fullScreen)) {
@@ -2303,14 +1716,12 @@
2303
1716
  this.particles.load(data.particles);
2304
1717
  this.resize.load(data.resize);
2305
1718
  this.style = deepExtend(this.style, data.style);
2306
- if (data.smooth !== undefined) {
2307
- this.smooth = data.smooth;
2308
- }
1719
+ loadProperty(this, "smooth", data.smooth);
2309
1720
  this.#pluginManager.plugins.forEach(plugin => {
2310
1721
  plugin.loadOptions(this.#container, this, data);
2311
1722
  });
2312
1723
  }
2313
- #importPalette = palette => {
1724
+ #importPalette(palette) {
2314
1725
  const paletteData = this.#pluginManager.getPalette(palette);
2315
1726
  if (!paletteData) {
2316
1727
  return;
@@ -2327,143 +1738,19 @@
2327
1738
  palette,
2328
1739
  },
2329
1740
  });
2330
- };
2331
- #importPreset = preset => {
2332
- this.load(this.#pluginManager.getPreset(preset));
2333
- };
2334
- }
2335
-
2336
- function paintBase(context, dimension, baseColor) {
2337
- context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
2338
- context.fillRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2339
- }
2340
- function paintImage(context, dimension, image, opacity) {
2341
- if (!image) {
2342
- return;
2343
- }
2344
- const prevAlpha = context.globalAlpha;
2345
- context.globalAlpha = opacity;
2346
- context.drawImage(image, originPoint.x, originPoint.y, dimension.width, dimension.height);
2347
- context.globalAlpha = prevAlpha;
2348
- }
2349
- function clear(context, dimension) {
2350
- context.clearRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2351
- }
2352
- function drawParticle(data) {
2353
- const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
2354
- x: pos.x,
2355
- y: pos.y,
2356
- };
2357
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
2358
- if (colorStyles.fill) {
2359
- context.fillStyle = colorStyles.fill;
2360
- }
2361
- const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
2362
- context.lineWidth = strokeWidth;
2363
- if (colorStyles.stroke) {
2364
- context.strokeStyle = colorStyles.stroke;
2365
- }
2366
- const drawData = {
2367
- context,
2368
- particle,
2369
- radius,
2370
- drawRadius: radius * drawScale,
2371
- opacity,
2372
- delta,
2373
- pixelRatio: container.retina.pixelRatio,
2374
- fill: fillEnabled,
2375
- stroke: strokeWidth > minStrokeWidth,
2376
- transformData,
2377
- position: { ...pos },
2378
- drawPosition,
2379
- drawScale,
2380
- };
2381
- for (const plugin of container.plugins) {
2382
- plugin.drawParticleTransform?.(drawData);
2383
- }
2384
- const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
2385
- drawBeforeEffect(effect, drawData);
2386
- drawShapeBeforeDraw(shape, drawData);
2387
- drawShape(shape, drawData);
2388
- drawShapeAfterDraw(shape, drawData);
2389
- drawAfterEffect(effect, drawData);
2390
- context.resetTransform();
2391
- }
2392
- function drawAfterEffect(drawer, data) {
2393
- if (!drawer?.drawAfter) {
2394
- return;
2395
- }
2396
- const { particle } = data;
2397
- if (!particle.effect) {
2398
- return;
2399
- }
2400
- drawer.drawAfter(data);
2401
- }
2402
- function drawBeforeEffect(drawer, data) {
2403
- if (!drawer?.drawBefore) {
2404
- return;
2405
- }
2406
- const { particle } = data;
2407
- if (!particle.effect) {
2408
- return;
2409
- }
2410
- drawer.drawBefore(data);
2411
- }
2412
- function drawShape(drawer, data) {
2413
- if (!drawer) {
2414
- return;
2415
- }
2416
- const { context, fill, particle, stroke } = data;
2417
- if (!particle.shape) {
2418
- return;
2419
- }
2420
- context.beginPath();
2421
- drawer.draw(data);
2422
- if (particle.shapeClose) {
2423
- context.closePath();
2424
- }
2425
- if (fill) {
2426
- context.fill();
2427
- }
2428
- if (stroke) {
2429
- context.stroke();
2430
- }
2431
- }
2432
- function drawShapeAfterDraw(drawer, data) {
2433
- if (!drawer?.afterDraw) {
2434
- return;
2435
- }
2436
- const { particle } = data;
2437
- if (!particle.shape) {
2438
- return;
2439
- }
2440
- drawer.afterDraw(data);
2441
- }
2442
- function drawShapeBeforeDraw(drawer, data) {
2443
- if (!drawer?.beforeDraw) {
2444
- return;
2445
1741
  }
2446
- const { particle } = data;
2447
- if (!particle.shape) {
2448
- return;
2449
- }
2450
- drawer.beforeDraw(data);
2451
- }
2452
- function drawParticlePlugin(context, plugin, particle, delta) {
2453
- if (!plugin.drawParticle) {
2454
- return;
1742
+ #importPreset(preset) {
1743
+ this.load(this.#pluginManager.getPreset(preset));
2455
1744
  }
2456
- plugin.drawParticle(context, particle, delta);
2457
1745
  }
2458
1746
 
2459
- const styleCache = new Map(), maxCacheSize = 1000, firstIndex = 0, rgbFixedPrecision = 2, hslFixedPrecision = 2;
1747
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
2460
1748
  function getCachedStyle(key, generator) {
2461
1749
  let cached = styleCache.get(key);
2462
1750
  if (!cached) {
2463
1751
  cached = generator();
2464
- if (styleCache.size >= maxCacheSize) {
2465
- const keysToDelete = [...styleCache.keys()].slice(firstIndex, maxCacheSize * half);
2466
- keysToDelete.forEach(k => styleCache.delete(k));
1752
+ if (styleCache.size > maxStyleCacheSize) {
1753
+ styleCache.clear();
2467
1754
  }
2468
1755
  styleCache.set(key, cached);
2469
1756
  }
@@ -2566,34 +1853,35 @@
2566
1853
  function stringToRgb(pluginManager, input) {
2567
1854
  return stringToRgba(pluginManager, input);
2568
1855
  }
1856
+ function hslChannel(temp1, temp2, temp3) {
1857
+ const temp3Min = 0, temp3Max = 1;
1858
+ if (temp3 < temp3Min) {
1859
+ temp3++;
1860
+ }
1861
+ if (temp3 > temp3Max) {
1862
+ temp3--;
1863
+ }
1864
+ if (temp3 * sextuple < temp3Max) {
1865
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1866
+ }
1867
+ if (temp3 * double < temp3Max) {
1868
+ return temp2;
1869
+ }
1870
+ if (temp3 * triple < temp3Max * double) {
1871
+ const temp3Offset = double / triple;
1872
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1873
+ }
1874
+ return temp1;
1875
+ }
2569
1876
  function hslToRgb(hsl) {
2570
1877
  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;
2571
1878
  if (s === sMin) {
2572
1879
  const grayscaleValue = Math.round(lNormalized * rgbMax);
2573
1880
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
2574
1881
  }
2575
- const channel = (temp1, temp2, temp3) => {
2576
- const temp3Min = 0, temp3Max = 1;
2577
- if (temp3 < temp3Min) {
2578
- temp3++;
2579
- }
2580
- if (temp3 > temp3Max) {
2581
- temp3--;
2582
- }
2583
- if (temp3 * sextuple < temp3Max) {
2584
- return temp1 + (temp2 - temp1) * sextuple * temp3;
2585
- }
2586
- if (temp3 * double < temp3Max) {
2587
- return temp2;
2588
- }
2589
- if (temp3 * triple < temp3Max * double) {
2590
- const temp3Offset = double / triple;
2591
- return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
2592
- }
2593
- return temp1;
2594
- }, temp1 = lNormalized < half
1882
+ const temp1 = lNormalized < half
2595
1883
  ? lNormalized * (sNormalizedOffset + sNormalized)
2596
- : 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));
1884
+ : 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));
2597
1885
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
2598
1886
  }
2599
1887
  function hslaToRgba(hsla) {
@@ -2606,7 +1894,7 @@
2606
1894
  };
2607
1895
  }
2608
1896
  function getRandomRgbColor(min) {
2609
- const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$1, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1897
+ const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
2610
1898
  return {
2611
1899
  b: getRgbInRangeValue(),
2612
1900
  g: getRgbInRangeValue(),
@@ -2617,21 +1905,18 @@
2617
1905
  const op = opacity ?? defaultOpacity$1, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2618
1906
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2619
1907
  }
2620
- function getHdrStyleFromRgb(color, opacity) {
2621
- return `color(display-p3 ${(color.r / rgbMax).toString()} ${(color.g / rgbMax).toString()} ${(color.b / rgbMax).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1908
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1909
+ const headroom = peakNits / sdrReferenceWhiteNits;
1910
+ return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2622
1911
  }
2623
1912
  function getSdrStyleFromRgb(color, opacity) {
2624
1913
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
2625
1914
  }
2626
1915
  function getStyleFromHsl(color, hdr, opacity) {
2627
1916
  const op = opacity ?? defaultOpacity$1, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2628
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromHsl(color, opacity) : getSdrStyleFromHsl(color, opacity)));
2629
- }
2630
- function getHdrStyleFromHsl(color, opacity) {
2631
- return getHdrStyleFromRgb(hslToRgb(color), opacity);
2632
- }
2633
- function getSdrStyleFromHsl(color, opacity) {
2634
- return `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${(opacity ?? defaultOpacity$1).toString()})`;
1917
+ return getCachedStyle(key, () => hdr
1918
+ ? getStyleFromRgb(hslToRgb(color), true, opacity)
1919
+ : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
2635
1920
  }
2636
1921
  function colorMix(color1, color2, size1, size2) {
2637
1922
  let rgb1 = color1, rgb2 = color2;
@@ -2810,22 +2095,14 @@
2810
2095
  const tsParticles = initEngine();
2811
2096
 
2812
2097
  class Blend {
2813
- enable;
2814
- mode;
2815
- constructor() {
2816
- this.mode = "destination-out";
2817
- this.enable = false;
2818
- }
2098
+ enable = false;
2099
+ mode = "destination-out";
2819
2100
  load(data) {
2820
2101
  if (isNull(data)) {
2821
2102
  return;
2822
2103
  }
2823
- if (data.mode !== undefined) {
2824
- this.mode = data.mode;
2825
- }
2826
- if (data.enable !== undefined) {
2827
- this.enable = data.enable;
2828
- }
2104
+ loadProperty(this, "mode", data.mode);
2105
+ loadProperty(this, "enable", data.enable);
2829
2106
  }
2830
2107
  }
2831
2108
 
@@ -2855,7 +2132,7 @@
2855
2132
  }
2856
2133
 
2857
2134
  async function loadBlendPlugin(engine) {
2858
- engine.checkVersion("4.1.3");
2135
+ engine.checkVersion("4.2.1");
2859
2136
  await engine.pluginManager.register(e => {
2860
2137
  e.pluginManager.addPlugin(new BlendPlugin());
2861
2138
  });
@@ -2892,7 +2169,7 @@
2892
2169
  }
2893
2170
 
2894
2171
  async function loadCircleShape(engine) {
2895
- engine.checkVersion("4.1.3");
2172
+ engine.checkVersion("4.2.1");
2896
2173
  await engine.pluginManager.register(e => {
2897
2174
  e.pluginManager.addShape(["circle"], () => {
2898
2175
  return Promise.resolve(new CircleDrawer());
@@ -2940,7 +2217,7 @@
2940
2217
  }
2941
2218
 
2942
2219
  async function loadHexColorPlugin(engine) {
2943
- engine.checkVersion("4.1.3");
2220
+ engine.checkVersion("4.2.1");
2944
2221
  await engine.pluginManager.register(e => {
2945
2222
  e.pluginManager.addColorManager("hex", new HexColorManager());
2946
2223
  });
@@ -2993,7 +2270,7 @@
2993
2270
  }
2994
2271
 
2995
2272
  async function loadHslColorPlugin(engine) {
2996
- engine.checkVersion("4.1.3");
2273
+ engine.checkVersion("4.2.1");
2997
2274
  await engine.pluginManager.register(e => {
2998
2275
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2999
2276
  });
@@ -3017,7 +2294,7 @@
3017
2294
  }
3018
2295
 
3019
2296
  async function loadMovePlugin(engine) {
3020
- engine.checkVersion("4.1.3");
2297
+ engine.checkVersion("4.2.1");
3021
2298
  await engine.pluginManager.register(e => {
3022
2299
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
3023
2300
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -3035,31 +2312,137 @@
3035
2312
  });
3036
2313
  }
3037
2314
 
3038
- class OpacityAnimation extends RangedAnimationOptions {
3039
- destroy;
3040
- constructor() {
3041
- super();
3042
- this.destroy = DestroyType.none;
3043
- this.speed = 2;
2315
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
2316
+ switch (destroyType) {
2317
+ case DestroyType.max:
2318
+ if (value >= maxValue) {
2319
+ particle.destroy();
2320
+ }
2321
+ break;
2322
+ case DestroyType.min:
2323
+ if (value <= minValue) {
2324
+ particle.destroy();
2325
+ }
2326
+ break;
2327
+ }
2328
+ }
2329
+ function initParticleNumericAnimationValue(options, pxRatio) {
2330
+ const valueRange = options.value, animationOptions = options.animation, res = {
2331
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
2332
+ enable: animationOptions.enable,
2333
+ value: getRangeValue(options.value) * pxRatio,
2334
+ max: getRangeMax(valueRange) * pxRatio,
2335
+ min: getRangeMin(valueRange) * pxRatio,
2336
+ loops: 0,
2337
+ maxLoops: getRangeValue(animationOptions.count),
2338
+ time: 0,
2339
+ }, decayOffset = 1;
2340
+ if (animationOptions.enable) {
2341
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
2342
+ switch (animationOptions.mode) {
2343
+ case AnimationMode.increase:
2344
+ res.status = AnimationStatus.increasing;
2345
+ break;
2346
+ case AnimationMode.decrease:
2347
+ res.status = AnimationStatus.decreasing;
2348
+ break;
2349
+ case AnimationMode.random:
2350
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2351
+ break;
2352
+ }
2353
+ const autoStatus = animationOptions.mode === AnimationMode.auto;
2354
+ switch (animationOptions.startValue) {
2355
+ case StartValueType.min:
2356
+ res.value = res.min;
2357
+ if (autoStatus) {
2358
+ res.status = AnimationStatus.increasing;
2359
+ }
2360
+ break;
2361
+ case StartValueType.max:
2362
+ res.value = res.max;
2363
+ if (autoStatus) {
2364
+ res.status = AnimationStatus.decreasing;
2365
+ }
2366
+ break;
2367
+ case StartValueType.random:
2368
+ default:
2369
+ res.value = randomInRangeValue(res);
2370
+ if (autoStatus) {
2371
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2372
+ }
2373
+ break;
2374
+ }
2375
+ }
2376
+ res.initialValue = res.value;
2377
+ return res;
2378
+ }
2379
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
2380
+ const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
2381
+ if (particle.destroyed ||
2382
+ !data.enable ||
2383
+ ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
2384
+ return;
2385
+ }
2386
+ const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
2387
+ data.time ??= 0;
2388
+ const delayTime = data.delayTime ?? minDelay;
2389
+ if (delayTime > minDelay && data.time < delayTime) {
2390
+ data.time += delta.value;
2391
+ if (data.time < delayTime) {
2392
+ return;
2393
+ }
2394
+ }
2395
+ switch (data.status) {
2396
+ case AnimationStatus.increasing:
2397
+ data.value += velocity;
2398
+ break;
2399
+ case AnimationStatus.decreasing:
2400
+ data.value -= velocity;
2401
+ break;
2402
+ }
2403
+ if (data.velocity && decay !== identity) {
2404
+ data.velocity *= decay;
2405
+ }
2406
+ switch (data.status) {
2407
+ case AnimationStatus.increasing:
2408
+ if (data.value >= maxValue) {
2409
+ {
2410
+ data.status = AnimationStatus.decreasing;
2411
+ }
2412
+ data.loops ??= minLoops;
2413
+ data.loops++;
2414
+ }
2415
+ break;
2416
+ case AnimationStatus.decreasing:
2417
+ if (data.value <= minValue) {
2418
+ {
2419
+ data.status = AnimationStatus.increasing;
2420
+ }
2421
+ data.loops ??= minLoops;
2422
+ data.loops++;
2423
+ }
2424
+ break;
3044
2425
  }
2426
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
2427
+ if (!particle.destroyed) {
2428
+ data.value = clamp(data.value, minValue, maxValue);
2429
+ }
2430
+ }
2431
+
2432
+ class OpacityAnimation extends RangedAnimationOptions {
2433
+ destroy = DestroyType.none;
3045
2434
  load(data) {
3046
2435
  super.load(data);
3047
2436
  if (isNull(data)) {
3048
2437
  return;
3049
2438
  }
3050
- if (data.destroy !== undefined) {
3051
- this.destroy = data.destroy;
3052
- }
2439
+ loadProperty(this, "destroy", data.destroy);
3053
2440
  }
3054
2441
  }
3055
2442
 
3056
2443
  class Opacity extends RangedAnimationValueWithRandom {
3057
- animation;
3058
- constructor() {
3059
- super();
3060
- this.animation = new OpacityAnimation();
3061
- this.value = 1;
3062
- }
2444
+ animation = new OpacityAnimation();
2445
+ value = 1;
3063
2446
  load(data) {
3064
2447
  if (isNull(data)) {
3065
2448
  return;
@@ -3103,10 +2486,7 @@
3103
2486
  (particle.opacity.loops ?? none) < (particle.opacity.maxLoops ?? none))));
3104
2487
  }
3105
2488
  loadOptions(options, ...sources) {
3106
- options.opacity ??= new Opacity();
3107
- for (const source of sources) {
3108
- options.opacity.load(source?.opacity);
3109
- }
2489
+ loadOptionProperty(options, "opacity", Opacity, ...sources);
3110
2490
  }
3111
2491
  reset(particle) {
3112
2492
  if (!particle.opacity) {
@@ -3124,7 +2504,7 @@
3124
2504
  }
3125
2505
 
3126
2506
  async function loadOpacityUpdater(engine) {
3127
- engine.checkVersion("4.1.3");
2507
+ engine.checkVersion("4.2.1");
3128
2508
  await engine.pluginManager.register(e => {
3129
2509
  e.pluginManager.addParticleUpdater("opacity", container => {
3130
2510
  return Promise.resolve(new OpacityUpdater(container));
@@ -3132,7 +2512,7 @@
3132
2512
  });
3133
2513
  }
3134
2514
 
3135
- const minVelocity$4 = 0, boundsMin = 0;
2515
+ const boundsMin = 0;
3136
2516
  function bounceHorizontal(data) {
3137
2517
  if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
3138
2518
  (data.direction !== OutModeDirection.left && data.direction !== OutModeDirection.right)) {
@@ -3147,8 +2527,8 @@
3147
2527
  const velocity = data.particle.velocity.x;
3148
2528
  let bounced = false;
3149
2529
  if (data.outOfCanvas &&
3150
- ((data.direction === OutModeDirection.right && velocity > minVelocity$4) ||
3151
- (data.direction === OutModeDirection.left && velocity < minVelocity$4))) {
2530
+ ((data.direction === OutModeDirection.right && velocity > minVelocity) ||
2531
+ (data.direction === OutModeDirection.left && velocity < minVelocity))) {
3152
2532
  const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
3153
2533
  data.particle.velocity.x *= -newVelocity;
3154
2534
  bounced = true;
@@ -3181,8 +2561,8 @@
3181
2561
  const velocity = data.particle.velocity.y;
3182
2562
  let bounced = false;
3183
2563
  if (data.outOfCanvas &&
3184
- ((data.direction === OutModeDirection.bottom && velocity > minVelocity$4) ||
3185
- (data.direction === OutModeDirection.top && velocity < minVelocity$4))) {
2564
+ ((data.direction === OutModeDirection.bottom && velocity > minVelocity) ||
2565
+ (data.direction === OutModeDirection.top && velocity < minVelocity))) {
3186
2566
  const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
3187
2567
  data.particle.velocity.y *= -newVelocity;
3188
2568
  bounced = true;
@@ -3235,7 +2615,6 @@
3235
2615
  }
3236
2616
  }
3237
2617
 
3238
- const minVelocity$3 = 0;
3239
2618
  class DestroyOutMode {
3240
2619
  modes;
3241
2620
  constructor(_container) {
@@ -3254,10 +2633,10 @@
3254
2633
  break;
3255
2634
  case ParticleOutType.inside: {
3256
2635
  const { dx, dy } = getDistances(particle.position, particle.moveCenter), { x: vx, y: vy } = particle.velocity;
3257
- if ((vx < minVelocity$3 && dx > particle.moveCenter.radius) ||
3258
- (vy < minVelocity$3 && dy > particle.moveCenter.radius) ||
3259
- (vx >= minVelocity$3 && dx < -particle.moveCenter.radius) ||
3260
- (vy >= minVelocity$3 && dy < -particle.moveCenter.radius)) {
2636
+ if ((vx < minVelocity && dx > particle.moveCenter.radius) ||
2637
+ (vy < minVelocity && dy > particle.moveCenter.radius) ||
2638
+ (vx >= minVelocity && dx < -particle.moveCenter.radius) ||
2639
+ (vy >= minVelocity && dy < -particle.moveCenter.radius)) {
3261
2640
  return;
3262
2641
  }
3263
2642
  break;
@@ -3267,7 +2646,6 @@
3267
2646
  }
3268
2647
  }
3269
2648
 
3270
- const minVelocity$2 = 0;
3271
2649
  class NoneOutMode {
3272
2650
  modes;
3273
2651
  #container;
@@ -3287,10 +2665,10 @@
3287
2665
  }
3288
2666
  const gravityOptions = particle.options.move.gravity, container = this.#container, canvasSize = container.canvas.size, pRadius = particle.getRadius();
3289
2667
  if (!gravityOptions.enable) {
3290
- if ((particle.velocity.y > minVelocity$2 && particle.position.y <= canvasSize.height + pRadius) ||
3291
- (particle.velocity.y < minVelocity$2 && particle.position.y >= -pRadius) ||
3292
- (particle.velocity.x > minVelocity$2 && particle.position.x <= canvasSize.width + pRadius) ||
3293
- (particle.velocity.x < minVelocity$2 && particle.position.x >= -pRadius)) {
2668
+ if ((particle.velocity.y > minVelocity && particle.position.y <= canvasSize.height + pRadius) ||
2669
+ (particle.velocity.y < minVelocity && particle.position.y >= -pRadius) ||
2670
+ (particle.velocity.x > minVelocity && particle.position.x <= canvasSize.width + pRadius) ||
2671
+ (particle.velocity.x < minVelocity && particle.position.x >= -pRadius)) {
3294
2672
  return;
3295
2673
  }
3296
2674
  if (!isPointInside(particle.position, container.canvas.size, originPoint, pRadius, direction)) {
@@ -3309,7 +2687,7 @@
3309
2687
  }
3310
2688
  }
3311
2689
 
3312
- const minVelocity$1 = 0, minDistance$2 = 0, updateVector = Vector.origin;
2690
+ const updateVector = Vector.origin;
3313
2691
  class OutOutMode {
3314
2692
  modes;
3315
2693
  #container;
@@ -3330,10 +2708,10 @@
3330
2708
  updateVector.angle = particle.velocity.angle + Math.PI;
3331
2709
  updateVector.addTo(particle.moveCenter);
3332
2710
  const { dx, dy } = getDistances(particle.position, updateVector);
3333
- if ((vx <= minVelocity$1 && dx >= minDistance$2) ||
3334
- (vy <= minVelocity$1 && dy >= minDistance$2) ||
3335
- (vx >= minVelocity$1 && dx <= minDistance$2) ||
3336
- (vy >= minVelocity$1 && dy <= minDistance$2)) {
2711
+ if ((vx <= minVelocity && dx >= minDistance$2) ||
2712
+ (vy <= minVelocity && dy >= minDistance$2) ||
2713
+ (vx >= minVelocity && dx <= minDistance$2) ||
2714
+ (vy >= minVelocity && dy <= minDistance$2)) {
3337
2715
  return;
3338
2716
  }
3339
2717
  particle.position.x = Math.floor(randomInRangeValue({
@@ -3457,21 +2835,21 @@
3457
2835
  this.#updateOutMode(particle, delta, outModes.right ?? outModes.default, OutModeDirection.right);
3458
2836
  this.#updateOutMode(particle, delta, outModes.top ?? outModes.default, OutModeDirection.top);
3459
2837
  }
3460
- #addUpdaterIfMissing = (particle, outMode, getUpdater) => {
2838
+ #addUpdaterIfMissing(particle, outMode, getUpdater) {
3461
2839
  const outModes = particle.options.move.outModes;
3462
2840
  if (!this.updaters.has(outMode) && checkOutMode(outModes, outMode)) {
3463
2841
  this.updaters.set(outMode, getUpdater(this.#container));
3464
2842
  }
3465
- };
3466
- #updateOutMode = (particle, delta, outMode, direction) => {
2843
+ }
2844
+ #updateOutMode(particle, delta, outMode, direction) {
3467
2845
  for (const updater of this.updaters.values()) {
3468
2846
  updater.update(particle, direction, delta, outMode);
3469
2847
  }
3470
- };
2848
+ }
3471
2849
  }
3472
2850
 
3473
2851
  async function loadOutModesUpdater(engine) {
3474
- engine.checkVersion("4.1.3");
2852
+ engine.checkVersion("4.2.1");
3475
2853
  await engine.pluginManager.register(e => {
3476
2854
  e.pluginManager.addParticleUpdater("outModes", container => {
3477
2855
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3542,7 +2920,7 @@
3542
2920
  }
3543
2921
 
3544
2922
  async function loadPaintUpdater(engine) {
3545
- engine.checkVersion("4.1.3");
2923
+ engine.checkVersion("4.2.1");
3546
2924
  await engine.pluginManager.register(e => {
3547
2925
  e.pluginManager.addParticleUpdater("paint", container => {
3548
2926
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3597,37 +2975,26 @@
3597
2975
  }
3598
2976
 
3599
2977
  async function loadRgbColorPlugin(engine) {
3600
- engine.checkVersion("4.1.3");
2978
+ engine.checkVersion("4.2.1");
3601
2979
  await engine.pluginManager.register(e => {
3602
2980
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3603
2981
  });
3604
2982
  }
3605
2983
 
3606
2984
  class SizeAnimation extends RangedAnimationOptions {
3607
- destroy;
3608
- constructor() {
3609
- super();
3610
- this.destroy = DestroyType.none;
3611
- this.speed = 5;
3612
- }
2985
+ destroy = DestroyType.none;
3613
2986
  load(data) {
3614
2987
  super.load(data);
3615
2988
  if (isNull(data)) {
3616
2989
  return;
3617
2990
  }
3618
- if (data.destroy !== undefined) {
3619
- this.destroy = data.destroy;
3620
- }
2991
+ loadProperty(this, "destroy", data.destroy);
3621
2992
  }
3622
2993
  }
3623
2994
 
3624
2995
  class Size extends RangedAnimationValueWithRandom {
3625
- animation;
3626
- constructor() {
3627
- super();
3628
- this.animation = new SizeAnimation();
3629
- this.value = 3;
3630
- }
2996
+ animation = new SizeAnimation();
2997
+ value = 3;
3631
2998
  load(data) {
3632
2999
  super.load(data);
3633
3000
  if (isNull(data)) {
@@ -3670,10 +3037,7 @@
3670
3037
  (particle.size.loops ?? minLoops) < (particle.size.maxLoops ?? minLoops))));
3671
3038
  }
3672
3039
  loadOptions(options, ...sources) {
3673
- options.size ??= new Size();
3674
- for (const source of sources) {
3675
- options.size.load(source?.size);
3676
- }
3040
+ loadOptionProperty(options, "size", Size, ...sources);
3677
3041
  }
3678
3042
  preInit(particle) {
3679
3043
  const pxRatio = this.#container.retina.pixelRatio, options = particle.options, sizeOptions = options.size;
@@ -3696,7 +3060,7 @@
3696
3060
  }
3697
3061
 
3698
3062
  async function loadSizeUpdater(engine) {
3699
- engine.checkVersion("4.1.3");
3063
+ engine.checkVersion("4.2.1");
3700
3064
  await engine.pluginManager.register(e => {
3701
3065
  e.pluginManager.addParticleUpdater("size", container => {
3702
3066
  return Promise.resolve(new SizeUpdater(container));
@@ -3705,7 +3069,7 @@
3705
3069
  }
3706
3070
 
3707
3071
  async function loadBasic(engine) {
3708
- engine.checkVersion("4.1.3");
3072
+ engine.checkVersion("4.2.1");
3709
3073
  await engine.pluginManager.register(async (e) => {
3710
3074
  await Promise.all([
3711
3075
  loadBlendPlugin(e),
@@ -3723,22 +3087,14 @@
3723
3087
  }
3724
3088
 
3725
3089
  class ClickEvent {
3726
- enable;
3727
- mode;
3728
- constructor() {
3729
- this.enable = false;
3730
- this.mode = [];
3731
- }
3090
+ enable = false;
3091
+ mode = [];
3732
3092
  load(data) {
3733
3093
  if (isNull(data)) {
3734
3094
  return;
3735
3095
  }
3736
- if (data.enable !== undefined) {
3737
- this.enable = data.enable;
3738
- }
3739
- if (data.mode !== undefined) {
3740
- this.mode = data.mode;
3741
- }
3096
+ loadProperty(this, "enable", data.enable);
3097
+ loadProperty(this, "mode", data.mode);
3742
3098
  }
3743
3099
  }
3744
3100
 
@@ -3749,64 +3105,37 @@
3749
3105
  })(DivType || (DivType = {}));
3750
3106
 
3751
3107
  class DivEvent {
3752
- enable;
3753
- mode;
3754
- selectors;
3755
- type;
3756
- constructor() {
3757
- this.selectors = [];
3758
- this.enable = false;
3759
- this.mode = [];
3760
- this.type = DivType.circle;
3761
- }
3108
+ enable = false;
3109
+ mode = [];
3110
+ selectors = [];
3111
+ type = DivType.circle;
3762
3112
  load(data) {
3763
3113
  if (isNull(data)) {
3764
3114
  return;
3765
3115
  }
3766
- if (data.selectors !== undefined) {
3767
- this.selectors = data.selectors;
3768
- }
3769
- if (data.enable !== undefined) {
3770
- this.enable = data.enable;
3771
- }
3772
- if (data.mode !== undefined) {
3773
- this.mode = data.mode;
3774
- }
3775
- if (data.type !== undefined) {
3776
- this.type = data.type;
3777
- }
3116
+ loadProperty(this, "selectors", data.selectors);
3117
+ loadProperty(this, "enable", data.enable);
3118
+ loadProperty(this, "mode", data.mode);
3119
+ loadProperty(this, "type", data.type);
3778
3120
  }
3779
3121
  }
3780
3122
 
3781
3123
  class HoverEvent {
3782
- enable;
3783
- mode;
3784
- constructor() {
3785
- this.enable = false;
3786
- this.mode = [];
3787
- }
3124
+ enable = false;
3125
+ mode = [];
3788
3126
  load(data) {
3789
3127
  if (isNull(data)) {
3790
3128
  return;
3791
3129
  }
3792
- if (data.enable !== undefined) {
3793
- this.enable = data.enable;
3794
- }
3795
- if (data.mode !== undefined) {
3796
- this.mode = data.mode;
3797
- }
3130
+ loadProperty(this, "enable", data.enable);
3131
+ loadProperty(this, "mode", data.mode);
3798
3132
  }
3799
3133
  }
3800
3134
 
3801
3135
  class Events {
3802
- onClick;
3803
- onDiv;
3804
- onHover;
3805
- constructor() {
3806
- this.onClick = new ClickEvent();
3807
- this.onDiv = new DivEvent();
3808
- this.onHover = new HoverEvent();
3809
- }
3136
+ onClick = new ClickEvent();
3137
+ onDiv = new DivEvent();
3138
+ onHover = new HoverEvent();
3810
3139
  load(data) {
3811
3140
  if (isNull(data)) {
3812
3141
  return;
@@ -3859,12 +3188,10 @@
3859
3188
  }
3860
3189
 
3861
3190
  class Interactivity {
3862
- detectsOn;
3863
- events;
3191
+ detectsOn = InteractivityDetect.window;
3192
+ events = new Events();
3864
3193
  modes;
3865
3194
  constructor(pluginManager, container) {
3866
- this.detectsOn = InteractivityDetect.window;
3867
- this.events = new Events();
3868
3195
  this.modes = new Modes(pluginManager, container);
3869
3196
  }
3870
3197
  load(data) {
@@ -3943,7 +3270,7 @@
3943
3270
  const clickEvent = "click", mouseDownEvent = "pointerdown", mouseUpEvent = "pointerup", mouseLeaveEvent = "pointerleave", mouseMoveEvent = "pointermove", touchStartEvent = "touchstart", touchEndEvent = "touchend", touchMoveEvent = "touchmove", touchCancelEvent = "touchcancel";
3944
3271
 
3945
3272
  async function loadInteractivityPlugin(engine) {
3946
- engine.checkVersion("4.1.3");
3273
+ engine.checkVersion("4.2.1");
3947
3274
  await engine.pluginManager.register(e => {
3948
3275
  const interactivityEngine = e, interactivityPluginManager = interactivityEngine.pluginManager;
3949
3276
  interactivityPluginManager.addPlugin(new InteractivityPlugin(interactivityPluginManager));
@@ -4026,38 +3353,27 @@
4026
3353
  }
4027
3354
 
4028
3355
  class LinksShadow {
4029
- blur;
4030
- color;
4031
- enable;
3356
+ blur = 5;
3357
+ color = new OptionsColor();
3358
+ enable = false;
4032
3359
  constructor() {
4033
- this.blur = 5;
4034
- this.color = new OptionsColor();
4035
3360
  this.color.value = "#000";
4036
- this.enable = false;
4037
3361
  }
4038
3362
  load(data) {
4039
3363
  if (isNull(data)) {
4040
3364
  return;
4041
3365
  }
4042
- if (data.blur !== undefined) {
4043
- this.blur = data.blur;
4044
- }
3366
+ loadProperty(this, "blur", data.blur);
4045
3367
  this.color = OptionsColor.create(this.color, data.color);
4046
- if (data.enable !== undefined) {
4047
- this.enable = data.enable;
4048
- }
3368
+ loadProperty(this, "enable", data.enable);
4049
3369
  }
4050
3370
  }
4051
3371
 
4052
3372
  class LinksTriangle {
4053
3373
  color;
4054
- enable;
4055
- frequency;
4056
- opacity;
4057
- constructor() {
4058
- this.enable = false;
4059
- this.frequency = 1;
4060
- }
3374
+ enable = false;
3375
+ frequency = 1;
3376
+ opacity;
4061
3377
  load(data) {
4062
3378
  if (isNull(data)) {
4063
3379
  return;
@@ -4065,79 +3381,44 @@
4065
3381
  if (data.color !== undefined) {
4066
3382
  this.color = OptionsColor.create(this.color, data.color);
4067
3383
  }
4068
- if (data.enable !== undefined) {
4069
- this.enable = data.enable;
4070
- }
4071
- if (data.frequency !== undefined) {
4072
- this.frequency = data.frequency;
4073
- }
4074
- if (data.opacity !== undefined) {
4075
- this.opacity = data.opacity;
4076
- }
3384
+ loadProperty(this, "enable", data.enable);
3385
+ loadProperty(this, "frequency", data.frequency);
3386
+ loadProperty(this, "opacity", data.opacity);
4077
3387
  }
4078
3388
  }
4079
3389
 
4080
3390
  class Links {
4081
- blink;
4082
- color;
4083
- consent;
4084
- distance;
4085
- enable;
4086
- frequency;
3391
+ blink = false;
3392
+ color = new OptionsColor();
3393
+ consent = false;
3394
+ distance = 100;
3395
+ enable = false;
3396
+ frequency = 1;
4087
3397
  id;
4088
- opacity;
4089
- shadow;
4090
- triangles;
4091
- warp;
4092
- width;
3398
+ opacity = 1;
3399
+ shadow = new LinksShadow();
3400
+ triangles = new LinksTriangle();
3401
+ warp = false;
3402
+ width = 1;
4093
3403
  constructor() {
4094
- this.blink = false;
4095
- this.color = new OptionsColor();
4096
3404
  this.color.value = "#fff";
4097
- this.consent = false;
4098
- this.distance = 100;
4099
- this.enable = false;
4100
- this.frequency = 1;
4101
- this.opacity = 1;
4102
- this.shadow = new LinksShadow();
4103
- this.triangles = new LinksTriangle();
4104
- this.width = 1;
4105
- this.warp = false;
4106
3405
  }
4107
3406
  load(data) {
4108
3407
  if (isNull(data)) {
4109
3408
  return;
4110
3409
  }
4111
- if (data.id !== undefined) {
4112
- this.id = data.id;
4113
- }
4114
- if (data.blink !== undefined) {
4115
- this.blink = data.blink;
4116
- }
3410
+ loadProperty(this, "id", data.id);
3411
+ loadProperty(this, "blink", data.blink);
4117
3412
  this.color = OptionsColor.create(this.color, data.color);
4118
- if (data.consent !== undefined) {
4119
- this.consent = data.consent;
4120
- }
4121
- if (data.distance !== undefined) {
4122
- this.distance = data.distance;
4123
- }
4124
- if (data.enable !== undefined) {
4125
- this.enable = data.enable;
4126
- }
4127
- if (data.frequency !== undefined) {
4128
- this.frequency = data.frequency;
4129
- }
4130
- if (data.opacity !== undefined) {
4131
- this.opacity = data.opacity;
4132
- }
3413
+ loadProperty(this, "consent", data.consent);
3414
+ loadProperty(this, "distance", data.distance);
3415
+ loadProperty(this, "enable", data.enable);
3416
+ loadProperty(this, "frequency", data.frequency);
3417
+ loadProperty(this, "opacity", data.opacity);
4133
3418
  this.shadow.load(data.shadow);
4134
3419
  this.triangles.load(data.triangles);
4135
- if (data.width !== undefined) {
4136
- this.width = data.width;
4137
- }
4138
- if (data.warp !== undefined) {
4139
- this.warp = data.warp;
4140
- }
3420
+ loadProperty(this, "width", data.width);
3421
+ loadProperty(this, "warp", data.warp);
4141
3422
  }
4142
3423
  }
4143
3424
 
@@ -4213,10 +3494,7 @@
4213
3494
  return !!particle.options.links?.enable;
4214
3495
  }
4215
3496
  loadParticlesOptions(options, ...sources) {
4216
- options.links ??= new Links();
4217
- for (const source of sources) {
4218
- options.links.load(source?.links);
4219
- }
3497
+ loadOptionProperty(options, "links", Links, ...sources);
4220
3498
  }
4221
3499
  reset() {
4222
3500
  }
@@ -4269,7 +3547,7 @@
4269
3547
  }
4270
3548
 
4271
3549
  async function loadParticlesLinksInteraction(engine) {
4272
- engine.checkVersion("4.1.3");
3550
+ engine.checkVersion("4.2.1");
4273
3551
  await engine.pluginManager.register((e) => {
4274
3552
  const pluginManager = e.pluginManager;
4275
3553
  ensureInteractivityPluginLoaded(e);
@@ -4383,7 +3661,7 @@
4383
3661
  return;
4384
3662
  }
4385
3663
  this.draw(ctx => {
4386
- clear(ctx, this.#canvasManager.size);
3664
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4387
3665
  });
4388
3666
  }
4389
3667
  clear() {
@@ -4445,7 +3723,7 @@
4445
3723
  plugin.drawParticleSetup?.(context, particle, delta);
4446
3724
  }
4447
3725
  this.#applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
4448
- drawParticle({
3726
+ this.#drawParticle({
4449
3727
  container,
4450
3728
  context,
4451
3729
  particle,
@@ -4464,7 +3742,7 @@
4464
3742
  drawParticlePlugins(particle, delta) {
4465
3743
  this.draw(ctx => {
4466
3744
  for (const plugin of this.#drawParticlePlugins) {
4467
- drawParticlePlugin(ctx, plugin, particle, delta);
3745
+ this.#drawParticlePlugin(ctx, plugin, particle, delta);
4468
3746
  }
4469
3747
  });
4470
3748
  }
@@ -4564,12 +3842,19 @@
4564
3842
  }
4565
3843
  paintBase(baseColor) {
4566
3844
  this.draw(ctx => {
4567
- paintBase(ctx, this.#canvasManager.size, baseColor);
3845
+ ctx.fillStyle = baseColor ?? "rgba(0,0,0,0)";
3846
+ ctx.fillRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4568
3847
  });
4569
3848
  }
4570
3849
  paintImage(image, opacity) {
4571
3850
  this.draw(ctx => {
4572
- paintImage(ctx, this.#canvasManager.size, image, opacity);
3851
+ if (!image) {
3852
+ return;
3853
+ }
3854
+ const prevAlpha = ctx.globalAlpha;
3855
+ ctx.globalAlpha = opacity;
3856
+ ctx.drawImage(image, originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
3857
+ ctx.globalAlpha = prevAlpha;
4573
3858
  });
4574
3859
  }
4575
3860
  setContext(context) {
@@ -4583,15 +3868,15 @@
4583
3868
  }
4584
3869
  stop() {
4585
3870
  this.draw(ctx => {
4586
- clear(ctx, this.#canvasManager.size);
3871
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4587
3872
  });
4588
3873
  }
4589
- #applyPostDrawUpdaters = particle => {
3874
+ #applyPostDrawUpdaters(particle) {
4590
3875
  for (const updater of this.#postDrawUpdaters) {
4591
3876
  updater.afterDraw?.(particle);
4592
3877
  }
4593
- };
4594
- #applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
3878
+ }
3879
+ #applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
4595
3880
  for (const updater of this.#preDrawUpdaters) {
4596
3881
  if (updater.getColorStyles) {
4597
3882
  const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
@@ -4610,8 +3895,114 @@
4610
3895
  }
4611
3896
  updater.beforeDraw?.(particle);
4612
3897
  }
4613
- };
4614
- #getPluginParticleColors = particle => {
3898
+ }
3899
+ #drawAfterEffect(drawer, data) {
3900
+ if (!drawer?.drawAfter) {
3901
+ return;
3902
+ }
3903
+ const { particle } = data;
3904
+ if (!particle.effect) {
3905
+ return;
3906
+ }
3907
+ drawer.drawAfter(data);
3908
+ }
3909
+ #drawBeforeEffect(drawer, data) {
3910
+ if (!drawer?.drawBefore) {
3911
+ return;
3912
+ }
3913
+ const { particle } = data;
3914
+ if (!particle.effect) {
3915
+ return;
3916
+ }
3917
+ drawer.drawBefore(data);
3918
+ }
3919
+ #drawParticle(data) {
3920
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
3921
+ x: pos.x,
3922
+ y: pos.y,
3923
+ };
3924
+ context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
3925
+ if (colorStyles.fill) {
3926
+ context.fillStyle = colorStyles.fill;
3927
+ }
3928
+ const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
3929
+ context.lineWidth = strokeWidth;
3930
+ if (colorStyles.stroke) {
3931
+ context.strokeStyle = colorStyles.stroke;
3932
+ }
3933
+ const drawData = {
3934
+ context,
3935
+ particle,
3936
+ radius,
3937
+ drawRadius: radius * drawScale,
3938
+ opacity,
3939
+ delta,
3940
+ pixelRatio: container.retina.pixelRatio,
3941
+ fill: fillEnabled,
3942
+ stroke: strokeWidth > minStrokeWidth,
3943
+ transformData,
3944
+ position: { ...pos },
3945
+ drawPosition,
3946
+ drawScale,
3947
+ };
3948
+ for (const plugin of container.plugins) {
3949
+ plugin.drawParticleTransform?.(drawData);
3950
+ }
3951
+ const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
3952
+ this.#drawBeforeEffect(effect, drawData);
3953
+ this.#drawShapeBeforeDraw(shape, drawData);
3954
+ this.#drawShape(shape, drawData);
3955
+ this.#drawShapeAfterDraw(shape, drawData);
3956
+ this.#drawAfterEffect(effect, drawData);
3957
+ context.resetTransform();
3958
+ }
3959
+ #drawParticlePlugin(context, plugin, particle, delta) {
3960
+ if (!plugin.drawParticle) {
3961
+ return;
3962
+ }
3963
+ plugin.drawParticle(context, particle, delta);
3964
+ }
3965
+ #drawShape(drawer, data) {
3966
+ if (!drawer) {
3967
+ return;
3968
+ }
3969
+ const { context, fill, particle, stroke } = data;
3970
+ if (!particle.shape) {
3971
+ return;
3972
+ }
3973
+ context.beginPath();
3974
+ drawer.draw(data);
3975
+ if (particle.shapeClose) {
3976
+ context.closePath();
3977
+ }
3978
+ if (fill) {
3979
+ context.fill();
3980
+ }
3981
+ if (stroke) {
3982
+ context.stroke();
3983
+ }
3984
+ }
3985
+ #drawShapeAfterDraw(drawer, data) {
3986
+ if (!drawer?.afterDraw) {
3987
+ return;
3988
+ }
3989
+ const { particle } = data;
3990
+ if (!particle.shape) {
3991
+ return;
3992
+ }
3993
+ drawer.afterDraw(data);
3994
+ }
3995
+ #drawShapeBeforeDraw(drawer, data) {
3996
+ if (!drawer?.beforeDraw) {
3997
+ return;
3998
+ }
3999
+ const { particle } = data;
4000
+ if (!particle.shape) {
4001
+ return;
4002
+ }
4003
+ drawer.beforeDraw(data);
4004
+ }
4005
+ #getPluginParticleColors(particle) {
4615
4006
  let fColor, sColor;
4616
4007
  for (const plugin of this.#colorPlugins) {
4617
4008
  if (!fColor && plugin.particleFillColor) {
@@ -4627,7 +4018,7 @@
4627
4018
  this.#reusablePluginColors[fColorIndex] = fColor;
4628
4019
  this.#reusablePluginColors[sColorIndex] = sColor;
4629
4020
  return this.#reusablePluginColors;
4630
- };
4021
+ }
4631
4022
  }
4632
4023
 
4633
4024
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -4759,6 +4150,7 @@
4759
4150
  obs.observe(element, { attributes: true });
4760
4151
  });
4761
4152
  this.initPlugins();
4153
+ this.#initContext();
4762
4154
  this.render.init();
4763
4155
  }
4764
4156
  initBackground() {
@@ -4768,7 +4160,7 @@
4768
4160
  }
4769
4161
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4770
4162
  if (color) {
4771
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity);
4163
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
4772
4164
  }
4773
4165
  else {
4774
4166
  elementStyle.backgroundColor = "";
@@ -4790,7 +4182,7 @@
4790
4182
  if (this.#generated && this.domElement) {
4791
4183
  this.domElement.remove();
4792
4184
  }
4793
- const container = this.#container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4185
+ const domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4794
4186
  this.domElement = domCanvas;
4795
4187
  this.#generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4796
4188
  this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
@@ -4811,26 +4203,6 @@
4811
4203
  const pxRatio = this.#container.retina.pixelRatio, retinaSize = this.size;
4812
4204
  renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4813
4205
  renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4814
- const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4815
- this.render.setContextSettings({
4816
- alpha: true,
4817
- colorSpace: canSupportHdrQuery?.matches && container.hdr ? "display-p3" : "srgb",
4818
- desynchronized: true,
4819
- willReadFrequently: false,
4820
- });
4821
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4822
- this.#safeMutationObserver(obs => {
4823
- obs.disconnect();
4824
- });
4825
- container.retina.init();
4826
- this.initBackground();
4827
- this.#safeMutationObserver(obs => {
4828
- const element = this.domElement;
4829
- if (!element || !(element instanceof Node)) {
4830
- return;
4831
- }
4832
- obs.observe(element, { attributes: true });
4833
- });
4834
4206
  }
4835
4207
  resize() {
4836
4208
  const element = this.domElement;
@@ -4898,12 +4270,30 @@
4898
4270
  await container.refresh();
4899
4271
  }
4900
4272
  }
4901
- #applyResizePlugins = () => {
4273
+ #applyResizePlugins() {
4902
4274
  for (const plugin of this.#resizePlugins) {
4903
4275
  plugin.resize?.();
4904
4276
  }
4905
- };
4906
- #initStyle = () => {
4277
+ }
4278
+ #initContext() {
4279
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4280
+ safeMatchMedia("(color-gamut: p3)")?.matches &&
4281
+ safeMatchMedia("(dynamic-range: high)")?.matches;
4282
+ this.render.setContextSettings({
4283
+ alpha: true,
4284
+ desynchronized: true,
4285
+ willReadFrequently: false,
4286
+ ...(canSupportHdr
4287
+ ? { colorSpace: "display-p3", colorType: "float16" }
4288
+ : { colorSpace: "srgb" }),
4289
+ });
4290
+ const renderCanvas = this.renderCanvas;
4291
+ if (!renderCanvas) {
4292
+ return;
4293
+ }
4294
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4295
+ }
4296
+ #initStyle() {
4907
4297
  const element = this.domElement, options = this.#container.actualOptions;
4908
4298
  if (!element) {
4909
4299
  return;
@@ -4924,8 +4314,8 @@
4924
4314
  }
4925
4315
  element.style.setProperty(key, value, "important");
4926
4316
  }
4927
- };
4928
- #repairStyle = () => {
4317
+ }
4318
+ #repairStyle() {
4929
4319
  const element = this.domElement;
4930
4320
  if (!element) {
4931
4321
  return;
@@ -4944,27 +4334,27 @@
4944
4334
  }
4945
4335
  observer.observe(element, { attributes: true });
4946
4336
  });
4947
- };
4948
- #resetOriginalStyle = () => {
4337
+ }
4338
+ #resetOriginalStyle() {
4949
4339
  const element = this.domElement, originalStyle = this.#originalStyle;
4950
4340
  if (!element || !originalStyle) {
4951
4341
  return;
4952
4342
  }
4953
4343
  setStyle(element, originalStyle, true);
4954
- };
4955
- #safeMutationObserver = callback => {
4344
+ }
4345
+ #safeMutationObserver(callback) {
4956
4346
  if (!this.#mutationObserver) {
4957
4347
  return;
4958
4348
  }
4959
4349
  callback(this.#mutationObserver);
4960
- };
4961
- #setFullScreenStyle = () => {
4350
+ }
4351
+ #setFullScreenStyle() {
4962
4352
  const element = this.domElement;
4963
4353
  if (!element) {
4964
4354
  return;
4965
4355
  }
4966
4356
  setStyle(element, getFullScreenStyle(this.#container.actualOptions.fullScreen.zIndex), true);
4967
- };
4357
+ }
4968
4358
  }
4969
4359
 
4970
4360
  class EventListeners {
@@ -4989,7 +4379,7 @@
4989
4379
  removeListeners() {
4990
4380
  this.#manageListeners(false);
4991
4381
  }
4992
- #handleVisibilityChange = () => {
4382
+ #handleVisibilityChange() {
4993
4383
  const container = this.#container, options = container.actualOptions;
4994
4384
  if (!options.pauseOnBlur) {
4995
4385
  return;
@@ -5007,8 +4397,8 @@
5007
4397
  container.draw(true);
5008
4398
  }
5009
4399
  }
5010
- };
5011
- #handleWindowResize = () => {
4400
+ }
4401
+ #handleWindowResize() {
5012
4402
  if (this.#resizeTimeout) {
5013
4403
  clearTimeout(this.#resizeTimeout);
5014
4404
  this.#resizeTimeout = undefined;
@@ -5018,13 +4408,13 @@
5018
4408
  await canvas.windowResize();
5019
4409
  };
5020
4410
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
5021
- };
5022
- #manageListeners = add => {
4411
+ }
4412
+ #manageListeners(add) {
5023
4413
  const handlers = this.#handlers;
5024
4414
  this.#manageResize(add);
5025
4415
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
5026
- };
5027
- #manageResize = add => {
4416
+ }
4417
+ #manageResize(add) {
5028
4418
  const handlers = this.#handlers, container = this.#container, options = container.actualOptions;
5029
4419
  if (!options.resize.enable) {
5030
4420
  return;
@@ -5051,7 +4441,7 @@
5051
4441
  });
5052
4442
  this.#resizeObserver.observe(canvasEl);
5053
4443
  }
5054
- };
4444
+ }
5055
4445
  }
5056
4446
 
5057
4447
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
@@ -5078,6 +4468,131 @@
5078
4468
  data.setCb(data.radius);
5079
4469
  }
5080
4470
  }
4471
+ function normalizeAngle(angle, modulus) {
4472
+ const normalized = angle % modulus;
4473
+ return normalized < defaultAngle ? normalized + modulus : normalized;
4474
+ }
4475
+ function initParticleState(particle, id, group) {
4476
+ particle.id = id;
4477
+ particle.group = group;
4478
+ particle.justWarped = false;
4479
+ particle.effectClose = true;
4480
+ particle.shapeClose = true;
4481
+ particle.pathRotation = false;
4482
+ particle.lastPathTime = 0;
4483
+ particle.destroyed = false;
4484
+ particle.unbreakable = false;
4485
+ particle.isRotating = false;
4486
+ particle.rotation = 0;
4487
+ particle.misplaced = false;
4488
+ particle.retina = {
4489
+ maxDistance: {},
4490
+ maxSpeed: 0,
4491
+ moveDrift: 0,
4492
+ moveSpeed: 0,
4493
+ sizeAnimationSpeed: 0,
4494
+ };
4495
+ particle.size = {
4496
+ value: 1,
4497
+ max: 1,
4498
+ min: 1,
4499
+ enable: false,
4500
+ };
4501
+ particle.outType = ParticleOutType.normal;
4502
+ particle.ignoresResizeRatio = true;
4503
+ }
4504
+ function resolveParticleOptions(particle, container, pluginManager, overrideOptions) {
4505
+ const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates;
4506
+ particle.effect = itemFromSingleOrMultiple(particlesOptions.effect.type, particle.id, reduceDuplicates);
4507
+ particle.shape = itemFromSingleOrMultiple(particlesOptions.shape.type, particle.id, reduceDuplicates);
4508
+ const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
4509
+ if (overrideOptions) {
4510
+ if (overrideOptions.effect) {
4511
+ const overrideEffectType = overrideOptions.effect.type;
4512
+ if (overrideEffectType && overrideEffectType !== particle.effect) {
4513
+ const effect = itemFromSingleOrMultiple(overrideEffectType, particle.id, reduceDuplicates);
4514
+ if (effect) {
4515
+ particle.effect = effect;
4516
+ }
4517
+ }
4518
+ effectOptions.load(overrideOptions.effect);
4519
+ }
4520
+ if (overrideOptions.shape) {
4521
+ const overrideShapeType = overrideOptions.shape.type;
4522
+ if (overrideShapeType && overrideShapeType !== particle.shape) {
4523
+ const shape = itemFromSingleOrMultiple(overrideShapeType, particle.id, reduceDuplicates);
4524
+ if (shape) {
4525
+ particle.shape = shape;
4526
+ }
4527
+ }
4528
+ shapeOptions.load(overrideOptions.shape);
4529
+ }
4530
+ }
4531
+ if (particle.effect === randomColorValue) {
4532
+ const availableEffects = [...container.effectDrawers.keys()];
4533
+ particle.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
4534
+ }
4535
+ if (particle.shape === randomColorValue) {
4536
+ const availableShapes = [...container.shapeDrawers.keys()];
4537
+ particle.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
4538
+ }
4539
+ particle.effectData = particle.effect
4540
+ ? loadEffectData(particle.effect, effectOptions, particle.id, reduceDuplicates)
4541
+ : undefined;
4542
+ particle.shapeData = particle.shape
4543
+ ? loadShapeData(particle.shape, shapeOptions, particle.id, reduceDuplicates)
4544
+ : undefined;
4545
+ particlesOptions.load(overrideOptions);
4546
+ const effectData = particle.effectData, shapeData = particle.shapeData;
4547
+ if (effectData) {
4548
+ particlesOptions.load(effectData.particles);
4549
+ }
4550
+ if (shapeData) {
4551
+ particlesOptions.load(shapeData.particles);
4552
+ }
4553
+ particle.effectClose = effectData?.close ?? particlesOptions.effect.close;
4554
+ particle.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4555
+ return particlesOptions;
4556
+ }
4557
+ function initParticleDrawers(particle, container) {
4558
+ let effectDrawer, shapeDrawer;
4559
+ if (particle.effect) {
4560
+ effectDrawer = container.effectDrawers.get(particle.effect);
4561
+ }
4562
+ if (effectDrawer?.loadEffect) {
4563
+ effectDrawer.loadEffect(particle);
4564
+ }
4565
+ if (particle.shape) {
4566
+ shapeDrawer = container.shapeDrawers.get(particle.shape);
4567
+ }
4568
+ if (shapeDrawer?.loadShape) {
4569
+ shapeDrawer.loadShape(particle);
4570
+ }
4571
+ const sideCountFunc = shapeDrawer?.getSidesCount;
4572
+ if (sideCountFunc) {
4573
+ particle.sides = sideCountFunc(particle);
4574
+ }
4575
+ }
4576
+ function runUpdaterPreInit(updaters, particle) {
4577
+ for (const updater of updaters) {
4578
+ updater.preInit?.(particle);
4579
+ }
4580
+ }
4581
+ function runUpdaterInit(updaters, particle) {
4582
+ for (const updater of updaters) {
4583
+ updater.init(particle);
4584
+ }
4585
+ }
4586
+ function runDrawerInit(container, particle) {
4587
+ const shapeDrawer = particle.shape ? container.shapeDrawers.get(particle.shape) : undefined, effectDrawer = particle.effect ? container.effectDrawers.get(particle.effect) : undefined;
4588
+ effectDrawer?.particleInit?.(container, particle);
4589
+ shapeDrawer?.particleInit?.(container, particle);
4590
+ }
4591
+ function runParticleCreatedPlugins(container, particle) {
4592
+ for (const plugin of container.particleCreatedPlugins) {
4593
+ plugin.particleCreated?.(particle);
4594
+ }
4595
+ }
5081
4596
  class Particle {
5082
4597
  backColor;
5083
4598
  bubble;
@@ -5203,94 +4718,20 @@
5203
4718
  const rotateData = this.getRotateData(), rotating = this.isRotating;
5204
4719
  this.#cachedTransform.a = rotateData.cos * (externalTransform.a ?? defaultTransform.a);
5205
4720
  this.#cachedTransform.b = rotating
5206
- ? rotateData.sin * (externalTransform.b ?? identity$1)
4721
+ ? rotateData.sin * (externalTransform.b ?? identity)
5207
4722
  : (externalTransform.b ?? defaultTransform.b);
5208
4723
  this.#cachedTransform.c = rotating
5209
- ? -rotateData.sin * (externalTransform.c ?? identity$1)
4724
+ ? -rotateData.sin * (externalTransform.c ?? identity)
5210
4725
  : (externalTransform.c ?? defaultTransform.c);
5211
4726
  this.#cachedTransform.d = rotateData.cos * (externalTransform.d ?? defaultTransform.d);
5212
4727
  return this.#cachedTransform;
5213
4728
  }
5214
4729
  init(id, position, overrideOptions, group) {
5215
4730
  const container = this.#container;
5216
- this.id = id;
5217
- this.group = group;
5218
- this.justWarped = false;
5219
- this.effectClose = true;
5220
- this.shapeClose = true;
5221
- this.pathRotation = false;
5222
- this.lastPathTime = 0;
5223
- this.destroyed = false;
5224
- this.unbreakable = false;
5225
- this.isRotating = false;
5226
- this.rotation = 0;
5227
- this.misplaced = false;
5228
- this.retina = {
5229
- maxDistance: {},
5230
- maxSpeed: 0,
5231
- moveDrift: 0,
5232
- moveSpeed: 0,
5233
- sizeAnimationSpeed: 0,
5234
- };
5235
- this.size = {
5236
- value: 1,
5237
- max: 1,
5238
- min: 1,
5239
- enable: false,
5240
- };
5241
- this.outType = ParticleOutType.normal;
5242
- this.ignoresResizeRatio = true;
5243
- const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
5244
- this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
5245
- this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
5246
- const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
5247
- if (overrideOptions) {
5248
- if (overrideOptions.effect) {
5249
- const overrideEffectType = overrideOptions.effect.type;
5250
- if (overrideEffectType && overrideEffectType !== this.effect) {
5251
- const effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
5252
- if (effect) {
5253
- this.effect = effect;
5254
- }
5255
- }
5256
- effectOptions.load(overrideOptions.effect);
5257
- }
5258
- if (overrideOptions.shape) {
5259
- const overrideShapeType = overrideOptions.shape.type;
5260
- if (overrideShapeType && overrideShapeType !== this.shape) {
5261
- const shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
5262
- if (shape) {
5263
- this.shape = shape;
5264
- }
5265
- }
5266
- shapeOptions.load(overrideOptions.shape);
5267
- }
5268
- }
5269
- if (this.effect === randomColorValue) {
5270
- const availableEffects = [...this.#container.effectDrawers.keys()];
5271
- this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
5272
- }
5273
- if (this.shape === randomColorValue) {
5274
- const availableShapes = [...this.#container.shapeDrawers.keys()];
5275
- this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
5276
- }
5277
- this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
5278
- this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
5279
- particlesOptions.load(overrideOptions);
5280
- const effectData = this.effectData, shapeData = this.shapeData;
5281
- if (effectData) {
5282
- particlesOptions.load(effectData.particles);
5283
- }
5284
- if (shapeData) {
5285
- particlesOptions.load(shapeData.particles);
5286
- }
5287
- this.effectClose = effectData?.close ?? particlesOptions.effect.close;
5288
- this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
5289
- this.options = particlesOptions;
4731
+ initParticleState(this, id, group);
4732
+ this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
5290
4733
  container.retina.initParticle(this);
5291
- for (const updater of container.particleUpdaters) {
5292
- updater.preInit?.(this);
5293
- }
4734
+ runUpdaterPreInit(container.particleUpdaters, this);
5294
4735
  this.bubble = {
5295
4736
  inRange: false,
5296
4737
  };
@@ -5303,32 +4744,11 @@
5303
4744
  this.velocity = this.initialVelocity.copy();
5304
4745
  this.zIndexFactor = this.position.z / container.zLayers;
5305
4746
  this.sides = 24;
5306
- let effectDrawer, shapeDrawer;
5307
- if (this.effect) {
5308
- effectDrawer = container.effectDrawers.get(this.effect);
5309
- }
5310
- if (effectDrawer?.loadEffect) {
5311
- effectDrawer.loadEffect(this);
5312
- }
5313
- if (this.shape) {
5314
- shapeDrawer = container.shapeDrawers.get(this.shape);
5315
- }
5316
- if (shapeDrawer?.loadShape) {
5317
- shapeDrawer.loadShape(this);
5318
- }
5319
- const sideCountFunc = shapeDrawer?.getSidesCount;
5320
- if (sideCountFunc) {
5321
- this.sides = sideCountFunc(this);
5322
- }
4747
+ initParticleDrawers(this, container);
5323
4748
  this.spawning = false;
5324
- for (const updater of container.particleUpdaters) {
5325
- updater.init(this);
5326
- }
5327
- effectDrawer?.particleInit?.(container, this);
5328
- shapeDrawer?.particleInit?.(container, this);
5329
- for (const plugin of container.particleCreatedPlugins) {
5330
- plugin.particleCreated?.(this);
5331
- }
4749
+ runUpdaterInit(container.particleUpdaters, this);
4750
+ runDrawerInit(container, this);
4751
+ runParticleCreatedPlugins(container, this);
5332
4752
  }
5333
4753
  isInsideCanvas(direction) {
5334
4754
  return this.#getInsideCanvasResult({ direction }).inside;
@@ -5342,15 +4762,15 @@
5342
4762
  }
5343
4763
  const angle = this.roll.angle;
5344
4764
  if (this.roll.horizontal && this.roll.vertical) {
5345
- const normalizedAngle = angle % doublePI, adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + doublePI : normalizedAngle;
4765
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5346
4766
  return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
5347
4767
  }
5348
4768
  if (this.roll.horizontal) {
5349
- const normalizedAngle = (angle + Math.PI * half) % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4769
+ const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
5350
4770
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5351
4771
  }
5352
4772
  if (this.roll.vertical) {
5353
- const normalizedAngle = angle % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4773
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5354
4774
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5355
4775
  }
5356
4776
  return false;
@@ -5363,10 +4783,10 @@
5363
4783
  updater.reset?.(this);
5364
4784
  }
5365
4785
  }
5366
- #calcPosition = (position, zIndex) => {
4786
+ #calcPosition(position, zIndex) {
5367
4787
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
5368
- const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
5369
- while (!signal.aborted) {
4788
+ const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
4789
+ for (;;) {
5370
4790
  for (const plugin of plugins) {
5371
4791
  const pluginPos = plugin.particlePosition?.(posVec, this);
5372
4792
  if (pluginPos) {
@@ -5394,9 +4814,8 @@
5394
4814
  tryCount += tryCountIncrement;
5395
4815
  posVec = undefined;
5396
4816
  }
5397
- return posVec;
5398
- };
5399
- #calculateVelocity = () => {
4817
+ }
4818
+ #calculateVelocity() {
5400
4819
  const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
5401
4820
  if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
5402
4821
  return res;
@@ -5412,8 +4831,8 @@
5412
4831
  res.length *= getRandom();
5413
4832
  }
5414
4833
  return res;
5415
- };
5416
- #fixHorizontal = (pos, radius, outMode) => {
4834
+ }
4835
+ #fixHorizontal(pos, radius, outMode) {
5417
4836
  fixOutMode({
5418
4837
  outMode,
5419
4838
  checkModes: [OutMode.bounce],
@@ -5422,8 +4841,8 @@
5422
4841
  setCb: (value) => (pos.x += value),
5423
4842
  radius,
5424
4843
  });
5425
- };
5426
- #fixVertical = (pos, radius, outMode) => {
4844
+ }
4845
+ #fixVertical(pos, radius, outMode) {
5427
4846
  fixOutMode({
5428
4847
  outMode,
5429
4848
  checkModes: [OutMode.bounce],
@@ -5432,8 +4851,8 @@
5432
4851
  setCb: (value) => (pos.y += value),
5433
4852
  radius,
5434
4853
  });
5435
- };
5436
- #getDefaultInsideCanvasResult = (direction, outMode) => {
4854
+ }
4855
+ #getDefaultInsideCanvasResult(direction, outMode) {
5437
4856
  const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
5438
4857
  if (direction === OutModeDirection.bottom) {
5439
4858
  return {
@@ -5466,8 +4885,8 @@
5466
4885
  position.x <= canvasSize.width + radius,
5467
4886
  reason: "default",
5468
4887
  };
5469
- };
5470
- #getInsideCanvasCallbackData = (direction, outMode) => {
4888
+ }
4889
+ #getInsideCanvasCallbackData(direction, outMode) {
5471
4890
  return {
5472
4891
  canvasSize: this.#container.canvas.size,
5473
4892
  direction,
@@ -5475,8 +4894,8 @@
5475
4894
  particle: this,
5476
4895
  radius: this.getRadius(),
5477
4896
  };
5478
- };
5479
- #getInsideCanvasResult = (data) => {
4897
+ }
4898
+ #getInsideCanvasResult(data) {
5480
4899
  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;
5481
4900
  if (!shapeCheck && !effectCheck) {
5482
4901
  return defaultResult;
@@ -5491,8 +4910,8 @@
5491
4910
  };
5492
4911
  }
5493
4912
  return shapeResult ?? effectResult ?? defaultResult;
5494
- };
5495
- #getRollColor = color => {
4913
+ }
4914
+ #getRollColor(color) {
5496
4915
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
5497
4916
  return color;
5498
4917
  }
@@ -5506,8 +4925,8 @@
5506
4925
  return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
5507
4926
  }
5508
4927
  return color;
5509
- };
5510
- #initPosition = position => {
4928
+ }
4929
+ #initPosition(position) {
5511
4930
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5512
4931
  if (!initialPosition) {
5513
4932
  throw new Error("a valid position cannot be found for particle");
@@ -5530,8 +4949,8 @@
5530
4949
  break;
5531
4950
  }
5532
4951
  this.offset = Vector.origin;
5533
- };
5534
- #normalizeInsideCanvasResult = (result, reason) => {
4952
+ }
4953
+ #normalizeInsideCanvasResult(result, reason) {
5535
4954
  if (typeof result === "boolean") {
5536
4955
  return {
5537
4956
  inside: result,
@@ -5543,7 +4962,7 @@
5543
4962
  margin: result.margin,
5544
4963
  reason: result.reason ?? reason,
5545
4964
  };
5546
- };
4965
+ }
5547
4966
  }
5548
4967
 
5549
4968
  class SpatialHashGrid {
@@ -5896,10 +5315,10 @@
5896
5315
  }
5897
5316
  this.#resizeFactor = undefined;
5898
5317
  }
5899
- #addToPool = (...particles) => {
5318
+ #addToPool(...particles) {
5900
5319
  this.#pool.push(...particles);
5901
- };
5902
- #applyDensity = (options, pluginsCount, group, groupOptions) => {
5320
+ }
5321
+ #applyDensity(options, pluginsCount, group, groupOptions) {
5903
5322
  const numberOptions = options.number;
5904
5323
  if (!numberOptions.density.enable) {
5905
5324
  if (group === undefined) {
@@ -5923,36 +5342,19 @@
5923
5342
  else if (particlesCount > particlesNumber) {
5924
5343
  this.removeQuantity(particlesCount - particlesNumber, group);
5925
5344
  }
5926
- };
5927
- #createBuckets = (zLayers) => {
5345
+ }
5346
+ #createBuckets(zLayers) {
5928
5347
  const bucketCount = Math.max(Math.floor(zLayers), one);
5929
5348
  return Array.from({ length: bucketCount }, () => []);
5930
- };
5931
- #getBucketIndex = (zIndex) => {
5349
+ }
5350
+ #getBucketIndex(zIndex) {
5932
5351
  const maxBucketIndex = this.#zBuckets.length - one;
5933
5352
  if (maxBucketIndex <= minIndex) {
5934
5353
  return minIndex;
5935
5354
  }
5936
5355
  return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
5937
- };
5938
- #getParticleInsertIndex = (bucket, particleId) => {
5939
- let start = minIndex, end = bucket.length;
5940
- while (start < end) {
5941
- const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
5942
- if (!middleParticle) {
5943
- end = middle;
5944
- continue;
5945
- }
5946
- if (middleParticle.id < particleId) {
5947
- start = middle + one;
5948
- }
5949
- else {
5950
- end = middle;
5951
- }
5952
- }
5953
- return start;
5954
- };
5955
- #initDensityFactor = densityOptions => {
5356
+ }
5357
+ #initDensityFactor(densityOptions) {
5956
5358
  const container = this.#container;
5957
5359
  if (!densityOptions.enable) {
5958
5360
  return defaultDensityFactor;
@@ -5962,16 +5364,16 @@
5962
5364
  return defaultDensityFactor;
5963
5365
  }
5964
5366
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5965
- };
5966
- #insertParticleIntoBucket = (particle) => {
5367
+ }
5368
+ #insertParticleIntoBucket(particle) {
5967
5369
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
5968
5370
  if (!bucket) {
5969
5371
  return;
5970
5372
  }
5971
- bucket.splice(this.#getParticleInsertIndex(bucket, particle.id), empty, particle);
5373
+ bucket.push(particle);
5972
5374
  this.#particleBuckets.set(particle.id, bucketIndex);
5973
- };
5974
- #removeParticle = (index, group, override) => {
5375
+ }
5376
+ #removeParticle(index, group, override) {
5975
5377
  const particle = this.#array[index];
5976
5378
  if (!particle) {
5977
5379
  return false;
@@ -5987,22 +5389,20 @@
5987
5389
  });
5988
5390
  this.#addToPool(particle);
5989
5391
  return true;
5990
- };
5991
- #removeParticleFromBucket = (particle) => {
5392
+ }
5393
+ #removeParticleFromBucket(particle) {
5992
5394
  const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
5993
5395
  if (!bucket) {
5994
5396
  this.#particleBuckets.delete(particle.id);
5995
5397
  return;
5996
5398
  }
5997
- const particleIndex = this.#getParticleInsertIndex(bucket, particle.id);
5998
- if (bucket[particleIndex]?.id !== particle.id) {
5999
- this.#particleBuckets.delete(particle.id);
6000
- return;
5399
+ const idx = bucket.findIndex(p => p.id === particle.id);
5400
+ if (idx >= minIndex) {
5401
+ bucket.splice(idx, deleteCount);
6001
5402
  }
6002
- bucket.splice(particleIndex, deleteCount);
6003
5403
  this.#particleBuckets.delete(particle.id);
6004
- };
6005
- #resetBuckets = (zLayers) => {
5404
+ }
5405
+ #resetBuckets(zLayers) {
6006
5406
  const bucketCount = Math.max(Math.floor(zLayers), one);
6007
5407
  if (this.#zBuckets.length !== bucketCount) {
6008
5408
  this.#zBuckets = this.#createBuckets(bucketCount);
@@ -6011,8 +5411,8 @@
6011
5411
  for (const bucket of this.#zBuckets) {
6012
5412
  bucket.length = minIndex;
6013
5413
  }
6014
- };
6015
- #updateParticleBucket = (particle) => {
5414
+ }
5415
+ #updateParticleBucket(particle) {
6016
5416
  const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
6017
5417
  if (currentBucketIndex === undefined) {
6018
5418
  this.#insertParticleIntoBucket(particle);
@@ -6023,9 +5423,9 @@
6023
5423
  }
6024
5424
  const currentBucket = this.#zBuckets[currentBucketIndex];
6025
5425
  if (currentBucket) {
6026
- const particleIndex = this.#getParticleInsertIndex(currentBucket, particle.id);
6027
- if (currentBucket[particleIndex]?.id === particle.id) {
6028
- currentBucket.splice(particleIndex, deleteCount);
5426
+ const idx = currentBucket.findIndex(p => p.id === particle.id);
5427
+ if (idx >= minIndex) {
5428
+ currentBucket.splice(idx, deleteCount);
6029
5429
  }
6030
5430
  }
6031
5431
  const newBucket = this.#zBuckets[newBucketIndex];
@@ -6033,10 +5433,16 @@
6033
5433
  this.#particleBuckets.set(particle.id, newBucketIndex);
6034
5434
  return;
6035
5435
  }
6036
- newBucket.splice(this.#getParticleInsertIndex(newBucket, particle.id), empty, particle);
5436
+ newBucket.push(particle);
5437
+ if (newBucket.length >= double) {
5438
+ const prev = newBucket[newBucket.length - double];
5439
+ if (prev && particle.id < prev.id) {
5440
+ newBucket.sort((a, b) => a.id - b.id);
5441
+ }
5442
+ }
6037
5443
  this.#particleBuckets.set(particle.id, newBucketIndex);
6038
- };
6039
- #updateParticlesPhase1 = (delta) => {
5444
+ }
5445
+ #updateParticlesPhase1(delta) {
6040
5446
  const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
6041
5447
  for (const particle of this.#array) {
6042
5448
  if (resizeFactor && !particle.ignoresResizeRatio) {
@@ -6062,8 +5468,8 @@
6062
5468
  this.grid.insert(particle);
6063
5469
  }
6064
5470
  return particlesToDelete;
6065
- };
6066
- #updateParticlesPhase2 = (delta, particlesToDelete) => {
5471
+ }
5472
+ #updateParticlesPhase2(delta, particlesToDelete) {
6067
5473
  for (const particle of this.#array) {
6068
5474
  if (particle.destroyed) {
6069
5475
  particlesToDelete.add(particle);
@@ -6079,7 +5485,7 @@
6079
5485
  }
6080
5486
  this.#updateParticleBucket(particle);
6081
5487
  }
6082
- };
5488
+ }
6083
5489
  }
6084
5490
 
6085
5491
  class Retina {
@@ -6441,7 +5847,7 @@
6441
5847
  }
6442
5848
  return refresh;
6443
5849
  }
6444
- #nextFrame = (timestamp) => {
5850
+ #nextFrame(timestamp) {
6445
5851
  try {
6446
5852
  if (!this.#smooth &&
6447
5853
  this.#lastFrameTime !== undefined &&
@@ -6469,7 +5875,7 @@
6469
5875
  catch (e) {
6470
5876
  getLogger().error("error in animation loop", e);
6471
5877
  }
6472
- };
5878
+ }
6473
5879
  }
6474
5880
 
6475
5881
  var Container$1 = /*#__PURE__*/Object.freeze({
@@ -6515,7 +5921,7 @@
6515
5921
  BlendPluginInstance: BlendPluginInstance
6516
5922
  });
6517
5923
 
6518
- const minVelocity = 0, identity = 1, moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
5924
+ const moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
6519
5925
  function applyDistance(particle) {
6520
5926
  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;
6521
5927
  if (!hDistance && !vDistance) {
@@ -6790,7 +6196,7 @@
6790
6196
  removeListeners() {
6791
6197
  this.#manageListeners(false);
6792
6198
  }
6793
- #doMouseTouchClick = e => {
6199
+ #doMouseTouchClick(e) {
6794
6200
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions;
6795
6201
  if (this.#canPush) {
6796
6202
  const mouseInteractivity = interactionManager.interactivityData.mouse, mousePos = mouseInteractivity.position;
@@ -6812,11 +6218,11 @@
6812
6218
  this.#mouseTouchFinish();
6813
6219
  }, touchDelay);
6814
6220
  }
6815
- };
6816
- #handleVisibilityChange = () => {
6221
+ }
6222
+ #handleVisibilityChange() {
6817
6223
  this.#mouseTouchFinish();
6818
- };
6819
- #manageInteractivityListeners = add => {
6224
+ }
6225
+ #manageInteractivityListeners(add) {
6820
6226
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivityEl = interactionManager.interactivityData.element;
6821
6227
  if (!interactivityEl) {
6822
6228
  return;
@@ -6847,8 +6253,8 @@
6847
6253
  }
6848
6254
  manageListener(interactivityEl, mouseLeaveEvent, handlers.mouseLeave, add);
6849
6255
  manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
6850
- };
6851
- #manageListeners = add => {
6256
+ }
6257
+ #manageListeners(add) {
6852
6258
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.domElement;
6853
6259
  if (detectType === InteractivityDetect.window) {
6854
6260
  interactionManager.interactivityData.element = safeDocument();
@@ -6861,13 +6267,13 @@
6861
6267
  }
6862
6268
  this.#manageInteractivityListeners(add);
6863
6269
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
6864
- };
6865
- #mouseDown = () => {
6270
+ }
6271
+ #mouseDown() {
6866
6272
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
6867
6273
  mouse.clicking = true;
6868
6274
  mouse.downPosition = mouse.position;
6869
- };
6870
- #mouseTouchClick = e => {
6275
+ }
6276
+ #mouseTouchClick(e) {
6871
6277
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, { mouse } = interactionManager.interactivityData;
6872
6278
  mouse.inside = true;
6873
6279
  let handled = false;
@@ -6885,8 +6291,8 @@
6885
6291
  this.#doMouseTouchClick(e);
6886
6292
  }
6887
6293
  mouse.clicking = false;
6888
- };
6889
- #mouseTouchFinish = () => {
6294
+ }
6295
+ #mouseTouchFinish() {
6890
6296
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
6891
6297
  delete mouse.position;
6892
6298
  delete mouse.clickPosition;
@@ -6894,8 +6300,8 @@
6894
6300
  interactivityData.status = mouseLeaveEvent;
6895
6301
  mouse.inside = false;
6896
6302
  mouse.clicking = false;
6897
- };
6898
- #mouseTouchMove = e => {
6303
+ }
6304
+ #mouseTouchMove(e) {
6899
6305
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.domElement;
6900
6306
  if (!interactivity.element) {
6901
6307
  return;
@@ -6957,31 +6363,37 @@
6957
6363
  }
6958
6364
  interactivity.mouse.position = pos;
6959
6365
  interactivity.status = mouseMoveEvent;
6960
- };
6961
- #touchEnd = e => {
6366
+ }
6367
+ #touchEnd(e) {
6962
6368
  const evt = e, touches = Array.from(evt.changedTouches);
6963
6369
  for (const touch of touches) {
6964
6370
  this.#touches.delete(touch.identifier);
6965
6371
  }
6966
6372
  this.#mouseTouchFinish();
6967
- };
6968
- #touchEndClick = e => {
6373
+ }
6374
+ #touchEndClick(e) {
6969
6375
  const evt = e, touches = Array.from(evt.changedTouches);
6970
6376
  for (const touch of touches) {
6971
6377
  this.#touches.delete(touch.identifier);
6972
6378
  }
6973
6379
  this.#mouseTouchClick(e);
6974
- };
6975
- #touchStart = e => {
6380
+ }
6381
+ #touchStart(e) {
6976
6382
  const evt = e, touches = Array.from(evt.changedTouches);
6977
6383
  for (const touch of touches) {
6978
6384
  this.#touches.set(touch.identifier, performance.now());
6979
6385
  }
6980
6386
  this.#mouseTouchMove(e);
6981
- };
6387
+ }
6982
6388
  }
6983
6389
 
6984
6390
  const clickRadius = 1, touchEndLengthOffset = 1, minCoordinate = 0;
6391
+ function safeIntersectionObserver(callback) {
6392
+ if (typeof IntersectionObserver === "undefined") {
6393
+ return;
6394
+ }
6395
+ return new IntersectionObserver(callback);
6396
+ }
6985
6397
  class InteractionManager {
6986
6398
  interactivityData;
6987
6399
  #clickHandlers;
@@ -7184,7 +6596,7 @@
7184
6596
  const container = this.#container;
7185
6597
  container.particles.grid.setCellSize(maxTotalDistance * container.retina.pixelRatio);
7186
6598
  }
7187
- #intersectionManager = entries => {
6599
+ #intersectionManager(entries) {
7188
6600
  const container = this.#container;
7189
6601
  if (container.destroyed || !container.actualOptions.pauseOnOutsideViewport) {
7190
6602
  return;
@@ -7200,7 +6612,7 @@
7200
6612
  container.pause();
7201
6613
  }
7202
6614
  }
7203
- };
6615
+ }
7204
6616
  }
7205
6617
 
7206
6618
  class InteractivityPluginInstance {