@tsparticles/preset-triangles 4.1.2 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  (function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
- /* Preset v4.1.2 */
2
+ /* Preset v4.2.0 */
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
5
5
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -15,7 +15,7 @@
15
15
  b: 0,
16
16
  c: 0,
17
17
  d: 1,
18
- }, randomColorValue = "random", 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.2";
802
+ return "4.2.0";
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,177 +1404,91 @@
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) {
@@ -2010,76 +1498,47 @@
2010
1498
  }
2011
1499
  }
2012
1500
  }
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;
2045
- }
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
1741
  }
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
- }
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.2");
2135
+ engine.checkVersion("4.2.0");
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.2");
2172
+ engine.checkVersion("4.2.0");
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.2");
2220
+ engine.checkVersion("4.2.0");
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.2");
2273
+ engine.checkVersion("4.2.0");
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.2");
2297
+ engine.checkVersion("4.2.0");
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;
2425
+ }
2426
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
2427
+ if (!particle.destroyed) {
2428
+ data.value = clamp(data.value, minValue, maxValue);
3044
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.2");
2507
+ engine.checkVersion("4.2.0");
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.2");
2852
+ engine.checkVersion("4.2.0");
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.2");
2923
+ engine.checkVersion("4.2.0");
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.2");
2978
+ engine.checkVersion("4.2.0");
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.2");
3063
+ engine.checkVersion("4.2.0");
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.2");
3072
+ engine.checkVersion("4.2.0");
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.2");
3273
+ engine.checkVersion("4.2.0");
3947
3274
  await engine.pluginManager.register(e => {
3948
3275
  const interactivityEngine = e, interactivityPluginManager = interactivityEngine.pluginManager;
3949
3276
  interactivityPluginManager.addPlugin(new InteractivityPlugin(interactivityPluginManager));
@@ -4026,118 +3353,72 @@
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;
3374
+ enable = false;
3375
+ frequency = 1;
4056
3376
  opacity;
4057
- constructor() {
4058
- this.enable = false;
4059
- this.frequency = 1;
4060
- }
4061
3377
  load(data) {
4062
3378
  if (isNull(data)) {
4063
3379
  return;
4064
3380
  }
4065
3381
  if (data.color !== undefined) {
4066
- this.color = OptionsColor.create(this.color, data.color);
4067
- }
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;
3382
+ this.color = OptionsColor.create(this.color, data.color);
4076
3383
  }
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.2");
3550
+ engine.checkVersion("4.2.0");
4273
3551
  await engine.pluginManager.register((e) => {
4274
3552
  const pluginManager = e.pluginManager;
4275
3553
  ensureInteractivityPluginLoaded(e);
@@ -4389,7 +3667,7 @@
4389
3667
  return;
4390
3668
  }
4391
3669
  this.draw(ctx => {
4392
- clear(ctx, this.#canvasManager.size);
3670
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4393
3671
  });
4394
3672
  }
4395
3673
  clear() {
@@ -4451,7 +3729,7 @@
4451
3729
  plugin.drawParticleSetup?.(context, particle, delta);
4452
3730
  }
4453
3731
  this.#applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
4454
- drawParticle({
3732
+ this.#drawParticle({
4455
3733
  container,
4456
3734
  context,
4457
3735
  particle,
@@ -4470,7 +3748,7 @@
4470
3748
  drawParticlePlugins(particle, delta) {
4471
3749
  this.draw(ctx => {
4472
3750
  for (const plugin of this.#drawParticlePlugins) {
4473
- drawParticlePlugin(ctx, plugin, particle, delta);
3751
+ this.#drawParticlePlugin(ctx, plugin, particle, delta);
4474
3752
  }
4475
3753
  });
4476
3754
  }
@@ -4570,12 +3848,19 @@
4570
3848
  }
4571
3849
  paintBase(baseColor) {
4572
3850
  this.draw(ctx => {
4573
- paintBase(ctx, this.#canvasManager.size, baseColor);
3851
+ ctx.fillStyle = baseColor ?? "rgba(0,0,0,0)";
3852
+ ctx.fillRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4574
3853
  });
4575
3854
  }
4576
3855
  paintImage(image, opacity) {
4577
3856
  this.draw(ctx => {
4578
- paintImage(ctx, this.#canvasManager.size, image, opacity);
3857
+ if (!image) {
3858
+ return;
3859
+ }
3860
+ const prevAlpha = ctx.globalAlpha;
3861
+ ctx.globalAlpha = opacity;
3862
+ ctx.drawImage(image, originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
3863
+ ctx.globalAlpha = prevAlpha;
4579
3864
  });
4580
3865
  }
4581
3866
  setContext(context) {
@@ -4589,15 +3874,15 @@
4589
3874
  }
4590
3875
  stop() {
4591
3876
  this.draw(ctx => {
4592
- clear(ctx, this.#canvasManager.size);
3877
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4593
3878
  });
4594
3879
  }
4595
- #applyPostDrawUpdaters = particle => {
3880
+ #applyPostDrawUpdaters(particle) {
4596
3881
  for (const updater of this.#postDrawUpdaters) {
4597
3882
  updater.afterDraw?.(particle);
4598
3883
  }
4599
- };
4600
- #applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
3884
+ }
3885
+ #applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
4601
3886
  for (const updater of this.#preDrawUpdaters) {
4602
3887
  if (updater.getColorStyles) {
4603
3888
  const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
@@ -4616,8 +3901,114 @@
4616
3901
  }
4617
3902
  updater.beforeDraw?.(particle);
4618
3903
  }
4619
- };
4620
- #getPluginParticleColors = particle => {
3904
+ }
3905
+ #drawAfterEffect(drawer, data) {
3906
+ if (!drawer?.drawAfter) {
3907
+ return;
3908
+ }
3909
+ const { particle } = data;
3910
+ if (!particle.effect) {
3911
+ return;
3912
+ }
3913
+ drawer.drawAfter(data);
3914
+ }
3915
+ #drawBeforeEffect(drawer, data) {
3916
+ if (!drawer?.drawBefore) {
3917
+ return;
3918
+ }
3919
+ const { particle } = data;
3920
+ if (!particle.effect) {
3921
+ return;
3922
+ }
3923
+ drawer.drawBefore(data);
3924
+ }
3925
+ #drawParticle(data) {
3926
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
3927
+ x: pos.x,
3928
+ y: pos.y,
3929
+ };
3930
+ context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
3931
+ if (colorStyles.fill) {
3932
+ context.fillStyle = colorStyles.fill;
3933
+ }
3934
+ const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
3935
+ context.lineWidth = strokeWidth;
3936
+ if (colorStyles.stroke) {
3937
+ context.strokeStyle = colorStyles.stroke;
3938
+ }
3939
+ const drawData = {
3940
+ context,
3941
+ particle,
3942
+ radius,
3943
+ drawRadius: radius * drawScale,
3944
+ opacity,
3945
+ delta,
3946
+ pixelRatio: container.retina.pixelRatio,
3947
+ fill: fillEnabled,
3948
+ stroke: strokeWidth > minStrokeWidth,
3949
+ transformData,
3950
+ position: { ...pos },
3951
+ drawPosition,
3952
+ drawScale,
3953
+ };
3954
+ for (const plugin of container.plugins) {
3955
+ plugin.drawParticleTransform?.(drawData);
3956
+ }
3957
+ const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
3958
+ this.#drawBeforeEffect(effect, drawData);
3959
+ this.#drawShapeBeforeDraw(shape, drawData);
3960
+ this.#drawShape(shape, drawData);
3961
+ this.#drawShapeAfterDraw(shape, drawData);
3962
+ this.#drawAfterEffect(effect, drawData);
3963
+ context.resetTransform();
3964
+ }
3965
+ #drawParticlePlugin(context, plugin, particle, delta) {
3966
+ if (!plugin.drawParticle) {
3967
+ return;
3968
+ }
3969
+ plugin.drawParticle(context, particle, delta);
3970
+ }
3971
+ #drawShape(drawer, data) {
3972
+ if (!drawer) {
3973
+ return;
3974
+ }
3975
+ const { context, fill, particle, stroke } = data;
3976
+ if (!particle.shape) {
3977
+ return;
3978
+ }
3979
+ context.beginPath();
3980
+ drawer.draw(data);
3981
+ if (particle.shapeClose) {
3982
+ context.closePath();
3983
+ }
3984
+ if (fill) {
3985
+ context.fill();
3986
+ }
3987
+ if (stroke) {
3988
+ context.stroke();
3989
+ }
3990
+ }
3991
+ #drawShapeAfterDraw(drawer, data) {
3992
+ if (!drawer?.afterDraw) {
3993
+ return;
3994
+ }
3995
+ const { particle } = data;
3996
+ if (!particle.shape) {
3997
+ return;
3998
+ }
3999
+ drawer.afterDraw(data);
4000
+ }
4001
+ #drawShapeBeforeDraw(drawer, data) {
4002
+ if (!drawer?.beforeDraw) {
4003
+ return;
4004
+ }
4005
+ const { particle } = data;
4006
+ if (!particle.shape) {
4007
+ return;
4008
+ }
4009
+ drawer.beforeDraw(data);
4010
+ }
4011
+ #getPluginParticleColors(particle) {
4621
4012
  let fColor, sColor;
