@tsparticles/preset-confetti-cannon 4.1.2 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  (function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
- /* Preset v4.1.2 */
2
+ /* Preset v4.2.0 */
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
5
5
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -15,7 +15,7 @@
15
15
  b: 0,
16
16
  c: 0,
17
17
  d: 1,
18
- }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter$1 = 0.25, threeQuarter = half + quarter$1, 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$3 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
18
+ }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter$1 = 0.25, threeQuarter = half + quarter$1, minVelocity = 0, minDistance$1 = 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$2 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, maxNits = 400, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
19
19
 
20
20
  var MoveDirection;
21
21
  (function (MoveDirection) {
@@ -82,11 +82,6 @@
82
82
  div(n) {
83
83
  return Vector3d.create(this.x / n, this.y / n, this.z / n);
84
84
  }
85
- divTo(n) {
86
- this.x /= n;
87
- this.y /= n;
88
- this.z /= n;
89
- }
90
85
  getLengthSq() {
91
86
  return this.x ** squareExp + this.y ** squareExp;
92
87
  }
@@ -282,27 +277,6 @@
282
277
  return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
283
278
  }
284
279
 
285
- var AnimationMode;
286
- (function (AnimationMode) {
287
- AnimationMode["auto"] = "auto";
288
- AnimationMode["increase"] = "increase";
289
- AnimationMode["decrease"] = "decrease";
290
- AnimationMode["random"] = "random";
291
- })(AnimationMode || (AnimationMode = {}));
292
-
293
- var AnimationStatus;
294
- (function (AnimationStatus) {
295
- AnimationStatus["increasing"] = "increasing";
296
- AnimationStatus["decreasing"] = "decreasing";
297
- })(AnimationStatus || (AnimationStatus = {}));
298
-
299
- var DestroyType;
300
- (function (DestroyType) {
301
- DestroyType["none"] = "none";
302
- DestroyType["max"] = "max";
303
- DestroyType["min"] = "min";
304
- })(DestroyType || (DestroyType = {}));
305
-
306
280
  var OutModeDirection;
307
281
  (function (OutModeDirection) {
308
282
  OutModeDirection["bottom"] = "bottom";
@@ -317,67 +291,7 @@
317
291
  PixelMode["percent"] = "percent";
318
292
  })(PixelMode || (PixelMode = {}));
319
293
 
320
- var StartValueType;
321
- (function (StartValueType) {
322
- StartValueType["max"] = "max";
323
- StartValueType["min"] = "min";
324
- StartValueType["random"] = "random";
325
- })(StartValueType || (StartValueType = {}));
326
-
327
294
  const minRadius = 0;
328
- function memoize(fn, options) {
329
- const cache = new Map(), stableStringify = (obj, seen = new WeakSet()) => {
330
- if (obj === null) {
331
- return "null";
332
- }
333
- const t = typeof obj;
334
- if (t === "undefined") {
335
- return "undefined";
336
- }
337
- if (t === "number" || t === "boolean" || t === "string") {
338
- return JSON.stringify(obj);
339
- }
340
- if (t === "function") {
341
- try {
342
- const fn = obj;
343
- return fn.toString();
344
- }
345
- catch {
346
- return '"[Function]"';
347
- }
348
- }
349
- if (t === "symbol") {
350
- try {
351
- return obj.toString();
352
- }
353
- catch {
354
- return '"[Symbol]"';
355
- }
356
- }
357
- if (Array.isArray(obj)) {
358
- return `[${obj.map(i => stableStringify(i, seen)).join(",")}]`;
359
- }
360
- if (seen.has(obj)) {
361
- return '"[Circular]"';
362
- }
363
- seen.add(obj);
364
- const keys = Object.keys(obj).sort();
365
- return `{${keys.map(k => `${JSON.stringify(k)}:${stableStringify(obj[k], seen)}`).join(",")}}`;
366
- }, defaultKeyer = (args) => stableStringify(args), makeKey = (args) => (defaultKeyer(args));
367
- return (...args) => {
368
- const key = makeKey(args), now = Date.now(), entry = cache.get(key);
369
- if (entry !== undefined) {
370
- {
371
- cache.delete(key);
372
- cache.set(key, { value: entry.value, ts: entry.ts });
373
- return entry.value;
374
- }
375
- }
376
- const result = fn(...args);
377
- cache.set(key, { value: result, ts: now });
378
- return result;
379
- };
380
- }
381
295
  function hasMatchMedia() {
382
296
  return typeof matchMedia !== "undefined";
383
297
  }
@@ -390,12 +304,6 @@
390
304
  }
391
305
  return matchMedia(query);
392
306
  }