4622
4013
  for (const plugin of this.#colorPlugins) {
4623
4014
  if (!fColor && plugin.particleFillColor) {
@@ -4633,7 +4024,7 @@
4633
4024
  this.#reusablePluginColors[fColorIndex] = fColor;
4634
4025
  this.#reusablePluginColors[sColorIndex] = sColor;
4635
4026
  return this.#reusablePluginColors;
4636
- };
4027
+ }
4637
4028
  }
4638
4029
 
4639
4030
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -4765,6 +4156,7 @@
4765
4156
  obs.observe(element, { attributes: true });
4766
4157
  });
4767
4158
  this.initPlugins();
4159
+ this.#initContext();
4768
4160
  this.render.init();
4769
4161
  }
4770
4162
  initBackground() {
@@ -4774,7 +4166,7 @@
4774
4166
  }
4775
4167
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4776
4168
  if (color) {
4777
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity);
4169
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
4778
4170
  }
4779
4171
  else {
4780
4172
  elementStyle.backgroundColor = "";
@@ -4796,7 +4188,7 @@
4796
4188
  if (this.#generated && this.domElement) {
4797
4189
  this.domElement.remove();
4798
4190
  }
4799
- const container = this.#container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4191
+ const domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4800
4192
  this.domElement = domCanvas;
4801
4193
  this.#generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4802
4194
  this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
@@ -4817,26 +4209,6 @@
4817
4209
  const pxRatio = this.#container.retina.pixelRatio, retinaSize = this.size;
4818
4210
  renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4819
4211
  renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4820
- const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4821
- this.render.setContextSettings({
4822
- alpha: true,
4823
- colorSpace: canSupportHdrQuery?.matches && container.hdr ? "display-p3" : "srgb",
4824
- desynchronized: true,
4825
- willReadFrequently: false,
4826
- });
4827
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4828
- this.#safeMutationObserver(obs => {
4829
- obs.disconnect();
4830
- });
4831
- container.retina.init();
4832
- this.initBackground();
4833
- this.#safeMutationObserver(obs => {
4834
- const element = this.domElement;
4835
- if (!element || !(element instanceof Node)) {
4836
- return;
4837
- }
4838
- obs.observe(element, { attributes: true });
4839
- });
4840
4212
  }
4841
4213
  resize() {
4842
4214
  const element = this.domElement;
@@ -4904,12 +4276,30 @@
4904
4276
  await container.refresh();
4905
4277
  }
4906
4278
  }
4907
- #applyResizePlugins = () => {
4279
+ #applyResizePlugins() {
4908
4280
  for (const plugin of this.#resizePlugins) {
4909
4281
  plugin.resize?.();
4910
4282
  }
4911
- };
4912
- #initStyle = () => {
4283
+ }
4284
+ #initContext() {
4285
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4286
+ safeMatchMedia("(color-gamut: p3)")?.matches &&
4287
+ safeMatchMedia("(dynamic-range: high)")?.matches;
4288
+ this.render.setContextSettings({
4289
+ alpha: true,
4290
+ desynchronized: true,
4291
+ willReadFrequently: false,
4292
+ ...(canSupportHdr
4293
+ ? { colorSpace: "display-p3", colorType: "float16" }
4294
+ : { colorSpace: "srgb" }),
4295
+ });
4296
+ const renderCanvas = this.renderCanvas;
4297
+ if (!renderCanvas) {
4298
+ return;
4299
+ }
4300
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4301
+ }
4302
+ #initStyle() {
4913
4303
  const element = this.domElement, options = this.#container.actualOptions;
4914
4304
  if (!element) {
4915
4305
  return;
@@ -4930,8 +4320,8 @@
4930
4320
  }
4931
4321
  element.style.setProperty(key, value, "important");
4932
4322
  }
4933
- };
4934
- #repairStyle = () => {
4323
+ }
4324
+ #repairStyle() {
4935
4325
  const element = this.domElement;
4936
4326
  if (!element) {
4937
4327
  return;
@@ -4950,27 +4340,27 @@
4950
4340
  }
4951
4341
  observer.observe(element, { attributes: true });
4952
4342
  });
4953
- };
4954
- #resetOriginalStyle = () => {
4343
+ }
4344
+ #resetOriginalStyle() {
4955
4345
  const element = this.domElement, originalStyle = this.#originalStyle;
4956
4346
  if (!element || !originalStyle) {
4957
4347
  return;
4958
4348
  }
4959
4349
  setStyle(element, originalStyle, true);
4960
- };
4961
- #safeMutationObserver = callback => {
4350
+ }
4351
+ #safeMutationObserver(callback) {
4962
4352
  if (!this.#mutationObserver) {
4963
4353
  return;
4964
4354
  }
4965
4355
  callback(this.#mutationObserver);
4966
- };
4967
- #setFullScreenStyle = () => {
4356
+ }
4357
+ #setFullScreenStyle() {
4968
4358
  const element = this.domElement;
4969
4359
  if (!element) {
4970
4360
  return;
4971
4361
  }
4972
4362
  setStyle(element, getFullScreenStyle(this.#container.actualOptions.fullScreen.zIndex), true);
4973
- };
4363
+ }
4974
4364
  }
4975
4365
 
4976
4366
  class EventListeners {
@@ -4995,7 +4385,7 @@
4995
4385
  removeListeners() {
4996
4386
  this.#manageListeners(false);
4997
4387
  }
4998
- #handleVisibilityChange = () => {
4388
+ #handleVisibilityChange() {
4999
4389
  const container = this.#container, options = container.actualOptions;
5000
4390
  if (!options.pauseOnBlur) {
5001
4391
  return;
@@ -5013,8 +4403,8 @@
5013
4403
  container.draw(true);
5014
4404
  }
5015
4405
  }
5016
- };
5017
- #handleWindowResize = () => {
4406
+ }
4407
+ #handleWindowResize() {
5018
4408
  if (this.#resizeTimeout) {
5019
4409
  clearTimeout(this.#resizeTimeout);
5020
4410
  this.#resizeTimeout = undefined;
@@ -5024,13 +4414,13 @@
5024
4414
  await canvas.windowResize();
5025
4415
  };
5026
4416
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
5027
- };
5028
- #manageListeners = add => {
4417
+ }
4418
+ #manageListeners(add) {
5029
4419
  const handlers = this.#handlers;
5030
4420
  this.#manageResize(add);
5031
4421
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
5032
- };
5033
- #manageResize = add => {
4422
+ }
4423
+ #manageResize(add) {
5034
4424
  const handlers = this.#handlers, container = this.#container, options = container.actualOptions;
5035
4425
  if (!options.resize.enable) {
5036
4426
  return;
@@ -5057,7 +4447,7 @@
5057
4447
  });
5058
4448
  this.#resizeObserver.observe(canvasEl);
5059
4449
  }
5060
- };
4450
+ }
5061
4451
  }
5062
4452
 
5063
4453
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
@@ -5084,6 +4474,131 @@
5084
4474
  data.setCb(data.radius);
5085
4475
  }
5086
4476
  }