393
- function safeIntersectionObserver(callback) {
394
- if (typeof IntersectionObserver === "undefined") {
395
- return;
396
- }
397
- return new IntersectionObserver(callback);
398
- }
399
307
  function safeMutationObserver(callback) {
400
308
  if (typeof MutationObserver === "undefined") {
401
309
  return;
@@ -405,11 +313,8 @@
405
313
  function isInArray(value, array) {
406
314
  return value === array || (isArray(array) && array.includes(value));
407
315
  }
408
- function arrayRandomIndex(array) {
409
- return Math.floor(getRandom() * array.length);
410
- }
411
316
  function itemFromArray(array, index, useIndex = true) {
412
- return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
317
+ return array[index !== undefined && useIndex ? index % array.length : Math.floor(getRandom() * array.length)];
413
318
  }
414
319
  function isPointInside(point, size, offset, radius, direction) {
415
320
  return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
@@ -493,56 +398,6 @@
493
398
  function itemFromSingleOrMultiple(obj, index, useIndex) {
494
399
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
495
400
  }
496
- function initParticleNumericAnimationValue(options, pxRatio) {
497
- const valueRange = options.value, animationOptions = options.animation, res = {
498
- delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
499
- enable: animationOptions.enable,
500
- value: getRangeValue(options.value) * pxRatio,
501
- max: getRangeMax(valueRange) * pxRatio,
502
- min: getRangeMin(valueRange) * pxRatio,
503
- loops: 0,
504
- maxLoops: getRangeValue(animationOptions.count),
505
- time: 0,
506
- }, decayOffset = 1;
507
- if (animationOptions.enable) {
508
- res.decay = decayOffset - getRangeValue(animationOptions.decay);
509
- switch (animationOptions.mode) {
510
- case AnimationMode.increase:
511
- res.status = AnimationStatus.increasing;
512
- break;
513
- case AnimationMode.decrease:
514
- res.status = AnimationStatus.decreasing;
515
- break;
516
- case AnimationMode.random:
517
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
518
- break;
519
- }
520
- const autoStatus = animationOptions.mode === AnimationMode.auto;
521
- switch (animationOptions.startValue) {
522
- case StartValueType.min:
523
- res.value = res.min;
524
- if (autoStatus) {
525
- res.status = AnimationStatus.increasing;
526
- }
527
- break;
528
- case StartValueType.max:
529
- res.value = res.max;
530
- if (autoStatus) {
531
- res.status = AnimationStatus.decreasing;
532
- }
533
- break;
534
- case StartValueType.random:
535
- default:
536
- res.value = randomInRangeValue(res);
537
- if (autoStatus) {
538
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
539
- }
540
- break;
541
- }
542
- }
543
- res.initialValue = res.value;
544
- return res;
545
- }
546
401
  function getPositionOrSize(positionOrSize, canvasSize) {
547
402
  const isPercent = positionOrSize.mode === PixelMode.percent;
548
403
  if (!isPercent) {
@@ -566,77 +421,6 @@
566
421
  function getPosition(position, canvasSize) {
567
422
  return getPositionOrSize(position, canvasSize);
568
423
  }
569
- function checkDestroy(particle, destroyType, value, minValue, maxValue) {
570
- switch (destroyType) {
571
- case DestroyType.max:
572
- if (value >= maxValue) {
573
- particle.destroy();
574
- }
575
- break;
576
- case DestroyType.min:
577
- if (value <= minValue) {
578
- particle.destroy();
579
- }
580
- break;
581
- }
582
- }
583
- function updateAnimation(particle, data, changeDirection, destroyType, delta) {
584
- const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
585
- if (particle.destroyed ||
586
- !data.enable ||
587
- ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
588
- return;
589
- }
590
- const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
591
- data.time ??= 0;
592
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
593
- data.time += delta.value;
594
- }
595
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
596
- return;
597
- }
598
- switch (data.status) {
599
- case AnimationStatus.increasing:
600
- data.value += velocity;
601
- break;
602
- case AnimationStatus.decreasing:
603
- data.value -= velocity;
604
- break;
605
- }
606
- if (data.velocity && decay !== identity) {
607
- data.velocity *= decay;
608
- }
609
- switch (data.status) {
610
- case AnimationStatus.increasing:
611
- if (data.value >= maxValue) {
612
- if (changeDirection) {
613
- data.status = AnimationStatus.decreasing;
614
- }
615
- else {
616
- data.value -= maxValue;
617
- }
618
- data.loops ??= minLoops;
619
- data.loops++;
620
- }
621
- break;
622
- case AnimationStatus.decreasing:
623
- if (data.value <= minValue) {
624
- if (changeDirection) {
625
- data.status = AnimationStatus.increasing;
626
- }
627
- else {
628
- data.value += maxValue;
629
- }
630
- data.loops ??= minLoops;
631
- data.loops++;
632
- }
633
- break;
634
- }
635
- checkDestroy(particle, destroyType, data.value, minValue, maxValue);
636
- if (!particle.destroyed) {
637
- data.value = clamp(data.value, minValue, maxValue);
638
- }
639
- }
640
424
  function cloneStyle(style) {
641
425
  const clonedStyle = safeDocument().createElement("div").style;
642
426
  for (const key in style) {
@@ -658,30 +442,34 @@
658
442
  }
659
443
  return clonedStyle;
660
444
  }
661
- function computeFullScreenStyle(zIndex) {
662
- const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
663
- width: "100%",
664
- height: "100%",
665
- margin: "0",
666
- padding: "0",
667
- borderWidth: "0",
668
- position: "fixed",
669
- zIndex: zIndex.toString(radix),
670
- "z-index": zIndex.toString(radix),
671
- top: "0",
672
- left: "0",
673
- "pointer-events": "none",
674
- };
675
- for (const key in style) {
676
- const value = style[key];
677
- if (value === undefined) {
678
- continue;
445
+ let _cachedZIndex, _cachedStyle;
446
+ function getFullScreenStyle(zIndex) {
447
+ if (_cachedZIndex !== zIndex || !_cachedStyle) {
448
+ _cachedZIndex = zIndex;
449
+ const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
450
+ width: "100%",
451
+ height: "100%",
452
+ margin: "0",
453
+ padding: "0",
454
+ borderWidth: "0",
455
+ position: "fixed",
456
+ zIndex: zIndex.toString(radix),
457
+ "z-index": zIndex.toString(radix),
458
+ top: "0",
459
+ left: "0",
460
+ "pointer-events": "none",
461
+ };
462
+ for (const key in style) {
463
+ const value = style[key];
464
+ if (value === undefined) {
465
+ continue;
466
+ }
467
+ fullScreenStyle.setProperty(key, value);
679
468
  }
680
- fullScreenStyle.setProperty(key, value);
469
+ _cachedStyle = fullScreenStyle;
681
470
  }
682
- return fullScreenStyle;
471
+ return _cachedStyle;
683
472
  }
684
- const getFullScreenStyle = memoize(computeFullScreenStyle);
685
473
  function manageListener(element, event, handler, add, options) {
686
474
  if (add) {
687
475
  let addOptions = { passive: true };
@@ -1008,7 +796,7 @@
1008
796
  return this.#domArray;
1009
797
  }
1010
798
  get version() {
1011
- return "4.1.2";
799
+ return "4.2.0";
1012
800
  }
1013
801
  addEventListener(type, listener) {
1014
802
  this.#eventDispatcher.addEventListener(type, listener);
@@ -1178,6 +966,14 @@
1178
966
  RotateDirection["random"] = "random";
1179
967
  })(RotateDirection || (RotateDirection = {}));
1180
968
 
969
+ var AnimationMode;
970
+ (function (AnimationMode) {
971
+ AnimationMode["auto"] = "auto";
972
+ AnimationMode["increase"] = "increase";
973
+ AnimationMode["decrease"] = "decrease";
974
+ AnimationMode["random"] = "random";
975
+ })(AnimationMode || (AnimationMode = {}));
976
+
1181
977
  var LimitMode;
1182
978
  (function (LimitMode) {
1183
979
  LimitMode["delete"] = "delete";
@@ -1199,6 +995,13 @@
1199
995
  AlterType["enlighten"] = "enlighten";
1200
996
  })(AlterType || (AlterType = {}));
1201
997
 
998
+ var DestroyType;
999
+ (function (DestroyType) {
1000
+ DestroyType["none"] = "none";
1001
+ DestroyType["max"] = "max";
1002
+ DestroyType["min"] = "min";
1003
+ })(DestroyType || (DestroyType = {}));
1004
+
1202
1005
  var GradientType;
1203
1006
  (function (GradientType) {
1204
1007
  GradientType["linear"] = "linear";
@@ -1213,160 +1016,121 @@
1213
1016
  ParticleOutType["outside"] = "outside";
1214
1017
  })(ParticleOutType || (ParticleOutType = {}));
1215
1018
 
1216
- var EasingType;
1217
- (function (EasingType) {
1218
- EasingType["easeInBack"] = "ease-in-back";
1219
- EasingType["easeInBounce"] = "ease-in-bounce";
1220
- EasingType["easeInCirc"] = "ease-in-circ";
1221
- EasingType["easeInCubic"] = "ease-in-cubic";
1222
- EasingType["easeInElastic"] = "ease-in-elastic";
1223
- EasingType["easeInExpo"] = "ease-in-expo";
1224
- EasingType["easeInGaussian"] = "ease-in-gaussian";
1225
- EasingType["easeInLinear"] = "ease-in-linear";
1226
- EasingType["easeInQuad"] = "ease-in-quad";
1227
- EasingType["easeInQuart"] = "ease-in-quart";
1228
- EasingType["easeInQuint"] = "ease-in-quint";
1229
- EasingType["easeInSigmoid"] = "ease-in-sigmoid";
1230
- EasingType["easeInSine"] = "ease-in-sine";
1231
- EasingType["easeInSmoothstep"] = "ease-in-smoothstep";
1232
- EasingType["easeOutBack"] = "ease-out-back";
1233
- EasingType["easeOutBounce"] = "ease-out-bounce";
1234
- EasingType["easeOutCirc"] = "ease-out-circ";
1235
- EasingType["easeOutCubic"] = "ease-out-cubic";
1236
- EasingType["easeOutElastic"] = "ease-out-elastic";
1237
- EasingType["easeOutExpo"] = "ease-out-expo";
1238
- EasingType["easeOutGaussian"] = "ease-out-gaussian";
1239
- EasingType["easeOutLinear"] = "ease-out-linear";
1240
- EasingType["easeOutQuad"] = "ease-out-quad";
1241
- EasingType["easeOutQuart"] = "ease-out-quart";
1242
- EasingType["easeOutQuint"] = "ease-out-quint";
1243
- EasingType["easeOutSigmoid"] = "ease-out-sigmoid";
1244
- EasingType["easeOutSine"] = "ease-out-sine";
1245
- EasingType["easeOutSmoothstep"] = "ease-out-smoothstep";
1246
- EasingType["easeInOutBack"] = "ease-in-out-back";
1247
- EasingType["easeInOutBounce"] = "ease-in-out-bounce";
1248
- EasingType["easeInOutCirc"] = "ease-in-out-circ";
1249
- EasingType["easeInOutCubic"] = "ease-in-out-cubic";
1250
- EasingType["easeInOutElastic"] = "ease-in-out-elastic";
1251
- EasingType["easeInOutExpo"] = "ease-in-out-expo";
1252
- EasingType["easeInOutGaussian"] = "ease-in-out-gaussian";
1253
- EasingType["easeInOutLinear"] = "ease-in-out-linear";
1254
- EasingType["easeInOutQuad"] = "ease-in-out-quad";
1255
- EasingType["easeInOutQuart"] = "ease-in-out-quart";
1256
- EasingType["easeInOutQuint"] = "ease-in-out-quint";
1257
- EasingType["easeInOutSigmoid"] = "ease-in-out-sigmoid";
1258
- EasingType["easeInOutSine"] = "ease-in-out-sine";
1259
- EasingType["easeInOutSmoothstep"] = "ease-in-out-smoothstep";
1260
- })(EasingType || (EasingType = {}));
1261
-
1262
- class AnimationOptions {
1263
- count;
1264
- decay;
1265
- delay;
1266
- enable;
1267
- speed;
1268
- sync;
1269
- constructor() {
1270
- this.count = 0;
1271
- this.enable = false;
1272
- this.speed = 1;
1273
- this.decay = 0;
1274
- this.delay = 0;
1275
- this.sync = false;
1276
- }
1019
+ var StartValueType;
1020
+ (function (StartValueType) {
1021
+ StartValueType["max"] = "max";
1022
+ StartValueType["min"] = "min";
1023
+ StartValueType["random"] = "random";
1024
+ })(StartValueType || (StartValueType = {}));
1025
+
1026
+ var AnimationStatus;
1027
+ (function (AnimationStatus) {
1028
+ AnimationStatus["increasing"] = "increasing";
1029
+ AnimationStatus["decreasing"] = "decreasing";
1030
+ })(AnimationStatus || (AnimationStatus = {}));
1031
+
1032
+ class OptionLoader {
1277
1033
  load(data) {
1278
1034
  if (isNull(data)) {
1279
1035
  return;
1280
1036
  }
1281
- if (data.count !== undefined) {
1282
- this.count = setRangeValue(data.count);
1283
- }
1284
- if (data.enable !== undefined) {
1285
- this.enable = data.enable;
1286
- }
1287
- if (data.speed !== undefined) {
1288
- this.speed = setRangeValue(data.speed);
1289
- }
1290
- if (data.decay !== undefined) {
1291
- this.decay = setRangeValue(data.decay);
1292
- }
1293
- if (data.delay !== undefined) {
1294
- this.delay = setRangeValue(data.delay);
1295
- }
1296
- if (data.sync !== undefined) {
1297
- this.sync = data.sync;
1298
- }
1037
+ this.doLoad(data);
1299
1038
  }
1300
1039
  }
1301
- class RangedAnimationOptions extends AnimationOptions {
1302
- mode;
1303
- startValue;
1304
- constructor() {
1305
- super();
1306
- this.mode = AnimationMode.auto;
1307
- this.startValue = StartValueType.random;
1040
+ function loadOptions(options, ...sourceOptionsArr) {
1041
+ for (const sourceOptions of sourceOptionsArr) {
1042
+ options.load(sourceOptions);
1308
1043
  }
1309
- load(data) {
1310
- super.load(data);
1311
- if (isNull(data)) {
1312
- return;
1313
- }
1314
- if (data.mode !== undefined) {
1315
- this.mode = data.mode;
1316
- }
1317
- if (data.startValue !== undefined) {
1318
- this.startValue = data.startValue;
1319
- }
1044
+ }
1045
+
1046
+ function loadProperty(obj, key, value) {
1047
+ if (value !== undefined) {
1048
+ obj[key] = value;
1049
+ }
1050
+ }
1051
+ function loadRangeProperty(obj, key, value) {
1052
+ if (value !== undefined) {
1053
+ obj[key] = setRangeValue(value);
1054
+ }
1055
+ }
1056
+ function loadNestedProperty(obj, key, value) {
1057
+ if (value !== undefined) {
1058
+ obj[key].load(value);
1059
+ }
1060
+ }
1061
+ function loadLazyProperty(obj, key, value, factory) {
1062
+ if (value !== undefined) {
1063
+ const objRecord = obj;
1064
+ objRecord[key] ??= factory();
1065
+ objRecord[key].load(value);
1066
+ }
1067
+ }
1068
+ function loadOptionProperty(obj, key, optionClass, ...sources) {
1069
+ const objRecord = obj;
1070
+ objRecord[key] ??= new optionClass();
1071
+ const target = objRecord[key];
1072
+ for (const source of sources) {
1073
+ target.load(source?.[key]);
1074
+ }
1075
+ }
1076
+
1077
+ class AnimationOptions extends OptionLoader {
1078
+ count = 0;
1079
+ decay = 0;
1080
+ delay = 0;
1081
+ enable = false;
1082
+ speed = 1;
1083
+ sync = false;
1084
+ doLoad(data) {
1085
+ loadRangeProperty(this, "count", data.count);
1086
+ loadProperty(this, "enable", data.enable);
1087
+ loadRangeProperty(this, "speed", data.speed);
1088
+ loadRangeProperty(this, "decay", data.decay);
1089
+ loadRangeProperty(this, "delay", data.delay);
1090
+ loadProperty(this, "sync", data.sync);
1091
+ }
1092
+ }
1093
+ class RangedAnimationOptions extends AnimationOptions {
1094
+ mode = AnimationMode.auto;
1095
+ startValue = StartValueType.random;
1096
+ doLoad(data) {
1097
+ super.doLoad(data);
1098
+ loadProperty(this, "mode", data.mode);
1099
+ loadProperty(this, "startValue", data.startValue);
1320
1100
  }
1321
1101
  }
1322
1102
 
1323
1103
  class ColorAnimation extends AnimationOptions {
1324
1104
  max;
1325
1105
  min;
1326
- offset;
1106
+ offset = 0;
1107
+ sync = true;
1327
1108
  constructor(min, max) {
1328
1109
  super();
1329
1110
  this.min = min;
1330
1111
  this.max = max;
1331
- this.offset = 0;
1332
- this.sync = true;
1333
1112
  }
1334
- load(data) {
1335
- super.load(data);
1336
- if (isNull(data)) {
1337
- return;
1338
- }
1339
- if (data.max !== undefined) {
1340
- this.max = data.max;
1341
- }
1342
- if (data.min !== undefined) {
1343
- this.min = data.min;
1344
- }
1345
- if (data.offset !== undefined) {
1346
- this.offset = setRangeValue(data.offset);
1347
- }
1113
+ doLoad(data) {
1114
+ super.doLoad(data);
1115
+ loadProperty(this, "max", data.max);
1116
+ loadProperty(this, "min", data.min);
1117
+ loadRangeProperty(this, "offset", data.offset);
1348
1118
  }
1349
1119
  }
1350
1120
 
1351
- class HslAnimation {
1121
+ class HslAnimation extends OptionLoader {
1352
1122
  h = new ColorAnimation(hMin, hMax);
1353
1123
  l = new ColorAnimation(lMin, lMax);
1354
1124
  s = new ColorAnimation(sMin, sMax);
1355
- load(data) {
1356
- if (isNull(data)) {
1357
- return;
1358
- }
1125
+ doLoad(data) {
1359
1126
  this.h.load(data.h);
1360
1127
  this.s.load(data.s);
1361
1128
  this.l.load(data.l);
1362
1129
  }
1363
1130
  }
1364
1131
 
1365
- class OptionsColor {
1366
- value;
1367
- constructor() {
1368
- this.value = "";
1369
- }
1132
+ class OptionsColor extends OptionLoader {
1133
+ value = "";
1370
1134
  static create(source, data) {
1371
1135
  const color = new OptionsColor();
1372
1136
  color.load(source);
@@ -1380,10 +1144,7 @@
1380
1144
  }
1381
1145
  return color;
1382
1146
  }
1383
- load(data) {
1384
- if (isNull(data)) {
1385
- return;
1386
- }
1147
+ doLoad(data) {
1387
1148
  if (!isNull(data.value)) {
1388
1149
  this.value = data.value;
1389
1150
  }
@@ -1391,11 +1152,7 @@
1391
1152
  }
1392
1153
 
1393
1154
  class AnimatableColor extends OptionsColor {
1394
- animation;
1395
- constructor() {
1396
- super();
1397
- this.animation = new HslAnimation();
1398
- }
1155
+ animation = new HslAnimation();
1399
1156
  static create(source, data) {
1400
1157
  const color = new AnimatableColor();
1401
1158
  color.load(source);
@@ -1409,11 +1166,8 @@
1409
1166
  }
1410
1167
  return color;
1411
1168
  }
1412
- load(data) {
1413
- super.load(data);
1414
- if (isNull(data)) {
1415
- return;
1416
- }
1169
+ doLoad(data) {
1170
+ super.doLoad(data);
1417
1171
  const colorAnimation = data.animation;
1418
1172
  if (colorAnimation !== undefined) {
1419
1173
  if (colorAnimation.enable === undefined) {
@@ -1426,100 +1180,53 @@
1426
1180
  }
1427
1181
  }
1428
1182
 
1429
- class Background {
1183
+ class Background extends OptionLoader {
1430
1184
  color;
1431
- image;
1432
- opacity;
1433
- position;
1434
- repeat;
1435
- size;
1185
+ image = "";
1186
+ opacity = 1;
1187
+ position = "";
1188
+ repeat = "";
1189
+ size = "";
1436
1190
  constructor() {
1191
+ super();
1437
1192
  this.color = new OptionsColor();
1438
1193
  this.color.value = "";
1439
- this.image = "";
1440
- this.position = "";
1441
- this.repeat = "";
1442
- this.size = "";
1443
- this.opacity = 1;
1444
1194
  }
1445
- load(data) {
1446
- if (isNull(data)) {
1447
- return;
1448
- }
1195
+ doLoad(data) {
1449
1196
  if (data.color !== undefined) {
1450
1197
  this.color = OptionsColor.create(this.color, data.color);
1451
1198
  }
1452
- if (data.image !== undefined) {
1453
- this.image = data.image;
1454
- }
1455
- if (data.position !== undefined) {
1456
- this.position = data.position;
1457
- }
1458
- if (data.repeat !== undefined) {
1459
- this.repeat = data.repeat;
1460
- }
1461
- if (data.size !== undefined) {
1462
- this.size = data.size;
1463
- }
1464
- if (data.opacity !== undefined) {
1465
- this.opacity = data.opacity;
1466
- }
1199
+ loadProperty(this, "image", data.image);
1200
+ loadProperty(this, "position", data.position);
1201
+ loadProperty(this, "repeat", data.repeat);
1202
+ loadProperty(this, "size", data.size);
1203
+ loadProperty(this, "opacity", data.opacity);
1467
1204
  }
1468
1205
  }
1469
1206
 
1470
- class FullScreen {
1471
- enable;
1472
- zIndex;
1473
- constructor() {
1474
- this.enable = true;
1475
- this.zIndex = 0;
1476
- }
1477
- load(data) {
1478
- if (isNull(data)) {
1479
- return;
1480
- }
1481
- if (data.enable !== undefined) {
1482
- this.enable = data.enable;
1483
- }
1484
- if (data.zIndex !== undefined) {
1485
- this.zIndex = data.zIndex;
1486
- }
1207
+ class FullScreen extends OptionLoader {
1208
+ enable = true;
1209
+ zIndex = 0;
1210
+ doLoad(data) {
1211
+ loadProperty(this, "enable", data.enable);
1212
+ loadProperty(this, "zIndex", data.zIndex);
1487
1213
  }
1488
1214
  }
1489
1215
 
1490
- class ResizeEvent {
1491
- delay;
1492
- enable;
1493
- constructor() {
1494
- this.delay = 0.5;
1495
- this.enable = true;
1496
- }
1497
- load(data) {
1498
- if (isNull(data)) {
1499
- return;
1500
- }
1501
- if (data.delay !== undefined) {
1502
- this.delay = data.delay;
1503
- }
1504
- if (data.enable !== undefined) {
1505
- this.enable = data.enable;
1506
- }
1216
+ class ResizeEvent extends OptionLoader {
1217
+ delay = 0.5;
1218
+ enable = true;
1219
+ doLoad(data) {
1220
+ loadProperty(this, "delay", data.delay);
1221
+ loadProperty(this, "enable", data.enable);
1507
1222
  }
1508
1223
  }
1509
1224
 
1510
- class Effect {
1511
- close;
1512
- options;
1513
- type;
1514
- constructor() {
1515
- this.close = true;
1516
- this.options = {};
1517
- this.type = [];
1518
- }
1519
- load(data) {
1520
- if (isNull(data)) {
1521
- return;
1522
- }
1225
+ class Effect extends OptionLoader {
1226
+ close = true;
1227
+ options = {};
1228
+ type = [];
1229
+ doLoad(data) {
1523
1230
  const options = data.options;
1524
1231
  if (options !== undefined) {
1525
1232
  for (const effect in options) {
@@ -1529,128 +1236,62 @@
1529
1236
  }
1530
1237
  }
1531
1238
  }
1532
- if (data.close !== undefined) {
1533
- this.close = data.close;
1534
- }
1535
- if (data.type !== undefined) {
1536
- this.type = data.type;
1537
- }
1239
+ loadProperty(this, "close", data.close);
1240
+ loadProperty(this, "type", data.type);
1538
1241
  }
1539
1242
  }
1540
1243
 
1541
- class Fill {
1244
+ class Fill extends OptionLoader {
1542
1245
  color;
1543
- enable;
1544
- opacity;
1545
- constructor() {
1546
- this.enable = true;
1547
- this.opacity = 1;
1548
- }
1549
- load(data) {
1550
- if (isNull(data)) {
1551
- return;
1552
- }
1246
+ enable = true;
1247
+ opacity = 1;
1248
+ doLoad(data) {
1553
1249
  if (data.color !== undefined) {
1554
1250
  this.color = AnimatableColor.create(this.color, data.color);
1555
1251
  }
1556
- if (data.enable !== undefined) {
1557
- this.enable = data.enable;
1558
- }
1559
- if (data.opacity !== undefined) {
1560
- this.opacity = setRangeValue(data.opacity);
1561
- }
1252
+ loadProperty(this, "enable", data.enable);
1253
+ loadRangeProperty(this, "opacity", data.opacity);
1562
1254
  }
1563
1255
  }
1564
1256
 
1565
- class MoveAngle {
1566
- offset;
1567
- value;
1568
- constructor() {
1569
- this.offset = 0;
1570
- this.value = 90;
1571
- }
1572
- load(data) {
1573
- if (isNull(data)) {
1574
- return;
1575
- }
1576
- if (data.offset !== undefined) {
1577
- this.offset = setRangeValue(data.offset);
1578
- }
1579
- if (data.value !== undefined) {
1580
- this.value = setRangeValue(data.value);
1581
- }
1257
+ class MoveAngle extends OptionLoader {
1258
+ offset = 0;
1259
+ value = 90;
1260
+ doLoad(data) {
1261
+ loadRangeProperty(this, "offset", data.offset);
1262
+ loadRangeProperty(this, "value", data.value);
1582
1263
  }
1583
1264
  }
1584
1265
 
1585
- class MoveCenter {
1586
- mode;
1587
- radius;
1588
- x;
1589
- y;
1590
- constructor() {
1591
- this.x = 50;
1592
- this.y = 50;
1593
- this.mode = PixelMode.percent;
1594
- this.radius = 0;
1595
- }
1596
- load(data) {
1597
- if (isNull(data)) {
1598
- return;
1599
- }
1600
- if (data.x !== undefined) {
1601
- this.x = data.x;
1602
- }
1603
- if (data.y !== undefined) {
1604
- this.y = data.y;
1605
- }
1606
- if (data.mode !== undefined) {
1607
- this.mode = data.mode;
1608
- }
1609
- if (data.radius !== undefined) {
1610
- this.radius = data.radius;
1611
- }
1266
+ class MoveCenter extends OptionLoader {
1267
+ mode = PixelMode.percent;
1268
+ radius = 0;
1269
+ x = 50;
1270
+ y = 50;
1271
+ doLoad(data) {
1272
+ loadProperty(this, "x", data.x);
1273
+ loadProperty(this, "y", data.y);
1274
+ loadProperty(this, "mode", data.mode);
1275
+ loadProperty(this, "radius", data.radius);
1612
1276
  }
1613
1277
  }
1614
1278
 
1615
- class MoveGravity {
1616
- acceleration;
1617
- enable;
1618
- inverse;
1619
- maxSpeed;
1620
- constructor() {
1621
- this.acceleration = 9.81;
1622
- this.enable = false;
1623
- this.inverse = false;
1624
- this.maxSpeed = 50;
1625
- }
1626
- load(data) {
1627
- if (isNull(data)) {
1628
- return;
1629
- }
1630
- if (data.acceleration !== undefined) {
1631
- this.acceleration = setRangeValue(data.acceleration);
1632
- }
1633
- if (data.enable !== undefined) {
1634
- this.enable = data.enable;
1635
- }
1636
- if (data.inverse !== undefined) {
1637
- this.inverse = data.inverse;
1638
- }
1639
- if (data.maxSpeed !== undefined) {
1640
- this.maxSpeed = setRangeValue(data.maxSpeed);
1641
- }
1279
+ class MoveGravity extends OptionLoader {
1280
+ acceleration = 9.81;
1281
+ enable = false;
1282
+ inverse = false;
1283
+ maxSpeed = 50;
1284
+ doLoad(data) {
1285
+ loadRangeProperty(this, "acceleration", data.acceleration);
1286
+ loadProperty(this, "enable", data.enable);
1287
+ loadProperty(this, "inverse", data.inverse);
1288
+ loadRangeProperty(this, "maxSpeed", data.maxSpeed);
1642
1289
  }
1643
1290
  }
1644
1291
 
1645
- class ValueWithRandom {
1646
- value;
1647
- constructor() {
1648
- this.value = 0;
1649
- }
1650
- load(data) {
1651
- if (isNull(data)) {
1652
- return;
1653
- }
1292
+ class ValueWithRandom extends OptionLoader {
1293
+ value = 0;
1294
+ doLoad(data) {
1654
1295
  if (!isNull(data.value)) {
1655
1296
  this.value = setRangeValue(data.value);
1656
1297
  }
@@ -1658,51 +1299,25 @@
1658
1299
  }
1659
1300
  class AnimationValueWithRandom extends ValueWithRandom {
1660
1301
  animation = new AnimationOptions();
1661
- load(data) {
1662
- super.load(data);
1663
- if (isNull(data)) {
1664
- return;
1665
- }
1666
- const animation = data.animation;
1667
- if (animation !== undefined) {
1668
- this.animation.load(animation);
1669
- }
1302
+ doLoad(data) {
1303
+ super.doLoad(data);
1304
+ loadNestedProperty(this, "animation", data.animation);
1670
1305
  }
1671
1306
  }
1672
1307
  class RangedAnimationValueWithRandom extends AnimationValueWithRandom {
1673
- animation;
1674
- constructor() {
1675
- super();
1676
- this.animation = new RangedAnimationOptions();
1677
- }
1678
- load(data) {
1679
- super.load(data);
1680
- }
1308
+ animation = new RangedAnimationOptions();
1681
1309
  }
1682
1310
 
1683
- class MovePath {
1684
- clamp;
1685
- delay;
1686
- enable;
1311
+ class MovePath extends OptionLoader {
1312
+ clamp = true;
1313
+ delay = new ValueWithRandom();
1314
+ enable = false;
1687
1315
  generator;
1688
- options;
1689
- constructor() {
1690
- this.clamp = true;
1691
- this.delay = new ValueWithRandom();
1692
- this.enable = false;
1693
- this.options = {};
1694
- }
1695
- load(data) {
1696
- if (isNull(data)) {
1697
- return;
1698
- }
1699
- if (data.clamp !== undefined) {
1700
- this.clamp = data.clamp;
1701
- }
1316
+ options = {};
1317
+ doLoad(data) {
1318
+ loadProperty(this, "clamp", data.clamp);
1702
1319
  this.delay.load(data.delay);
1703
- if (data.enable !== undefined) {
1704
- this.enable = data.enable;
1705
- }
1320
+ loadProperty(this, "enable", data.enable);
1706
1321
  this.generator = data.generator;
1707
1322
  if (data.options) {
1708
1323
  this.options = deepExtend(this.options, data.options);
@@ -1710,19 +1325,13 @@
1710
1325
  }
1711
1326
  }
1712
1327
 
1713
- class OutModes {
1328
+ class OutModes extends OptionLoader {
1714
1329
  bottom;
1715
- default;
1330
+ default = OutMode.out;
1716
1331
  left;
1717
1332
  right;
1718
1333
  top;
1719
- constructor() {
1720
- this.default = OutMode.out;
1721
- }
1722
- load(data) {
1723
- if (isNull(data)) {
1724
- return;
1725
- }
1334
+ doLoad(data) {
1726
1335
  if (data.default !== undefined) {
1727
1336
  this.default = data.default;
1728
1337
  }
@@ -1733,79 +1342,42 @@
1733
1342
  }
1734
1343
  }
1735
1344
 
1736
- class Spin {
1737
- acceleration;
1738
- enable;
1345
+ class Spin extends OptionLoader {
1346
+ acceleration = 0;
1347
+ enable = false;
1739
1348
  position;
1740
- constructor() {
1741
- this.acceleration = 0;
1742
- this.enable = false;
1743
- }
1744
- load(data) {
1745
- if (isNull(data)) {
1746
- return;
1747
- }
1748
- if (data.acceleration !== undefined) {
1749
- this.acceleration = setRangeValue(data.acceleration);
1750
- }
1751
- if (data.enable !== undefined) {
1752
- this.enable = data.enable;
1753
- }
1349
+ doLoad(data) {
1350
+ loadRangeProperty(this, "acceleration", data.acceleration);
1351
+ loadProperty(this, "enable", data.enable);
1754
1352
  if (data.position) {
1755
1353
  this.position = deepExtend({}, data.position);
1756
1354
  }
1757
1355
  }
1758
1356
  }
1759
1357
 
1760
- class Move {
1761
- angle;
1762
- center;
1763
- decay;
1764
- direction;
1765
- distance;
1766
- drift;
1767
- enable;
1768
- gravity;
1769
- outModes;
1770
- path;
1771
- random;
1772
- size;
1773
- speed;
1774
- spin;
1775
- straight;
1776
- vibrate;
1777
- warp;
1778
- constructor() {
1779
- this.angle = new MoveAngle();
1780
- this.center = new MoveCenter();
1781
- this.decay = 0;
1782
- this.distance = {};
1783
- this.direction = MoveDirection.none;
1784
- this.drift = 0;
1785
- this.enable = false;
1786
- this.gravity = new MoveGravity();
1787
- this.path = new MovePath();
1788
- this.outModes = new OutModes();
1789
- this.random = false;
1790
- this.size = false;
1791
- this.speed = 2;
1792
- this.spin = new Spin();
1793
- this.straight = false;
1794
- this.vibrate = false;
1795
- this.warp = false;
1796
- }
1797
- load(data) {
1798
- if (isNull(data)) {
1799
- return;
1800
- }
1358
+ class Move extends OptionLoader {
1359
+ angle = new MoveAngle();
1360
+ center = new MoveCenter();
1361
+ decay = 0;
1362
+ direction = MoveDirection.none;
1363
+ distance = {};
1364
+ drift = 0;
1365
+ enable = false;
1366
+ gravity = new MoveGravity();
1367
+ outModes = new OutModes();
1368
+ path = new MovePath();
1369
+ random = false;
1370
+ size = false;
1371
+ speed = 2;
1372
+ spin = new Spin();
1373
+ straight = false;
1374
+ vibrate = false;
1375
+ warp = false;
1376
+ doLoad(data) {
1801
1377
  this.angle.load(isNumber(data.angle) ? { value: data.angle } : data.angle);
1802
1378
  this.center.load(data.center);
1803
- if (data.decay !== undefined) {
1804
- this.decay = setRangeValue(data.decay);
1805
- }
1806
- if (data.direction !== undefined) {
1807
- this.direction = data.direction;
1808
- }
1379
+ loadRangeProperty(this, "decay", data.decay);
1380
+ loadProperty(this, "direction", data.direction);
1809
1381
  if (data.distance !== undefined) {
1810
1382
  this.distance = isNumber(data.distance)
1811
1383
  ? {
@@ -1814,12 +1386,8 @@
1814
1386
  }
1815
1387
  : { ...data.distance };
1816
1388
  }
1817
- if (data.drift !== undefined) {
1818
- this.drift = setRangeValue(data.drift);
1819
- }
1820
- if (data.enable !== undefined) {
1821
- this.enable = data.enable;
1822
- }
1389
+ loadRangeProperty(this, "drift", data.drift);
1390
+ loadProperty(this, "enable", data.enable);
1823
1391
  this.gravity.load(data.gravity);
1824
1392
  const outModes = data.outModes;
1825
1393
  if (outModes !== undefined) {
@@ -1833,177 +1401,91 @@
1833
1401
  }
1834
1402
  }
1835
1403
  this.path.load(data.path);
1836
- if (data.random !== undefined) {
1837
- this.random = data.random;
1838
- }
1839
- if (data.size !== undefined) {
1840
- this.size = data.size;
1841
- }
1842
- if (data.speed !== undefined) {
1843
- this.speed = setRangeValue(data.speed);
1844
- }
1404
+ loadProperty(this, "random", data.random);
1405
+ loadProperty(this, "size", data.size);
1406
+ loadRangeProperty(this, "speed", data.speed);
1845
1407
  this.spin.load(data.spin);
1846
- if (data.straight !== undefined) {
1847
- this.straight = data.straight;
1848
- }
1849
- if (data.vibrate !== undefined) {
1850
- this.vibrate = data.vibrate;
1851
- }
1852
- if (data.warp !== undefined) {
1853
- this.warp = data.warp;
1854
- }
1408
+ loadProperty(this, "straight", data.straight);
1409
+ loadProperty(this, "vibrate", data.vibrate);
1410
+ loadProperty(this, "warp", data.warp);
1855
1411
  }
1856
1412
  }
1857
1413
 
1858
- class Stroke {
1414
+ class Stroke extends OptionLoader {
1859
1415
  color;
1860
1416
  opacity;
1861
- width;
1862
- constructor() {
1863
- this.width = 0;
1864
- }
1865
- load(data) {
1866
- if (isNull(data)) {
1867
- return;
1868
- }
1417
+ width = 0;
1418
+ doLoad(data) {
1869
1419
  if (data.color !== undefined) {
1870
1420
  this.color = AnimatableColor.create(this.color, data.color);
1871
1421
  }
1872
- if (data.width !== undefined) {
1873
- this.width = setRangeValue(data.width);
1874
- }
1875
- if (data.opacity !== undefined) {
1876
- this.opacity = setRangeValue(data.opacity);
1877
- }
1422
+ loadRangeProperty(this, "width", data.width);
1423
+ loadRangeProperty(this, "opacity", data.opacity);
1878
1424
  }
1879
1425
  }
1880
1426
 
1881
- class Paint {
1427
+ class Paint extends OptionLoader {
1882
1428
  color;
1883
1429
  fill;
1884
1430
  stroke;
1885
- load(data) {
1886
- if (isNull(data)) {
1887
- return;
1888
- }
1431
+ doLoad(data) {
1889
1432
  if (data.color !== undefined) {
1890
1433
  this.color = AnimatableColor.create(this.color, data.color);
1891
1434
  }
1892
- if (data.fill !== undefined) {
1893
- this.fill ??= new Fill();
1894
- this.fill.load(data.fill);
1895
- }
1896
- if (data.stroke !== undefined) {
1897
- this.stroke ??= new Stroke();
1898
- this.stroke.load(data.stroke);
1899
- }
1435
+ loadLazyProperty(this, "fill", data.fill, () => new Fill());
1436
+ loadLazyProperty(this, "stroke", data.stroke, () => new Stroke());
1900
1437
  }
1901
1438
  }
1902
1439
 
1903
1440
  class ParticlesBounceFactor extends ValueWithRandom {
1904
- constructor() {
1905
- super();
1906
- this.value = 1;
1907
- }
1441
+ value = 1;
1908
1442
  }
1909
1443
 
1910
- class ParticlesBounce {
1911
- horizontal;
1912
- vertical;
1913
- constructor() {
1914
- this.horizontal = new ParticlesBounceFactor();
1915
- this.vertical = new ParticlesBounceFactor();
1916
- }
1917
- load(data) {
1918
- if (isNull(data)) {
1919
- return;
1920
- }
1444
+ class ParticlesBounce extends OptionLoader {
1445
+ horizontal = new ParticlesBounceFactor();
1446
+ vertical = new ParticlesBounceFactor();
1447
+ doLoad(data) {
1921
1448
  this.horizontal.load(data.horizontal);
1922
1449
  this.vertical.load(data.vertical);
1923
1450
  }
1924
1451
  }
1925
1452
 
1926
- class ParticlesDensity {
1927
- enable;
1928
- height;
1929
- width;
1930
- constructor() {
1931
- this.enable = false;
1932
- this.width = 1920;
1933
- this.height = 1080;
1934
- }
1935
- load(data) {
1936
- if (isNull(data)) {
1937
- return;
1938
- }
1939
- if (data.enable !== undefined) {
1940
- this.enable = data.enable;
1941
- }
1942
- const width = data.width;
1943
- if (width !== undefined) {
1944
- this.width = width;
1945
- }
1946
- const height = data.height;
1947
- if (height !== undefined) {
1948
- this.height = height;
1949
- }
1453
+ class ParticlesDensity extends OptionLoader {
1454
+ enable = false;
1455
+ height = 1080;
1456
+ width = 1920;
1457
+ doLoad(data) {
1458
+ loadProperty(this, "enable", data.enable);
1459
+ loadProperty(this, "width", data.width);
1460
+ loadProperty(this, "height", data.height);
1950
1461
  }
1951
1462
  }
1952
1463
 
1953
- class ParticlesNumberLimit {
1954
- mode;
1955
- value;
1956
- constructor() {
1957
- this.mode = LimitMode.delete;
1958
- this.value = 0;
1959
- }
1960
- load(data) {
1961
- if (isNull(data)) {
1962
- return;
1963
- }
1964
- if (data.mode !== undefined) {
1965
- this.mode = data.mode;
1966
- }
1967
- if (data.value !== undefined) {
1968
- this.value = data.value;
1969
- }
1464
+ class ParticlesNumberLimit extends OptionLoader {
1465
+ mode = LimitMode.delete;
1466
+ value = 0;
1467
+ doLoad(data) {
1468
+ loadProperty(this, "mode", data.mode);
1469
+ loadProperty(this, "value", data.value);
1970
1470
  }
1971
1471
  }
1972
1472
 
1973
- class ParticlesNumber {
1974
- density;
1975
- limit;
1976
- value;
1977
- constructor() {
1978
- this.density = new ParticlesDensity();
1979
- this.limit = new ParticlesNumberLimit();
1980
- this.value = 0;
1981
- }
1982
- load(data) {
1983
- if (isNull(data)) {
1984
- return;
1985
- }
1473
+ class ParticlesNumber extends OptionLoader {
1474
+ density = new ParticlesDensity();
1475
+ limit = new ParticlesNumberLimit();
1476
+ value = 0;
1477
+ doLoad(data) {
1986
1478
  this.density.load(data.density);
1987
1479
  this.limit.load(data.limit);
1988
- if (data.value !== undefined) {
1989
- this.value = data.value;
1990
- }
1480
+ loadProperty(this, "value", data.value);
1991
1481
  }
1992
1482
  }
1993
1483
 
1994
- class Shape {
1995
- close;
1996
- options;
1997
- type;
1998
- constructor() {
1999
- this.close = true;
2000
- this.options = {};
2001
- this.type = "circle";
2002
- }
2003
- load(data) {
2004
- if (isNull(data)) {
2005
- return;
2006
- }
1484
+ class Shape extends OptionLoader {
1485
+ close = true;
1486
+ options = {};
1487
+ type = "circle";
1488
+ doLoad(data) {
2007
1489
  const options = data.options;
2008
1490
  if (options !== undefined) {
2009
1491
  for (const shape in options) {
@@ -2013,76 +1495,47 @@
2013
1495
  }
2014
1496
  }
2015
1497
  }
2016
- if (data.close !== undefined) {
2017
- this.close = data.close;
2018
- }
2019
- if (data.type !== undefined) {
2020
- this.type = data.type;
2021
- }
1498
+ loadProperty(this, "close", data.close);
1499
+ loadProperty(this, "type", data.type);
2022
1500
  }
2023
1501
  }
2024
1502
 
2025
1503
  class ZIndex extends ValueWithRandom {
2026
- opacityRate;
2027
- sizeRate;
2028
- velocityRate;
2029
- constructor() {
2030
- super();
2031
- this.opacityRate = 1;
2032
- this.sizeRate = 1;
2033
- this.velocityRate = 1;
2034
- }
2035
- load(data) {
2036
- super.load(data);
2037
- if (isNull(data)) {
2038
- return;
2039
- }
2040
- if (data.opacityRate !== undefined) {
2041
- this.opacityRate = data.opacityRate;
2042
- }
2043
- if (data.sizeRate !== undefined) {
2044
- this.sizeRate = data.sizeRate;
2045
- }
2046
- if (data.velocityRate !== undefined) {
2047
- this.velocityRate = data.velocityRate;
2048
- }
2049
- }
2050
- }
2051
-
2052
- class ParticlesOptions {
2053
- bounce;
2054
- effect;
2055
- groups;
2056
- move;
2057
- number;
1504
+ opacityRate = 1;
1505
+ sizeRate = 1;
1506
+ velocityRate = 1;
1507
+ doLoad(data) {
1508
+ super.doLoad(data);
1509
+ loadProperty(this, "opacityRate", data.opacityRate);
1510
+ loadProperty(this, "sizeRate", data.sizeRate);
1511
+ loadProperty(this, "velocityRate", data.velocityRate);
1512
+ }
1513
+ }
1514
+
1515
+ class ParticlesOptions extends OptionLoader {
1516
+ bounce = new ParticlesBounce();
1517
+ effect = new Effect();
1518
+ groups = {};
1519
+ move = new Move();
1520
+ number = new ParticlesNumber();
2058
1521
  paint;
2059
1522
  palette;
2060
- reduceDuplicates;
2061
- shape;
2062
- zIndex;
1523
+ reduceDuplicates = false;
1524
+ shape = new Shape();
1525
+ zIndex = new ZIndex();
2063
1526
  #container;
2064
1527
  #pluginManager;
2065
1528
  constructor(pluginManager, container) {
1529
+ super();
2066
1530
  this.#pluginManager = pluginManager;
2067
1531
  this.#container = container;
2068
- this.bounce = new ParticlesBounce();
2069
- this.effect = new Effect();
2070
- this.groups = {};
2071
- this.move = new Move();
2072
- this.number = new ParticlesNumber();
2073
1532
  this.paint = new Paint();
2074
1533
  this.paint.color = new AnimatableColor();
2075
1534
  this.paint.color.value = "#fff";
2076
1535
  this.paint.fill = new Fill();
2077
1536
  this.paint.fill.enable = true;
2078
- this.reduceDuplicates = false;
2079
- this.shape = new Shape();
2080
- this.zIndex = new ZIndex();
2081
1537
  }
2082
- load(data) {
2083
- if (isNull(data)) {
2084
- return;
2085
- }
1538
+ doLoad(data) {
2086
1539
  if (data.palette) {
2087
1540
  this.palette = data.palette;
2088
1541
  this.#importPalette(this.palette);
@@ -2140,7 +1593,7 @@
2140
1593
  }
2141
1594
  }
2142
1595
  }
2143
- #importPalette = (palette) => {
1596
+ #importPalette(palette) {
2144
1597
  const paletteData = this.#pluginManager.getPalette(palette);
2145
1598
  if (!paletteData) {
2146
1599
  return;
@@ -2184,69 +1637,49 @@
2184
1637
  mode: paletteData.blendMode,
2185
1638
  },
2186
1639
  });
2187
- };
2188
- }
2189
-
2190
- function loadOptions(options, ...sourceOptionsArr) {
2191
- for (const sourceOptions of sourceOptionsArr) {
2192
- options.load(sourceOptions);
2193
1640
  }
2194
1641
  }
1642
+
2195
1643
  function loadParticlesOptions(pluginManager, container, ...sourceOptionsArr) {
2196
1644
  const options = new ParticlesOptions(pluginManager, container);
2197
1645
  loadOptions(options, ...sourceOptionsArr);
2198
1646
  return options;
2199
1647
  }
2200
1648
 
2201
- class Options {
2202
- autoPlay;
1649
+ class Options extends OptionLoader {
1650
+ autoPlay = true;
2203
1651
  background;
2204
- clear;
2205
- defaultThemes;
2206
- delay;
2207
- detectRetina;
2208
- duration;
2209
- fpsLimit;
1652
+ clear = true;
1653
+ defaultThemes = {};
1654
+ delay = 0;
1655
+ detectRetina = true;
1656
+ duration = 0;
1657
+ fpsLimit = 120;
2210
1658
  fullScreen;
2211
- hdr;
1659
+ hdr = true;
2212
1660
  key;
2213
1661
  name;
2214
1662
  palette;
2215
1663
  particles;
2216
- pauseOnBlur;
2217
- pauseOnOutsideViewport;
1664
+ pauseOnBlur = true;
1665
+ pauseOnOutsideViewport = true;
2218
1666
  preset;
2219
1667
  resize;
2220
- smooth;
2221
- style;
2222
- zLayers;
1668
+ smooth = false;
1669
+ style = {};
1670
+ zLayers = 100;
2223
1671
  #container;
2224
1672
  #pluginManager;
2225
1673
  constructor(pluginManager, container) {
1674
+ super();
2226
1675
  this.#pluginManager = pluginManager;
2227
1676
  this.#container = container;
2228
- this.autoPlay = true;
2229
1677
  this.background = new Background();
2230
- this.clear = true;
2231
- this.defaultThemes = {};
2232
- this.delay = 0;
2233
1678
  this.fullScreen = new FullScreen();
2234
- this.detectRetina = true;
2235
- this.duration = 0;
2236
- this.fpsLimit = 120;
2237
- this.hdr = true;
2238
1679
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
2239
- this.pauseOnBlur = true;
2240
- this.pauseOnOutsideViewport = true;
2241
1680
  this.resize = new ResizeEvent();
2242
- this.smooth = false;
2243
- this.style = {};
2244
- this.zLayers = 100;
2245
1681
  }
2246
- load(data) {
2247
- if (isNull(data)) {
2248
- return;
2249
- }
1682
+ doLoad(data) {
2250
1683
  if (data.preset !== undefined) {
2251
1684
  this.preset = data.preset;
2252
1685
  executeOnSingleOrMultiple(this.preset, preset => {
@@ -2257,44 +1690,18 @@
2257
1690
  this.palette = data.palette;
2258
1691
  this.#importPalette(this.palette);
2259
1692
  }
2260
- if (data.autoPlay !== undefined) {
2261
- this.autoPlay = data.autoPlay;
2262
- }
2263
- if (data.clear !== undefined) {
2264
- this.clear = data.clear;
2265
- }
2266
- if (data.key !== undefined) {
2267
- this.key = data.key;
2268
- }
2269
- if (data.name !== undefined) {
2270
- this.name = data.name;
2271
- }
2272
- if (data.delay !== undefined) {
2273
- this.delay = setRangeValue(data.delay);
2274
- }
2275
- const detectRetina = data.detectRetina;
2276
- if (detectRetina !== undefined) {
2277
- this.detectRetina = detectRetina;
2278
- }
2279
- if (data.duration !== undefined) {
2280
- this.duration = setRangeValue(data.duration);
2281
- }
2282
- const fpsLimit = data.fpsLimit;
2283
- if (fpsLimit !== undefined) {
2284
- this.fpsLimit = fpsLimit;
2285
- }
2286
- if (data.hdr !== undefined) {
2287
- this.hdr = data.hdr;
2288
- }
2289
- if (data.pauseOnBlur !== undefined) {
2290
- this.pauseOnBlur = data.pauseOnBlur;
2291
- }
2292
- if (data.pauseOnOutsideViewport !== undefined) {
2293
- this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
2294
- }
2295
- if (data.zLayers !== undefined) {
2296
- this.zLayers = data.zLayers;
2297
- }
1693
+ loadProperty(this, "autoPlay", data.autoPlay);
1694
+ loadProperty(this, "clear", data.clear);
1695
+ loadProperty(this, "key", data.key);
1696
+ loadProperty(this, "name", data.name);
1697
+ loadRangeProperty(this, "delay", data.delay);
1698
+ loadProperty(this, "detectRetina", data.detectRetina);
1699
+ loadRangeProperty(this, "duration", data.duration);
1700
+ loadProperty(this, "fpsLimit", data.fpsLimit);
1701
+ loadProperty(this, "hdr", data.hdr);
1702
+ loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1703
+ loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1704
+ loadProperty(this, "zLayers", data.zLayers);
2298
1705
  this.background.load(data.background);
2299
1706
  const fullScreen = data.fullScreen;
2300
1707
  if (isBoolean(fullScreen)) {
@@ -2306,14 +1713,12 @@
2306
1713
  this.particles.load(data.particles);
2307
1714
  this.resize.load(data.resize);
2308
1715
  this.style = deepExtend(this.style, data.style);
2309
- if (data.smooth !== undefined) {
2310
- this.smooth = data.smooth;
2311
- }
1716
+ loadProperty(this, "smooth", data.smooth);
2312
1717
  this.#pluginManager.plugins.forEach(plugin => {
2313
1718
  plugin.loadOptions(this.#container, this, data);
2314
1719
  });
2315
1720
  }
2316
- #importPalette = palette => {
1721
+ #importPalette(palette) {
2317
1722
  const paletteData = this.#pluginManager.getPalette(palette);
2318
1723
  if (!paletteData) {
2319
1724
  return;
@@ -2322,151 +1727,27 @@
2322
1727
  background: {
2323
1728
  color: paletteData.background,
2324
1729
  },
2325
- blend: {
2326
- enable: true,
2327
- mode: paletteData.blendMode,
2328
- },
2329
- particles: {
2330
- palette,
2331
- },
2332
- });
2333
- };
2334
- #importPreset = preset => {
2335
- this.load(this.#pluginManager.getPreset(preset));
2336
- };
2337
- }
2338
-
2339
- function paintBase(context, dimension, baseColor) {
2340
- context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
2341
- context.fillRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2342
- }
2343
- function paintImage(context, dimension, image, opacity) {
2344
- if (!image) {
2345
- return;
2346
- }
2347
- const prevAlpha = context.globalAlpha;
2348
- context.globalAlpha = opacity;
2349
- context.drawImage(image, originPoint.x, originPoint.y, dimension.width, dimension.height);
2350
- context.globalAlpha = prevAlpha;
2351
- }
2352
- function clear(context, dimension) {
2353
- context.clearRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2354
- }
2355
- function drawParticle(data) {
2356
- const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
2357
- x: pos.x,
2358
- y: pos.y,
2359
- };
2360
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
2361
- if (colorStyles.fill) {
2362
- context.fillStyle = colorStyles.fill;
2363
- }
2364
- const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
2365
- context.lineWidth = strokeWidth;
2366
- if (colorStyles.stroke) {
2367
- context.strokeStyle = colorStyles.stroke;
2368
- }
2369
- const drawData = {
2370
- context,
2371
- particle,
2372
- radius,
2373
- drawRadius: radius * drawScale,
2374
- opacity,
2375
- delta,
2376
- pixelRatio: container.retina.pixelRatio,
2377
- fill: fillEnabled,
2378
- stroke: strokeWidth > minStrokeWidth,
2379
- transformData,
2380
- position: { ...pos },
2381
- drawPosition,
2382
- drawScale,
2383
- };
2384
- for (const plugin of container.plugins) {
2385
- plugin.drawParticleTransform?.(drawData);
2386
- }
2387
- const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
2388
- drawBeforeEffect(effect, drawData);
2389
- drawShapeBeforeDraw(shape, drawData);
2390
- drawShape(shape, drawData);
2391
- drawShapeAfterDraw(shape, drawData);
2392
- drawAfterEffect(effect, drawData);
2393
- context.resetTransform();
2394
- }
2395
- function drawAfterEffect(drawer, data) {
2396
- if (!drawer?.drawAfter) {
2397
- return;
2398
- }
2399
- const { particle } = data;
2400
- if (!particle.effect) {
2401
- return;
2402
- }
2403
- drawer.drawAfter(data);
2404
- }
2405
- function drawBeforeEffect(drawer, data) {
2406
- if (!drawer?.drawBefore) {
2407
- return;
2408
- }
2409
- const { particle } = data;
2410
- if (!particle.effect) {
2411
- return;
2412
- }
2413
- drawer.drawBefore(data);
2414
- }
2415
- function drawShape(drawer, data) {
2416
- if (!drawer) {
2417
- return;
2418
- }
2419
- const { context, fill, particle, stroke } = data;
2420
- if (!particle.shape) {
2421
- return;
2422
- }
2423
- context.beginPath();
2424
- drawer.draw(data);
2425
- if (particle.shapeClose) {
2426
- context.closePath();
2427
- }
2428
- if (fill) {
2429
- context.fill();
2430
- }
2431
- if (stroke) {
2432
- context.stroke();
2433
- }
2434
- }
2435
- function drawShapeAfterDraw(drawer, data) {
2436
- if (!drawer?.afterDraw) {
2437
- return;
2438
- }
2439
- const { particle } = data;
2440
- if (!particle.shape) {
2441
- return;
2442
- }
2443
- drawer.afterDraw(data);
2444
- }
2445
- function drawShapeBeforeDraw(drawer, data) {
2446
- if (!drawer?.beforeDraw) {
2447
- return;
2448
- }
2449
- const { particle } = data;
2450
- if (!particle.shape) {
2451
- return;
1730
+ blend: {
1731
+ enable: true,
1732
+ mode: paletteData.blendMode,
1733
+ },
1734
+ particles: {
1735
+ palette,
1736
+ },
1737
+ });
2452
1738
  }
2453
- drawer.beforeDraw(data);
2454
- }
2455
- function drawParticlePlugin(context, plugin, particle, delta) {
2456
- if (!plugin.drawParticle) {
2457
- return;
1739
+ #importPreset(preset) {
1740
+ this.load(this.#pluginManager.getPreset(preset));
2458
1741
  }
2459
- plugin.drawParticle(context, particle, delta);
2460
1742
  }
2461
1743
 
2462
- const styleCache = new Map(), maxCacheSize = 1000, firstIndex = 0, rgbFixedPrecision = 2, hslFixedPrecision = 2;
1744
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
2463
1745
  function getCachedStyle(key, generator) {
2464
1746
  let cached = styleCache.get(key);
2465
1747
  if (!cached) {
2466
1748
  cached = generator();
2467
- if (styleCache.size >= maxCacheSize) {
2468
- const keysToDelete = [...styleCache.keys()].slice(firstIndex, maxCacheSize * half);
2469
- keysToDelete.forEach(k => styleCache.delete(k));
1749
+ if (styleCache.size > maxStyleCacheSize) {
1750
+ styleCache.clear();
2470
1751
  }
2471
1752
  styleCache.set(key, cached);
2472
1753
  }
@@ -2569,34 +1850,35 @@
2569
1850
  function stringToRgb(pluginManager, input) {
2570
1851
  return stringToRgba(pluginManager, input);
2571
1852
  }
1853
+ function hslChannel(temp1, temp2, temp3) {
1854
+ const temp3Min = 0, temp3Max = 1;
1855
+ if (temp3 < temp3Min) {
1856
+ temp3++;
1857
+ }
1858
+ if (temp3 > temp3Max) {
1859
+ temp3--;
1860
+ }
1861
+ if (temp3 * sextuple < temp3Max) {
1862
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1863
+ }
1864
+ if (temp3 * double < temp3Max) {
1865
+ return temp2;
1866
+ }
1867
+ if (temp3 * triple < temp3Max * double) {
1868
+ const temp3Offset = double / triple;
1869
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1870
+ }
1871
+ return temp1;
1872
+ }
2572
1873
  function hslToRgb(hsl) {
2573
1874
  const h = ((hsl.h % hMax) + hMax) % hMax, s = Math.max(sMin, Math.min(sMax, hsl.s)), l = Math.max(lMin, Math.min(lMax, hsl.l)), hNormalized = h / hMax, sNormalized = s / sMax, lNormalized = l / lMax;
2574
1875
  if (s === sMin) {
2575
1876
  const grayscaleValue = Math.round(lNormalized * rgbMax);
2576
1877
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
2577
1878
  }
2578
- const channel = (temp1, temp2, temp3) => {
2579
- const temp3Min = 0, temp3Max = 1;
2580
- if (temp3 < temp3Min) {
2581
- temp3++;
2582
- }
2583
- if (temp3 > temp3Max) {
2584
- temp3--;
2585
- }
2586
- if (temp3 * sextuple < temp3Max) {
2587
- return temp1 + (temp2 - temp1) * sextuple * temp3;
2588
- }
2589
- if (temp3 * double < temp3Max) {
2590
- return temp2;
2591
- }
2592
- if (temp3 * triple < temp3Max * double) {
2593
- const temp3Offset = double / triple;
2594
- return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
2595
- }
2596
- return temp1;
2597
- }, temp1 = lNormalized < half
1879
+ const temp1 = lNormalized < half
2598
1880
  ? lNormalized * (sNormalizedOffset + sNormalized)
2599
- : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized - phaseThird));
1881
+ : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized - phaseThird));
2600
1882
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
2601
1883
  }
2602
1884
  function hslaToRgba(hsla) {
@@ -2609,7 +1891,7 @@
2609
1891
  };
2610
1892
  }
2611
1893
  function getRandomRgbColor(min) {
2612
- const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$3, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1894
+ const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$2, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
2613
1895
  return {
2614
1896
  b: getRgbInRangeValue(),
2615
1897
  g: getRgbInRangeValue(),
@@ -2620,21 +1902,18 @@
2620
1902
  const op = opacity ?? defaultOpacity$1, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2621
1903
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2622
1904
  }
2623
- function getHdrStyleFromRgb(color, opacity) {
2624
- return `color(display-p3 ${(color.r / rgbMax).toString()} ${(color.g / rgbMax).toString()} ${(color.b / rgbMax).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1905
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1906
+ const headroom = peakNits / sdrReferenceWhiteNits;
1907
+ return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2625
1908
  }
2626
1909
  function getSdrStyleFromRgb(color, opacity) {
2627
1910
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
2628
1911
  }
2629
1912
  function getStyleFromHsl(color, hdr, opacity) {
2630
1913
  const op = opacity ?? defaultOpacity$1, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2631
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromHsl(color, opacity) : getSdrStyleFromHsl(color, opacity)));
2632
- }
2633
- function getHdrStyleFromHsl(color, opacity) {
2634
- return getHdrStyleFromRgb(hslToRgb(color), opacity);
2635
- }
2636
- function getSdrStyleFromHsl(color, opacity) {
2637
- return `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${(opacity ?? defaultOpacity$1).toString()})`;
1914
+ return getCachedStyle(key, () => hdr
1915
+ ? getStyleFromRgb(hslToRgb(color), true, opacity)
1916
+ : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
2638
1917
  }
2639
1918
  function getHslFromAnimation(animation) {
2640
1919
  return animation === undefined
@@ -2756,22 +2035,14 @@
2756
2035
  const tsParticles = initEngine();
2757
2036
 
2758
2037
  class Blend {
2759
- enable;
2760
- mode;
2761
- constructor() {
2762
- this.mode = "destination-out";
2763
- this.enable = false;
2764
- }
2038
+ enable = false;
2039
+ mode = "destination-out";
2765
2040
  load(data) {
2766
2041
  if (isNull(data)) {
2767
2042
  return;
2768
2043
  }
2769
- if (data.mode !== undefined) {
2770
- this.mode = data.mode;
2771
- }
2772
- if (data.enable !== undefined) {
2773
- this.enable = data.enable;
2774
- }
2044
+ loadProperty(this, "mode", data.mode);
2045
+ loadProperty(this, "enable", data.enable);
2775
2046
  }
2776
2047
  }
2777
2048
 
@@ -2801,7 +2072,7 @@
2801
2072
  }
2802
2073
 
2803
2074
  async function loadBlendPlugin(engine) {
2804
- engine.checkVersion("4.1.2");
2075
+ engine.checkVersion("4.2.0");
2805
2076
  await engine.pluginManager.register(e => {
2806
2077
  e.pluginManager.addPlugin(new BlendPlugin());
2807
2078
  });
@@ -2838,7 +2109,7 @@
2838
2109
  }
2839
2110
 
2840
2111
  async function loadCircleShape(engine) {
2841
- engine.checkVersion("4.1.2");
2112
+ engine.checkVersion("4.2.0");
2842
2113
  await engine.pluginManager.register(e => {
2843
2114
  e.pluginManager.addShape(["circle"], () => {
2844
2115
  return Promise.resolve(new CircleDrawer());
@@ -2886,7 +2157,7 @@
2886
2157
  }
2887
2158
 
2888
2159
  async function loadHexColorPlugin(engine) {
2889
- engine.checkVersion("4.1.2");
2160
+ engine.checkVersion("4.2.0");
2890
2161
  await engine.pluginManager.register(e => {
2891
2162
  e.pluginManager.addColorManager("hex", new HexColorManager());
2892
2163
  });
@@ -2939,7 +2210,7 @@
2939
2210
  }
2940
2211
 
2941
2212
  async function loadHslColorPlugin(engine) {
2942
- engine.checkVersion("4.1.2");
2213
+ engine.checkVersion("4.2.0");
2943
2214
  await engine.pluginManager.register(e => {
2944
2215
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2945
2216
  });
@@ -2963,7 +2234,7 @@
2963
2234
  }
2964
2235
 
2965
2236
  async function loadMovePlugin(engine) {
2966
- engine.checkVersion("4.1.2");
2237
+ engine.checkVersion("4.2.0");
2967
2238
  await engine.pluginManager.register(e => {
2968
2239
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2969
2240
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2981,31 +2252,143 @@
2981
2252
  });
2982
2253
  }
2983
2254
 
2984
- class OpacityAnimation extends RangedAnimationOptions {
2985
- destroy;
2986
- constructor() {
2987
- super();
2988
- this.destroy = DestroyType.none;
2989
- this.speed = 2;
2255
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
2256
+ switch (destroyType) {
2257
+ case DestroyType.max:
2258
+ if (value >= maxValue) {
2259
+ particle.destroy();
2260
+ }
2261
+ break;
2262
+ case DestroyType.min:
2263
+ if (value <= minValue) {
2264
+ particle.destroy();
2265
+ }
2266
+ break;
2267
+ }
2268
+ }
2269
+ function initParticleNumericAnimationValue(options, pxRatio) {
2270
+ const valueRange = options.value, animationOptions = options.animation, res = {
2271
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
2272
+ enable: animationOptions.enable,
2273
+ value: getRangeValue(options.value) * pxRatio,
2274
+ max: getRangeMax(valueRange) * pxRatio,
2275
+ min: getRangeMin(valueRange) * pxRatio,
2276
+ loops: 0,
2277
+ maxLoops: getRangeValue(animationOptions.count),
2278
+ time: 0,
2279
+ }, decayOffset = 1;
2280
+ if (animationOptions.enable) {
2281
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
2282
+ switch (animationOptions.mode) {
2283
+ case AnimationMode.increase:
2284
+ res.status = AnimationStatus.increasing;
2285
+ break;
2286
+ case AnimationMode.decrease:
2287
+ res.status = AnimationStatus.decreasing;
2288
+ break;
2289
+ case AnimationMode.random:
2290
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2291
+ break;
2292
+ }
2293
+ const autoStatus = animationOptions.mode === AnimationMode.auto;
2294
+ switch (animationOptions.startValue) {
2295
+ case StartValueType.min:
2296
+ res.value = res.min;
2297
+ if (autoStatus) {
2298
+ res.status = AnimationStatus.increasing;
2299
+ }
2300
+ break;
2301
+ case StartValueType.max:
2302
+ res.value = res.max;
2303
+ if (autoStatus) {
2304
+ res.status = AnimationStatus.decreasing;
2305
+ }
2306
+ break;
2307
+ case StartValueType.random:
2308
+ default:
2309
+ res.value = randomInRangeValue(res);
2310
+ if (autoStatus) {
2311
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2312
+ }
2313
+ break;
2314
+ }
2315
+ }
2316
+ res.initialValue = res.value;
2317
+ return res;
2318
+ }
2319
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
2320
+ const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
2321
+ if (particle.destroyed ||
2322
+ !data.enable ||
2323
+ ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
2324
+ return;
2325
+ }
2326
+ const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
2327
+ data.time ??= 0;
2328
+ const delayTime = data.delayTime ?? minDelay;
2329
+ if (delayTime > minDelay && data.time < delayTime) {
2330
+ data.time += delta.value;
2331
+ if (data.time < delayTime) {
2332
+ return;
2333
+ }
2334
+ }
2335
+ switch (data.status) {
2336
+ case AnimationStatus.increasing:
2337
+ data.value += velocity;
2338
+ break;
2339
+ case AnimationStatus.decreasing:
2340
+ data.value -= velocity;
2341
+ break;
2342
+ }
2343
+ if (data.velocity && decay !== identity) {
2344
+ data.velocity *= decay;
2345
+ }
2346
+ switch (data.status) {
2347
+ case AnimationStatus.increasing:
2348
+ if (data.value >= maxValue) {
2349
+ if (changeDirection) {
2350
+ data.status = AnimationStatus.decreasing;
2351
+ }
2352
+ else {
2353
+ data.value -= maxValue;
2354
+ }
2355
+ data.loops ??= minLoops;
2356
+ data.loops++;
2357
+ }
2358
+ break;
2359
+ case AnimationStatus.decreasing:
2360
+ if (data.value <= minValue) {
2361
+ if (changeDirection) {
2362
+ data.status = AnimationStatus.increasing;
2363
+ }
2364
+ else {
2365
+ data.value += maxValue;
2366
+ }
2367
+ data.loops ??= minLoops;
2368
+ data.loops++;
2369
+ }
2370
+ break;
2990
2371
  }
2372
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
2373
+ if (!particle.destroyed) {
2374
+ data.value = clamp(data.value, minValue, maxValue);
2375
+ }
2376
+ }
2377
+
2378
+ class OpacityAnimation extends RangedAnimationOptions {
2379
+ destroy = DestroyType.none;
2991
2380
  load(data) {
2992
2381
  super.load(data);
2993
2382
  if (isNull(data)) {
2994
2383
  return;
2995
2384
  }
2996
- if (data.destroy !== undefined) {
2997
- this.destroy = data.destroy;
2998
- }
2385
+ loadProperty(this, "destroy", data.destroy);
2999
2386
  }
3000
2387
  }
3001
2388
 
3002
2389
  class Opacity extends RangedAnimationValueWithRandom {
3003
- animation;
3004
- constructor() {
3005
- super();
3006
- this.animation = new OpacityAnimation();
3007
- this.value = 1;
3008
- }
2390
+ animation = new OpacityAnimation();
2391
+ value = 1;
3009
2392
  load(data) {
3010
2393
  if (isNull(data)) {
3011
2394
  return;
@@ -3049,10 +2432,7 @@
3049
2432
  (particle.opacity.loops ?? none) < (particle.opacity.maxLoops ?? none))));
3050
2433
  }
3051
2434
  loadOptions(options, ...sources) {
3052
- options.opacity ??= new Opacity();
3053
- for (const source of sources) {
3054
- options.opacity.load(source?.opacity);
3055
- }
2435
+ loadOptionProperty(options, "opacity", Opacity, ...sources);
3056
2436
  }
3057
2437
  reset(particle) {
3058
2438
  if (!particle.opacity) {
@@ -3070,7 +2450,7 @@
3070
2450
  }
3071
2451
 
3072
2452
  async function loadOpacityUpdater(engine) {
3073
- engine.checkVersion("4.1.2");
2453
+ engine.checkVersion("4.2.0");
3074
2454
  await engine.pluginManager.register(e => {
3075
2455
  e.pluginManager.addParticleUpdater("opacity", container => {
3076
2456
  return Promise.resolve(new OpacityUpdater(container));
@@ -3078,7 +2458,7 @@
3078
2458
  });
3079
2459
  }
3080
2460
 
3081
- const minVelocity$4 = 0, boundsMin = 0;
2461
+ const boundsMin = 0;
3082
2462
  function bounceHorizontal(data) {
3083
2463
  if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
3084
2464
  (data.direction !== OutModeDirection.left && data.direction !== OutModeDirection.right)) {
@@ -3093,8 +2473,8 @@
3093
2473
  const velocity = data.particle.velocity.x;
3094
2474
  let bounced = false;
3095
2475
  if (data.outOfCanvas &&
3096
- ((data.direction === OutModeDirection.right && velocity > minVelocity$4) ||
3097
- (data.direction === OutModeDirection.left && velocity < minVelocity$4))) {
2476
+ ((data.direction === OutModeDirection.right && velocity > minVelocity) ||
2477
+ (data.direction === OutModeDirection.left && velocity < minVelocity))) {
3098
2478
  const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
3099
2479
  data.particle.velocity.x *= -newVelocity;
3100
2480
  bounced = true;
@@ -3127,8 +2507,8 @@
3127
2507
  const velocity = data.particle.velocity.y;
3128
2508
  let bounced = false;
3129
2509
  if (data.outOfCanvas &&
3130
- ((data.direction === OutModeDirection.bottom && velocity > minVelocity$4) ||
3131
- (data.direction === OutModeDirection.top && velocity < minVelocity$4))) {
2510
+ ((data.direction === OutModeDirection.bottom && velocity > minVelocity) ||
2511
+ (data.direction === OutModeDirection.top && velocity < minVelocity))) {
3132
2512
  const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
3133
2513
  data.particle.velocity.y *= -newVelocity;
3134
2514
  bounced = true;
@@ -3181,7 +2561,6 @@
3181
2561
  }
3182
2562
  }
3183
2563
 
3184
- const minVelocity$3 = 0;
3185
2564
  class DestroyOutMode {
3186
2565
  modes;
3187
2566
  constructor(_container) {
@@ -3200,10 +2579,10 @@
3200
2579
  break;
3201
2580
  case ParticleOutType.inside: {
3202
2581
  const { dx, dy } = getDistances(particle.position, particle.moveCenter), { x: vx, y: vy } = particle.velocity;
3203
- if ((vx < minVelocity$3 && dx > particle.moveCenter.radius) ||
3204
- (vy < minVelocity$3 && dy > particle.moveCenter.radius) ||
3205
- (vx >= minVelocity$3 && dx < -particle.moveCenter.radius) ||
3206
- (vy >= minVelocity$3 && dy < -particle.moveCenter.radius)) {
2582
+ if ((vx < minVelocity && dx > particle.moveCenter.radius) ||
2583
+ (vy < minVelocity && dy > particle.moveCenter.radius) ||
2584
+ (vx >= minVelocity && dx < -particle.moveCenter.radius) ||
2585
+ (vy >= minVelocity && dy < -particle.moveCenter.radius)) {
3207
2586
  return;
3208
2587
  }
3209
2588
  break;
@@ -3213,7 +2592,6 @@
3213
2592
  }
3214
2593
  }
3215
2594
 
3216
- const minVelocity$2 = 0;
3217
2595
  class NoneOutMode {
3218
2596
  modes;
3219
2597
  #container;
@@ -3233,10 +2611,10 @@
3233
2611
  }
3234
2612
  const gravityOptions = particle.options.move.gravity, container = this.#container, canvasSize = container.canvas.size, pRadius = particle.getRadius();
3235
2613
  if (!gravityOptions.enable) {
3236
- if ((particle.velocity.y > minVelocity$2 && particle.position.y <= canvasSize.height + pRadius) ||
3237
- (particle.velocity.y < minVelocity$2 && particle.position.y >= -pRadius) ||
3238
- (particle.velocity.x > minVelocity$2 && particle.position.x <= canvasSize.width + pRadius) ||
3239
- (particle.velocity.x < minVelocity$2 && particle.position.x >= -pRadius)) {
2614
+ if ((particle.velocity.y > minVelocity && particle.position.y <= canvasSize.height + pRadius) ||
2615
+ (particle.velocity.y < minVelocity && particle.position.y >= -pRadius) ||
2616
+ (particle.velocity.x > minVelocity && particle.position.x <= canvasSize.width + pRadius) ||
2617
+ (particle.velocity.x < minVelocity && particle.position.x >= -pRadius)) {
3240
2618
  return;
3241
2619
  }
3242
2620
  if (!isPointInside(particle.position, container.canvas.size, originPoint, pRadius, direction)) {
@@ -3255,7 +2633,7 @@
3255
2633
  }
3256
2634
  }
3257
2635
 
3258
- const minVelocity$1 = 0, minDistance$1 = 0, updateVector = Vector.origin;
2636
+ const updateVector = Vector.origin;
3259
2637
  class OutOutMode {
3260
2638
  modes;
3261
2639
  #container;
@@ -3276,10 +2654,10 @@
3276
2654
  updateVector.angle = particle.velocity.angle + Math.PI;
3277
2655
  updateVector.addTo(particle.moveCenter);
3278
2656
  const { dx, dy } = getDistances(particle.position, updateVector);
3279
- if ((vx <= minVelocity$1 && dx >= minDistance$1) ||
3280
- (vy <= minVelocity$1 && dy >= minDistance$1) ||
3281
- (vx >= minVelocity$1 && dx <= minDistance$1) ||
3282
- (vy >= minVelocity$1 && dy <= minDistance$1)) {
2657
+ if ((vx <= minVelocity && dx >= minDistance$1) ||
2658
+ (vy <= minVelocity && dy >= minDistance$1) ||
2659
+ (vx >= minVelocity && dx <= minDistance$1) ||
2660
+ (vy >= minVelocity && dy <= minDistance$1)) {
3283
2661
  return;
3284
2662
  }
3285
2663
  particle.position.x = Math.floor(randomInRangeValue({
@@ -3403,21 +2781,21 @@
3403
2781
  this.#updateOutMode(particle, delta, outModes.right ?? outModes.default, OutModeDirection.right);
3404
2782
  this.#updateOutMode(particle, delta, outModes.top ?? outModes.default, OutModeDirection.top);
3405
2783
  }
3406
- #addUpdaterIfMissing = (particle, outMode, getUpdater) => {
2784
+ #addUpdaterIfMissing(particle, outMode, getUpdater) {
3407
2785
  const outModes = particle.options.move.outModes;
3408
2786
  if (!this.updaters.has(outMode) && checkOutMode(outModes, outMode)) {
3409
2787
  this.updaters.set(outMode, getUpdater(this.#container));
3410
2788
  }
3411
- };
3412
- #updateOutMode = (particle, delta, outMode, direction) => {
2789
+ }
2790
+ #updateOutMode(particle, delta, outMode, direction) {
3413
2791
  for (const updater of this.updaters.values()) {
3414
2792
  updater.update(particle, direction, delta, outMode);
3415
2793
  }
3416
- };
2794
+ }
3417
2795
  }
3418
2796
 
3419
2797
  async function loadOutModesUpdater(engine) {
3420
- engine.checkVersion("4.1.2");
2798
+ engine.checkVersion("4.2.0");
3421
2799
  await engine.pluginManager.register(e => {
3422
2800
  e.pluginManager.addParticleUpdater("outModes", container => {
3423
2801
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3488,7 +2866,7 @@
3488
2866
  }
3489
2867
 
3490
2868
  async function loadPaintUpdater(engine) {
3491
- engine.checkVersion("4.1.2");
2869
+ engine.checkVersion("4.2.0");
3492
2870
  await engine.pluginManager.register(e => {
3493
2871
  e.pluginManager.addParticleUpdater("paint", container => {
3494
2872
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3543,37 +2921,26 @@
3543
2921
  }
3544
2922
 
3545
2923
  async function loadRgbColorPlugin(engine) {
3546
- engine.checkVersion("4.1.2");
2924
+ engine.checkVersion("4.2.0");
3547
2925
  await engine.pluginManager.register(e => {
3548
2926
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3549
2927
  });
3550
2928
  }
3551
2929
 
3552
2930
  class SizeAnimation extends RangedAnimationOptions {
3553
- destroy;
3554
- constructor() {
3555
- super();
3556
- this.destroy = DestroyType.none;
3557
- this.speed = 5;
3558
- }
2931
+ destroy = DestroyType.none;
3559
2932
  load(data) {
3560
2933
  super.load(data);
3561
2934
  if (isNull(data)) {
3562
2935
  return;
3563
2936
  }
3564
- if (data.destroy !== undefined) {
3565
- this.destroy = data.destroy;
3566
- }
2937
+ loadProperty(this, "destroy", data.destroy);
3567
2938
  }
3568
2939
  }
3569
2940
 
3570
2941
  class Size extends RangedAnimationValueWithRandom {
3571
- animation;
3572
- constructor() {
3573
- super();
3574
- this.animation = new SizeAnimation();
3575
- this.value = 3;
3576
- }
2942
+ animation = new SizeAnimation();
2943
+ value = 3;
3577
2944
  load(data) {
3578
2945
  super.load(data);
3579
2946
  if (isNull(data)) {
@@ -3616,10 +2983,7 @@
3616
2983
  (particle.size.loops ?? minLoops) < (particle.size.maxLoops ?? minLoops))));
3617
2984
  }
3618
2985
  loadOptions(options, ...sources) {
3619
- options.size ??= new Size();
3620
- for (const source of sources) {
3621
- options.size.load(source?.size);
3622
- }
2986
+ loadOptionProperty(options, "size", Size, ...sources);
3623
2987
  }
3624
2988
  preInit(particle) {
3625
2989
  const pxRatio = this.#container.retina.pixelRatio, options = particle.options, sizeOptions = options.size;
@@ -3642,7 +3006,7 @@
3642
3006
  }
3643
3007
 
3644
3008
  async function loadSizeUpdater(engine) {
3645
- engine.checkVersion("4.1.2");
3009
+ engine.checkVersion("4.2.0");
3646
3010
  await engine.pluginManager.register(e => {
3647
3011
  e.pluginManager.addParticleUpdater("size", container => {
3648
3012
  return Promise.resolve(new SizeUpdater(container));
@@ -3651,7 +3015,7 @@
3651
3015
  }
3652
3016
 
3653
3017
  async function loadBasic(engine) {
3654
- engine.checkVersion("4.1.2");
3018
+ engine.checkVersion("4.2.0");
3655
3019
  await engine.pluginManager.register(async (e) => {
3656
3020
  await Promise.all([
3657
3021
  loadBlendPlugin(e),
@@ -3699,22 +3063,14 @@
3699
3063
  }
3700
3064
 
3701
3065
  class ClickEvent {
3702
- enable;
3703
- mode;
3704
- constructor() {
3705
- this.enable = false;
3706
- this.mode = [];
3707
- }
3066
+ enable = false;
3067
+ mode = [];
3708
3068
  load(data) {
3709
3069
  if (isNull(data)) {
3710
3070
  return;
3711
3071
  }
3712
- if (data.enable !== undefined) {
3713
- this.enable = data.enable;
3714
- }
3715
- if (data.mode !== undefined) {
3716
- this.mode = data.mode;
3717
- }
3072
+ loadProperty(this, "enable", data.enable);
3073
+ loadProperty(this, "mode", data.mode);
3718
3074
  }
3719
3075
  }
3720
3076
 
@@ -3725,64 +3081,37 @@
3725
3081
  })(DivType || (DivType = {}));
3726
3082
 
3727
3083
  class DivEvent {
3728
- enable;
3729
- mode;
3730
- selectors;
3731
- type;
3732
- constructor() {
3733
- this.selectors = [];
3734
- this.enable = false;
3735
- this.mode = [];
3736
- this.type = DivType.circle;
3737
- }
3084
+ enable = false;
3085
+ mode = [];
3086
+ selectors = [];
3087
+ type = DivType.circle;
3738
3088
  load(data) {
3739
3089
  if (isNull(data)) {
3740
3090
  return;
3741
3091
  }
3742
- if (data.selectors !== undefined) {
3743
- this.selectors = data.selectors;
3744
- }
3745
- if (data.enable !== undefined) {
3746
- this.enable = data.enable;
3747
- }
3748
- if (data.mode !== undefined) {
3749
- this.mode = data.mode;
3750
- }
3751
- if (data.type !== undefined) {
3752
- this.type = data.type;
3753
- }
3092
+ loadProperty(this, "selectors", data.selectors);
3093
+ loadProperty(this, "enable", data.enable);
3094
+ loadProperty(this, "mode", data.mode);
3095
+ loadProperty(this, "type", data.type);
3754
3096
  }
3755
3097
  }
3756
3098
 
3757
3099
  class HoverEvent {
3758
- enable;
3759
- mode;
3760
- constructor() {
3761
- this.enable = false;
3762
- this.mode = [];
3763
- }
3100
+ enable = false;
3101
+ mode = [];
3764
3102
  load(data) {
3765
3103
  if (isNull(data)) {
3766
3104
  return;
3767
3105
  }
3768
- if (data.enable !== undefined) {
3769
- this.enable = data.enable;
3770
- }
3771
- if (data.mode !== undefined) {
3772
- this.mode = data.mode;
3773
- }
3106
+ loadProperty(this, "enable", data.enable);
3107
+ loadProperty(this, "mode", data.mode);
3774
3108
  }
3775
3109
  }
3776
3110
 
3777
3111
  class Events {
3778
- onClick;
3779
- onDiv;
3780
- onHover;
3781
- constructor() {
3782
- this.onClick = new ClickEvent();
3783
- this.onDiv = new DivEvent();
3784
- this.onHover = new HoverEvent();
3785
- }
3112
+ onClick = new ClickEvent();
3113
+ onDiv = new DivEvent();
3114
+ onHover = new HoverEvent();
3786
3115
  load(data) {
3787
3116
  if (isNull(data)) {
3788
3117
  return;
@@ -3835,12 +3164,10 @@
3835
3164
  }
3836
3165
 
3837
3166
  class Interactivity {
3838
- detectsOn;
3839
- events;
3167
+ detectsOn = InteractivityDetect.window;
3168
+ events = new Events();
3840
3169
  modes;
3841
3170
  constructor(pluginManager, container) {
3842
- this.detectsOn = InteractivityDetect.window;
3843
- this.events = new Events();
3844
3171
  this.modes = new Modes(pluginManager, container);
3845
3172
  }
3846
3173
  load(data) {
@@ -3919,7 +3246,7 @@
3919
3246
  const clickEvent = "click", mouseDownEvent = "pointerdown", mouseUpEvent = "pointerup", mouseLeaveEvent = "pointerleave", mouseMoveEvent = "pointermove", touchStartEvent = "touchstart", touchEndEvent = "touchend", touchMoveEvent = "touchmove", touchCancelEvent = "touchcancel";
3920
3247
 
3921
3248
  async function loadInteractivityPlugin(engine) {
3922
- engine.checkVersion("4.1.2");
3249
+ engine.checkVersion("4.2.0");
3923
3250
  await engine.pluginManager.register(e => {
3924
3251
  const interactivityEngine = e, interactivityPluginManager = interactivityEngine.pluginManager;
3925
3252
  interactivityPluginManager.addPlugin(new InteractivityPlugin(interactivityPluginManager));
@@ -3953,52 +3280,26 @@
3953
3280
  }
3954
3281
 
3955
3282
  class Cannon {
3956
- drawVector;
3957
- maxDragDistance;
3958
- maxParticles;
3959
- minParticles;
3960
- particleFactor;
3961
- spread;
3962
- vectorColor;
3963
- velocityFactor;
3964
- constructor() {
3965
- this.spread = 30;
3966
- this.velocityFactor = 0.5;
3967
- this.particleFactor = 0.2;
3968
- this.maxDragDistance = 0;
3969
- this.minParticles = 5;
3970
- this.maxParticles = 200;
3971
- this.drawVector = true;
3972
- this.vectorColor = "#ffffff80";
3973
- }
3283
+ drawVector = true;
3284
+ maxDragDistance = 0;
3285
+ maxParticles = 200;
3286
+ minParticles = 5;
3287
+ particleFactor = 0.2;
3288
+ spread = 30;
3289
+ vectorColor = "#ffffff80";
3290
+ velocityFactor = 0.5;
3974
3291
  load(data) {
3975
3292
  if (!data) {
3976
3293
  return;
3977
3294
  }
3978
- if (data.spread !== undefined) {
3979
- this.spread = data.spread;
3980
- }
3981
- if (data.velocityFactor !== undefined) {
3982
- this.velocityFactor = data.velocityFactor;
3983
- }
3984
- if (data.particleFactor !== undefined) {
3985
- this.particleFactor = data.particleFactor;
3986
- }
3987
- if (data.minParticles !== undefined) {
3988
- this.minParticles = data.minParticles;
3989
- }
3990
- if (data.maxParticles !== undefined) {
3991
- this.maxParticles = data.maxParticles;
3992
- }
3993
- if (data.maxDragDistance !== undefined) {
3994
- this.maxDragDistance = data.maxDragDistance;
3995
- }
3996
- if (data.drawVector !== undefined) {
3997
- this.drawVector = data.drawVector;
3998
- }
3999
- if (data.vectorColor !== undefined) {
4000
- this.vectorColor = data.vectorColor;
4001
- }
3295
+ loadProperty(this, "spread", data.spread);
3296
+ loadProperty(this, "velocityFactor", data.velocityFactor);
3297
+ loadProperty(this, "particleFactor", data.particleFactor);
3298
+ loadProperty(this, "minParticles", data.minParticles);
3299
+ loadProperty(this, "maxParticles", data.maxParticles);
3300
+ loadProperty(this, "maxDragDistance", data.maxDragDistance);
3301
+ loadProperty(this, "drawVector", data.drawVector);
3302
+ loadProperty(this, "vectorColor", data.vectorColor);
4002
3303
  }
4003
3304
  }
4004
3305
 
@@ -4008,7 +3309,7 @@
4008
3309
  CannonState[CannonState["aiming"] = 1] = "aiming";
4009
3310
  CannonState[CannonState["fired"] = 2] = "fired";
4010
3311
  })(CannonState || (CannonState = {}));
4011
- const cannonMode = "cannon", minAngle = 0, powerRadiusMin = 4, powerRadiusMaxDenominator = 20, powerRadiusMaxFactor = identity$3 / powerRadiusMaxDenominator, minTapsLength = 2, piDeg = 180, quarter = 0.25, minDistance = 0;
3312
+ const cannonMode = "cannon", minAngle = 0, powerRadiusMin = 4, powerRadiusMaxDenominator = 20, powerRadiusMaxFactor = identity$2 / powerRadiusMaxDenominator, minTapsLength = 2, piDeg = 180, quarter = 0.25, minDistance = 0;
4012
3313
  function angleRad(x0, y0, x1, y1) {
4013
3314
  return Math.atan2(y1 - y0, x1 - x0);
4014
3315
  }
@@ -4073,10 +3374,7 @@
4073
3374
  return this.#state !== CannonState.idle || interactivityData.mouse.clicking;
4074
3375
  }
4075
3376
  loadModeOptions(options, ...sources) {
4076
- options.cannon ??= new Cannon();
4077
- for (const source of sources) {
4078
- options.cannon.load(source?.cannon);
4079
- }
3377
+ loadOptionProperty(options, "cannon", Cannon, ...sources);
4080
3378
  }
4081
3379
  reset(_interactivityData, _particle) {
4082
3380
  }
@@ -4112,7 +3410,7 @@
4112
3410
  if (dragLength < minTapsLength) {
4113
3411
  return;
4114
3412
  }
4115
- const pxRatioFactor = identity$3 / pxRatio, launchAngle = angleRad(current.x, current.y, origin.x, origin.y), velocity = dragLength * pxRatioFactor * opts.velocityFactor, count = Math.min(opts.maxParticles, Math.max(opts.minParticles, Math.round(dragLength * opts.particleFactor))), toDeg = piDeg / Math.PI;
3413
+ const pxRatioFactor = identity$2 / pxRatio, launchAngle = angleRad(current.x, current.y, origin.x, origin.y), velocity = dragLength * pxRatioFactor * opts.velocityFactor, count = Math.min(opts.maxParticles, Math.max(opts.minParticles, Math.round(dragLength * opts.particleFactor))), toDeg = piDeg / Math.PI;
4116
3414
  for (let i = 0; i < count; i++) {
4117
3415
  const spreadAngle = launchAngle + getRandomInRange(-opts.spread, opts.spread), speed = getRandomInRange(velocity * quarter, velocity);
4118
3416
  this.container.particles.addParticle(origin, {
@@ -4127,7 +3425,7 @@
4127
3425
  }
4128
3426
 
4129
3427
  async function loadExternalCannonInteraction(engine) {
4130
- engine.checkVersion("4.1.2");
3428
+ engine.checkVersion("4.2.0");
4131
3429
  await engine.pluginManager.register((e) => {
4132
3430
  ensureInteractivityPluginLoaded(e);
4133
3431
  e.pluginManager.addInteractor?.("externalCannon", container => {
@@ -4137,55 +3435,36 @@
4137
3435
  }
4138
3436
 
4139
3437
  class LifeDelay extends ValueWithRandom {
4140
- sync;
4141
- constructor() {
4142
- super();
4143
- this.sync = false;
4144
- }
3438
+ sync = false;
4145
3439
  load(data) {
4146
3440
  if (isNull(data)) {
4147
3441
  return;
4148
3442
  }
4149
3443
  super.load(data);
4150
- if (data.sync !== undefined) {
4151
- this.sync = data.sync;
4152
- }
3444
+ loadProperty(this, "sync", data.sync);
4153
3445
  }
4154
3446
  }
4155
3447
 
4156
3448
  class LifeDuration extends ValueWithRandom {
4157
- sync;
4158
- constructor() {
4159
- super();
4160
- this.sync = false;
4161
- }
3449
+ sync = false;
4162
3450
  load(data) {
4163
3451
  if (isNull(data)) {
4164
3452
  return;
4165
3453
  }
4166
3454
  super.load(data);
4167
- if (data.sync !== undefined) {
4168
- this.sync = data.sync;
4169
- }
3455
+ loadProperty(this, "sync", data.sync);
4170
3456
  }
4171
3457
  }
4172
3458
 
4173
3459
  class Life {
4174
- count;
4175
- delay;
4176
- duration;
4177
- constructor() {
4178
- this.count = 0;
4179
- this.delay = new LifeDelay();
4180
- this.duration = new LifeDuration();
4181
- }
3460
+ count = 0;
3461
+ delay = new LifeDelay();
3462
+ duration = new LifeDuration();
4182
3463
  load(data) {
4183
3464
  if (isNull(data)) {
4184
3465
  return;
4185
3466
  }
4186
- if (data.count !== undefined) {
4187
- this.count = data.count;
4188
- }
3467
+ loadProperty(this, "count", data.count);
4189
3468
  this.delay.load(data.delay);
4190
3469
  this.duration.load(data.duration);
4191
3470
  }
@@ -4244,7 +3523,7 @@
4244
3523
  }
4245
3524
  }
4246
3525
 
4247
- const noTime = 0, identity$2 = 1, infiniteValue = -1;
3526
+ const noTime = 0, identity$1 = 1, infiniteValue = -1;
4248
3527
  class LifeUpdater {
4249
3528
  #container;
4250
3529
  constructor(container) {
@@ -4255,7 +3534,7 @@
4255
3534
  if (!lifeOptions) {
4256
3535
  return;
4257
3536
  }
4258
- const delayFactor = lifeOptions.delay.sync ? identity$2 : getRandom(), durationFactor = lifeOptions.duration.sync ? identity$2 : getRandom();
3537
+ const delayFactor = lifeOptions.delay.sync ? identity$1 : getRandom(), durationFactor = lifeOptions.duration.sync ? identity$1 : getRandom();
4259
3538
  particle.life = {
4260
3539
  delay: container.retina.reduceFactor
4261
3540
  ? ((getRangeValue(lifeOptions.delay.value) * delayFactor) / container.retina.reduceFactor) *
@@ -4281,10 +3560,7 @@
4281
3560
  return !particle.destroyed;
4282
3561
  }
4283
3562
  loadOptions(options, ...sources) {
4284
- options.life ??= new Life();
4285
- for (const source of sources) {
4286
- options.life.load(source?.life);
4287
- }
3563
+ loadOptionProperty(options, "life", Life, ...sources);
4288
3564
  }
4289
3565
  update(particle, delta) {
4290
3566
  if (!this.isEnabled(particle) || !particle.life) {
@@ -4295,7 +3571,7 @@
4295
3571
  }
4296
3572
 
4297
3573
  async function loadLifeUpdater(engine) {
4298
- engine.checkVersion("4.1.2");
3574
+ engine.checkVersion("4.2.0");
4299
3575
  await engine.pluginManager.register(e => {
4300
3576
  e.pluginManager.addParticleUpdater("life", container => {
4301
3577
  return Promise.resolve(new LifeUpdater(container));
@@ -4304,39 +3580,25 @@
4304
3580
  }
4305
3581
 
4306
3582
  class MotionReduce {
4307
- factor;
4308
- value;
4309
- constructor() {
4310
- this.factor = 4;
4311
- this.value = true;
4312
- }
3583
+ factor = 4;
3584
+ value = true;
4313
3585
  load(data) {
4314
3586
  if (isNull(data)) {
4315
3587
  return;
4316
3588
  }
4317
- if (data.factor !== undefined) {
4318
- this.factor = data.factor;
4319
- }
4320
- if (data.value !== undefined) {
4321
- this.value = data.value;
4322
- }
3589
+ loadProperty(this, "factor", data.factor);
3590
+ loadProperty(this, "value", data.value);
4323
3591
  }
4324
3592
  }
4325
3593
 
4326
3594
  class Motion {
4327
- disable;
4328
- reduce;
4329
- constructor() {
4330
- this.disable = true;
4331
- this.reduce = new MotionReduce();
4332
- }
3595
+ disable = true;
3596
+ reduce = new MotionReduce();
4333
3597
  load(data) {
4334
3598
  if (isNull(data)) {
4335
3599
  return;
4336
3600
  }
4337
- if (data.disable !== undefined) {
4338
- this.disable = data.disable;
4339
- }
3601
+ loadProperty(this, "disable", data.disable);
4340
3602
  this.reduce.load(data.reduce);
4341
3603
  }
4342
3604
  }
@@ -4363,7 +3625,7 @@
4363
3625
  }
4364
3626
 
4365
3627
  async function loadMotionPlugin(engine) {
4366
- engine.checkVersion("4.1.2");
3628
+ engine.checkVersion("4.2.0");
4367
3629
  await engine.pluginManager.register(e => {
4368
3630
  e.pluginManager.addPlugin(new MotionPlugin());
4369
3631
  });
@@ -4432,39 +3694,24 @@
4432
3694
  }
4433
3695
 
4434
3696
  class RollLight {
4435
- enable;
4436
- value;
4437
- constructor() {
4438
- this.enable = false;
4439
- this.value = 0;
4440
- }
3697
+ enable = false;
3698
+ value = 0;
4441
3699
  load(data) {
4442
3700
  if (isNull(data)) {
4443
3701
  return;
4444
3702
  }
4445
- if (data.enable !== undefined) {
4446
- this.enable = data.enable;
4447
- }
4448
- if (data.value !== undefined) {
4449
- this.value = setRangeValue(data.value);
4450
- }
3703
+ loadProperty(this, "enable", data.enable);
3704
+ loadRangeProperty(this, "value", data.value);
4451
3705
  }
4452
3706
  }
4453
3707
 
4454
3708
  class Roll {
4455
3709
  backColor;
4456
- darken;
4457
- enable;
4458
- enlighten;
4459
- mode;
4460
- speed;
4461
- constructor() {
4462
- this.darken = new RollLight();
4463
- this.enable = false;
4464
- this.enlighten = new RollLight();
4465
- this.mode = RollMode.vertical;
4466
- this.speed = 25;
4467
- }
3710
+ darken = new RollLight();
3711
+ enable = false;
3712
+ enlighten = new RollLight();
3713
+ mode = RollMode.vertical;
3714
+ speed = 25;
4468
3715
  load(data) {
4469
3716
  if (isNull(data)) {
4470
3717
  return;
@@ -4473,16 +3720,10 @@
4473
3720
  this.backColor = OptionsColor.create(this.backColor, data.backColor);
4474
3721
  }
4475
3722
  this.darken.load(data.darken);
4476
- if (data.enable !== undefined) {
4477
- this.enable = data.enable;
4478
- }
3723
+ loadProperty(this, "enable", data.enable);
4479
3724
  this.enlighten.load(data.enlighten);
4480
- if (data.mode !== undefined) {
4481
- this.mode = data.mode;
4482
- }
4483
- if (data.speed !== undefined) {
4484
- this.speed = setRangeValue(data.speed);
4485
- }
3725
+ loadProperty(this, "mode", data.mode);
3726
+ loadRangeProperty(this, "speed", data.speed);
4486
3727
  }
4487
3728
  }
4488
3729
 
@@ -4506,10 +3747,7 @@
4506
3747
  return !particle.destroyed && !particle.spawning && !!roll?.enable;
4507
3748
  }
4508
3749
  loadOptions(options, ...sources) {
4509
- options.roll ??= new Roll();
4510
- for (const source of sources) {
4511
- options.roll.load(source?.roll);
4512
- }
3750
+ loadOptionProperty(options, "roll", Roll, ...sources);
4513
3751
  }
4514
3752
  update(particle, delta) {
4515
3753
  if (!this.isEnabled(particle)) {
@@ -4520,7 +3758,7 @@
4520
3758
  }
4521
3759
 
4522
3760
  async function loadRollUpdater(engine) {
4523
- engine.checkVersion("4.1.2");
3761
+ engine.checkVersion("4.2.0");
4524
3762
  await engine.pluginManager.register(e => {
4525
3763
  e.pluginManager.addParticleUpdater("roll", () => {
4526
3764
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -4529,58 +3767,33 @@
4529
3767
  }
4530
3768
 
4531
3769
  class RotateAnimation {
4532
- decay;
4533
- enable;
4534
- speed;
4535
- sync;
4536
- constructor() {
4537
- this.enable = false;
4538
- this.speed = 0;
4539
- this.decay = 0;
4540
- this.sync = false;
4541
- }
3770
+ decay = 0;
3771
+ enable = false;
3772
+ speed = 0;
3773
+ sync = false;
4542
3774
  load(data) {
4543
3775
  if (isNull(data)) {
4544
3776
  return;
4545
3777
  }
4546
- if (data.enable !== undefined) {
4547
- this.enable = data.enable;
4548
- }
4549
- if (data.speed !== undefined) {
4550
- this.speed = setRangeValue(data.speed);
4551
- }
4552
- if (data.decay !== undefined) {
4553
- this.decay = setRangeValue(data.decay);
4554
- }
4555
- if (data.sync !== undefined) {
4556
- this.sync = data.sync;
4557
- }
3778
+ loadProperty(this, "enable", data.enable);
3779
+ loadRangeProperty(this, "speed", data.speed);
3780
+ loadRangeProperty(this, "decay", data.decay);
3781
+ loadProperty(this, "sync", data.sync);
4558
3782
  }
4559
3783
  }
4560
3784
 
4561
3785
  class Rotate extends ValueWithRandom {
4562
- animation;
4563
- direction;
4564
- path;
4565
- constructor() {
4566
- super();
4567
- this.animation = new RotateAnimation();
4568
- this.direction = RotateDirection.clockwise;
4569
- this.path = false;
4570
- this.value = 0;
4571
- }
3786
+ animation = new RotateAnimation();
3787
+ direction = RotateDirection.clockwise;
3788
+ path = false;
4572
3789
  load(data) {
4573
3790
  if (isNull(data)) {
4574
3791
  return;
4575
3792
  }
4576
3793
  super.load(data);
4577
- if (data.direction !== undefined) {
4578
- this.direction = data.direction;
4579
- }
3794
+ loadProperty(this, "direction", data.direction);
4580
3795
  this.animation.load(data.animation);
4581
- if (data.path !== undefined) {
4582
- this.path = data.path;
4583
- }
3796
+ loadProperty(this, "path", data.path);
4584
3797
  }
4585
3798
  }
4586
3799
 
@@ -4618,7 +3831,7 @@
4618
3831
  }
4619
3832
  const rotateAnimation = rotateOptions.animation;
4620
3833
  if (rotateAnimation.enable) {
4621
- particle.rotate.decay = identity$3 - getRangeValue(rotateAnimation.decay);
3834
+ particle.rotate.decay = identity$2 - getRangeValue(rotateAnimation.decay);
4622
3835
  particle.rotate.velocity =
4623
3836
  (getRangeValue(rotateAnimation.speed) / doublePIDeg) * this.#container.retina.reduceFactor;
4624
3837
  if (!rotateAnimation.sync) {
@@ -4635,10 +3848,7 @@
4635
3848
  return !particle.destroyed && !particle.spawning && (!!rotate.value || rotate.animation.enable || rotate.path);
4636
3849
  }
4637
3850
  loadOptions(options, ...sources) {
4638
- options.rotate ??= new Rotate();
4639
- for (const source of sources) {
4640
- options.rotate.load(source?.rotate);
4641
- }
3851
+ loadOptionProperty(options, "rotate", Rotate, ...sources);
4642
3852
  }
4643
3853
  update(particle, delta) {
4644
3854
  if (!this.isEnabled(particle)) {
@@ -4654,7 +3864,7 @@
4654
3864
  }
4655
3865
 
4656
3866
  async function loadRotateUpdater(engine) {
4657
- engine.checkVersion("4.1.2");
3867
+ engine.checkVersion("4.2.0");
4658
3868
  await engine.pluginManager.register(e => {
4659
3869
  e.pluginManager.addParticleUpdater("rotate", container => {
4660
3870
  return Promise.resolve(new RotateUpdater(container));
@@ -4678,7 +3888,7 @@
4678
3888
  }
4679
3889
 
4680
3890
  async function loadSquareShape(engine) {
4681
- engine.checkVersion("4.1.2");
3891
+ engine.checkVersion("4.2.0");
4682
3892
  await engine.pluginManager.register(e => {
4683
3893
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
4684
3894
  });
@@ -4692,58 +3902,33 @@
4692
3902
  })(TiltDirection || (TiltDirection = {}));
4693
3903
 
4694
3904
  class TiltAnimation {
4695
- decay;
4696
- enable;
4697
- speed;
4698
- sync;
4699
- constructor() {
4700
- this.enable = false;
4701
- this.speed = 0;
4702
- this.decay = 0;
4703
- this.sync = false;
4704
- }
3905
+ decay = 0;
3906
+ enable = false;
3907
+ speed = 0;
3908
+ sync = false;
4705
3909
  load(data) {
4706
3910
  if (isNull(data)) {
4707
3911
  return;
4708
3912
  }
4709
- if (data.enable !== undefined) {
4710
- this.enable = data.enable;
4711
- }
4712
- if (data.speed !== undefined) {
4713
- this.speed = setRangeValue(data.speed);
4714
- }
4715
- if (data.decay !== undefined) {
4716
- this.decay = setRangeValue(data.decay);
4717
- }
4718
- if (data.sync !== undefined) {
4719
- this.sync = data.sync;
4720
- }
4721
- }
4722
- }
4723
-
4724
- class Tilt extends ValueWithRandom {
4725
- animation;
4726
- direction;
4727
- enable;
4728
- constructor() {
4729
- super();
4730
- this.animation = new TiltAnimation();
4731
- this.direction = TiltDirection.clockwise;
4732
- this.enable = false;
4733
- this.value = 0;
3913
+ loadProperty(this, "enable", data.enable);
3914
+ loadRangeProperty(this, "speed", data.speed);
3915
+ loadRangeProperty(this, "decay", data.decay);
3916
+ loadProperty(this, "sync", data.sync);
4734
3917
  }
3918
+ }
3919
+
3920
+ class Tilt extends ValueWithRandom {
3921
+ animation = new TiltAnimation();
3922
+ direction = TiltDirection.clockwise;
3923
+ enable = false;
4735
3924
  load(data) {
4736
3925
  super.load(data);
4737
3926
  if (isNull(data)) {
4738
3927
  return;
4739
3928
  }
4740
3929
  this.animation.load(data.animation);
4741
- if (data.direction !== undefined) {
4742
- this.direction = data.direction;
4743
- }
4744
- if (data.enable !== undefined) {
4745
- this.enable = data.enable;
4746
- }
3930
+ loadProperty(this, "direction", data.direction);
3931
+ loadProperty(this, "enable", data.enable);
4747
3932
  }
4748
3933
  }
4749
3934
 
@@ -4768,8 +3953,8 @@
4768
3953
  particle.tilt = {
4769
3954
  enable: tiltOptions.enable,
4770
3955
  value: degToRad(getRangeValue(tiltOptions.value)),
4771
- sinDirection: getRandom() >= half ? identity$3 : -identity$3,
4772
- cosDirection: getRandom() >= half ? identity$3 : -identity$3,
3956
+ sinDirection: getRandom() >= half ? identity$2 : -identity$2,
3957
+ cosDirection: getRandom() >= half ? identity$2 : -identity$2,
4773
3958
  min: 0,
4774
3959
  max: doublePI,
4775
3960
  };
@@ -4789,7 +3974,7 @@
4789
3974
  }
4790
3975
  const tiltAnimation = particle.options.tilt?.animation;
4791
3976
  if (tiltAnimation?.enable) {
4792
- particle.tilt.decay = identity$3 - getRangeValue(tiltAnimation.decay);
3977
+ particle.tilt.decay = identity$2 - getRangeValue(tiltAnimation.decay);
4793
3978
  particle.tilt.velocity = (getRangeValue(tiltAnimation.speed) / maxAngle$1) * this.#container.retina.reduceFactor;
4794
3979
  if (!tiltAnimation.sync) {
4795
3980
  particle.tilt.velocity *= getRandom();
@@ -4801,10 +3986,7 @@
4801
3986
  return !particle.destroyed && !particle.spawning && !!tiltAnimation?.enable;
4802
3987
  }
4803
3988
  loadOptions(options, ...sources) {
4804
- options.tilt ??= new Tilt();
4805
- for (const source of sources) {
4806
- options.tilt.load(source?.tilt);
4807
- }
3989
+ loadOptionProperty(options, "tilt", Tilt, ...sources);
4808
3990
  }
4809
3991
  update(particle, delta) {
4810
3992
  if (!this.isEnabled(particle) || !particle.tilt) {
@@ -4815,7 +3997,7 @@
4815
3997
  }
4816
3998
 
4817
3999
  async function loadTiltUpdater(engine) {
4818
- engine.checkVersion("4.1.2");
4000
+ engine.checkVersion("4.2.0");
4819
4001
  await engine.pluginManager.register(e => {
4820
4002
  e.pluginManager.addParticleUpdater("tilt", container => {
4821
4003
  return Promise.resolve(new TiltUpdater(container));
@@ -4824,44 +4006,27 @@
4824
4006
  }
4825
4007
 
4826
4008
  class WobbleSpeed {
4827
- angle;
4828
- move;
4829
- constructor() {
4830
- this.angle = 50;
4831
- this.move = 10;
4832
- }
4009
+ angle = 50;
4010
+ move = 10;
4833
4011
  load(data) {
4834
4012
  if (isNull(data)) {
4835
4013
  return;
4836
4014
  }
4837
- if (data.angle !== undefined) {
4838
- this.angle = setRangeValue(data.angle);
4839
- }
4840
- if (data.move !== undefined) {
4841
- this.move = setRangeValue(data.move);
4842
- }
4015
+ loadRangeProperty(this, "angle", data.angle);
4016
+ loadRangeProperty(this, "move", data.move);
4843
4017
  }
4844
4018
  }
4845
4019
 
4846
4020
  class Wobble {
4847
- distance;
4848
- enable;
4849
- speed;
4850
- constructor() {
4851
- this.distance = 5;
4852
- this.enable = false;
4853
- this.speed = new WobbleSpeed();
4854
- }
4021
+ distance = 5;
4022
+ enable = false;
4023
+ speed = new WobbleSpeed();
4855
4024
  load(data) {
4856
4025
  if (isNull(data)) {
4857
4026
  return;
4858
4027
  }
4859
- if (data.distance !== undefined) {
4860
- this.distance = setRangeValue(data.distance);
4861
- }
4862
- if (data.enable !== undefined) {
4863
- this.enable = data.enable;
4864
- }
4028
+ loadRangeProperty(this, "distance", data.distance);
4029
+ loadProperty(this, "enable", data.enable);
4865
4030
  if (data.speed !== undefined) {
4866
4031
  if (isNumber(data.speed)) {
4867
4032
  this.speed.load({ angle: data.speed });
@@ -4923,10 +4088,7 @@
4923
4088
  return !particle.destroyed && !particle.spawning && !!particle.options.wobble?.enable;
4924
4089
  }
4925
4090
  loadOptions(options, ...sources) {
4926
- options.wobble ??= new Wobble();
4927
- for (const source of sources) {
4928
- options.wobble.load(source?.wobble);
4929
- }
4091
+ loadOptionProperty(options, "wobble", Wobble, ...sources);
4930
4092
  }
4931
4093
  update(particle, delta) {
4932
4094
  if (!this.isEnabled(particle)) {
@@ -4937,7 +4099,7 @@
4937
4099
  }
4938
4100
 
4939
4101
  async function loadWobbleUpdater(engine) {
4940
- engine.checkVersion("4.1.2");
4102
+ engine.checkVersion("4.2.0");
4941
4103
  await engine.pluginManager.register(e => {
4942
4104
  e.pluginManager.addParticleUpdater("wobble", container => {
4943
4105
  return Promise.resolve(new WobbleUpdater(container));
@@ -5138,7 +4300,7 @@
5138
4300
  return;
5139
4301
  }
5140
4302
  this.draw(ctx => {
5141
- clear(ctx, this.#canvasManager.size);
4303
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
5142
4304
  });
5143
4305
  }
5144
4306
  clear() {
@@ -5200,7 +4362,7 @@
5200
4362
  plugin.drawParticleSetup?.(context, particle, delta);
5201
4363
  }
5202
4364
  this.#applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
5203
- drawParticle({
4365
+ this.#drawParticle({
5204
4366
  container,
5205
4367
  context,
5206
4368
  particle,
@@ -5219,7 +4381,7 @@
5219
4381
  drawParticlePlugins(particle, delta) {
5220
4382
  this.draw(ctx => {
5221
4383
  for (const plugin of this.#drawParticlePlugins) {
5222
- drawParticlePlugin(ctx, plugin, particle, delta);
4384
+ this.#drawParticlePlugin(ctx, plugin, particle, delta);
5223
4385
  }
5224
4386
  });
5225
4387
  }
@@ -5319,12 +4481,19 @@
5319
4481
  }
5320
4482
  paintBase(baseColor) {
5321
4483
  this.draw(ctx => {
5322
- paintBase(ctx, this.#canvasManager.size, baseColor);
4484
+ ctx.fillStyle = baseColor ?? "rgba(0,0,0,0)";
4485
+ ctx.fillRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
5323
4486
  });
5324
4487
  }
5325
4488
  paintImage(image, opacity) {
5326
4489
  this.draw(ctx => {
5327
- paintImage(ctx, this.#canvasManager.size, image, opacity);
4490
+ if (!image) {
4491
+ return;
4492
+ }
4493
+ const prevAlpha = ctx.globalAlpha;
4494
+ ctx.globalAlpha = opacity;
4495
+ ctx.drawImage(image, originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4496
+ ctx.globalAlpha = prevAlpha;
5328
4497
  });
5329
4498
  }
5330
4499
  setContext(context) {
@@ -5338,15 +4507,15 @@
5338
4507
  }
5339
4508
  stop() {
5340
4509
  this.draw(ctx => {
5341
- clear(ctx, this.#canvasManager.size);
4510
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
5342
4511
  });
5343
4512
  }
5344
- #applyPostDrawUpdaters = particle => {
4513
+ #applyPostDrawUpdaters(particle) {
5345
4514
  for (const updater of this.#postDrawUpdaters) {
5346
4515
  updater.afterDraw?.(particle);
5347
4516
  }
5348
- };
5349
- #applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
4517
+ }
4518
+ #applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
5350
4519
  for (const updater of this.#preDrawUpdaters) {
5351
4520
  if (updater.getColorStyles) {
5352
4521
  const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
@@ -5365,8 +4534,114 @@
5365
4534
  }
5366
4535
  updater.beforeDraw?.(particle);
5367
4536
  }
5368
- };
5369
- #getPluginParticleColors = particle => {
4537
+ }
4538
+ #drawAfterEffect(drawer, data) {
4539
+ if (!drawer?.drawAfter) {
4540
+ return;
4541
+ }
4542
+ const { particle } = data;
4543
+ if (!particle.effect) {
4544
+ return;
4545
+ }
4546
+ drawer.drawAfter(data);
4547
+ }
4548
+ #drawBeforeEffect(drawer, data) {
4549
+ if (!drawer?.drawBefore) {
4550
+ return;
4551
+ }
4552
+ const { particle } = data;
4553
+ if (!particle.effect) {
4554
+ return;
4555
+ }
4556
+ drawer.drawBefore(data);
4557
+ }
4558
+ #drawParticle(data) {
4559
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
4560
+ x: pos.x,
4561
+ y: pos.y,
4562
+ };
4563
+ context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
4564
+ if (colorStyles.fill) {
4565
+ context.fillStyle = colorStyles.fill;
4566
+ }
4567
+ const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
4568
+ context.lineWidth = strokeWidth;
4569
+ if (colorStyles.stroke) {
4570
+ context.strokeStyle = colorStyles.stroke;
4571
+ }
4572
+ const drawData = {
4573
+ context,
4574
+ particle,
4575
+ radius,
4576
+ drawRadius: radius * drawScale,
4577
+ opacity,
4578
+ delta,
4579
+ pixelRatio: container.retina.pixelRatio,
4580
+ fill: fillEnabled,
4581
+ stroke: strokeWidth > minStrokeWidth,
4582
+ transformData,
4583
+ position: { ...pos },
4584
+ drawPosition,
4585
+ drawScale,
4586
+ };
4587
+ for (const plugin of container.plugins) {
4588
+ plugin.drawParticleTransform?.(drawData);
4589
+ }
4590
+ const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
4591
+ this.#drawBeforeEffect(effect, drawData);
4592
+ this.#drawShapeBeforeDraw(shape, drawData);
4593
+ this.#drawShape(shape, drawData);
4594
+ this.#drawShapeAfterDraw(shape, drawData);
4595
+ this.#drawAfterEffect(effect, drawData);
4596
+ context.resetTransform();
4597
+ }
4598
+ #drawParticlePlugin(context, plugin, particle, delta) {
4599
+ if (!plugin.drawParticle) {
4600
+ return;
4601
+ }
4602
+ plugin.drawParticle(context, particle, delta);
4603
+ }
4604
+ #drawShape(drawer, data) {
4605
+ if (!drawer) {
4606
+ return;
4607
+ }
4608
+ const { context, fill, particle, stroke } = data;
4609
+ if (!particle.shape) {
4610
+ return;
4611
+ }
4612
+ context.beginPath();
4613
+ drawer.draw(data);
4614
+ if (particle.shapeClose) {
4615
+ context.closePath();
4616
+ }
4617
+ if (fill) {
4618
+ context.fill();
4619
+ }
4620
+ if (stroke) {
4621
+ context.stroke();
4622
+ }
4623
+ }
4624
+ #drawShapeAfterDraw(drawer, data) {
4625
+ if (!drawer?.afterDraw) {
4626
+ return;
4627
+ }
4628
+ const { particle } = data;
4629
+ if (!particle.shape) {
4630
+ return;
4631
+ }
4632
+ drawer.afterDraw(data);
4633
+ }
4634
+ #drawShapeBeforeDraw(drawer, data) {
4635
+ if (!drawer?.beforeDraw) {
4636
+ return;
4637
+ }
4638
+ const { particle } = data;
4639
+ if (!particle.shape) {
4640
+ return;
4641
+ }
4642
+ drawer.beforeDraw(data);
4643
+ }
4644
+ #getPluginParticleColors(particle) {
5370
4645
  let fColor, sColor;
5371
4646
  for (const plugin of this.#colorPlugins) {
5372
4647
  if (!fColor && plugin.particleFillColor) {
@@ -5382,7 +4657,7 @@
5382
4657
  this.#reusablePluginColors[fColorIndex] = fColor;
5383
4658
  this.#reusablePluginColors[sColorIndex] = sColor;
5384
4659
  return this.#reusablePluginColors;
5385
- };
4660
+ }
5386
4661
  }
5387
4662
 
5388
4663
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -5514,6 +4789,7 @@
5514
4789
  obs.observe(element, { attributes: true });
5515
4790
  });
5516
4791
  this.initPlugins();
4792
+ this.#initContext();
5517
4793
  this.render.init();
5518
4794
  }
5519
4795
  initBackground() {
@@ -5523,7 +4799,7 @@
5523
4799
  }
5524
4800
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
5525
4801
  if (color) {
5526
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity);
4802
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
5527
4803
  }
5528
4804
  else {
5529
4805
  elementStyle.backgroundColor = "";
@@ -5545,7 +4821,7 @@
5545
4821
  if (this.#generated && this.domElement) {
5546
4822
  this.domElement.remove();
5547
4823
  }
5548
- const container = this.#container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4824
+ const domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
5549
4825
  this.domElement = domCanvas;
5550
4826
  this.#generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
5551
4827
  this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
@@ -5566,26 +4842,6 @@
5566
4842
  const pxRatio = this.#container.retina.pixelRatio, retinaSize = this.size;
5567
4843
  renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
5568
4844
  renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
5569
- const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
5570
- this.render.setContextSettings({
5571
- alpha: true,
5572
- colorSpace: canSupportHdrQuery?.matches && container.hdr ? "display-p3" : "srgb",
5573
- desynchronized: true,
5574
- willReadFrequently: false,
5575
- });
5576
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
5577
- this.#safeMutationObserver(obs => {
5578
- obs.disconnect();
5579
- });
5580
- container.retina.init();
5581
- this.initBackground();
5582
- this.#safeMutationObserver(obs => {
5583
- const element = this.domElement;
5584
- if (!element || !(element instanceof Node)) {
5585
- return;
5586
- }
5587
- obs.observe(element, { attributes: true });
5588
- });
5589
4845
  }
5590
4846
  resize() {
5591
4847
  const element = this.domElement;
@@ -5653,12 +4909,30 @@
5653
4909
  await container.refresh();
5654
4910
  }
5655
4911
  }
5656
- #applyResizePlugins = () => {
4912
+ #applyResizePlugins() {
5657
4913
  for (const plugin of this.#resizePlugins) {
5658
4914
  plugin.resize?.();
5659
4915
  }
5660
- };
5661
- #initStyle = () => {
4916
+ }
4917
+ #initContext() {
4918
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4919
+ safeMatchMedia("(color-gamut: p3)")?.matches &&
4920
+ safeMatchMedia("(dynamic-range: high)")?.matches;
4921
+ this.render.setContextSettings({
4922
+ alpha: true,
4923
+ desynchronized: true,
4924
+ willReadFrequently: false,
4925
+ ...(canSupportHdr
4926
+ ? { colorSpace: "display-p3", colorType: "float16" }
4927
+ : { colorSpace: "srgb" }),
4928
+ });
4929
+ const renderCanvas = this.renderCanvas;
4930
+ if (!renderCanvas) {
4931
+ return;
4932
+ }
4933
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4934
+ }
4935
+ #initStyle() {
5662
4936
  const element = this.domElement, options = this.#container.actualOptions;
5663
4937
  if (!element) {
5664
4938
  return;
@@ -5679,8 +4953,8 @@
5679
4953
  }
5680
4954
  element.style.setProperty(key, value, "important");
5681
4955
  }
5682
- };
5683
- #repairStyle = () => {
4956
+ }
4957
+ #repairStyle() {
5684
4958
  const element = this.domElement;
5685
4959
  if (!element) {
5686
4960
  return;
@@ -5699,27 +4973,27 @@
5699
4973
  }
5700
4974
  observer.observe(element, { attributes: true });
5701
4975
  });
5702
- };
5703
- #resetOriginalStyle = () => {
4976
+ }
4977
+ #resetOriginalStyle() {
5704
4978
  const element = this.domElement, originalStyle = this.#originalStyle;
5705
4979
  if (!element || !originalStyle) {
5706
4980
  return;
5707
4981
  }
5708
4982
  setStyle(element, originalStyle, true);
5709
- };
5710
- #safeMutationObserver = callback => {
4983
+ }
4984
+ #safeMutationObserver(callback) {
5711
4985
  if (!this.#mutationObserver) {
5712
4986
  return;
5713
4987
  }
5714
4988
  callback(this.#mutationObserver);
5715
- };
5716
- #setFullScreenStyle = () => {
4989
+ }
4990
+ #setFullScreenStyle() {
5717
4991
  const element = this.domElement;
5718
4992
  if (!element) {
5719
4993
  return;
5720
4994
  }
5721
4995
  setStyle(element, getFullScreenStyle(this.#container.actualOptions.fullScreen.zIndex), true);
5722
- };
4996
+ }
5723
4997
  }
5724
4998
 
5725
4999
  class EventListeners {
@@ -5744,7 +5018,7 @@
5744
5018
  removeListeners() {
5745
5019
  this.#manageListeners(false);
5746
5020
  }
5747
- #handleVisibilityChange = () => {
5021
+ #handleVisibilityChange() {
5748
5022
  const container = this.#container, options = container.actualOptions;
5749
5023
  if (!options.pauseOnBlur) {
5750
5024
  return;
@@ -5762,8 +5036,8 @@
5762
5036
  container.draw(true);
5763
5037
  }
5764
5038
  }
5765
- };
5766
- #handleWindowResize = () => {
5039
+ }
5040
+ #handleWindowResize() {
5767
5041
  if (this.#resizeTimeout) {
5768
5042
  clearTimeout(this.#resizeTimeout);
5769
5043
  this.#resizeTimeout = undefined;
@@ -5773,13 +5047,13 @@
5773
5047
  await canvas.windowResize();
5774
5048
  };
5775
5049
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
5776
- };
5777
- #manageListeners = add => {
5050
+ }
5051
+ #manageListeners(add) {
5778
5052
  const handlers = this.#handlers;
5779
5053
  this.#manageResize(add);
5780
5054
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
5781
- };
5782
- #manageResize = add => {
5055
+ }
5056
+ #manageResize(add) {
5783
5057
  const handlers = this.#handlers, container = this.#container, options = container.actualOptions;
5784
5058
  if (!options.resize.enable) {
5785
5059
  return;
@@ -5806,7 +5080,7 @@
5806
5080
  });
5807
5081
  this.#resizeObserver.observe(canvasEl);
5808
5082
  }
5809
- };
5083
+ }
5810
5084
  }
5811
5085
 
5812
5086
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
@@ -5833,6 +5107,131 @@
5833
5107
  data.setCb(data.radius);
5834
5108
  }
5835
5109
  }
5110
+ function normalizeAngle(angle, modulus) {
5111
+ const normalized = angle % modulus;
5112
+ return normalized < defaultAngle ? normalized + modulus : normalized;
5113
+ }
5114
+ function initParticleState(particle, id, group) {
5115
+ particle.id = id;
5116
+ particle.group = group;
5117
+ particle.justWarped = false;
5118
+ particle.effectClose = true;
5119
+ particle.shapeClose = true;
5120
+ particle.pathRotation = false;
5121
+ particle.lastPathTime = 0;
5122
+ particle.destroyed = false;
5123
+ particle.unbreakable = false;
5124
+ particle.isRotating = false;
5125
+ particle.rotation = 0;
5126
+ particle.misplaced = false;
5127
+ particle.retina = {
5128
+ maxDistance: {},
5129
+ maxSpeed: 0,
5130
+ moveDrift: 0,
5131
+ moveSpeed: 0,
5132
+ sizeAnimationSpeed: 0,
5133
+ };
5134
+ particle.size = {
5135
+ value: 1,
5136
+ max: 1,
5137
+ min: 1,
5138
+ enable: false,
5139
+ };
5140
+ particle.outType = ParticleOutType.normal;
5141
+ particle.ignoresResizeRatio = true;
5142
+ }
5143
+ function resolveParticleOptions(particle, container, pluginManager, overrideOptions) {
5144
+ const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates;
5145
+ particle.effect = itemFromSingleOrMultiple(particlesOptions.effect.type, particle.id, reduceDuplicates);
5146
+ particle.shape = itemFromSingleOrMultiple(particlesOptions.shape.type, particle.id, reduceDuplicates);
5147
+ const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
5148
+ if (overrideOptions) {
5149
+ if (overrideOptions.effect) {
5150
+ const overrideEffectType = overrideOptions.effect.type;
5151
+ if (overrideEffectType && overrideEffectType !== particle.effect) {
5152
+ const effect = itemFromSingleOrMultiple(overrideEffectType, particle.id, reduceDuplicates);
5153
+ if (effect) {
5154
+ particle.effect = effect;
5155
+ }
5156
+ }
5157
+ effectOptions.load(overrideOptions.effect);
5158
+ }
5159
+ if (overrideOptions.shape) {
5160
+ const overrideShapeType = overrideOptions.shape.type;
5161
+ if (overrideShapeType && overrideShapeType !== particle.shape) {
5162
+ const shape = itemFromSingleOrMultiple(overrideShapeType, particle.id, reduceDuplicates);
5163
+ if (shape) {
5164
+ particle.shape = shape;
5165
+ }
5166
+ }
5167
+ shapeOptions.load(overrideOptions.shape);
5168
+ }
5169
+ }
5170
+ if (particle.effect === randomColorValue) {
5171
+ const availableEffects = [...container.effectDrawers.keys()];
5172
+ particle.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
5173
+ }
5174
+ if (particle.shape === randomColorValue) {
5175
+ const availableShapes = [...container.shapeDrawers.keys()];
5176
+ particle.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
5177
+ }
5178
+ particle.effectData = particle.effect
5179
+ ? loadEffectData(particle.effect, effectOptions, particle.id, reduceDuplicates)
5180
+ : undefined;
5181
+ particle.shapeData = particle.shape
5182
+ ? loadShapeData(particle.shape, shapeOptions, particle.id, reduceDuplicates)
5183
+ : undefined;
5184
+ particlesOptions.load(overrideOptions);
5185
+ const effectData = particle.effectData, shapeData = particle.shapeData;
5186
+ if (effectData) {
5187
+ particlesOptions.load(effectData.particles);
5188
+ }
5189
+ if (shapeData) {
5190
+ particlesOptions.load(shapeData.particles);
5191
+ }
5192
+ particle.effectClose = effectData?.close ?? particlesOptions.effect.close;
5193
+ particle.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
5194
+ return particlesOptions;
5195
+ }
5196
+ function initParticleDrawers(particle, container) {
5197
+ let effectDrawer, shapeDrawer;
5198
+ if (particle.effect) {
5199
+ effectDrawer = container.effectDrawers.get(particle.effect);
5200
+ }
5201
+ if (effectDrawer?.loadEffect) {
5202
+ effectDrawer.loadEffect(particle);
5203
+ }
5204
+ if (particle.shape) {
5205
+ shapeDrawer = container.shapeDrawers.get(particle.shape);
5206
+ }
5207
+ if (shapeDrawer?.loadShape) {
5208
+ shapeDrawer.loadShape(particle);
5209
+ }
5210
+ const sideCountFunc = shapeDrawer?.getSidesCount;
5211
+ if (sideCountFunc) {
5212
+ particle.sides = sideCountFunc(particle);
5213
+ }
5214
+ }
5215
+ function runUpdaterPreInit(updaters, particle) {
5216
+ for (const updater of updaters) {
5217
+ updater.preInit?.(particle);
5218
+ }
5219
+ }
5220
+ function runUpdaterInit(updaters, particle) {
5221
+ for (const updater of updaters) {
5222
+ updater.init(particle);
5223
+ }
5224
+ }
5225
+ function runDrawerInit(container, particle) {
5226
+ const shapeDrawer = particle.shape ? container.shapeDrawers.get(particle.shape) : undefined, effectDrawer = particle.effect ? container.effectDrawers.get(particle.effect) : undefined;
5227
+ effectDrawer?.particleInit?.(container, particle);
5228
+ shapeDrawer?.particleInit?.(container, particle);
5229
+ }
5230
+ function runParticleCreatedPlugins(container, particle) {
5231
+ for (const plugin of container.particleCreatedPlugins) {
5232
+ plugin.particleCreated?.(particle);
5233
+ }
5234
+ }
5836
5235
  class Particle {
5837
5236
  backColor;
5838
5237
  bubble;
@@ -5958,88 +5357,20 @@
5958
5357
  const rotateData = this.getRotateData(), rotating = this.isRotating;
5959
5358
  this.#cachedTransform.a = rotateData.cos * (externalTransform.a ?? defaultTransform.a);
5960
5359
  this.#cachedTransform.b = rotating
5961
- ? rotateData.sin * (externalTransform.b ?? identity$3)
5360
+ ? rotateData.sin * (externalTransform.b ?? identity$2)
5962
5361
  : (externalTransform.b ?? defaultTransform.b);
5963
5362
  this.#cachedTransform.c = rotating
5964
- ? -rotateData.sin * (externalTransform.c ?? identity$3)
5363
+ ? -rotateData.sin * (externalTransform.c ?? identity$2)
5965
5364
  : (externalTransform.c ?? defaultTransform.c);
5966
5365
  this.#cachedTransform.d = rotateData.cos * (externalTransform.d ?? defaultTransform.d);
5967
5366
  return this.#cachedTransform;
5968
5367
  }
5969
5368
  init(id, position, overrideOptions, group) {
5970
5369
  const container = this.#container;
5971
- this.id = id;
5972
- this.group = group;
5973
- this.justWarped = false;
5974
- this.effectClose = true;
5975
- this.shapeClose = true;
5976
- this.pathRotation = false;
5977
- this.lastPathTime = 0;
5978
- this.destroyed = false;
5979
- this.unbreakable = false;
5980
- this.isRotating = false;
5981
- this.rotation = 0;
5982
- this.misplaced = false;
5983
- this.retina = {
5984
- maxDistance: {},
5985
- maxSpeed: 0,
5986
- moveDrift: 0,
5987
- moveSpeed: 0,
5988
- sizeAnimationSpeed: 0,
5989
- };
5990
- this.size = {
5991
- value: 1,
5992
- max: 1,
5993
- min: 1,
5994
- enable: false,
5995
- };
5996
- this.outType = ParticleOutType.normal;
5997
- this.ignoresResizeRatio = true;
5998
- const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
5999
- this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
6000
- this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
6001
- const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
6002
- if (overrideOptions) {
6003
- if (overrideOptions.effect?.type && overrideOptions.effect.type !== this.effect) {
6004
- const overrideEffectType = overrideOptions.effect.type, effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
6005
- if (effect) {
6006
- this.effect = effect;
6007
- effectOptions.load(overrideOptions.effect);
6008
- }
6009
- }
6010
- if (overrideOptions.shape?.type && overrideOptions.shape.type !== this.shape) {
6011
- const overrideShapeType = overrideOptions.shape.type, shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
6012
- if (shape) {
6013
- this.shape = shape;
6014
- shapeOptions.load(overrideOptions.shape);
6015
- }
6016
- }
6017
- }
6018
- if (this.effect === randomColorValue) {
6019
- const availableEffects = [...this.#container.effectDrawers.keys()];
6020
- this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
6021
- }
6022
- if (this.shape === randomColorValue) {
6023
- const availableShapes = [...this.#container.shapeDrawers.keys()];
6024
- this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
6025
- }
6026
- this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
6027
- this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
6028
- particlesOptions.load(overrideOptions);
6029
- const effectData = this.effectData, shapeData = this.shapeData;
6030
- if (effectData) {
6031
- particlesOptions.load(effectData.particles);
6032
- }
6033
- if (shapeData) {
6034
- particlesOptions.load(shapeData.particles);
6035
- }
6036
- this.effectClose = effectData?.close ?? particlesOptions.effect.close;
6037
- this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
6038
- this.options = particlesOptions;
5370
+ initParticleState(this, id, group);
5371
+ this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
6039
5372
  container.retina.initParticle(this);
6040
- for (const updater of container.particleUpdaters) {
6041
- updater.preInit?.(this);
6042
- }
5373
+ runUpdaterPreInit(container.particleUpdaters, this);
6043
5374
  this.bubble = {
6044
5375
  inRange: false,
6045
5376
  };
@@ -6052,32 +5383,11 @@
6052
5383
  this.velocity = this.initialVelocity.copy();
6053
5384
  this.zIndexFactor = this.position.z / container.zLayers;
6054
5385
  this.sides = 24;
6055
- let effectDrawer, shapeDrawer;
6056
- if (this.effect) {
6057
- effectDrawer = container.effectDrawers.get(this.effect);
6058
- }
6059
- if (effectDrawer?.loadEffect) {
6060
- effectDrawer.loadEffect(this);
6061
- }
6062
- if (this.shape) {
6063
- shapeDrawer = container.shapeDrawers.get(this.shape);
6064
- }
6065
- if (shapeDrawer?.loadShape) {
6066
- shapeDrawer.loadShape(this);
6067
- }
6068
- const sideCountFunc = shapeDrawer?.getSidesCount;
6069
- if (sideCountFunc) {
6070
- this.sides = sideCountFunc(this);
6071
- }
5386
+ initParticleDrawers(this, container);
6072
5387
  this.spawning = false;
6073
- for (const updater of container.particleUpdaters) {
6074
- updater.init(this);
6075
- }
6076
- effectDrawer?.particleInit?.(container, this);
6077
- shapeDrawer?.particleInit?.(container, this);
6078
- for (const plugin of container.particleCreatedPlugins) {
6079
- plugin.particleCreated?.(this);
6080
- }
5388
+ runUpdaterInit(container.particleUpdaters, this);
5389
+ runDrawerInit(container, this);
5390
+ runParticleCreatedPlugins(container, this);
6081
5391
  }
6082
5392
  isInsideCanvas(direction) {
6083
5393
  return this.#getInsideCanvasResult({ direction }).inside;
@@ -6091,15 +5401,15 @@
6091
5401
  }
6092
5402
  const angle = this.roll.angle;
6093
5403
  if (this.roll.horizontal && this.roll.vertical) {
6094
- const normalizedAngle = angle % doublePI, adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + doublePI : normalizedAngle;
5404
+ const adjustedAngle = normalizeAngle(angle, doublePI);
6095
5405
  return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
6096
5406
  }
6097
5407
  if (this.roll.horizontal) {
6098
- const normalizedAngle = (angle + Math.PI * half) % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
5408
+ const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
6099
5409
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
6100
5410
  }
6101
5411
  if (this.roll.vertical) {
6102
- const normalizedAngle = angle % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
5412
+ const adjustedAngle = normalizeAngle(angle, doublePI);
6103
5413
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
6104
5414
  }
6105
5415
  return false;
@@ -6112,10 +5422,10 @@
6112
5422
  updater.reset?.(this);
6113
5423
  }
6114
5424
  }
6115
- #calcPosition = (position, zIndex) => {
5425
+ #calcPosition(position, zIndex) {
6116
5426
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
6117
- const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
6118
- while (!signal.aborted) {
5427
+ const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
5428
+ for (;;) {
6119
5429
  for (const plugin of plugins) {
6120
5430
  const pluginPos = plugin.particlePosition?.(posVec, this);
6121
5431
  if (pluginPos) {
@@ -6143,9 +5453,8 @@
6143
5453
  tryCount += tryCountIncrement;
6144
5454
  posVec = undefined;
6145
5455
  }
6146
- return posVec;
6147
- };
6148
- #calculateVelocity = () => {
5456
+ }
5457
+ #calculateVelocity() {
6149
5458
  const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
6150
5459
  if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
6151
5460
  return res;
@@ -6161,8 +5470,8 @@
6161
5470
  res.length *= getRandom();
6162
5471
  }
6163
5472
  return res;
6164
- };
6165
- #fixHorizontal = (pos, radius, outMode) => {
5473
+ }
5474
+ #fixHorizontal(pos, radius, outMode) {
6166
5475
  fixOutMode({
6167
5476
  outMode,
6168
5477
  checkModes: [OutMode.bounce],
@@ -6171,8 +5480,8 @@
6171
5480
  setCb: (value) => (pos.x += value),
6172
5481
  radius,
6173
5482
  });
6174
- };
6175
- #fixVertical = (pos, radius, outMode) => {
5483
+ }
5484
+ #fixVertical(pos, radius, outMode) {
6176
5485
  fixOutMode({
6177
5486
  outMode,
6178
5487
  checkModes: [OutMode.bounce],
@@ -6181,8 +5490,8 @@
6181
5490
  setCb: (value) => (pos.y += value),
6182
5491
  radius,
6183
5492
  });
6184
- };
6185
- #getDefaultInsideCanvasResult = (direction, outMode) => {
5493
+ }
5494
+ #getDefaultInsideCanvasResult(direction, outMode) {
6186
5495
  const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
6187
5496
  if (direction === OutModeDirection.bottom) {
6188
5497
  return {
@@ -6215,8 +5524,8 @@
6215
5524
  position.x <= canvasSize.width + radius,
6216
5525
  reason: "default",
6217
5526
  };
6218
- };
6219
- #getInsideCanvasCallbackData = (direction, outMode) => {
5527
+ }
5528
+ #getInsideCanvasCallbackData(direction, outMode) {
6220
5529
  return {
6221
5530
  canvasSize: this.#container.canvas.size,
6222
5531
  direction,
@@ -6224,8 +5533,8 @@
6224
5533
  particle: this,
6225
5534
  radius: this.getRadius(),
6226
5535
  };
6227
- };
6228
- #getInsideCanvasResult = (data) => {
5536
+ }
5537
+ #getInsideCanvasResult(data) {
6229
5538
  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;
6230
5539
  if (!shapeCheck && !effectCheck) {
6231
5540
  return defaultResult;
@@ -6240,8 +5549,8 @@
6240
5549
  };
6241
5550
  }
6242
5551
  return shapeResult ?? effectResult ?? defaultResult;
6243
- };
6244
- #getRollColor = color => {
5552
+ }
5553
+ #getRollColor(color) {
6245
5554
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
6246
5555
  return color;
6247
5556
  }
@@ -6255,8 +5564,8 @@
6255
5564
  return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
6256
5565
  }
6257
5566
  return color;
6258
- };
6259
- #initPosition = position => {
5567
+ }
5568
+ #initPosition(position) {
6260
5569
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
6261
5570
  if (!initialPosition) {
6262
5571
  throw new Error("a valid position cannot be found for particle");
@@ -6279,8 +5588,8 @@
6279
5588
  break;
6280
5589
  }
6281
5590
  this.offset = Vector.origin;
6282
- };
6283
- #normalizeInsideCanvasResult = (result, reason) => {
5591
+ }
5592
+ #normalizeInsideCanvasResult(result, reason) {
6284
5593
  if (typeof result === "boolean") {
6285
5594
  return {
6286
5595
  inside: result,
@@ -6292,7 +5601,7 @@
6292
5601
  margin: result.margin,
6293
5602
  reason: result.reason ?? reason,
6294
5603
  };
6295
- };
5604
+ }
6296
5605
  }
6297
5606
 
6298
5607
  class SpatialHashGrid {
@@ -6645,10 +5954,10 @@
6645
5954
  }
6646
5955
  this.#resizeFactor = undefined;
6647
5956
  }
6648
- #addToPool = (...particles) => {
5957
+ #addToPool(...particles) {
6649
5958
  this.#pool.push(...particles);
6650
- };
6651
- #applyDensity = (options, pluginsCount, group, groupOptions) => {
5959
+ }
5960
+ #applyDensity(options, pluginsCount, group, groupOptions) {
6652
5961
  const numberOptions = options.number;
6653
5962
  if (!numberOptions.density.enable) {
6654
5963
  if (group === undefined) {
@@ -6672,36 +5981,19 @@
6672
5981
  else if (particlesCount > particlesNumber) {
6673
5982
  this.removeQuantity(particlesCount - particlesNumber, group);
6674
5983
  }
6675
- };
6676
- #createBuckets = (zLayers) => {
5984
+ }
5985
+ #createBuckets(zLayers) {
6677
5986
  const bucketCount = Math.max(Math.floor(zLayers), one);
6678
5987
  return Array.from({ length: bucketCount }, () => []);
6679
- };
6680
- #getBucketIndex = (zIndex) => {
5988
+ }
5989
+ #getBucketIndex(zIndex) {
6681
5990
  const maxBucketIndex = this.#zBuckets.length - one;
6682
5991
  if (maxBucketIndex <= minIndex) {
6683
5992
  return minIndex;
6684
5993
  }
6685
5994
  return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
6686
- };
6687
- #getParticleInsertIndex = (bucket, particleId) => {
6688
- let start = minIndex, end = bucket.length;
6689
- while (start < end) {
6690
- const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
6691
- if (!middleParticle) {
6692
- end = middle;
6693
- continue;
6694
- }
6695
- if (middleParticle.id < particleId) {
6696
- start = middle + one;
6697
- }
6698
- else {
6699
- end = middle;
6700
- }
6701
- }
6702
- return start;
6703
- };
6704
- #initDensityFactor = densityOptions => {
5995
+ }
5996
+ #initDensityFactor(densityOptions) {
6705
5997
  const container = this.#container;
6706
5998
  if (!densityOptions.enable) {
6707
5999
  return defaultDensityFactor;
@@ -6711,16 +6003,16 @@
6711
6003
  return defaultDensityFactor;
6712
6004
  }
6713
6005
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
6714
- };
6715
- #insertParticleIntoBucket = (particle) => {
6006
+ }
6007
+ #insertParticleIntoBucket(particle) {
6716
6008
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6717
6009
  if (!bucket) {
6718
6010
  return;
6719
6011
  }
6720
- bucket.splice(this.#getParticleInsertIndex(bucket, particle.id), empty, particle);
6012
+ bucket.push(particle);
6721
6013
  this.#particleBuckets.set(particle.id, bucketIndex);
6722
- };
6723
- #removeParticle = (index, group, override) => {
6014
+ }
6015
+ #removeParticle(index, group, override) {
6724
6016
  const particle = this.#array[index];
6725
6017
  if (!particle) {
6726
6018
  return false;
@@ -6736,22 +6028,20 @@
6736
6028
  });
6737
6029
  this.#addToPool(particle);
6738
6030
  return true;
6739
- };
6740
- #removeParticleFromBucket = (particle) => {
6031
+ }
6032
+ #removeParticleFromBucket(particle) {
6741
6033
  const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6742
6034
  if (!bucket) {
6743
6035
  this.#particleBuckets.delete(particle.id);
6744
6036
  return;
6745
6037
  }
6746
- const particleIndex = this.#getParticleInsertIndex(bucket, particle.id);
6747
- if (bucket[particleIndex]?.id !== particle.id) {
6748
- this.#particleBuckets.delete(particle.id);
6749
- return;
6038
+ const idx = bucket.findIndex(p => p.id === particle.id);
6039
+ if (idx >= minIndex) {
6040
+ bucket.splice(idx, deleteCount);
6750
6041
  }
6751
- bucket.splice(particleIndex, deleteCount);
6752
6042
  this.#particleBuckets.delete(particle.id);
6753
- };
6754
- #resetBuckets = (zLayers) => {
6043
+ }
6044
+ #resetBuckets(zLayers) {
6755
6045
  const bucketCount = Math.max(Math.floor(zLayers), one);
6756
6046
  if (this.#zBuckets.length !== bucketCount) {
6757
6047
  this.#zBuckets = this.#createBuckets(bucketCount);
@@ -6760,8 +6050,8 @@
6760
6050
  for (const bucket of this.#zBuckets) {
6761
6051
  bucket.length = minIndex;
6762
6052
  }
6763
- };
6764
- #updateParticleBucket = (particle) => {
6053
+ }
6054
+ #updateParticleBucket(particle) {
6765
6055
  const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
6766
6056
  if (currentBucketIndex === undefined) {
6767
6057
  this.#insertParticleIntoBucket(particle);
@@ -6772,9 +6062,9 @@
6772
6062
  }
6773
6063
  const currentBucket = this.#zBuckets[currentBucketIndex];
6774
6064
  if (currentBucket) {
6775
- const particleIndex = this.#getParticleInsertIndex(currentBucket, particle.id);
6776
- if (currentBucket[particleIndex]?.id === particle.id) {
6777
- currentBucket.splice(particleIndex, deleteCount);
6065
+ const idx = currentBucket.findIndex(p => p.id === particle.id);
6066
+ if (idx >= minIndex) {
6067
+ currentBucket.splice(idx, deleteCount);
6778
6068
  }
6779
6069
  }
6780
6070
  const newBucket = this.#zBuckets[newBucketIndex];
@@ -6782,10 +6072,16 @@
6782
6072
  this.#particleBuckets.set(particle.id, newBucketIndex);
6783
6073
  return;
6784
6074
  }
6785
- newBucket.splice(this.#getParticleInsertIndex(newBucket, particle.id), empty, particle);
6075
+ newBucket.push(particle);
6076
+ if (newBucket.length >= double) {
6077
+ const prev = newBucket[newBucket.length - double];
6078
+ if (prev && particle.id < prev.id) {
6079
+ newBucket.sort((a, b) => a.id - b.id);
6080
+ }
6081
+ }
6786
6082
  this.#particleBuckets.set(particle.id, newBucketIndex);
6787
- };
6788
- #updateParticlesPhase1 = (delta) => {
6083
+ }
6084
+ #updateParticlesPhase1(delta) {
6789
6085
  const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
6790
6086
  for (const particle of this.#array) {
6791
6087
  if (resizeFactor && !particle.ignoresResizeRatio) {
@@ -6811,8 +6107,8 @@
6811
6107
  this.grid.insert(particle);
6812
6108
  }
6813
6109
  return particlesToDelete;
6814
- };
6815
- #updateParticlesPhase2 = (delta, particlesToDelete) => {
6110
+ }
6111
+ #updateParticlesPhase2(delta, particlesToDelete) {
6816
6112
  for (const particle of this.#array) {
6817
6113
  if (particle.destroyed) {
6818
6114
  particlesToDelete.add(particle);
@@ -6828,7 +6124,7 @@
6828
6124
  }
6829
6125
  this.#updateParticleBucket(particle);
6830
6126
  }
6831
- };
6127
+ }
6832
6128
  }
6833
6129
 
6834
6130
  class Retina {
@@ -7190,7 +6486,7 @@
7190
6486
  }
7191
6487
  return refresh;
7192
6488
  }
7193
- #nextFrame = (timestamp) => {
6489
+ #nextFrame(timestamp) {
7194
6490
  try {
7195
6491
  if (!this.#smooth &&
7196
6492
  this.#lastFrameTime !== undefined &&
@@ -7218,7 +6514,7 @@
7218
6514
  catch (e) {
7219
6515
  getLogger().error("error in animation loop", e);
7220
6516
  }
7221
- };
6517
+ }
7222
6518
  }
7223
6519
 
7224
6520
  var Container$1 = /*#__PURE__*/Object.freeze({
@@ -7264,7 +6560,7 @@
7264
6560
  BlendPluginInstance: BlendPluginInstance
7265
6561
  });
7266
6562
 
7267
- const minVelocity = 0, identity$1 = 1, moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
6563
+ const moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
7268
6564
  function applyDistance(particle) {
7269
6565
  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;
7270
6566
  if (!hDistance && !vDistance) {
@@ -7297,7 +6593,7 @@
7297
6593
  }
7298
6594
  function move(particle, moveOptions, moveSpeed, maxSpeed, moveDrift, reduceFactor, delta) {
7299
6595
  applyPath(particle, delta);
7300
- const gravityOptions = particle.gravity, gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity$1 : identity$1;
6596
+ const gravityOptions = particle.gravity, gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity$2 : identity$2;
7301
6597
  if (moveDrift && moveSpeed) {
7302
6598
  particle.velocity.x += (moveDrift * delta.factor) / (moveSpeedFactor * moveSpeed);
7303
6599
  }
@@ -7317,7 +6613,7 @@
7317
6613
  particle.velocity.y = velocity.y / moveSpeed;
7318
6614
  }
7319
6615
  }
7320
- const zIndexOptions = particle.options.zIndex, zVelocityFactor = (identity$1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
6616
+ const zIndexOptions = particle.options.zIndex, zVelocityFactor = (identity$2 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
7321
6617
  velocity.multTo(zVelocityFactor);
7322
6618
  velocity.multTo(reduceFactor);
7323
6619
  const { position } = particle;
@@ -7343,13 +6639,13 @@
7343
6639
  const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height), halfMaxSize = maxCanvasSize * half;
7344
6640
  if (particle.spin.radius > halfMaxSize) {
7345
6641
  particle.spin.radius = halfMaxSize;
7346
- particle.spin.acceleration *= -identity$1;
6642
+ particle.spin.acceleration *= -identity$2;
7347
6643
  }
7348
6644
  else if (particle.spin.radius < minSpinRadius) {
7349
6645
  particle.spin.radius = minSpinRadius;
7350
- particle.spin.acceleration *= -identity$1;
6646
+ particle.spin.acceleration *= -identity$2;
7351
6647
  }
7352
- particle.spin.angle += moveSpeed * spinFactor * (identity$1 - particle.spin.radius / maxCanvasSize);
6648
+ particle.spin.angle += moveSpeed * spinFactor * (identity$2 - particle.spin.radius / maxCanvasSize);
7353
6649
  }
7354
6650
  function applyPath(particle, delta) {
7355
6651
  const particlesOptions = particle.options, pathOptions = particlesOptions.move.path, pathEnabled = pathOptions.enable;
@@ -7366,13 +6662,13 @@
7366
6662
  particle.velocity.addTo(path);
7367
6663
  }
7368
6664
  if (pathOptions.clamp) {
7369
- particle.velocity.x = clamp(particle.velocity.x, -identity$1, identity$1);
7370
- particle.velocity.y = clamp(particle.velocity.y, -identity$1, identity$1);
6665
+ particle.velocity.x = clamp(particle.velocity.x, -identity$2, identity$2);
6666
+ particle.velocity.y = clamp(particle.velocity.y, -identity$2, identity$2);
7371
6667
  }
7372
6668
  particle.lastPathTime -= pathDelay;
7373
6669
  }
7374
6670
  function getProximitySpeedFactor(particle) {
7375
- return particle.slow.inRange ? particle.slow.factor : identity$1;
6671
+ return particle.slow.inRange ? particle.slow.factor : identity$2;
7376
6672
  }
7377
6673
  function initSpin(container, particle) {
7378
6674
  const options = particle.options, spinOptions = options.move.spin;
@@ -7539,7 +6835,7 @@
7539
6835
  removeListeners() {
7540
6836
  this.#manageListeners(false);
7541
6837
  }
7542
- #doMouseTouchClick = e => {
6838
+ #doMouseTouchClick(e) {
7543
6839
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions;
7544
6840
  if (this.#canPush) {
7545
6841
  const mouseInteractivity = interactionManager.interactivityData.mouse, mousePos = mouseInteractivity.position;
@@ -7561,11 +6857,11 @@
7561
6857
  this.#mouseTouchFinish();
7562
6858
  }, touchDelay);
7563
6859
  }
7564
- };
7565
- #handleVisibilityChange = () => {
6860
+ }
6861
+ #handleVisibilityChange() {
7566
6862
  this.#mouseTouchFinish();
7567
- };
7568
- #manageInteractivityListeners = add => {
6863
+ }
6864
+ #manageInteractivityListeners(add) {
7569
6865
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivityEl = interactionManager.interactivityData.element;
7570
6866
  if (!interactivityEl) {
7571
6867
  return;
@@ -7596,8 +6892,8 @@
7596
6892
  }
7597
6893
  manageListener(interactivityEl, mouseLeaveEvent, handlers.mouseLeave, add);
7598
6894
  manageListener(interactivityEl, touchCancelEvent, handlers.touchCancel, add);
7599
- };
7600
- #manageListeners = add => {
6895
+ }
6896
+ #manageListeners(add) {
7601
6897
  const handlers = this.#handlers, container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, detectType = options.interactivity?.detectsOn, canvasEl = container.canvas.domElement;
7602
6898
  if (detectType === InteractivityDetect.window) {
7603
6899
  interactionManager.interactivityData.element = safeDocument();
@@ -7610,13 +6906,13 @@
7610
6906
  }
7611
6907
  this.#manageInteractivityListeners(add);
7612
6908
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
7613
- };
7614
- #mouseDown = () => {
6909
+ }
6910
+ #mouseDown() {
7615
6911
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
7616
6912
  mouse.clicking = true;
7617
6913
  mouse.downPosition = mouse.position;
7618
- };
7619
- #mouseTouchClick = e => {
6914
+ }
6915
+ #mouseTouchClick(e) {
7620
6916
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, { mouse } = interactionManager.interactivityData;
7621
6917
  mouse.inside = true;
7622
6918
  let handled = false;
@@ -7634,8 +6930,8 @@
7634
6930
  this.#doMouseTouchClick(e);
7635
6931
  }
7636
6932
  mouse.clicking = false;
7637
- };
7638
- #mouseTouchFinish = () => {
6933
+ }
6934
+ #mouseTouchFinish() {
7639
6935
  const { interactivityData } = this.#interactionManager, { mouse } = interactivityData;
7640
6936
  delete mouse.position;
7641
6937
  delete mouse.clickPosition;
@@ -7643,8 +6939,8 @@
7643
6939
  interactivityData.status = mouseLeaveEvent;
7644
6940
  mouse.inside = false;
7645
6941
  mouse.clicking = false;
7646
- };
7647
- #mouseTouchMove = e => {
6942
+ }
6943
+ #mouseTouchMove(e) {
7648
6944
  const container = this.#container, interactionManager = this.#interactionManager, options = container.actualOptions, interactivity = interactionManager.interactivityData, canvasEl = container.canvas.domElement;
7649
6945
  if (!interactivity.element) {
7650
6946
  return;
@@ -7706,31 +7002,37 @@
7706
7002
  }
7707
7003
  interactivity.mouse.position = pos;
7708
7004
  interactivity.status = mouseMoveEvent;
7709
- };
7710
- #touchEnd = e => {
7005
+ }
7006
+ #touchEnd(e) {
7711
7007
  const evt = e, touches = Array.from(evt.changedTouches);
7712
7008
  for (const touch of touches) {
7713
7009
  this.#touches.delete(touch.identifier);
7714
7010
  }
7715
7011
  this.#mouseTouchFinish();
7716
- };
7717
- #touchEndClick = e => {
7012
+ }
7013
+ #touchEndClick(e) {
7718
7014
  const evt = e, touches = Array.from(evt.changedTouches);
7719
7015
  for (const touch of touches) {
7720
7016
  this.#touches.delete(touch.identifier);
7721
7017
  }
7722
7018
  this.#mouseTouchClick(e);
7723
- };
7724
- #touchStart = e => {
7019
+ }
7020
+ #touchStart(e) {
7725
7021
  const evt = e, touches = Array.from(evt.changedTouches);
7726
7022
  for (const touch of touches) {
7727
7023
  this.#touches.set(touch.identifier, performance.now());
7728
7024
  }
7729
7025
  this.#mouseTouchMove(e);
7730
- };
7026
+ }
7731
7027
  }
7732
7028
 
7733
7029
  const clickRadius = 1, touchEndLengthOffset = 1, minCoordinate = 0;
7030
+ function safeIntersectionObserver(callback) {
7031
+ if (typeof IntersectionObserver === "undefined") {
7032
+ return;
7033
+ }
7034
+ return new IntersectionObserver(callback);
7035
+ }
7734
7036
  class InteractionManager {
7735
7037
  interactivityData;
7736
7038
  #clickHandlers;
@@ -7933,7 +7235,7 @@
7933
7235
  const container = this.#container;
7934
7236
  container.particles.grid.setCellSize(maxTotalDistance * container.retina.pixelRatio);
7935
7237
  }
7936
- #intersectionManager = entries => {
7238
+ #intersectionManager(entries) {
7937
7239
  const container = this.#container;
7938
7240
  if (container.destroyed || !container.actualOptions.pauseOnOutsideViewport) {
7939
7241
  return;
@@ -7949,7 +7251,7 @@
7949
7251
  container.pause();
7950
7252
  }
7951
7253
  }
7952
- };
7254
+ }
7953
7255
  }
7954
7256
 
7955
7257
  class InteractivityPluginInstance {
@@ -8045,7 +7347,7 @@
8045
7347
  mediaQuery.addEventListener("change", handleChange);
8046
7348
  await Promise.resolve();
8047
7349
  }
8048
- #handleMotionChange = mediaQuery => {
7350
+ #handleMotionChange(mediaQuery) {
8049
7351
  const container = this.#container, motion = container.actualOptions.motion;
8050
7352
  if (!motion) {
8051
7353
  return;
@@ -8061,7 +7363,7 @@
8061
7363
  else {
8062
7364
  container.retina.reduceFactor = defaultReduce;
8063
7365
  }
8064
- };
7366
+ }
8065
7367
  }
8066
7368
 
8067
7369
  var MotionPluginInstance$1 = /*#__PURE__*/Object.freeze({