4477
+ function normalizeAngle(angle, modulus) {
4478
+ const normalized = angle % modulus;
4479
+ return normalized < defaultAngle ? normalized + modulus : normalized;
4480
+ }
4481
+ function initParticleState(particle, id, group) {
4482
+ particle.id = id;
4483
+ particle.group = group;
4484
+ particle.justWarped = false;
4485
+ particle.effectClose = true;
4486
+ particle.shapeClose = true;
4487
+ particle.pathRotation = false;
4488
+ particle.lastPathTime = 0;
4489
+ particle.destroyed = false;
4490
+ particle.unbreakable = false;
4491
+ particle.isRotating = false;
4492
+ particle.rotation = 0;
4493
+ particle.misplaced = false;
4494
+ particle.retina = {
4495
+ maxDistance: {},
4496
+ maxSpeed: 0,
4497
+ moveDrift: 0,
4498
+ moveSpeed: 0,
4499
+ sizeAnimationSpeed: 0,
4500
+ };
4501
+ particle.size = {
4502
+ value: 1,
4503
+ max: 1,
4504
+ min: 1,
4505
+ enable: false,
4506
+ };
4507
+ particle.outType = ParticleOutType.normal;
4508
+ particle.ignoresResizeRatio = true;
4509
+ }
4510
+ function resolveParticleOptions(particle, container, pluginManager, overrideOptions) {
4511
+ const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates;
4512
+ particle.effect = itemFromSingleOrMultiple(particlesOptions.effect.type, particle.id, reduceDuplicates);
4513
+ particle.shape = itemFromSingleOrMultiple(particlesOptions.shape.type, particle.id, reduceDuplicates);
4514
+ const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
4515
+ if (overrideOptions) {
4516
+ if (overrideOptions.effect) {
4517
+ const overrideEffectType = overrideOptions.effect.type;
4518
+ if (overrideEffectType && overrideEffectType !== particle.effect) {
4519
+ const effect = itemFromSingleOrMultiple(overrideEffectType, particle.id, reduceDuplicates);
4520
+ if (effect) {
4521
+ particle.effect = effect;
4522
+ }
4523
+ }
4524
+ effectOptions.load(overrideOptions.effect);
4525
+ }
4526
+ if (overrideOptions.shape) {
4527
+ const overrideShapeType = overrideOptions.shape.type;
4528
+ if (overrideShapeType && overrideShapeType !== particle.shape) {
4529
+ const shape = itemFromSingleOrMultiple(overrideShapeType, particle.id, reduceDuplicates);
4530
+ if (shape) {
4531
+ particle.shape = shape;
4532
+ }
4533
+ }
4534
+ shapeOptions.load(overrideOptions.shape);
4535
+ }
4536
+ }
4537
+ if (particle.effect === randomColorValue) {
4538
+ const availableEffects = [...container.effectDrawers.keys()];
4539
+ particle.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
4540
+ }
4541
+ if (particle.shape === randomColorValue) {
4542
+ const availableShapes = [...container.shapeDrawers.keys()];
4543
+ particle.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
4544
+ }
4545
+ particle.effectData = particle.effect
4546
+ ? loadEffectData(particle.effect, effectOptions, particle.id, reduceDuplicates)
4547
+ : undefined;
4548
+ particle.shapeData = particle.shape
4549
+ ? loadShapeData(particle.shape, shapeOptions, particle.id, reduceDuplicates)
4550
+ : undefined;
4551
+ particlesOptions.load(overrideOptions);
4552
+ const effectData = particle.effectData, shapeData = particle.shapeData;
4553
+ if (effectData) {
4554
+ particlesOptions.load(effectData.particles);
4555
+ }
4556
+ if (shapeData) {
4557
+ particlesOptions.load(shapeData.particles);
4558
+ }
4559
+ particle.effectClose = effectData?.close ?? particlesOptions.effect.close;
4560
+ particle.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4561
+ return particlesOptions;
4562
+ }
4563
+ function initParticleDrawers(particle, container) {
4564
+ let effectDrawer, shapeDrawer;
4565
+ if (particle.effect) {
4566
+ effectDrawer = container.effectDrawers.get(particle.effect);
4567
+ }
4568
+ if (effectDrawer?.loadEffect) {
4569
+ effectDrawer.loadEffect(particle);
4570
+ }
4571
+ if (particle.shape) {
4572
+ shapeDrawer = container.shapeDrawers.get(particle.shape);
4573
+ }
4574
+ if (shapeDrawer?.loadShape) {
4575
+ shapeDrawer.loadShape(particle);
4576
+ }
4577
+ const sideCountFunc = shapeDrawer?.getSidesCount;
4578
+ if (sideCountFunc) {
4579
+ particle.sides = sideCountFunc(particle);
4580
+ }
4581
+ }
4582
+ function runUpdaterPreInit(updaters, particle) {
4583
+ for (const updater of updaters) {
4584
+ updater.preInit?.(particle);
4585
+ }
4586
+ }
4587
+ function runUpdaterInit(updaters, particle) {
4588
+ for (const updater of updaters) {
4589
+ updater.init(particle);
4590
+ }
4591
+ }
4592
+ function runDrawerInit(container, particle) {
4593
+ const shapeDrawer = particle.shape ? container.shapeDrawers.get(particle.shape) : undefined, effectDrawer = particle.effect ? container.effectDrawers.get(particle.effect) : undefined;
4594
+ effectDrawer?.particleInit?.(container, particle);
4595
+ shapeDrawer?.particleInit?.(container, particle);
4596
+ }
4597
+ function runParticleCreatedPlugins(container, particle) {
4598
+ for (const plugin of container.particleCreatedPlugins) {
4599
+ plugin.particleCreated?.(particle);
4600
+ }
4601
+ }
5087
4602
  class Particle {
5088
4603
  backColor;
5089
4604
  bubble;
@@ -5209,88 +4724,20 @@
5209
4724
  const rotateData = this.getRotateData(), rotating = this.isRotating;
5210
4725
  this.#cachedTransform.a = rotateData.cos * (externalTransform.a ?? defaultTransform.a);
5211
4726
  this.#cachedTransform.b = rotating
5212
- ? rotateData.sin * (externalTransform.b ?? identity$1)
4727
+ ? rotateData.sin * (externalTransform.b ?? identity)
5213
4728
  : (externalTransform.b ?? defaultTransform.b);
5214
4729
  this.#cachedTransform.c = rotating
5215
- ? -rotateData.sin * (externalTransform.c ?? identity$1)
4730
+ ? -rotateData.sin * (externalTransform.c ?? identity)
5216
4731
  : (externalTransform.c ?? defaultTransform.c);
5217
4732
  this.#cachedTransform.d = rotateData.cos * (externalTransform.d ?? defaultTransform.d);
5218
4733
  return this.#cachedTransform;
5219
4734
  }
5220
4735
  init(id, position, overrideOptions, group) {
5221
4736
  const container = this.#container;
5222
- this.id = id;
5223
- this.group = group;
5224
- this.justWarped = false;
5225
- this.effectClose = true;
5226
- this.shapeClose = true;
5227
- this.pathRotation = false;
5228
- this.lastPathTime = 0;
5229
- this.destroyed = false;
5230
- this.unbreakable = false;
5231
- this.isRotating = false;
5232
- this.rotation = 0;
5233
- this.misplaced = false;
5234
- this.retina = {
5235
- maxDistance: {},
5236
- maxSpeed: 0,
5237
- moveDrift: 0,
5238
- moveSpeed: 0,
5239
- sizeAnimationSpeed: 0,
5240
- };
5241
- this.size = {
5242
- value: 1,
5243
- max: 1,
5244
- min: 1,
5245
- enable: false,
5246
- };
5247
- this.outType = ParticleOutType.normal;
5248
- this.ignoresResizeRatio = true;
5249
- const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
5250
- this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
5251
- this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
5252
- const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
5253
- if (overrideOptions) {
5254
- if (overrideOptions.effect?.type && overrideOptions.effect.type !== this.effect) {
5255
- const overrideEffectType = overrideOptions.effect.type, effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
5256
- if (effect) {
5257
- this.effect = effect;
5258
- effectOptions.load(overrideOptions.effect);
5259
- }
5260
- }
5261
- if (overrideOptions.shape?.type && overrideOptions.shape.type !== this.shape) {
5262
- const overrideShapeType = overrideOptions.shape.type, shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
5263
- if (shape) {
5264
- this.shape = shape;
5265
- shapeOptions.load(overrideOptions.shape);
5266
- }
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;
4737
+ initParticleState(this, id, group);
4738
+ this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
5290
4739
  container.retina.initParticle(this);
5291
- for (const updater of container.particleUpdaters) {
5292
- updater.preInit?.(this);
5293
- }
4740
+ runUpdaterPreInit(container.particleUpdaters, this);
5294
4741
  this.bubble = {
5295
4742
  inRange: false,
5296
4743
  };
@@ -5303,32 +4750,11 @@
5303
4750
  this.velocity = this.initialVelocity.copy();
5304
4751
  this.zIndexFactor = this.position.z / container.zLayers;
5305
4752
  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
- }
4753
+ initParticleDrawers(this, container);
5323
4754
  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
- }
4755
+ runUpdaterInit(container.particleUpdaters, this);
4756
+ runDrawerInit(container, this);
4757
+ runParticleCreatedPlugins(container, this);
5332
4758
  }
5333
4759
  isInsideCanvas(direction) {
5334
4760
  return this.#getInsideCanvasResult({ direction }).inside;
@@ -5342,15 +4768,15 @@
5342
4768
  }
5343
4769
  const angle = this.roll.angle;
5344
4770
  if (this.roll.horizontal && this.roll.vertical) {
5345
- const normalizedAngle = angle % doublePI, adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + doublePI : normalizedAngle;
4771
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5346
4772
  return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
5347
4773
  }
5348
4774
  if (this.roll.horizontal) {
5349
- const normalizedAngle = (angle + Math.PI * half) % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4775
+ const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
5350
4776
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5351
4777
  }
5352
4778
  if (this.roll.vertical) {
5353
- const normalizedAngle = angle % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4779
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5354
4780
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5355
4781
  }
5356
4782
  return false;
@@ -5363,10 +4789,10 @@
5363
4789
  updater.reset?.(this);
5364
4790
  }
5365
4791
  }
5366
- #calcPosition = (position, zIndex) => {
4792
+ #calcPosition(position, zIndex) {
5367
4793
  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) {
4794
+ const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
4795
+ for (;;) {
5370
4796
  for (const plugin of plugins) {
5371
4797
  const pluginPos = plugin.particlePosition?.(posVec, this);
5372
4798
  if (pluginPos) {
@@ -5394,9 +4820,8 @@
5394
4820
  tryCount += tryCountIncrement;
5395
4821
  posVec = undefined;
5396
4822
  }
5397
- return posVec;
5398
- };
5399
- #calculateVelocity = () => {
4823
+ }
4824
+ #calculateVelocity() {
5400
4825
  const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
5401
4826
  if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
5402
4827
  return res;
@@ -5412,8 +4837,8 @@
5412
4837
  res.length *= getRandom();
5413
4838
  }
5414
4839
  return res;
5415
- };
5416
- #fixHorizontal = (pos, radius, outMode) => {
4840
+ }
4841
+ #fixHorizontal(pos, radius, outMode) {
5417
4842
  fixOutMode({
5418
4843
  outMode,
5419
4844
  checkModes: [OutMode.bounce],
@@ -5422,8 +4847,8 @@
5422
4847
  setCb: (value) => (pos.x += value),
5423
4848
  radius,
5424
4849
  });
5425
- };
5426
- #fixVertical = (pos, radius, outMode) => {
4850
+ }
4851
+ #fixVertical(pos, radius, outMode) {
5427
4852
  fixOutMode({
5428
4853
  outMode,
5429
4854
  checkModes: [OutMode.bounce],
@@ -5432,8 +4857,8 @@
5432
4857
  setCb: (value) => (pos.y += value),
5433
4858
  radius,
5434
4859
  });
5435
- };
5436
- #getDefaultInsideCanvasResult = (direction, outMode) => {
4860
+ }
4861
+ #getDefaultInsideCanvasResult(direction, outMode) {
5437
4862
  const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
5438
4863
  if (direction === OutModeDirection.bottom) {
5439
4864
  return {
@@ -5466,8 +4891,8 @@
5466
4891
  position.x <= canvasSize.width + radius,
5467
4892
  reason: "default",
5468
4893
  };
5469
- };
5470
- #getInsideCanvasCallbackData = (direction, outMode) => {
4894
+ }
4895
+ #getInsideCanvasCallbackData(direction, outMode) {
5471
4896
  return {
5472
4897
  canvasSize: this.#container.canvas.size,
5473
4898
  direction,
@@ -5475,8 +4900,8 @@
5475
4900
  particle: this,
5476
4901
  radius: this.getRadius(),
5477
4902
  };
5478
- };
5479
- #getInsideCanvasResult = (data) => {
4903
+ }
4904
+ #getInsideCanvasResult(data) {
5480
4905
  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
4906
  if (!shapeCheck && !effectCheck) {
5482
4907
  return defaultResult;
@@ -5491,8 +4916,8 @@
5491
4916
  };
5492
4917
  }
5493
4918
  return shapeResult ?? effectResult ?? defaultResult;
5494
- };
5495
- #getRollColor = color => {
4919
+ }
4920
+ #getRollColor(color) {
5496
4921
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
5497
4922
  return color;
5498
4923
  }
@@ -5506,8 +4931,8 @@
5506
4931
  return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
5507
4932
  }
5508
4933
  return color;
5509
- };
5510
- #initPosition = position => {
4934
+ }
4935
+ #initPosition(position) {
5511
4936
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5512
4937
  if (!initialPosition) {
5513
4938
  throw new Error("a valid position cannot be found for particle");
@@ -5530,8 +4955,8 @@
5530
4955
  break;
5531
4956
  }
5532
4957
  this.offset = Vector.origin;
5533
- };
5534
- #normalizeInsideCanvasResult = (result, reason) => {
4958
+ }
4959
+ #normalizeInsideCanvasResult(result, reason) {
5535
4960
  if (typeof result === "boolean") {
5536
4961
  return {
5537
4962
  inside: result,
@@ -5543,7 +4968,7 @@
5543
4968
  margin: result.margin,
5544
4969
  reason: result.reason ?? reason,
5545
4970
  };
5546
- };
4971
+ }
5547
4972
  }
5548
4973
 
5549
4974
  class SpatialHashGrid {
@@ -5896,10 +5321,10 @@
5896
5321
  }
5897
5322
  this.#resizeFactor = undefined;
5898
5323
  }
5899
- #addToPool = (...particles) => {
5324
+ #addToPool(...particles) {
5900
5325
  this.#pool.push(...particles);
5901
- };
5902
- #applyDensity = (options, pluginsCount, group, groupOptions) => {
5326
+ }
5327
+ #applyDensity(options, pluginsCount, group, groupOptions) {
5903
5328
  const numberOptions = options.number;
5904
5329
  if (!numberOptions.density.enable) {
5905
5330
  if (group === undefined) {
@@ -5923,36 +5348,19 @@
5923
5348
  else if (particlesCount > particlesNumber) {
5924
5349
  this.removeQuantity(particlesCount - particlesNumber, group);
5925
5350
  }
5926
- };
5927
- #createBuckets = (zLayers) => {
5351
+ }
5352
+ #createBuckets(zLayers) {
5928
5353
  const bucketCount = Math.max(Math.floor(zLayers), one);
5929
5354
  return Array.from({ length: bucketCount }, () => []);
5930
- };
5931
- #getBucketIndex = (zIndex) => {
5355
+ }
5356
+ #getBucketIndex(zIndex) {
5932
5357
  const maxBucketIndex = this.#zBuckets.length - one;
5933
5358
  if (maxBucketIndex <= minIndex) {
5934
5359
  return minIndex;
5935
5360
  }
5936
5361
  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 => {
5362
+ }
5363
+ #initDensityFactor(densityOptions) {
5956
5364
  const container = this.#container;
5957
5365
  if (!densityOptions.enable) {
5958
5366
  return defaultDensityFactor;
@@ -5962,16 +5370,16 @@
5962
5370
  return defaultDensityFactor;
5963
5371
  }
5964
5372
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5965
- };
5966
- #insertParticleIntoBucket = (particle) => {
5373
+ }
5374
+ #insertParticleIntoBucket(particle) {
5967
5375
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
5968
5376
  if (!bucket) {
5969
5377
  return;
5970
5378
  }
5971
- bucket.splice(this.#getParticleInsertIndex(bucket, particle.id), empty, particle);
5379
+ bucket.push(particle);
5972
5380
  this.#particleBuckets.set(particle.id, bucketIndex);
5973
- };
5974
- #removeParticle = (index, group, override) => {
5381
+ }
5382
+ #removeParticle(index, group, override) {
5975
5383
  const particle = this.#array[index];
5976
5384
  if (!particle) {
5977
5385
  return false;
@@ -5987,22 +5395,20 @@
5987
5395
  });
5988
5396
  this.#addToPool(particle);
5989
5397
  return true;
5990
- };
5991
- #removeParticleFromBucket = (particle) => {
5398
+ }
5399
+ #removeParticleFromBucket(particle) {
5992
5400
  const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
5993
5401
  if (!bucket) {
5994
5402
  this.#particleBuckets.delete(particle.id);
5995
5403
  return;
5996
5404
  }
5997
- const particleIndex = this.#getParticleInsertIndex(bucket, particle.id);
5998
- if (bucket[particleIndex]?.id !== particle.id) {
5999
- this.#particleBuckets.delete(particle.id);
6000
- return;
5405
+ const idx = bucket.findIndex(p => p.id === particle.id);
5406
+ if (idx >= minIndex) {
5407
+ bucket.splice(idx, deleteCount);
6001
5408
  }
6002
- bucket.splice(particleIndex, deleteCount);
6003
5409
  this.#particleBuckets.delete(particle.id);
6004
- };
6005
- #resetBuckets = (zLayers) => {
5410
+ }
5411
+ #resetBuckets(zLayers) {
6006
5412
  const bucketCount = Math.max(Math.floor(zLayers), one);
6007
5413
  if (this.#zBuckets.length !== bucketCount) {
6008
5414
  this.#zBuckets = this.#createBuckets(bucketCount);
@@ -6011,8 +5417,8 @@
6011
5417
  for (const bucket of this.#zBuckets) {
6012
5418
  bucket.length = minIndex;
6013
5419
  }
6014
- };
6015
- #updateParticleBucket = (particle) => {
5420
+ }
5421
+ #updateParticleBucket(particle) {
6016
5422
  const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
6017
5423
  if (currentBucketIndex === undefined) {
6018
5424
  this.#insertParticleIntoBucket(particle);
@@ -6023,9 +5429,9 @@
6023
5429
  }
6024
5430
  const currentBucket = this.#zBuckets[currentBucketIndex];
6025
5431
  if (currentBucket) {
6026
- const particleIndex = this.#getParticleInsertIndex(currentBucket, particle.id);
6027
- if (currentBucket[particleIndex]?.id === particle.id) {
6028
- currentBucket.splice(particleIndex, deleteCount);
5432
+ const idx = currentBucket.findIndex(p => p.id === particle.id);
5433
+ if (idx >= minIndex) {
5434
+ currentBucket.splice(idx, deleteCount);
6029
5435
  }
6030
5436
  }
6031
5437
  const newBucket = this.#zBuckets[newBucketIndex];
@@ -6033,10 +5439,16 @@
6033
5439
  this.#particleBuckets.set(particle.id, newBucketIndex);
6034
5440
  return;
6035
5441
  }
6036
- newBucket.splice(this.#getParticleInsertIndex(newBucket, particle.id), empty, particle);
5442
+ newBucket.push(particle);
5443
+ if (newBucket.length >= double) {
5444
+ const prev = newBucket[newBucket.length - double];
5445
+ if (prev && particle.id < prev.id) {
5446
+ newBucket.sort((a, b) => a.id - b.id);
5447
+ }
5448
+ }
6037
5449
  this.#particleBuckets.set(particle.id, newBucketIndex);
6038
- };
6039
- #updateParticlesPhase1 = (delta) => {
5450
+ }
5451
+ #updateParticlesPhase1(delta) {
6040
5452
  const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
6041
5453
  for (const particle of this.#array) {
6042
5454
  if (resizeFactor && !particle.ignoresResizeRatio) {
@@ -6062,8 +5474,8 @@
6062
5474
  this.grid.insert(particle);
6063
5475
  }
6064
5476
  return particlesToDelete;
6065
- };
6066
- #updateParticlesPhase2 = (delta, particlesToDelete) => {
5477
+ }
5478
+ #updateParticlesPhase2(delta, particlesToDelete) {
6067
5479
  for (const particle of this.#array) {
6068
5480
  if (particle.destroyed) {
6069
5481
  particlesToDelete.add(particle);
@@ -6079,7 +5491,7 @@
6079
5491
  }
6080
5492
  this.#updateParticleBucket(particle);
6081
5493
  }
6082
- };
5494
+ }
6083
5495
  }
6084
5496
 
6085
5497
  class Retina {
@@ -6441,7 +5853,7 @@
6441
5853
  }
6442
5854
  return refresh;
6443
5855
  }
6444
- #nextFrame = (timestamp) => {
5856
+ #nextFrame(timestamp) {
6445
5857
  try {
6446
5858
  if (!this.#smooth &&
6447
5859
  this.#lastFrameTime !== undefined &&
@@ -6469,7 +5881,7 @@
6469
5881
  catch (e) {
6470
5882
  getLogger().error("error in animation loop", e);
6471
5883
  }
6472
- };
5884
+ }
6473
5885
  }
6474
5886
 
6475
5887
  var Container$1 = /*#__PURE__*/Object.freeze({
@@ -6515,7 +5927,7 @@
6515
5927
  BlendPluginInstance: BlendPluginInstance
6516
5928
  });
6517
5929
 
6518
- const minVelocity = 0, identity = 1, moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
5930
+ const moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
6519
5931
  function applyDistance(particle) {
6520
5932
  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
5933
  if (!hDistance && !vDistance) {
@@ -6790,7 +6202,7 @@
6790
6202
  removeListeners() {
6791
6203
  this.#manageListeners(false);
6792
6204
  }
6793
- #doMouseTouchClick = e => {
6205
+ #doMouseTouchClick(e) {
6794
6206
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions;
6795
6207
  if (this.#canPush) {
6796
6208
  const mouseInteractivity = interactionManager.interactivityData.mouse, mousePos = mouseInteractivity.position;
@@ -6812,11 +6224,11 @@
6812
6224
  this.#mouseTouchFinish();
6813
6225
  }, touchDelay);
6814
6226
  }
6815
- };
6816
- #handleVisibilityChange = () => {
6227
+ }
6228
+ #handleVisibilityChange() {
6817
6229
  this.#mouseTouchFinish();
6818
- };
6819
- #manageInteractivityListeners = add => {
6230
+ }
6231
+ #manageInteractivityListeners(add) {
6820
6232
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivityEl = interactionManager.interactivityData.element;
6821
6233
  if (!interactivityEl) {
6822
6234
  return;
@@ -6847,8 +6259,8 @@
6847
6259
  }
6848
6260
  manageListener(interactivityEl, mouseLeaveEvent, handlers.mouseLeave, add);
6849
6261
  manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
6850
- };
6851
- #manageListeners = add => {
6262
+ }
6263
+ #manageListeners(add) {
6852
6264
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.domElement;
6853
6265
  if (detectType === InteractivityDetect.window) {
6854
6266
  interactionManager.interactivityData.element = safeDocument();
@@ -6861,13 +6273,13 @@
6861
6273
  }
6862
6274
  this.#manageInteractivityListeners(add);
6863
6275
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
6864
- };
6865
- #mouseDown = () => {
6276
+ }
6277
+ #mouseDown() {
6866
6278
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
6867
6279
  mouse.clicking = true;
6868
6280
  mouse.downPosition = mouse.position;
6869
- };
6870
- #mouseTouchClick = e => {
6281
+ }
6282
+ #mouseTouchClick(e) {
6871
6283
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, { mouse } = interactionManager.interactivityData;
6872
6284
  mouse.inside = true;
6873
6285
  let handled = false;
@@ -6885,8 +6297,8 @@
6885
6297
  this.#doMouseTouchClick(e);
6886
6298
  }
6887
6299
  mouse.clicking = false;
6888
- };
6889
- #mouseTouchFinish = () => {
6300
+ }
6301
+ #mouseTouchFinish() {
6890
6302
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
6891
6303
  delete mouse.position;
6892
6304
  delete mouse.clickPosition;
@@ -6894,8 +6306,8 @@
6894
6306
  interactivityData.status = mouseLeaveEvent;
6895
6307
  mouse.inside = false;
6896
6308
  mouse.clicking = false;
6897
- };
6898
- #mouseTouchMove = e => {
6309
+ }
6310
+ #mouseTouchMove(e) {
6899
6311
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.domElement;
6900
6312
  if (!interactivity.element) {
6901
6313
  return;
@@ -6957,31 +6369,37 @@
6957
6369
  }
6958
6370
  interactivity.mouse.position = pos;
6959
6371
  interactivity.status = mouseMoveEvent;
6960
- };
6961
- #touchEnd = e => {
6372
+ }
6373
+ #touchEnd(e) {
6962
6374
  const evt = e, touches = Array.from(evt.changedTouches);
6963
6375
  for (const touch of touches) {
6964
6376
  this.#touches.delete(touch.identifier);
6965
6377
  }
6966
6378
  this.#mouseTouchFinish();
6967
- };
6968
- #touchEndClick = e => {
6379
+ }
6380
+ #touchEndClick(e) {
6969
6381
  const evt = e, touches = Array.from(evt.changedTouches);
6970
6382
  for (const touch of touches) {
6971
6383
  this.#touches.delete(touch.identifier);
6972
6384
  }
6973
6385
  this.#mouseTouchClick(e);
6974
- };
6975
- #touchStart = e => {
6386
+ }
6387
+ #touchStart(e) {
6976
6388
  const evt = e, touches = Array.from(evt.changedTouches);
6977
6389
  for (const touch of touches) {
6978
6390
  this.#touches.set(touch.identifier, performance.now());
6979
6391
  }
6980
6392
  this.#mouseTouchMove(e);
6981
- };
6393
+ }
6982
6394
  }
6983
6395
 
6984
6396
  const clickRadius = 1, touchEndLengthOffset = 1, minCoordinate = 0;
6397
+ function safeIntersectionObserver(callback) {
6398
+ if (typeof IntersectionObserver === "undefined") {
6399
+ return;
6400
+ }
6401
+ return new IntersectionObserver(callback);
6402
+ }
6985
6403
  class InteractionManager {
6986
6404
  interactivityData;
6987
6405
  #clickHandlers;
@@ -7184,7 +6602,7 @@
7184
6602
  const container = this.#container;
7185
6603
  container.particles.grid.setCellSize(maxTotalDistance * container.retina.pixelRatio);
7186
6604
  }
7187
- #intersectionManager = entries => {
6605
+ #intersectionManager(entries) {
7188
6606
  const container = this.#container;
7189
6607
  if (container.destroyed || !container.actualOptions.pauseOnOutsideViewport) {
7190
6608
  return;
@@ -7200,7 +6618,7 @@
7200
6618
  container.pause();
7201
6619
  }
7202
6620
  }
7203
- };
6621
+ }
7204
6622
  }
7205
6623
 
7206
6624
  class InteractivityPluginInstance {