@tsparticles/preset-confetti 4.1.2 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  (function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
- /* Preset v4.1.2 */
2
+ /* Preset v4.2.0 */
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
5
5
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -15,7 +15,7 @@
15
15
  b: 0,
16
16
  c: 0,
17
17
  d: 1,
18
- }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, 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 = 0.25, threeQuarter = half + quarter, minVelocity = 0, minDistance = 0, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, 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
  }
@@ -295,27 +290,6 @@
295
290
  return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
296
291
  }
297
292
 
298
- var AnimationMode;
299
- (function (AnimationMode) {
300
- AnimationMode["auto"] = "auto";
301
- AnimationMode["increase"] = "increase";
302
- AnimationMode["decrease"] = "decrease";
303
- AnimationMode["random"] = "random";
304
- })(AnimationMode || (AnimationMode = {}));
305
-
306
- var AnimationStatus;
307
- (function (AnimationStatus) {
308
- AnimationStatus["increasing"] = "increasing";
309
- AnimationStatus["decreasing"] = "decreasing";
310
- })(AnimationStatus || (AnimationStatus = {}));
311
-
312
- var DestroyType;
313
- (function (DestroyType) {
314
- DestroyType["none"] = "none";
315
- DestroyType["max"] = "max";
316
- DestroyType["min"] = "min";
317
- })(DestroyType || (DestroyType = {}));
318
-
319
293
  var OutModeDirection;
320
294
  (function (OutModeDirection) {
321
295
  OutModeDirection["bottom"] = "bottom";
@@ -330,67 +304,7 @@
330
304
  PixelMode["percent"] = "percent";
331
305
  })(PixelMode || (PixelMode = {}));
332
306
 
333
- var StartValueType;
334
- (function (StartValueType) {
335
- StartValueType["max"] = "max";
336
- StartValueType["min"] = "min";
337
- StartValueType["random"] = "random";
338
- })(StartValueType || (StartValueType = {}));
339
-
340
307
  const minRadius = 0;
341
- function memoize(fn, options) {
342
- const cache = new Map(), stableStringify = (obj, seen = new WeakSet()) => {
343
- if (obj === null) {
344
- return "null";
345
- }
346
- const t = typeof obj;
347
- if (t === "undefined") {
348
- return "undefined";
349
- }
350
- if (t === "number" || t === "boolean" || t === "string") {
351
- return JSON.stringify(obj);
352
- }
353
- if (t === "function") {
354
- try {
355
- const fn = obj;
356
- return fn.toString();
357
- }
358
- catch {
359
- return '"[Function]"';
360
- }
361
- }
362
- if (t === "symbol") {
363
- try {
364
- return obj.toString();
365
- }
366
- catch {
367
- return '"[Symbol]"';
368
- }
369
- }
370
- if (Array.isArray(obj)) {
371
- return `[${obj.map(i => stableStringify(i, seen)).join(",")}]`;
372
- }
373
- if (seen.has(obj)) {
374
- return '"[Circular]"';
375
- }
376
- seen.add(obj);
377
- const keys = Object.keys(obj).sort();
378
- return `{${keys.map(k => `${JSON.stringify(k)}:${stableStringify(obj[k], seen)}`).join(",")}}`;
379
- }, defaultKeyer = (args) => stableStringify(args), makeKey = (args) => (defaultKeyer(args));
380
- return (...args) => {
381
- const key = makeKey(args), now = Date.now(), entry = cache.get(key);
382
- if (entry !== undefined) {
383
- {
384
- cache.delete(key);
385
- cache.set(key, { value: entry.value, ts: entry.ts });
386
- return entry.value;
387
- }
388
- }
389
- const result = fn(...args);
390
- cache.set(key, { value: result, ts: now });
391
- return result;
392
- };
393
- }
394
308
  function hasMatchMedia() {
395
309
  return typeof matchMedia !== "undefined";
396
310
  }
@@ -412,11 +326,8 @@
412
326
  function isInArray(value, array) {
413
327
  return value === array || (isArray(array) && array.includes(value));
414
328
  }
415
- function arrayRandomIndex(array) {
416
- return Math.floor(getRandom() * array.length);
417
- }
418
329
  function itemFromArray(array, index, useIndex = true) {
419
- return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
330
+ return array[index !== undefined && useIndex ? index % array.length : Math.floor(getRandom() * array.length)];
420
331
  }
421
332
  function isPointInside(point, size, offset, radius, direction) {
422
333
  return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
@@ -500,56 +411,6 @@
500
411
  function itemFromSingleOrMultiple(obj, index, useIndex) {
501
412
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
502
413
  }
503
- function initParticleNumericAnimationValue(options, pxRatio) {
504
- const valueRange = options.value, animationOptions = options.animation, res = {
505
- delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
506
- enable: animationOptions.enable,
507
- value: getRangeValue(options.value) * pxRatio,
508
- max: getRangeMax(valueRange) * pxRatio,
509
- min: getRangeMin(valueRange) * pxRatio,
510
- loops: 0,
511
- maxLoops: getRangeValue(animationOptions.count),
512
- time: 0,
513
- }, decayOffset = 1;
514
- if (animationOptions.enable) {
515
- res.decay = decayOffset - getRangeValue(animationOptions.decay);
516
- switch (animationOptions.mode) {
517
- case AnimationMode.increase:
518
- res.status = AnimationStatus.increasing;
519
- break;
520
- case AnimationMode.decrease:
521
- res.status = AnimationStatus.decreasing;
522
- break;
523
- case AnimationMode.random:
524
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
525
- break;
526
- }
527
- const autoStatus = animationOptions.mode === AnimationMode.auto;
528
- switch (animationOptions.startValue) {
529
- case StartValueType.min:
530
- res.value = res.min;
531
- if (autoStatus) {
532
- res.status = AnimationStatus.increasing;
533
- }
534
- break;
535
- case StartValueType.max:
536
- res.value = res.max;
537
- if (autoStatus) {
538
- res.status = AnimationStatus.decreasing;
539
- }
540
- break;
541
- case StartValueType.random:
542
- default:
543
- res.value = randomInRangeValue(res);
544
- if (autoStatus) {
545
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
546
- }
547
- break;
548
- }
549
- }
550
- res.initialValue = res.value;
551
- return res;
552
- }
553
414
  function getPositionOrSize(positionOrSize, canvasSize) {
554
415
  const isPercent = positionOrSize.mode === PixelMode.percent;
555
416
  if (!isPercent) {
@@ -573,80 +434,6 @@
573
434
  function getPosition(position, canvasSize) {
574
435
  return getPositionOrSize(position, canvasSize);
575
436
  }
576
- function getSize(size, canvasSize) {
577
- return getPositionOrSize(size, canvasSize);
578
- }
579
- function checkDestroy(particle, destroyType, value, minValue, maxValue) {
580
- switch (destroyType) {
581
- case DestroyType.max:
582
- if (value >= maxValue) {
583
- particle.destroy();
584
- }
585
- break;
586
- case DestroyType.min:
587
- if (value <= minValue) {
588
- particle.destroy();
589
- }
590
- break;
591
- }
592
- }
593
- function updateAnimation(particle, data, changeDirection, destroyType, delta) {
594
- const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
595
- if (particle.destroyed ||
596
- !data.enable ||
597
- ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
598
- return;
599
- }
600
- const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
601
- data.time ??= 0;
602
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
603
- data.time += delta.value;
604
- }
605
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
606
- return;
607
- }
608
- switch (data.status) {
609
- case AnimationStatus.increasing:
610
- data.value += velocity;
611
- break;
612
- case AnimationStatus.decreasing:
613
- data.value -= velocity;
614
- break;
615
- }
616
- if (data.velocity && decay !== identity) {
617
- data.velocity *= decay;
618
- }
619
- switch (data.status) {
620
- case AnimationStatus.increasing:
621
- if (data.value >= maxValue) {
622
- if (changeDirection) {
623
- data.status = AnimationStatus.decreasing;
624
- }
625
- else {
626
- data.value -= maxValue;
627
- }
628
- data.loops ??= minLoops;
629
- data.loops++;
630
- }
631
- break;
632
- case AnimationStatus.decreasing:
633
- if (data.value <= minValue) {
634
- if (changeDirection) {
635
- data.status = AnimationStatus.increasing;
636
- }
637
- else {
638
- data.value += maxValue;
639
- }
640
- data.loops ??= minLoops;
641
- data.loops++;
642
- }
643
- break;
644
- }
645
- checkDestroy(particle, destroyType, data.value, minValue, maxValue);
646
- if (!particle.destroyed) {
647
- data.value = clamp(data.value, minValue, maxValue);
648
- }
649
- }
650
437
  function cloneStyle(style) {
651
438
  const clonedStyle = safeDocument().createElement("div").style;
652
439
  for (const key in style) {
@@ -668,30 +455,34 @@
668
455
  }
669
456
  return clonedStyle;
670
457
  }
671
- function computeFullScreenStyle(zIndex) {
672
- const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
673
- width: "100%",
674
- height: "100%",
675
- margin: "0",
676
- padding: "0",
677
- borderWidth: "0",
678
- position: "fixed",
679
- zIndex: zIndex.toString(radix),
680
- "z-index": zIndex.toString(radix),
681
- top: "0",
682
- left: "0",
683
- "pointer-events": "none",
684
- };
685
- for (const key in style) {
686
- const value = style[key];
687
- if (value === undefined) {
688
- continue;
458
+ let _cachedZIndex, _cachedStyle;
459
+ function getFullScreenStyle(zIndex) {
460
+ if (_cachedZIndex !== zIndex || !_cachedStyle) {
461
+ _cachedZIndex = zIndex;
462
+ const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
463
+ width: "100%",
464
+ height: "100%",
465
+ margin: "0",
466
+ padding: "0",
467
+ borderWidth: "0",
468
+ position: "fixed",
469
+ zIndex: zIndex.toString(radix),
470
+ "z-index": zIndex.toString(radix),
471
+ top: "0",
472
+ left: "0",
473
+ "pointer-events": "none",
474
+ };
475
+ for (const key in style) {
476
+ const value = style[key];
477
+ if (value === undefined) {
478
+ continue;
479
+ }
480
+ fullScreenStyle.setProperty(key, value);
689
481
  }
690
- fullScreenStyle.setProperty(key, value);
482
+ _cachedStyle = fullScreenStyle;
691
483
  }
692
- return fullScreenStyle;
484
+ return _cachedStyle;
693
485
  }
694
- const getFullScreenStyle = memoize(computeFullScreenStyle);
695
486
  function manageListener(element, event, handler, add, options) {
696
487
  if (add) {
697
488
  let addOptions = { passive: true };
@@ -1018,7 +809,7 @@
1018
809
  return this.#domArray;
1019
810
  }
1020
811
  get version() {
1021
- return "4.1.2";
812
+ return "4.2.0";
1022
813
  }
1023
814
  addEventListener(type, listener) {
1024
815
  this.#eventDispatcher.addEventListener(type, listener);
@@ -1188,6 +979,14 @@
1188
979
  RotateDirection["random"] = "random";
1189
980
  })(RotateDirection || (RotateDirection = {}));
1190
981
 
982
+ var AnimationMode;
983
+ (function (AnimationMode) {
984
+ AnimationMode["auto"] = "auto";
985
+ AnimationMode["increase"] = "increase";
986
+ AnimationMode["decrease"] = "decrease";
987
+ AnimationMode["random"] = "random";
988
+ })(AnimationMode || (AnimationMode = {}));
989
+
1191
990
  var LimitMode;
1192
991
  (function (LimitMode) {
1193
992
  LimitMode["delete"] = "delete";
@@ -1209,6 +1008,13 @@
1209
1008
  AlterType["enlighten"] = "enlighten";
1210
1009
  })(AlterType || (AlterType = {}));
1211
1010
 
1011
+ var DestroyType;
1012
+ (function (DestroyType) {
1013
+ DestroyType["none"] = "none";
1014
+ DestroyType["max"] = "max";
1015
+ DestroyType["min"] = "min";
1016
+ })(DestroyType || (DestroyType = {}));
1017
+
1212
1018
  var GradientType;
1213
1019
  (function (GradientType) {
1214
1020
  GradientType["linear"] = "linear";
@@ -1223,160 +1029,121 @@
1223
1029
  ParticleOutType["outside"] = "outside";
1224
1030
  })(ParticleOutType || (ParticleOutType = {}));
1225
1031
 
1226
- var EasingType;
1227
- (function (EasingType) {
1228
- EasingType["easeInBack"] = "ease-in-back";
1229
- EasingType["easeInBounce"] = "ease-in-bounce";
1230
- EasingType["easeInCirc"] = "ease-in-circ";
1231
- EasingType["easeInCubic"] = "ease-in-cubic";
1232
- EasingType["easeInElastic"] = "ease-in-elastic";
1233
- EasingType["easeInExpo"] = "ease-in-expo";
1234
- EasingType["easeInGaussian"] = "ease-in-gaussian";
1235
- EasingType["easeInLinear"] = "ease-in-linear";
1236
- EasingType["easeInQuad"] = "ease-in-quad";
1237
- EasingType["easeInQuart"] = "ease-in-quart";
1238
- EasingType["easeInQuint"] = "ease-in-quint";
1239
- EasingType["easeInSigmoid"] = "ease-in-sigmoid";
1240
- EasingType["easeInSine"] = "ease-in-sine";
1241
- EasingType["easeInSmoothstep"] = "ease-in-smoothstep";
1242
- EasingType["easeOutBack"] = "ease-out-back";
1243
- EasingType["easeOutBounce"] = "ease-out-bounce";
1244
- EasingType["easeOutCirc"] = "ease-out-circ";
1245
- EasingType["easeOutCubic"] = "ease-out-cubic";
1246
- EasingType["easeOutElastic"] = "ease-out-elastic";
1247
- EasingType["easeOutExpo"] = "ease-out-expo";
1248
- EasingType["easeOutGaussian"] = "ease-out-gaussian";
1249
- EasingType["easeOutLinear"] = "ease-out-linear";
1250
- EasingType["easeOutQuad"] = "ease-out-quad";
1251
- EasingType["easeOutQuart"] = "ease-out-quart";
1252
- EasingType["easeOutQuint"] = "ease-out-quint";
1253
- EasingType["easeOutSigmoid"] = "ease-out-sigmoid";
1254
- EasingType["easeOutSine"] = "ease-out-sine";
1255
- EasingType["easeOutSmoothstep"] = "ease-out-smoothstep";
1256
- EasingType["easeInOutBack"] = "ease-in-out-back";
1257
- EasingType["easeInOutBounce"] = "ease-in-out-bounce";
1258
- EasingType["easeInOutCirc"] = "ease-in-out-circ";
1259
- EasingType["easeInOutCubic"] = "ease-in-out-cubic";
1260
- EasingType["easeInOutElastic"] = "ease-in-out-elastic";
1261
- EasingType["easeInOutExpo"] = "ease-in-out-expo";
1262
- EasingType["easeInOutGaussian"] = "ease-in-out-gaussian";
1263
- EasingType["easeInOutLinear"] = "ease-in-out-linear";
1264
- EasingType["easeInOutQuad"] = "ease-in-out-quad";
1265
- EasingType["easeInOutQuart"] = "ease-in-out-quart";
1266
- EasingType["easeInOutQuint"] = "ease-in-out-quint";
1267
- EasingType["easeInOutSigmoid"] = "ease-in-out-sigmoid";
1268
- EasingType["easeInOutSine"] = "ease-in-out-sine";
1269
- EasingType["easeInOutSmoothstep"] = "ease-in-out-smoothstep";
1270
- })(EasingType || (EasingType = {}));
1271
-
1272
- class AnimationOptions {
1273
- count;
1274
- decay;
1275
- delay;
1276
- enable;
1277
- speed;
1278
- sync;
1279
- constructor() {
1280
- this.count = 0;
1281
- this.enable = false;
1282
- this.speed = 1;
1283
- this.decay = 0;
1284
- this.delay = 0;
1285
- this.sync = false;
1286
- }
1032
+ var StartValueType;
1033
+ (function (StartValueType) {
1034
+ StartValueType["max"] = "max";
1035
+ StartValueType["min"] = "min";
1036
+ StartValueType["random"] = "random";
1037
+ })(StartValueType || (StartValueType = {}));
1038
+
1039
+ var AnimationStatus;
1040
+ (function (AnimationStatus) {
1041
+ AnimationStatus["increasing"] = "increasing";
1042
+ AnimationStatus["decreasing"] = "decreasing";
1043
+ })(AnimationStatus || (AnimationStatus = {}));
1044
+
1045
+ class OptionLoader {
1287
1046
  load(data) {
1288
1047
  if (isNull(data)) {
1289
1048
  return;
1290
1049
  }
1291
- if (data.count !== undefined) {
1292
- this.count = setRangeValue(data.count);
1293
- }
1294
- if (data.enable !== undefined) {
1295
- this.enable = data.enable;
1296
- }
1297
- if (data.speed !== undefined) {
1298
- this.speed = setRangeValue(data.speed);
1299
- }
1300
- if (data.decay !== undefined) {
1301
- this.decay = setRangeValue(data.decay);
1302
- }
1303
- if (data.delay !== undefined) {
1304
- this.delay = setRangeValue(data.delay);
1305
- }
1306
- if (data.sync !== undefined) {
1307
- this.sync = data.sync;
1308
- }
1050
+ this.doLoad(data);
1309
1051
  }
1310
1052
  }
1311
- class RangedAnimationOptions extends AnimationOptions {
1312
- mode;
1313
- startValue;
1314
- constructor() {
1315
- super();
1316
- this.mode = AnimationMode.auto;
1317
- this.startValue = StartValueType.random;
1053
+ function loadOptions(options, ...sourceOptionsArr) {
1054
+ for (const sourceOptions of sourceOptionsArr) {
1055
+ options.load(sourceOptions);
1318
1056
  }
1319
- load(data) {
1320
- super.load(data);
1321
- if (isNull(data)) {
1322
- return;
1323
- }
1324
- if (data.mode !== undefined) {
1325
- this.mode = data.mode;
1326
- }
1327
- if (data.startValue !== undefined) {
1328
- this.startValue = data.startValue;
1329
- }
1057
+ }
1058
+
1059
+ function loadProperty(obj, key, value) {
1060
+ if (value !== undefined) {
1061
+ obj[key] = value;
1062
+ }
1063
+ }
1064
+ function loadRangeProperty(obj, key, value) {
1065
+ if (value !== undefined) {
1066
+ obj[key] = setRangeValue(value);
1067
+ }
1068
+ }
1069
+ function loadNestedProperty(obj, key, value) {
1070
+ if (value !== undefined) {
1071
+ obj[key].load(value);
1072
+ }
1073
+ }
1074
+ function loadLazyProperty(obj, key, value, factory) {
1075
+ if (value !== undefined) {
1076
+ const objRecord = obj;
1077
+ objRecord[key] ??= factory();
1078
+ objRecord[key].load(value);
1079
+ }
1080
+ }
1081
+ function loadOptionProperty(obj, key, optionClass, ...sources) {
1082
+ const objRecord = obj;
1083
+ objRecord[key] ??= new optionClass();
1084
+ const target = objRecord[key];
1085
+ for (const source of sources) {
1086
+ target.load(source?.[key]);
1087
+ }
1088
+ }
1089
+
1090
+ class AnimationOptions extends OptionLoader {
1091
+ count = 0;
1092
+ decay = 0;
1093
+ delay = 0;
1094
+ enable = false;
1095
+ speed = 1;
1096
+ sync = false;
1097
+ doLoad(data) {
1098
+ loadRangeProperty(this, "count", data.count);
1099
+ loadProperty(this, "enable", data.enable);
1100
+ loadRangeProperty(this, "speed", data.speed);
1101
+ loadRangeProperty(this, "decay", data.decay);
1102
+ loadRangeProperty(this, "delay", data.delay);
1103
+ loadProperty(this, "sync", data.sync);
1104
+ }
1105
+ }
1106
+ class RangedAnimationOptions extends AnimationOptions {
1107
+ mode = AnimationMode.auto;
1108
+ startValue = StartValueType.random;
1109
+ doLoad(data) {
1110
+ super.doLoad(data);
1111
+ loadProperty(this, "mode", data.mode);
1112
+ loadProperty(this, "startValue", data.startValue);
1330
1113
  }
1331
1114
  }
1332
1115
 
1333
1116
  class ColorAnimation extends AnimationOptions {
1334
1117
  max;
1335
1118
  min;
1336
- offset;
1119
+ offset = 0;
1120
+ sync = true;
1337
1121
  constructor(min, max) {
1338
1122
  super();
1339
1123
  this.min = min;
1340
1124
  this.max = max;
1341
- this.offset = 0;
1342
- this.sync = true;
1343
1125
  }
1344
- load(data) {
1345
- super.load(data);
1346
- if (isNull(data)) {
1347
- return;
1348
- }
1349
- if (data.max !== undefined) {
1350
- this.max = data.max;
1351
- }
1352
- if (data.min !== undefined) {
1353
- this.min = data.min;
1354
- }
1355
- if (data.offset !== undefined) {
1356
- this.offset = setRangeValue(data.offset);
1357
- }
1126
+ doLoad(data) {
1127
+ super.doLoad(data);
1128
+ loadProperty(this, "max", data.max);
1129
+ loadProperty(this, "min", data.min);
1130
+ loadRangeProperty(this, "offset", data.offset);
1358
1131
  }
1359
1132
  }
1360
1133
 
1361
- class HslAnimation {
1134
+ class HslAnimation extends OptionLoader {
1362
1135
  h = new ColorAnimation(hMin, hMax);
1363
1136
  l = new ColorAnimation(lMin, lMax);
1364
1137
  s = new ColorAnimation(sMin, sMax);
1365
- load(data) {
1366
- if (isNull(data)) {
1367
- return;
1368
- }
1138
+ doLoad(data) {
1369
1139
  this.h.load(data.h);
1370
1140
  this.s.load(data.s);
1371
1141
  this.l.load(data.l);
1372
1142
  }
1373
1143
  }
1374
1144
 
1375
- class OptionsColor {
1376
- value;
1377
- constructor() {
1378
- this.value = "";
1379
- }
1145
+ class OptionsColor extends OptionLoader {
1146
+ value = "";
1380
1147
  static create(source, data) {
1381
1148
  const color = new OptionsColor();
1382
1149
  color.load(source);
@@ -1390,10 +1157,7 @@
1390
1157
  }
1391
1158
  return color;
1392
1159
  }
1393
- load(data) {
1394
- if (isNull(data)) {
1395
- return;
1396
- }
1160
+ doLoad(data) {
1397
1161
  if (!isNull(data.value)) {
1398
1162
  this.value = data.value;
1399
1163
  }
@@ -1401,11 +1165,7 @@
1401
1165
  }
1402
1166
 
1403
1167
  class AnimatableColor extends OptionsColor {
1404
- animation;
1405
- constructor() {
1406
- super();
1407
- this.animation = new HslAnimation();
1408
- }
1168
+ animation = new HslAnimation();
1409
1169
  static create(source, data) {
1410
1170
  const color = new AnimatableColor();
1411
1171
  color.load(source);
@@ -1419,11 +1179,8 @@
1419
1179
  }
1420
1180
  return color;
1421
1181
  }
1422
- load(data) {
1423
- super.load(data);
1424
- if (isNull(data)) {
1425
- return;
1426
- }
1182
+ doLoad(data) {
1183
+ super.doLoad(data);
1427
1184
  const colorAnimation = data.animation;
1428
1185
  if (colorAnimation !== undefined) {
1429
1186
  if (colorAnimation.enable === undefined) {
@@ -1436,100 +1193,53 @@
1436
1193
  }
1437
1194
  }
1438
1195
 
1439
- class Background {
1196
+ class Background extends OptionLoader {
1440
1197
  color;
1441
- image;
1442
- opacity;
1443
- position;
1444
- repeat;
1445
- size;
1198
+ image = "";
1199
+ opacity = 1;
1200
+ position = "";
1201
+ repeat = "";
1202
+ size = "";
1446
1203
  constructor() {
1204
+ super();
1447
1205
  this.color = new OptionsColor();
1448
1206
  this.color.value = "";
1449
- this.image = "";
1450
- this.position = "";
1451
- this.repeat = "";
1452
- this.size = "";
1453
- this.opacity = 1;
1454
1207
  }
1455
- load(data) {
1456
- if (isNull(data)) {
1457
- return;
1458
- }
1208
+ doLoad(data) {
1459
1209
  if (data.color !== undefined) {
1460
1210
  this.color = OptionsColor.create(this.color, data.color);
1461
1211
  }
1462
- if (data.image !== undefined) {
1463
- this.image = data.image;
1464
- }
1465
- if (data.position !== undefined) {
1466
- this.position = data.position;
1467
- }
1468
- if (data.repeat !== undefined) {
1469
- this.repeat = data.repeat;
1470
- }
1471
- if (data.size !== undefined) {
1472
- this.size = data.size;
1473
- }
1474
- if (data.opacity !== undefined) {
1475
- this.opacity = data.opacity;
1476
- }
1212
+ loadProperty(this, "image", data.image);
1213
+ loadProperty(this, "position", data.position);
1214
+ loadProperty(this, "repeat", data.repeat);
1215
+ loadProperty(this, "size", data.size);
1216
+ loadProperty(this, "opacity", data.opacity);
1477
1217
  }
1478
1218
  }
1479
1219
 
1480
- class FullScreen {
1481
- enable;
1482
- zIndex;
1483
- constructor() {
1484
- this.enable = true;
1485
- this.zIndex = 0;
1486
- }
1487
- load(data) {
1488
- if (isNull(data)) {
1489
- return;
1490
- }
1491
- if (data.enable !== undefined) {
1492
- this.enable = data.enable;
1493
- }
1494
- if (data.zIndex !== undefined) {
1495
- this.zIndex = data.zIndex;
1496
- }
1220
+ class FullScreen extends OptionLoader {
1221
+ enable = true;
1222
+ zIndex = 0;
1223
+ doLoad(data) {
1224
+ loadProperty(this, "enable", data.enable);
1225
+ loadProperty(this, "zIndex", data.zIndex);
1497
1226
  }
1498
1227
  }
1499
1228
 
1500
- class ResizeEvent {
1501
- delay;
1502
- enable;
1503
- constructor() {
1504
- this.delay = 0.5;
1505
- this.enable = true;
1506
- }
1507
- load(data) {
1508
- if (isNull(data)) {
1509
- return;
1510
- }
1511
- if (data.delay !== undefined) {
1512
- this.delay = data.delay;
1513
- }
1514
- if (data.enable !== undefined) {
1515
- this.enable = data.enable;
1516
- }
1229
+ class ResizeEvent extends OptionLoader {
1230
+ delay = 0.5;
1231
+ enable = true;
1232
+ doLoad(data) {
1233
+ loadProperty(this, "delay", data.delay);
1234
+ loadProperty(this, "enable", data.enable);
1517
1235
  }
1518
1236
  }
1519
1237
 
1520
- class Effect {
1521
- close;
1522
- options;
1523
- type;
1524
- constructor() {
1525
- this.close = true;
1526
- this.options = {};
1527
- this.type = [];
1528
- }
1529
- load(data) {
1530
- if (isNull(data)) {
1531
- return;
1532
- }
1238
+ class Effect extends OptionLoader {
1239
+ close = true;
1240
+ options = {};
1241
+ type = [];
1242
+ doLoad(data) {
1533
1243
  const options = data.options;
1534
1244
  if (options !== undefined) {
1535
1245
  for (const effect in options) {
@@ -1539,128 +1249,62 @@
1539
1249
  }
1540
1250
  }
1541
1251
  }
1542
- if (data.close !== undefined) {
1543
- this.close = data.close;
1544
- }
1545
- if (data.type !== undefined) {
1546
- this.type = data.type;
1547
- }
1252
+ loadProperty(this, "close", data.close);
1253
+ loadProperty(this, "type", data.type);
1548
1254
  }
1549
1255
  }
1550
1256
 
1551
- class Fill {
1257
+ class Fill extends OptionLoader {
1552
1258
  color;
1553
- enable;
1554
- opacity;
1555
- constructor() {
1556
- this.enable = true;
1557
- this.opacity = 1;
1558
- }
1559
- load(data) {
1560
- if (isNull(data)) {
1561
- return;
1562
- }
1259
+ enable = true;
1260
+ opacity = 1;
1261
+ doLoad(data) {
1563
1262
  if (data.color !== undefined) {
1564
1263
  this.color = AnimatableColor.create(this.color, data.color);
1565
1264
  }
1566
- if (data.enable !== undefined) {
1567
- this.enable = data.enable;
1568
- }
1569
- if (data.opacity !== undefined) {
1570
- this.opacity = setRangeValue(data.opacity);
1571
- }
1265
+ loadProperty(this, "enable", data.enable);
1266
+ loadRangeProperty(this, "opacity", data.opacity);
1572
1267
  }
1573
1268
  }
1574
1269
 
1575
- class MoveAngle {
1576
- offset;
1577
- value;
1578
- constructor() {
1579
- this.offset = 0;
1580
- this.value = 90;
1581
- }
1582
- load(data) {
1583
- if (isNull(data)) {
1584
- return;
1585
- }
1586
- if (data.offset !== undefined) {
1587
- this.offset = setRangeValue(data.offset);
1588
- }
1589
- if (data.value !== undefined) {
1590
- this.value = setRangeValue(data.value);
1591
- }
1270
+ class MoveAngle extends OptionLoader {
1271
+ offset = 0;
1272
+ value = 90;
1273
+ doLoad(data) {
1274
+ loadRangeProperty(this, "offset", data.offset);
1275
+ loadRangeProperty(this, "value", data.value);
1592
1276
  }
1593
1277
  }
1594
1278
 
1595
- class MoveCenter {
1596
- mode;
1597
- radius;
1598
- x;
1599
- y;
1600
- constructor() {
1601
- this.x = 50;
1602
- this.y = 50;
1603
- this.mode = PixelMode.percent;
1604
- this.radius = 0;
1605
- }
1606
- load(data) {
1607
- if (isNull(data)) {
1608
- return;
1609
- }
1610
- if (data.x !== undefined) {
1611
- this.x = data.x;
1612
- }
1613
- if (data.y !== undefined) {
1614
- this.y = data.y;
1615
- }
1616
- if (data.mode !== undefined) {
1617
- this.mode = data.mode;
1618
- }
1619
- if (data.radius !== undefined) {
1620
- this.radius = data.radius;
1621
- }
1279
+ class MoveCenter extends OptionLoader {
1280
+ mode = PixelMode.percent;
1281
+ radius = 0;
1282
+ x = 50;
1283
+ y = 50;
1284
+ doLoad(data) {
1285
+ loadProperty(this, "x", data.x);
1286
+ loadProperty(this, "y", data.y);
1287
+ loadProperty(this, "mode", data.mode);
1288
+ loadProperty(this, "radius", data.radius);
1622
1289
  }
1623
1290
  }
1624
1291
 
1625
- class MoveGravity {
1626
- acceleration;
1627
- enable;
1628
- inverse;
1629
- maxSpeed;
1630
- constructor() {
1631
- this.acceleration = 9.81;
1632
- this.enable = false;
1633
- this.inverse = false;
1634
- this.maxSpeed = 50;
1635
- }
1636
- load(data) {
1637
- if (isNull(data)) {
1638
- return;
1639
- }
1640
- if (data.acceleration !== undefined) {
1641
- this.acceleration = setRangeValue(data.acceleration);
1642
- }
1643
- if (data.enable !== undefined) {
1644
- this.enable = data.enable;
1645
- }
1646
- if (data.inverse !== undefined) {
1647
- this.inverse = data.inverse;
1648
- }
1649
- if (data.maxSpeed !== undefined) {
1650
- this.maxSpeed = setRangeValue(data.maxSpeed);
1651
- }
1292
+ class MoveGravity extends OptionLoader {
1293
+ acceleration = 9.81;
1294
+ enable = false;
1295
+ inverse = false;
1296
+ maxSpeed = 50;
1297
+ doLoad(data) {
1298
+ loadRangeProperty(this, "acceleration", data.acceleration);
1299
+ loadProperty(this, "enable", data.enable);
1300
+ loadProperty(this, "inverse", data.inverse);
1301
+ loadRangeProperty(this, "maxSpeed", data.maxSpeed);
1652
1302
  }
1653
1303
  }
1654
1304
 
1655
- class ValueWithRandom {
1656
- value;
1657
- constructor() {
1658
- this.value = 0;
1659
- }
1660
- load(data) {
1661
- if (isNull(data)) {
1662
- return;
1663
- }
1305
+ class ValueWithRandom extends OptionLoader {
1306
+ value = 0;
1307
+ doLoad(data) {
1664
1308
  if (!isNull(data.value)) {
1665
1309
  this.value = setRangeValue(data.value);
1666
1310
  }
@@ -1668,51 +1312,25 @@
1668
1312
  }
1669
1313
  class AnimationValueWithRandom extends ValueWithRandom {
1670
1314
  animation = new AnimationOptions();
1671
- load(data) {
1672
- super.load(data);
1673
- if (isNull(data)) {
1674
- return;
1675
- }
1676
- const animation = data.animation;
1677
- if (animation !== undefined) {
1678
- this.animation.load(animation);
1679
- }
1315
+ doLoad(data) {
1316
+ super.doLoad(data);
1317
+ loadNestedProperty(this, "animation", data.animation);
1680
1318
  }
1681
1319
  }
1682
1320
  class RangedAnimationValueWithRandom extends AnimationValueWithRandom {
1683
- animation;
1684
- constructor() {
1685
- super();
1686
- this.animation = new RangedAnimationOptions();
1687
- }
1688
- load(data) {
1689
- super.load(data);
1690
- }
1321
+ animation = new RangedAnimationOptions();
1691
1322
  }
1692
1323
 
1693
- class MovePath {
1694
- clamp;
1695
- delay;
1696
- enable;
1324
+ class MovePath extends OptionLoader {
1325
+ clamp = true;
1326
+ delay = new ValueWithRandom();
1327
+ enable = false;
1697
1328
  generator;
1698
- options;
1699
- constructor() {
1700
- this.clamp = true;
1701
- this.delay = new ValueWithRandom();
1702
- this.enable = false;
1703
- this.options = {};
1704
- }
1705
- load(data) {
1706
- if (isNull(data)) {
1707
- return;
1708
- }
1709
- if (data.clamp !== undefined) {
1710
- this.clamp = data.clamp;
1711
- }
1329
+ options = {};
1330
+ doLoad(data) {
1331
+ loadProperty(this, "clamp", data.clamp);
1712
1332
  this.delay.load(data.delay);
1713
- if (data.enable !== undefined) {
1714
- this.enable = data.enable;
1715
- }
1333
+ loadProperty(this, "enable", data.enable);
1716
1334
  this.generator = data.generator;
1717
1335
  if (data.options) {
1718
1336
  this.options = deepExtend(this.options, data.options);
@@ -1720,19 +1338,13 @@
1720
1338
  }
1721
1339
  }
1722
1340
 
1723
- class OutModes {
1341
+ class OutModes extends OptionLoader {
1724
1342
  bottom;
1725
- default;
1343
+ default = OutMode.out;
1726
1344
  left;
1727
1345
  right;
1728
1346
  top;
1729
- constructor() {
1730
- this.default = OutMode.out;
1731
- }
1732
- load(data) {
1733
- if (isNull(data)) {
1734
- return;
1735
- }
1347
+ doLoad(data) {
1736
1348
  if (data.default !== undefined) {
1737
1349
  this.default = data.default;
1738
1350
  }
@@ -1743,79 +1355,42 @@
1743
1355
  }
1744
1356
  }
1745
1357
 
1746
- class Spin {
1747
- acceleration;
1748
- enable;
1358
+ class Spin extends OptionLoader {
1359
+ acceleration = 0;
1360
+ enable = false;
1749
1361
  position;
1750
- constructor() {
1751
- this.acceleration = 0;
1752
- this.enable = false;
1753
- }
1754
- load(data) {
1755
- if (isNull(data)) {
1756
- return;
1757
- }
1758
- if (data.acceleration !== undefined) {
1759
- this.acceleration = setRangeValue(data.acceleration);
1760
- }
1761
- if (data.enable !== undefined) {
1762
- this.enable = data.enable;
1763
- }
1362
+ doLoad(data) {
1363
+ loadRangeProperty(this, "acceleration", data.acceleration);
1364
+ loadProperty(this, "enable", data.enable);
1764
1365
  if (data.position) {
1765
1366
  this.position = deepExtend({}, data.position);
1766
1367
  }
1767
1368
  }
1768
1369
  }
1769
1370
 
1770
- class Move {
1771
- angle;
1772
- center;
1773
- decay;
1774
- direction;
1775
- distance;
1776
- drift;
1777
- enable;
1778
- gravity;
1779
- outModes;
1780
- path;
1781
- random;
1782
- size;
1783
- speed;
1784
- spin;
1785
- straight;
1786
- vibrate;
1787
- warp;
1788
- constructor() {
1789
- this.angle = new MoveAngle();
1790
- this.center = new MoveCenter();
1791
- this.decay = 0;
1792
- this.distance = {};
1793
- this.direction = MoveDirection.none;
1794
- this.drift = 0;
1795
- this.enable = false;
1796
- this.gravity = new MoveGravity();
1797
- this.path = new MovePath();
1798
- this.outModes = new OutModes();
1799
- this.random = false;
1800
- this.size = false;
1801
- this.speed = 2;
1802
- this.spin = new Spin();
1803
- this.straight = false;
1804
- this.vibrate = false;
1805
- this.warp = false;
1806
- }
1807
- load(data) {
1808
- if (isNull(data)) {
1809
- return;
1810
- }
1371
+ class Move extends OptionLoader {
1372
+ angle = new MoveAngle();
1373
+ center = new MoveCenter();
1374
+ decay = 0;
1375
+ direction = MoveDirection.none;
1376
+ distance = {};
1377
+ drift = 0;
1378
+ enable = false;
1379
+ gravity = new MoveGravity();
1380
+ outModes = new OutModes();
1381
+ path = new MovePath();
1382
+ random = false;
1383
+ size = false;
1384
+ speed = 2;
1385
+ spin = new Spin();
1386
+ straight = false;
1387
+ vibrate = false;
1388
+ warp = false;
1389
+ doLoad(data) {
1811
1390
  this.angle.load(isNumber(data.angle) ? { value: data.angle } : data.angle);
1812
1391
  this.center.load(data.center);
1813
- if (data.decay !== undefined) {
1814
- this.decay = setRangeValue(data.decay);
1815
- }
1816
- if (data.direction !== undefined) {
1817
- this.direction = data.direction;
1818
- }
1392
+ loadRangeProperty(this, "decay", data.decay);
1393
+ loadProperty(this, "direction", data.direction);
1819
1394
  if (data.distance !== undefined) {
1820
1395
  this.distance = isNumber(data.distance)
1821
1396
  ? {
@@ -1824,12 +1399,8 @@
1824
1399
  }
1825
1400
  : { ...data.distance };
1826
1401
  }
1827
- if (data.drift !== undefined) {
1828
- this.drift = setRangeValue(data.drift);
1829
- }
1830
- if (data.enable !== undefined) {
1831
- this.enable = data.enable;
1832
- }
1402
+ loadRangeProperty(this, "drift", data.drift);
1403
+ loadProperty(this, "enable", data.enable);
1833
1404
  this.gravity.load(data.gravity);
1834
1405
  const outModes = data.outModes;
1835
1406
  if (outModes !== undefined) {
@@ -1843,177 +1414,91 @@
1843
1414
  }
1844
1415
  }
1845
1416
  this.path.load(data.path);
1846
- if (data.random !== undefined) {
1847
- this.random = data.random;
1848
- }
1849
- if (data.size !== undefined) {
1850
- this.size = data.size;
1851
- }
1852
- if (data.speed !== undefined) {
1853
- this.speed = setRangeValue(data.speed);
1854
- }
1417
+ loadProperty(this, "random", data.random);
1418
+ loadProperty(this, "size", data.size);
1419
+ loadRangeProperty(this, "speed", data.speed);
1855
1420
  this.spin.load(data.spin);
1856
- if (data.straight !== undefined) {
1857
- this.straight = data.straight;
1858
- }
1859
- if (data.vibrate !== undefined) {
1860
- this.vibrate = data.vibrate;
1861
- }
1862
- if (data.warp !== undefined) {
1863
- this.warp = data.warp;
1864
- }
1421
+ loadProperty(this, "straight", data.straight);
1422
+ loadProperty(this, "vibrate", data.vibrate);
1423
+ loadProperty(this, "warp", data.warp);
1865
1424
  }
1866
1425
  }
1867
1426
 
1868
- class Stroke {
1427
+ class Stroke extends OptionLoader {
1869
1428
  color;
1870
1429
  opacity;
1871
- width;
1872
- constructor() {
1873
- this.width = 0;
1874
- }
1875
- load(data) {
1876
- if (isNull(data)) {
1877
- return;
1878
- }
1430
+ width = 0;
1431
+ doLoad(data) {
1879
1432
  if (data.color !== undefined) {
1880
1433
  this.color = AnimatableColor.create(this.color, data.color);
1881
1434
  }
1882
- if (data.width !== undefined) {
1883
- this.width = setRangeValue(data.width);
1884
- }
1885
- if (data.opacity !== undefined) {
1886
- this.opacity = setRangeValue(data.opacity);
1887
- }
1435
+ loadRangeProperty(this, "width", data.width);
1436
+ loadRangeProperty(this, "opacity", data.opacity);
1888
1437
  }
1889
1438
  }
1890
1439
 
1891
- class Paint {
1440
+ class Paint extends OptionLoader {
1892
1441
  color;
1893
1442
  fill;
1894
1443
  stroke;
1895
- load(data) {
1896
- if (isNull(data)) {
1897
- return;
1898
- }
1444
+ doLoad(data) {
1899
1445
  if (data.color !== undefined) {
1900
1446
  this.color = AnimatableColor.create(this.color, data.color);
1901
1447
  }
1902
- if (data.fill !== undefined) {
1903
- this.fill ??= new Fill();
1904
- this.fill.load(data.fill);
1905
- }
1906
- if (data.stroke !== undefined) {
1907
- this.stroke ??= new Stroke();
1908
- this.stroke.load(data.stroke);
1909
- }
1448
+ loadLazyProperty(this, "fill", data.fill, () => new Fill());
1449
+ loadLazyProperty(this, "stroke", data.stroke, () => new Stroke());
1910
1450
  }
1911
1451
  }
1912
1452
 
1913
1453
  class ParticlesBounceFactor extends ValueWithRandom {
1914
- constructor() {
1915
- super();
1916
- this.value = 1;
1917
- }
1454
+ value = 1;
1918
1455
  }
1919
1456
 
1920
- class ParticlesBounce {
1921
- horizontal;
1922
- vertical;
1923
- constructor() {
1924
- this.horizontal = new ParticlesBounceFactor();
1925
- this.vertical = new ParticlesBounceFactor();
1926
- }
1927
- load(data) {
1928
- if (isNull(data)) {
1929
- return;
1930
- }
1457
+ class ParticlesBounce extends OptionLoader {
1458
+ horizontal = new ParticlesBounceFactor();
1459
+ vertical = new ParticlesBounceFactor();
1460
+ doLoad(data) {
1931
1461
  this.horizontal.load(data.horizontal);
1932
1462
  this.vertical.load(data.vertical);
1933
1463
  }
1934
1464
  }
1935
1465
 
1936
- class ParticlesDensity {
1937
- enable;
1938
- height;
1939
- width;
1940
- constructor() {
1941
- this.enable = false;
1942
- this.width = 1920;
1943
- this.height = 1080;
1944
- }
1945
- load(data) {
1946
- if (isNull(data)) {
1947
- return;
1948
- }
1949
- if (data.enable !== undefined) {
1950
- this.enable = data.enable;
1951
- }
1952
- const width = data.width;
1953
- if (width !== undefined) {
1954
- this.width = width;
1955
- }
1956
- const height = data.height;
1957
- if (height !== undefined) {
1958
- this.height = height;
1959
- }
1466
+ class ParticlesDensity extends OptionLoader {
1467
+ enable = false;
1468
+ height = 1080;
1469
+ width = 1920;
1470
+ doLoad(data) {
1471
+ loadProperty(this, "enable", data.enable);
1472
+ loadProperty(this, "width", data.width);
1473
+ loadProperty(this, "height", data.height);
1960
1474
  }
1961
1475
  }
1962
1476
 
1963
- class ParticlesNumberLimit {
1964
- mode;
1965
- value;
1966
- constructor() {
1967
- this.mode = LimitMode.delete;
1968
- this.value = 0;
1969
- }
1970
- load(data) {
1971
- if (isNull(data)) {
1972
- return;
1973
- }
1974
- if (data.mode !== undefined) {
1975
- this.mode = data.mode;
1976
- }
1977
- if (data.value !== undefined) {
1978
- this.value = data.value;
1979
- }
1477
+ class ParticlesNumberLimit extends OptionLoader {
1478
+ mode = LimitMode.delete;
1479
+ value = 0;
1480
+ doLoad(data) {
1481
+ loadProperty(this, "mode", data.mode);
1482
+ loadProperty(this, "value", data.value);
1980
1483
  }
1981
1484
  }
1982
1485
 
1983
- class ParticlesNumber {
1984
- density;
1985
- limit;
1986
- value;
1987
- constructor() {
1988
- this.density = new ParticlesDensity();
1989
- this.limit = new ParticlesNumberLimit();
1990
- this.value = 0;
1991
- }
1992
- load(data) {
1993
- if (isNull(data)) {
1994
- return;
1995
- }
1486
+ class ParticlesNumber extends OptionLoader {
1487
+ density = new ParticlesDensity();
1488
+ limit = new ParticlesNumberLimit();
1489
+ value = 0;
1490
+ doLoad(data) {
1996
1491
  this.density.load(data.density);
1997
1492
  this.limit.load(data.limit);
1998
- if (data.value !== undefined) {
1999
- this.value = data.value;
2000
- }
1493
+ loadProperty(this, "value", data.value);
2001
1494
  }
2002
1495
  }
2003
1496
 
2004
- class Shape {
2005
- close;
2006
- options;
2007
- type;
2008
- constructor() {
2009
- this.close = true;
2010
- this.options = {};
2011
- this.type = "circle";
2012
- }
2013
- load(data) {
2014
- if (isNull(data)) {
2015
- return;
2016
- }
1497
+ class Shape extends OptionLoader {
1498
+ close = true;
1499
+ options = {};
1500
+ type = "circle";
1501
+ doLoad(data) {
2017
1502
  const options = data.options;
2018
1503
  if (options !== undefined) {
2019
1504
  for (const shape in options) {
@@ -2023,76 +1508,47 @@
2023
1508
  }
2024
1509
  }
2025
1510
  }
2026
- if (data.close !== undefined) {
2027
- this.close = data.close;
2028
- }
2029
- if (data.type !== undefined) {
2030
- this.type = data.type;
2031
- }
1511
+ loadProperty(this, "close", data.close);
1512
+ loadProperty(this, "type", data.type);
2032
1513
  }
2033
1514
  }
2034
1515
 
2035
1516
  class ZIndex extends ValueWithRandom {
2036
- opacityRate;
2037
- sizeRate;
2038
- velocityRate;
2039
- constructor() {
2040
- super();
2041
- this.opacityRate = 1;
2042
- this.sizeRate = 1;
2043
- this.velocityRate = 1;
2044
- }
2045
- load(data) {
2046
- super.load(data);
2047
- if (isNull(data)) {
2048
- return;
2049
- }
2050
- if (data.opacityRate !== undefined) {
2051
- this.opacityRate = data.opacityRate;
2052
- }
2053
- if (data.sizeRate !== undefined) {
2054
- this.sizeRate = data.sizeRate;
2055
- }
2056
- if (data.velocityRate !== undefined) {
2057
- this.velocityRate = data.velocityRate;
2058
- }
2059
- }
2060
- }
2061
-
2062
- class ParticlesOptions {
2063
- bounce;
2064
- effect;
2065
- groups;
2066
- move;
2067
- number;
1517
+ opacityRate = 1;
1518
+ sizeRate = 1;
1519
+ velocityRate = 1;
1520
+ doLoad(data) {
1521
+ super.doLoad(data);
1522
+ loadProperty(this, "opacityRate", data.opacityRate);
1523
+ loadProperty(this, "sizeRate", data.sizeRate);
1524
+ loadProperty(this, "velocityRate", data.velocityRate);
1525
+ }
1526
+ }
1527
+
1528
+ class ParticlesOptions extends OptionLoader {
1529
+ bounce = new ParticlesBounce();
1530
+ effect = new Effect();
1531
+ groups = {};
1532
+ move = new Move();
1533
+ number = new ParticlesNumber();
2068
1534
  paint;
2069
1535
  palette;
2070
- reduceDuplicates;
2071
- shape;
2072
- zIndex;
1536
+ reduceDuplicates = false;
1537
+ shape = new Shape();
1538
+ zIndex = new ZIndex();
2073
1539
  #container;
2074
1540
  #pluginManager;
2075
1541
  constructor(pluginManager, container) {
1542
+ super();
2076
1543
  this.#pluginManager = pluginManager;
2077
1544
  this.#container = container;
2078
- this.bounce = new ParticlesBounce();
2079
- this.effect = new Effect();
2080
- this.groups = {};
2081
- this.move = new Move();
2082
- this.number = new ParticlesNumber();
2083
1545
  this.paint = new Paint();
2084
1546
  this.paint.color = new AnimatableColor();
2085
1547
  this.paint.color.value = "#fff";
2086
1548
  this.paint.fill = new Fill();
2087
1549
  this.paint.fill.enable = true;
2088
- this.reduceDuplicates = false;
2089
- this.shape = new Shape();
2090
- this.zIndex = new ZIndex();
2091
1550
  }
2092
- load(data) {
2093
- if (isNull(data)) {
2094
- return;
2095
- }
1551
+ doLoad(data) {
2096
1552
  if (data.palette) {
2097
1553
  this.palette = data.palette;
2098
1554
  this.#importPalette(this.palette);
@@ -2150,7 +1606,7 @@
2150
1606
  }
2151
1607
  }
2152
1608
  }
2153
- #importPalette = (palette) => {
1609
+ #importPalette(palette) {
2154
1610
  const paletteData = this.#pluginManager.getPalette(palette);
2155
1611
  if (!paletteData) {
2156
1612
  return;
@@ -2194,69 +1650,49 @@
2194
1650
  mode: paletteData.blendMode,
2195
1651
  },
2196
1652
  });
2197
- };
2198
- }
2199
-
2200
- function loadOptions(options, ...sourceOptionsArr) {
2201
- for (const sourceOptions of sourceOptionsArr) {
2202
- options.load(sourceOptions);
2203
1653
  }
2204
1654
  }
1655
+
2205
1656
  function loadParticlesOptions(pluginManager, container, ...sourceOptionsArr) {
2206
1657
  const options = new ParticlesOptions(pluginManager, container);
2207
1658
  loadOptions(options, ...sourceOptionsArr);
2208
1659
  return options;
2209
1660
  }
2210
1661
 
2211
- class Options {
2212
- autoPlay;
1662
+ class Options extends OptionLoader {
1663
+ autoPlay = true;
2213
1664
  background;
2214
- clear;
2215
- defaultThemes;
2216
- delay;
2217
- detectRetina;
2218
- duration;
2219
- fpsLimit;
1665
+ clear = true;
1666
+ defaultThemes = {};
1667
+ delay = 0;
1668
+ detectRetina = true;
1669
+ duration = 0;
1670
+ fpsLimit = 120;
2220
1671
  fullScreen;
2221
- hdr;
1672
+ hdr = true;
2222
1673
  key;
2223
1674
  name;
2224
1675
  palette;
2225
1676
  particles;
2226
- pauseOnBlur;
2227
- pauseOnOutsideViewport;
1677
+ pauseOnBlur = true;
1678
+ pauseOnOutsideViewport = true;
2228
1679
  preset;
2229
1680
  resize;
2230
- smooth;
2231
- style;
2232
- zLayers;
1681
+ smooth = false;
1682
+ style = {};
1683
+ zLayers = 100;
2233
1684
  #container;
2234
1685
  #pluginManager;
2235
1686
  constructor(pluginManager, container) {
1687
+ super();
2236
1688
  this.#pluginManager = pluginManager;
2237
1689
  this.#container = container;
2238
- this.autoPlay = true;
2239
1690
  this.background = new Background();
2240
- this.clear = true;
2241
- this.defaultThemes = {};
2242
- this.delay = 0;
2243
1691
  this.fullScreen = new FullScreen();
2244
- this.detectRetina = true;
2245
- this.duration = 0;
2246
- this.fpsLimit = 120;
2247
- this.hdr = true;
2248
1692
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
2249
- this.pauseOnBlur = true;
2250
- this.pauseOnOutsideViewport = true;
2251
1693
  this.resize = new ResizeEvent();
2252
- this.smooth = false;
2253
- this.style = {};
2254
- this.zLayers = 100;
2255
1694
  }
2256
- load(data) {
2257
- if (isNull(data)) {
2258
- return;
2259
- }
1695
+ doLoad(data) {
2260
1696
  if (data.preset !== undefined) {
2261
1697
  this.preset = data.preset;
2262
1698
  executeOnSingleOrMultiple(this.preset, preset => {
@@ -2267,44 +1703,18 @@
2267
1703
  this.palette = data.palette;
2268
1704
  this.#importPalette(this.palette);
2269
1705
  }
2270
- if (data.autoPlay !== undefined) {
2271
- this.autoPlay = data.autoPlay;
2272
- }
2273
- if (data.clear !== undefined) {
2274
- this.clear = data.clear;
2275
- }
2276
- if (data.key !== undefined) {
2277
- this.key = data.key;
2278
- }
2279
- if (data.name !== undefined) {
2280
- this.name = data.name;
2281
- }
2282
- if (data.delay !== undefined) {
2283
- this.delay = setRangeValue(data.delay);
2284
- }
2285
- const detectRetina = data.detectRetina;
2286
- if (detectRetina !== undefined) {
2287
- this.detectRetina = detectRetina;
2288
- }
2289
- if (data.duration !== undefined) {
2290
- this.duration = setRangeValue(data.duration);
2291
- }
2292
- const fpsLimit = data.fpsLimit;
2293
- if (fpsLimit !== undefined) {
2294
- this.fpsLimit = fpsLimit;
2295
- }
2296
- if (data.hdr !== undefined) {
2297
- this.hdr = data.hdr;
2298
- }
2299
- if (data.pauseOnBlur !== undefined) {
2300
- this.pauseOnBlur = data.pauseOnBlur;
2301
- }
2302
- if (data.pauseOnOutsideViewport !== undefined) {
2303
- this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
2304
- }
2305
- if (data.zLayers !== undefined) {
2306
- this.zLayers = data.zLayers;
2307
- }
1706
+ loadProperty(this, "autoPlay", data.autoPlay);
1707
+ loadProperty(this, "clear", data.clear);
1708
+ loadProperty(this, "key", data.key);
1709
+ loadProperty(this, "name", data.name);
1710
+ loadRangeProperty(this, "delay", data.delay);
1711
+ loadProperty(this, "detectRetina", data.detectRetina);
1712
+ loadRangeProperty(this, "duration", data.duration);
1713
+ loadProperty(this, "fpsLimit", data.fpsLimit);
1714
+ loadProperty(this, "hdr", data.hdr);
1715
+ loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1716
+ loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1717
+ loadProperty(this, "zLayers", data.zLayers);
2308
1718
  this.background.load(data.background);
2309
1719
  const fullScreen = data.fullScreen;
2310
1720
  if (isBoolean(fullScreen)) {
@@ -2313,170 +1723,44 @@
2313
1723
  else {
2314
1724
  this.fullScreen.load(fullScreen);
2315
1725
  }
2316
- this.particles.load(data.particles);
2317
- this.resize.load(data.resize);
2318
- this.style = deepExtend(this.style, data.style);
2319
- if (data.smooth !== undefined) {
2320
- this.smooth = data.smooth;
2321
- }
2322
- this.#pluginManager.plugins.forEach(plugin => {
2323
- plugin.loadOptions(this.#container, this, data);
2324
- });
2325
- }
2326
- #importPalette = palette => {
2327
- const paletteData = this.#pluginManager.getPalette(palette);
2328
- if (!paletteData) {
2329
- return;
2330
- }
2331
- this.load({
2332
- background: {
2333
- color: paletteData.background,
2334
- },
2335
- blend: {
2336
- enable: true,
2337
- mode: paletteData.blendMode,
2338
- },
2339
- particles: {
2340
- palette,
2341
- },
2342
- });
2343
- };
2344
- #importPreset = preset => {
2345
- this.load(this.#pluginManager.getPreset(preset));
2346
- };
2347
- }
2348
-
2349
- function paintBase(context, dimension, baseColor) {
2350
- context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
2351
- context.fillRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2352
- }
2353
- function paintImage(context, dimension, image, opacity) {
2354
- if (!image) {
2355
- return;
2356
- }
2357
- const prevAlpha = context.globalAlpha;
2358
- context.globalAlpha = opacity;
2359
- context.drawImage(image, originPoint.x, originPoint.y, dimension.width, dimension.height);
2360
- context.globalAlpha = prevAlpha;
2361
- }
2362
- function clear(context, dimension) {
2363
- context.clearRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2364
- }
2365
- function drawParticle(data) {
2366
- const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
2367
- x: pos.x,
2368
- y: pos.y,
2369
- };
2370
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
2371
- if (colorStyles.fill) {
2372
- context.fillStyle = colorStyles.fill;
2373
- }
2374
- const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
2375
- context.lineWidth = strokeWidth;
2376
- if (colorStyles.stroke) {
2377
- context.strokeStyle = colorStyles.stroke;
2378
- }
2379
- const drawData = {
2380
- context,
2381
- particle,
2382
- radius,
2383
- drawRadius: radius * drawScale,
2384
- opacity,
2385
- delta,
2386
- pixelRatio: container.retina.pixelRatio,
2387
- fill: fillEnabled,
2388
- stroke: strokeWidth > minStrokeWidth,
2389
- transformData,
2390
- position: { ...pos },
2391
- drawPosition,
2392
- drawScale,
2393
- };
2394
- for (const plugin of container.plugins) {
2395
- plugin.drawParticleTransform?.(drawData);
2396
- }
2397
- const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
2398
- drawBeforeEffect(effect, drawData);
2399
- drawShapeBeforeDraw(shape, drawData);
2400
- drawShape(shape, drawData);
2401
- drawShapeAfterDraw(shape, drawData);
2402
- drawAfterEffect(effect, drawData);
2403
- context.resetTransform();
2404
- }
2405
- function drawAfterEffect(drawer, data) {
2406
- if (!drawer?.drawAfter) {
2407
- return;
2408
- }
2409
- const { particle } = data;
2410
- if (!particle.effect) {
2411
- return;
2412
- }
2413
- drawer.drawAfter(data);
2414
- }
2415
- function drawBeforeEffect(drawer, data) {
2416
- if (!drawer?.drawBefore) {
2417
- return;
2418
- }
2419
- const { particle } = data;
2420
- if (!particle.effect) {
2421
- return;
2422
- }
2423
- drawer.drawBefore(data);
2424
- }
2425
- function drawShape(drawer, data) {
2426
- if (!drawer) {
2427
- return;
2428
- }
2429
- const { context, fill, particle, stroke } = data;
2430
- if (!particle.shape) {
2431
- return;
2432
- }
2433
- context.beginPath();
2434
- drawer.draw(data);
2435
- if (particle.shapeClose) {
2436
- context.closePath();
2437
- }
2438
- if (fill) {
2439
- context.fill();
2440
- }
2441
- if (stroke) {
2442
- context.stroke();
2443
- }
2444
- }
2445
- function drawShapeAfterDraw(drawer, data) {
2446
- if (!drawer?.afterDraw) {
2447
- return;
2448
- }
2449
- const { particle } = data;
2450
- if (!particle.shape) {
2451
- return;
2452
- }
2453
- drawer.afterDraw(data);
2454
- }
2455
- function drawShapeBeforeDraw(drawer, data) {
2456
- if (!drawer?.beforeDraw) {
2457
- return;
1726
+ this.particles.load(data.particles);
1727
+ this.resize.load(data.resize);
1728
+ this.style = deepExtend(this.style, data.style);
1729
+ loadProperty(this, "smooth", data.smooth);
1730
+ this.#pluginManager.plugins.forEach(plugin => {
1731
+ plugin.loadOptions(this.#container, this, data);
1732
+ });
2458
1733
  }
2459
- const { particle } = data;
2460
- if (!particle.shape) {
2461
- return;
1734
+ #importPalette(palette) {
1735
+ const paletteData = this.#pluginManager.getPalette(palette);
1736
+ if (!paletteData) {
1737
+ return;
1738
+ }
1739
+ this.load({
1740
+ background: {
1741
+ color: paletteData.background,
1742
+ },
1743
+ blend: {
1744
+ enable: true,
1745
+ mode: paletteData.blendMode,
1746
+ },
1747
+ particles: {
1748
+ palette,
1749
+ },
1750
+ });
2462
1751
  }
2463
- drawer.beforeDraw(data);
2464
- }
2465
- function drawParticlePlugin(context, plugin, particle, delta) {
2466
- if (!plugin.drawParticle) {
2467
- return;
1752
+ #importPreset(preset) {
1753
+ this.load(this.#pluginManager.getPreset(preset));
2468
1754
  }
2469
- plugin.drawParticle(context, particle, delta);
2470
1755
  }
2471
1756
 
2472
- const styleCache = new Map(), maxCacheSize = 1000, firstIndex = 0, rgbFixedPrecision = 2, hslFixedPrecision = 2;
1757
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
2473
1758
  function getCachedStyle(key, generator) {
2474
1759
  let cached = styleCache.get(key);
2475
1760
  if (!cached) {
2476
1761
  cached = generator();
2477
- if (styleCache.size >= maxCacheSize) {
2478
- const keysToDelete = [...styleCache.keys()].slice(firstIndex, maxCacheSize * half);
2479
- keysToDelete.forEach(k => styleCache.delete(k));
1762
+ if (styleCache.size > maxStyleCacheSize) {
1763
+ styleCache.clear();
2480
1764
  }
2481
1765
  styleCache.set(key, cached);
2482
1766
  }
@@ -2579,34 +1863,35 @@
2579
1863
  function stringToRgb(pluginManager, input) {
2580
1864
  return stringToRgba(pluginManager, input);
2581
1865
  }
1866
+ function hslChannel(temp1, temp2, temp3) {
1867
+ const temp3Min = 0, temp3Max = 1;
1868
+ if (temp3 < temp3Min) {
1869
+ temp3++;
1870
+ }
1871
+ if (temp3 > temp3Max) {
1872
+ temp3--;
1873
+ }
1874
+ if (temp3 * sextuple < temp3Max) {
1875
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1876
+ }
1877
+ if (temp3 * double < temp3Max) {
1878
+ return temp2;
1879
+ }
1880
+ if (temp3 * triple < temp3Max * double) {
1881
+ const temp3Offset = double / triple;
1882
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1883
+ }
1884
+ return temp1;
1885
+ }
2582
1886
  function hslToRgb(hsl) {
2583
1887
  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;
2584
1888
  if (s === sMin) {
2585
1889
  const grayscaleValue = Math.round(lNormalized * rgbMax);
2586
1890
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
2587
1891
  }
2588
- const channel = (temp1, temp2, temp3) => {
2589
- const temp3Min = 0, temp3Max = 1;
2590
- if (temp3 < temp3Min) {
2591
- temp3++;
2592
- }
2593
- if (temp3 > temp3Max) {
2594
- temp3--;
2595
- }
2596
- if (temp3 * sextuple < temp3Max) {
2597
- return temp1 + (temp2 - temp1) * sextuple * temp3;
2598
- }
2599
- if (temp3 * double < temp3Max) {
2600
- return temp2;
2601
- }
2602
- if (temp3 * triple < temp3Max * double) {
2603
- const temp3Offset = double / triple;
2604
- return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
2605
- }
2606
- return temp1;
2607
- }, temp1 = lNormalized < half
1892
+ const temp1 = lNormalized < half
2608
1893
  ? lNormalized * (sNormalizedOffset + sNormalized)
2609
- : 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));
1894
+ : 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));
2610
1895
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
2611
1896
  }
2612
1897
  function hslaToRgba(hsla) {
@@ -2619,7 +1904,7 @@
2619
1904
  };
2620
1905
  }
2621
1906
  function getRandomRgbColor(min) {
2622
- const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$3, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1907
+ const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$2, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
2623
1908
  return {
2624
1909
  b: getRgbInRangeValue(),
2625
1910
  g: getRgbInRangeValue(),
@@ -2630,21 +1915,18 @@
2630
1915
  const op = opacity ?? defaultOpacity$1, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2631
1916
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2632
1917
  }
2633
- function getHdrStyleFromRgb(color, opacity) {
2634
- return `color(display-p3 ${(color.r / rgbMax).toString()} ${(color.g / rgbMax).toString()} ${(color.b / rgbMax).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1918
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1919
+ const headroom = peakNits / sdrReferenceWhiteNits;
1920
+ return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2635
1921
  }
2636
1922
  function getSdrStyleFromRgb(color, opacity) {
2637
1923
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
2638
1924
  }
2639
1925
  function getStyleFromHsl(color, hdr, opacity) {
2640
1926
  const op = opacity ?? defaultOpacity$1, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2641
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromHsl(color, opacity) : getSdrStyleFromHsl(color, opacity)));
2642
- }
2643
- function getHdrStyleFromHsl(color, opacity) {
2644
- return getHdrStyleFromRgb(hslToRgb(color), opacity);
2645
- }
2646
- function getSdrStyleFromHsl(color, opacity) {
2647
- return `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${(opacity ?? defaultOpacity$1).toString()})`;
1927
+ return getCachedStyle(key, () => hdr
1928
+ ? getStyleFromRgb(hslToRgb(color), true, opacity)
1929
+ : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
2648
1930
  }
2649
1931
  function getHslFromAnimation(animation) {
2650
1932
  return animation === undefined
@@ -2766,22 +2048,14 @@
2766
2048
  const tsParticles = initEngine();
2767
2049
 
2768
2050
  class Blend {
2769
- enable;
2770
- mode;
2771
- constructor() {
2772
- this.mode = "destination-out";
2773
- this.enable = false;
2774
- }
2051
+ enable = false;
2052
+ mode = "destination-out";
2775
2053
  load(data) {
2776
2054
  if (isNull(data)) {
2777
2055
  return;
2778
2056
  }
2779
- if (data.mode !== undefined) {
2780
- this.mode = data.mode;
2781
- }
2782
- if (data.enable !== undefined) {
2783
- this.enable = data.enable;
2784
- }
2057
+ loadProperty(this, "mode", data.mode);
2058
+ loadProperty(this, "enable", data.enable);
2785
2059
  }
2786
2060
  }
2787
2061
 
@@ -2811,7 +2085,7 @@
2811
2085
  }
2812
2086
 
2813
2087
  async function loadBlendPlugin(engine) {
2814
- engine.checkVersion("4.1.2");
2088
+ engine.checkVersion("4.2.0");
2815
2089
  await engine.pluginManager.register(e => {
2816
2090
  e.pluginManager.addPlugin(new BlendPlugin());
2817
2091
  });
@@ -2848,7 +2122,7 @@
2848
2122
  }
2849
2123
 
2850
2124
  async function loadCircleShape(engine) {
2851
- engine.checkVersion("4.1.2");
2125
+ engine.checkVersion("4.2.0");
2852
2126
  await engine.pluginManager.register(e => {
2853
2127
  e.pluginManager.addShape(["circle"], () => {
2854
2128
  return Promise.resolve(new CircleDrawer());
@@ -2896,7 +2170,7 @@
2896
2170
  }
2897
2171
 
2898
2172
  async function loadHexColorPlugin(engine) {
2899
- engine.checkVersion("4.1.2");
2173
+ engine.checkVersion("4.2.0");
2900
2174
  await engine.pluginManager.register(e => {
2901
2175
  e.pluginManager.addColorManager("hex", new HexColorManager());
2902
2176
  });
@@ -2949,7 +2223,7 @@
2949
2223
  }
2950
2224
 
2951
2225
  async function loadHslColorPlugin(engine) {
2952
- engine.checkVersion("4.1.2");
2226
+ engine.checkVersion("4.2.0");
2953
2227
  await engine.pluginManager.register(e => {
2954
2228
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2955
2229
  });
@@ -2973,7 +2247,7 @@
2973
2247
  }
2974
2248
 
2975
2249
  async function loadMovePlugin(engine) {
2976
- engine.checkVersion("4.1.2");
2250
+ engine.checkVersion("4.2.0");
2977
2251
  await engine.pluginManager.register(e => {
2978
2252
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2979
2253
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2991,31 +2265,143 @@
2991
2265
  });
2992
2266
  }
2993
2267
 
2994
- class OpacityAnimation extends RangedAnimationOptions {
2995
- destroy;
2996
- constructor() {
2997
- super();
2998
- this.destroy = DestroyType.none;
2999
- this.speed = 2;
2268
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
2269
+ switch (destroyType) {
2270
+ case DestroyType.max:
2271
+ if (value >= maxValue) {
2272
+ particle.destroy();
2273
+ }
2274
+ break;
2275
+ case DestroyType.min:
2276
+ if (value <= minValue) {
2277
+ particle.destroy();
2278
+ }
2279
+ break;
2280
+ }
2281
+ }
2282
+ function initParticleNumericAnimationValue(options, pxRatio) {
2283
+ const valueRange = options.value, animationOptions = options.animation, res = {
2284
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
2285
+ enable: animationOptions.enable,
2286
+ value: getRangeValue(options.value) * pxRatio,
2287
+ max: getRangeMax(valueRange) * pxRatio,
2288
+ min: getRangeMin(valueRange) * pxRatio,
2289
+ loops: 0,
2290
+ maxLoops: getRangeValue(animationOptions.count),
2291
+ time: 0,
2292
+ }, decayOffset = 1;
2293
+ if (animationOptions.enable) {
2294
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
2295
+ switch (animationOptions.mode) {
2296
+ case AnimationMode.increase:
2297
+ res.status = AnimationStatus.increasing;
2298
+ break;
2299
+ case AnimationMode.decrease:
2300
+ res.status = AnimationStatus.decreasing;
2301
+ break;
2302
+ case AnimationMode.random:
2303
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2304
+ break;
2305
+ }
2306
+ const autoStatus = animationOptions.mode === AnimationMode.auto;
2307
+ switch (animationOptions.startValue) {
2308
+ case StartValueType.min:
2309
+ res.value = res.min;
2310
+ if (autoStatus) {
2311
+ res.status = AnimationStatus.increasing;
2312
+ }
2313
+ break;
2314
+ case StartValueType.max:
2315
+ res.value = res.max;
2316
+ if (autoStatus) {
2317
+ res.status = AnimationStatus.decreasing;
2318
+ }
2319
+ break;
2320
+ case StartValueType.random:
2321
+ default:
2322
+ res.value = randomInRangeValue(res);
2323
+ if (autoStatus) {
2324
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2325
+ }
2326
+ break;
2327
+ }
2328
+ }
2329
+ res.initialValue = res.value;
2330
+ return res;
2331
+ }
2332
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
2333
+ const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
2334
+ if (particle.destroyed ||
2335
+ !data.enable ||
2336
+ ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
2337
+ return;
2338
+ }
2339
+ const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
2340
+ data.time ??= 0;
2341
+ const delayTime = data.delayTime ?? minDelay;
2342
+ if (delayTime > minDelay && data.time < delayTime) {
2343
+ data.time += delta.value;
2344
+ if (data.time < delayTime) {
2345
+ return;
2346
+ }
2347
+ }
2348
+ switch (data.status) {
2349
+ case AnimationStatus.increasing:
2350
+ data.value += velocity;
2351
+ break;
2352
+ case AnimationStatus.decreasing:
2353
+ data.value -= velocity;
2354
+ break;
2355
+ }
2356
+ if (data.velocity && decay !== identity) {
2357
+ data.velocity *= decay;
2358
+ }
2359
+ switch (data.status) {
2360
+ case AnimationStatus.increasing:
2361
+ if (data.value >= maxValue) {
2362
+ if (changeDirection) {
2363
+ data.status = AnimationStatus.decreasing;
2364
+ }
2365
+ else {
2366
+ data.value -= maxValue;
2367
+ }
2368
+ data.loops ??= minLoops;
2369
+ data.loops++;
2370
+ }
2371
+ break;
2372
+ case AnimationStatus.decreasing:
2373
+ if (data.value <= minValue) {
2374
+ if (changeDirection) {
2375
+ data.status = AnimationStatus.increasing;
2376
+ }
2377
+ else {
2378
+ data.value += maxValue;
2379
+ }
2380
+ data.loops ??= minLoops;
2381
+ data.loops++;
2382
+ }
2383
+ break;
2384
+ }
2385
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
2386
+ if (!particle.destroyed) {
2387
+ data.value = clamp(data.value, minValue, maxValue);
3000
2388
  }
2389
+ }
2390
+
2391
+ class OpacityAnimation extends RangedAnimationOptions {
2392
+ destroy = DestroyType.none;
3001
2393
  load(data) {
3002
2394
  super.load(data);
3003
2395
  if (isNull(data)) {
3004
2396
  return;
3005
2397
  }
3006
- if (data.destroy !== undefined) {
3007
- this.destroy = data.destroy;
3008
- }
2398
+ loadProperty(this, "destroy", data.destroy);
3009
2399
  }
3010
2400
  }
3011
2401
 
3012
2402
  class Opacity extends RangedAnimationValueWithRandom {
3013
- animation;
3014
- constructor() {
3015
- super();
3016
- this.animation = new OpacityAnimation();
3017
- this.value = 1;
3018
- }
2403
+ animation = new OpacityAnimation();
2404
+ value = 1;
3019
2405
  load(data) {
3020
2406
  if (isNull(data)) {
3021
2407
  return;
@@ -3059,10 +2445,7 @@
3059
2445
  (particle.opacity.loops ?? none) < (particle.opacity.maxLoops ?? none))));
3060
2446
  }
3061
2447
  loadOptions(options, ...sources) {
3062
- options.opacity ??= new Opacity();
3063
- for (const source of sources) {
3064
- options.opacity.load(source?.opacity);
3065
- }
2448
+ loadOptionProperty(options, "opacity", Opacity, ...sources);
3066
2449
  }
3067
2450
  reset(particle) {
3068
2451
  if (!particle.opacity) {
@@ -3080,7 +2463,7 @@
3080
2463
  }
3081
2464
 
3082
2465
  async function loadOpacityUpdater(engine) {
3083
- engine.checkVersion("4.1.2");
2466
+ engine.checkVersion("4.2.0");
3084
2467
  await engine.pluginManager.register(e => {
3085
2468
  e.pluginManager.addParticleUpdater("opacity", container => {
3086
2469
  return Promise.resolve(new OpacityUpdater(container));
@@ -3088,7 +2471,7 @@
3088
2471
  });
3089
2472
  }
3090
2473
 
3091
- const minVelocity$4 = 0, boundsMin = 0;
2474
+ const boundsMin = 0;
3092
2475
  function bounceHorizontal(data) {
3093
2476
  if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
3094
2477
  (data.direction !== OutModeDirection.left && data.direction !== OutModeDirection.right)) {
@@ -3103,8 +2486,8 @@
3103
2486
  const velocity = data.particle.velocity.x;
3104
2487
  let bounced = false;
3105
2488
  if (data.outOfCanvas &&
3106
- ((data.direction === OutModeDirection.right && velocity > minVelocity$4) ||
3107
- (data.direction === OutModeDirection.left && velocity < minVelocity$4))) {
2489
+ ((data.direction === OutModeDirection.right && velocity > minVelocity) ||
2490
+ (data.direction === OutModeDirection.left && velocity < minVelocity))) {
3108
2491
  const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
3109
2492
  data.particle.velocity.x *= -newVelocity;
3110
2493
  bounced = true;
@@ -3137,8 +2520,8 @@
3137
2520
  const velocity = data.particle.velocity.y;
3138
2521
  let bounced = false;
3139
2522
  if (data.outOfCanvas &&
3140
- ((data.direction === OutModeDirection.bottom && velocity > minVelocity$4) ||
3141
- (data.direction === OutModeDirection.top && velocity < minVelocity$4))) {
2523
+ ((data.direction === OutModeDirection.bottom && velocity > minVelocity) ||
2524
+ (data.direction === OutModeDirection.top && velocity < minVelocity))) {
3142
2525
  const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
3143
2526
  data.particle.velocity.y *= -newVelocity;
3144
2527
  bounced = true;
@@ -3191,7 +2574,6 @@
3191
2574
  }
3192
2575
  }
3193
2576
 
3194
- const minVelocity$3 = 0;
3195
2577
  class DestroyOutMode {
3196
2578
  modes;
3197
2579
  constructor(_container) {
@@ -3210,10 +2592,10 @@
3210
2592
  break;
3211
2593
  case ParticleOutType.inside: {
3212
2594
  const { dx, dy } = getDistances(particle.position, particle.moveCenter), { x: vx, y: vy } = particle.velocity;
3213
- if ((vx < minVelocity$3 && dx > particle.moveCenter.radius) ||
3214
- (vy < minVelocity$3 && dy > particle.moveCenter.radius) ||
3215
- (vx >= minVelocity$3 && dx < -particle.moveCenter.radius) ||
3216
- (vy >= minVelocity$3 && dy < -particle.moveCenter.radius)) {
2595
+ if ((vx < minVelocity && dx > particle.moveCenter.radius) ||
2596
+ (vy < minVelocity && dy > particle.moveCenter.radius) ||
2597
+ (vx >= minVelocity && dx < -particle.moveCenter.radius) ||
2598
+ (vy >= minVelocity && dy < -particle.moveCenter.radius)) {
3217
2599
  return;
3218
2600
  }
3219
2601
  break;
@@ -3223,7 +2605,6 @@
3223
2605
  }
3224
2606
  }
3225
2607
 
3226
- const minVelocity$2 = 0;
3227
2608
  class NoneOutMode {
3228
2609
  modes;
3229
2610
  #container;
@@ -3243,10 +2624,10 @@
3243
2624
  }
3244
2625
  const gravityOptions = particle.options.move.gravity, container = this.#container, canvasSize = container.canvas.size, pRadius = particle.getRadius();
3245
2626
  if (!gravityOptions.enable) {
3246
- if ((particle.velocity.y > minVelocity$2 && particle.position.y <= canvasSize.height + pRadius) ||
3247
- (particle.velocity.y < minVelocity$2 && particle.position.y >= -pRadius) ||
3248
- (particle.velocity.x > minVelocity$2 && particle.position.x <= canvasSize.width + pRadius) ||
3249
- (particle.velocity.x < minVelocity$2 && particle.position.x >= -pRadius)) {
2627
+ if ((particle.velocity.y > minVelocity && particle.position.y <= canvasSize.height + pRadius) ||
2628
+ (particle.velocity.y < minVelocity && particle.position.y >= -pRadius) ||
2629
+ (particle.velocity.x > minVelocity && particle.position.x <= canvasSize.width + pRadius) ||
2630
+ (particle.velocity.x < minVelocity && particle.position.x >= -pRadius)) {
3250
2631
  return;
3251
2632
  }
3252
2633
  if (!isPointInside(particle.position, container.canvas.size, originPoint, pRadius, direction)) {
@@ -3265,7 +2646,7 @@
3265
2646
  }
3266
2647
  }
3267
2648
 
3268
- const minVelocity$1 = 0, minDistance = 0, updateVector = Vector.origin;
2649
+ const updateVector = Vector.origin;
3269
2650
  class OutOutMode {
3270
2651
  modes;
3271
2652
  #container;
@@ -3286,10 +2667,10 @@
3286
2667
  updateVector.angle = particle.velocity.angle + Math.PI;
3287
2668
  updateVector.addTo(particle.moveCenter);
3288
2669
  const { dx, dy } = getDistances(particle.position, updateVector);
3289
- if ((vx <= minVelocity$1 && dx >= minDistance) ||
3290
- (vy <= minVelocity$1 && dy >= minDistance) ||
3291
- (vx >= minVelocity$1 && dx <= minDistance) ||
3292
- (vy >= minVelocity$1 && dy <= minDistance)) {
2670
+ if ((vx <= minVelocity && dx >= minDistance) ||
2671
+ (vy <= minVelocity && dy >= minDistance) ||
2672
+ (vx >= minVelocity && dx <= minDistance) ||
2673
+ (vy >= minVelocity && dy <= minDistance)) {
3293
2674
  return;
3294
2675
  }
3295
2676
  particle.position.x = Math.floor(randomInRangeValue({
@@ -3413,21 +2794,21 @@
3413
2794
  this.#updateOutMode(particle, delta, outModes.right ?? outModes.default, OutModeDirection.right);
3414
2795
  this.#updateOutMode(particle, delta, outModes.top ?? outModes.default, OutModeDirection.top);
3415
2796
  }
3416
- #addUpdaterIfMissing = (particle, outMode, getUpdater) => {
2797
+ #addUpdaterIfMissing(particle, outMode, getUpdater) {
3417
2798
  const outModes = particle.options.move.outModes;
3418
2799
  if (!this.updaters.has(outMode) && checkOutMode(outModes, outMode)) {
3419
2800
  this.updaters.set(outMode, getUpdater(this.#container));
3420
2801
  }
3421
- };
3422
- #updateOutMode = (particle, delta, outMode, direction) => {
2802
+ }
2803
+ #updateOutMode(particle, delta, outMode, direction) {
3423
2804
  for (const updater of this.updaters.values()) {
3424
2805
  updater.update(particle, direction, delta, outMode);
3425
2806
  }
3426
- };
2807
+ }
3427
2808
  }
3428
2809
 
3429
2810
  async function loadOutModesUpdater(engine) {
3430
- engine.checkVersion("4.1.2");
2811
+ engine.checkVersion("4.2.0");
3431
2812
  await engine.pluginManager.register(e => {
3432
2813
  e.pluginManager.addParticleUpdater("outModes", container => {
3433
2814
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3498,7 +2879,7 @@
3498
2879
  }
3499
2880
 
3500
2881
  async function loadPaintUpdater(engine) {
3501
- engine.checkVersion("4.1.2");
2882
+ engine.checkVersion("4.2.0");
3502
2883
  await engine.pluginManager.register(e => {
3503
2884
  e.pluginManager.addParticleUpdater("paint", container => {
3504
2885
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3553,37 +2934,26 @@
3553
2934
  }
3554
2935
 
3555
2936
  async function loadRgbColorPlugin(engine) {
3556
- engine.checkVersion("4.1.2");
2937
+ engine.checkVersion("4.2.0");
3557
2938
  await engine.pluginManager.register(e => {
3558
2939
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3559
2940
  });
3560
2941
  }
3561
2942
 
3562
2943
  class SizeAnimation extends RangedAnimationOptions {
3563
- destroy;
3564
- constructor() {
3565
- super();
3566
- this.destroy = DestroyType.none;
3567
- this.speed = 5;
3568
- }
2944
+ destroy = DestroyType.none;
3569
2945
  load(data) {
3570
2946
  super.load(data);
3571
2947
  if (isNull(data)) {
3572
2948
  return;
3573
2949
  }
3574
- if (data.destroy !== undefined) {
3575
- this.destroy = data.destroy;
3576
- }
2950
+ loadProperty(this, "destroy", data.destroy);
3577
2951
  }
3578
2952
  }
3579
2953
 
3580
2954
  class Size extends RangedAnimationValueWithRandom {
3581
- animation;
3582
- constructor() {
3583
- super();
3584
- this.animation = new SizeAnimation();
3585
- this.value = 3;
3586
- }
2955
+ animation = new SizeAnimation();
2956
+ value = 3;
3587
2957
  load(data) {
3588
2958
  super.load(data);
3589
2959
  if (isNull(data)) {
@@ -3626,10 +2996,7 @@
3626
2996
  (particle.size.loops ?? minLoops) < (particle.size.maxLoops ?? minLoops))));
3627
2997
  }
3628
2998
  loadOptions(options, ...sources) {
3629
- options.size ??= new Size();
3630
- for (const source of sources) {
3631
- options.size.load(source?.size);
3632
- }
2999
+ loadOptionProperty(options, "size", Size, ...sources);
3633
3000
  }
3634
3001
  preInit(particle) {
3635
3002
  const pxRatio = this.#container.retina.pixelRatio, options = particle.options, sizeOptions = options.size;
@@ -3652,7 +3019,7 @@
3652
3019
  }
3653
3020
 
3654
3021
  async function loadSizeUpdater(engine) {
3655
- engine.checkVersion("4.1.2");
3022
+ engine.checkVersion("4.2.0");
3656
3023
  await engine.pluginManager.register(e => {
3657
3024
  e.pluginManager.addParticleUpdater("size", container => {
3658
3025
  return Promise.resolve(new SizeUpdater(container));
@@ -3661,7 +3028,7 @@
3661
3028
  }
3662
3029
 
3663
3030
  async function loadBasic(engine) {
3664
- engine.checkVersion("4.1.2");
3031
+ engine.checkVersion("4.2.0");
3665
3032
  await engine.pluginManager.register(async (e) => {
3666
3033
  await Promise.all([
3667
3034
  loadBlendPlugin(e),
@@ -3712,78 +3079,46 @@
3712
3079
  count;
3713
3080
  delay;
3714
3081
  duration;
3715
- wait;
3716
- constructor() {
3717
- this.wait = false;
3718
- }
3082
+ wait = false;
3719
3083
  load(data) {
3720
3084
  if (isNull(data)) {
3721
3085
  return;
3722
3086
  }
3723
- if (data.count !== undefined) {
3724
- this.count = data.count;
3725
- }
3726
- if (data.delay !== undefined) {
3727
- this.delay = setRangeValue(data.delay);
3728
- }
3729
- if (data.duration !== undefined) {
3730
- this.duration = setRangeValue(data.duration);
3731
- }
3732
- if (data.wait !== undefined) {
3733
- this.wait = data.wait;
3734
- }
3087
+ loadProperty(this, "count", data.count);
3088
+ loadRangeProperty(this, "delay", data.delay);
3089
+ loadRangeProperty(this, "duration", data.duration);
3090
+ loadProperty(this, "wait", data.wait);
3735
3091
  }
3736
3092
  }
3737
3093
 
3738
3094
  class EmitterRate {
3739
- delay;
3740
- quantity;
3741
- constructor() {
3742
- this.quantity = 1;
3743
- this.delay = 0.1;
3744
- }
3095
+ delay = 0.1;
3096
+ quantity = 1;
3745
3097
  load(data) {
3746
3098
  if (isNull(data)) {
3747
3099
  return;
3748
3100
  }
3749
- if (data.quantity !== undefined) {
3750
- this.quantity = setRangeValue(data.quantity);
3751
- }
3752
- if (data.delay !== undefined) {
3753
- this.delay = setRangeValue(data.delay);
3754
- }
3101
+ loadRangeProperty(this, "quantity", data.quantity);
3102
+ loadRangeProperty(this, "delay", data.delay);
3755
3103
  }
3756
3104
  }
3757
3105
 
3758
3106
  class EmitterShapeReplace {
3759
- color;
3760
- opacity;
3761
- constructor() {
3762
- this.color = false;
3763
- this.opacity = false;
3764
- }
3107
+ color = false;
3108
+ opacity = false;
3765
3109
  load(data) {
3766
3110
  if (isNull(data)) {
3767
3111
  return;
3768
3112
  }
3769
- if (data.color !== undefined) {
3770
- this.color = data.color;
3771
- }
3772
- if (data.opacity !== undefined) {
3773
- this.opacity = data.opacity;
3774
- }
3113
+ loadProperty(this, "color", data.color);
3114
+ loadProperty(this, "opacity", data.opacity);
3775
3115
  }
3776
3116
  }
3777
3117
 
3778
3118
  class EmitterShape {
3779
- options;
3780
- replace;
3781
- type;
3782
- constructor() {
3783
- this.options = {};
3784
- this.replace = new EmitterShapeReplace();
3785
- this.type = "square";
3786
- }
3119
+ options = {};
3120
+ replace = new EmitterShapeReplace();
3121
+ type = "square";
3787
3122
  load(data) {
3788
3123
  if (isNull(data)) {
3789
3124
  return;
@@ -3792,34 +3127,21 @@
3792
3127
  this.options = deepExtend({}, data.options ?? {});
3793
3128
  }
3794
3129
  this.replace.load(data.replace);
3795
- if (data.type !== undefined) {
3796
- this.type = data.type;
3797
- }
3130
+ loadProperty(this, "type", data.type);
3798
3131
  }
3799
3132
  }
3800
3133
 
3801
3134
  class EmitterSize {
3802
- height;
3803
- mode;
3804
- width;
3805
- constructor() {
3806
- this.mode = PixelMode.percent;
3807
- this.height = 0;
3808
- this.width = 0;
3809
- }
3135
+ height = 0;
3136
+ mode = PixelMode.percent;
3137
+ width = 0;
3810
3138
  load(data) {
3811
3139
  if (isNull(data)) {
3812
3140
  return;
3813
3141
  }
3814
- if (data.mode !== undefined) {
3815
- this.mode = data.mode;
3816
- }
3817
- if (data.height !== undefined) {
3818
- this.height = data.height;
3819
- }
3820
- if (data.width !== undefined) {
3821
- this.width = data.width;
3822
- }
3142
+ loadProperty(this, "mode", data.mode);
3143
+ loadProperty(this, "height", data.height);
3144
+ loadProperty(this, "width", data.width);
3823
3145
  }
3824
3146
  }
3825
3147
 
@@ -3842,50 +3164,35 @@
3842
3164
  }
3843
3165
 
3844
3166
  class Emitter {
3845
- autoPlay;
3167
+ autoPlay = true;
3846
3168
  direction;
3847
3169
  domId;
3848
- fill;
3849
- life;
3170
+ fill = true;
3171
+ life = new EmitterLife();
3850
3172
  name;
3851
3173
  particles;
3852
3174
  position;
3853
- rate;
3854
- shape;
3175
+ rate = new EmitterRate();
3176
+ shape = new EmitterShape();
3855
3177
  size;
3856
- spawn;
3178
+ spawn = new EmitterSpawn();
3857
3179
  spawnFillColor;
3858
3180
  spawnStrokeColor;
3859
- startCount;
3860
- constructor() {
3861
- this.autoPlay = true;
3862
- this.fill = true;
3863
- this.life = new EmitterLife();
3864
- this.rate = new EmitterRate();
3865
- this.shape = new EmitterShape();
3866
- this.spawn = new EmitterSpawn();
3867
- this.startCount = 0;
3868
- }
3181
+ startCount = 0;
3869
3182
  load(data) {
3870
3183
  if (isNull(data)) {
3871
3184
  return;
3872
3185
  }
3873
- if (data.autoPlay !== undefined) {
3874
- this.autoPlay = data.autoPlay;
3875
- }
3186
+ loadProperty(this, "autoPlay", data.autoPlay);
3876
3187
  if (data.size !== undefined) {
3877
3188
  this.size ??= new EmitterSize();
3878
3189
  this.size.load(data.size);
3879
3190
  }
3880
- if (data.direction !== undefined) {
3881
- this.direction = data.direction;
3882
- }
3883
- this.domId = data.domId;
3884
- if (data.fill !== undefined) {
3885
- this.fill = data.fill;
3886
- }
3191
+ loadProperty(this, "direction", data.direction);
3192
+ loadProperty(this, "domId", data.domId);
3193
+ loadProperty(this, "fill", data.fill);
3887
3194
  this.life.load(data.life);
3888
- this.name = data.name;
3195
+ loadProperty(this, "name", data.name);
3889
3196
  this.particles = executeOnSingleOrMultiple(data.particles, particles => {
3890
3197
  return deepExtend({}, particles);
3891
3198
  });
@@ -3909,9 +3216,7 @@
3909
3216
  this.spawnStrokeColor ??= new AnimatableColor();
3910
3217
  this.spawnStrokeColor.load(data.spawnStrokeColor);
3911
3218
  }
3912
- if (data.startCount !== undefined) {
3913
- this.startCount = data.startCount;
3914
- }
3219
+ loadProperty(this, "startCount", data.startCount);
3915
3220
  }
3916
3221
  }
3917
3222
 
@@ -3976,7 +3281,7 @@
3976
3281
  })(EmitterClickMode || (EmitterClickMode = {}));
3977
3282
 
3978
3283
  async function loadEmittersPluginSimple(engine) {
3979
- engine.checkVersion("4.1.2");
3284
+ engine.checkVersion("4.2.0");
3980
3285
  await engine.pluginManager.register(async (e) => {
3981
3286
  const instancesManager = await getEmittersInstancesManager(e);
3982
3287
  await addEmittersShapesManager(e);
@@ -3985,55 +3290,36 @@
3985
3290
  }
3986
3291
 
3987
3292
  class LifeDelay extends ValueWithRandom {
3988
- sync;
3989
- constructor() {
3990
- super();
3991
- this.sync = false;
3992
- }
3293
+ sync = false;
3993
3294
  load(data) {
3994
3295
  if (isNull(data)) {
3995
3296
  return;
3996
3297
  }
3997
3298
  super.load(data);
3998
- if (data.sync !== undefined) {
3999
- this.sync = data.sync;
4000
- }
3299
+ loadProperty(this, "sync", data.sync);
4001
3300
  }
4002
3301
  }
4003
3302
 
4004
3303
  class LifeDuration extends ValueWithRandom {
4005
- sync;
4006
- constructor() {
4007
- super();
4008
- this.sync = false;
4009
- }
3304
+ sync = false;
4010
3305
  load(data) {
4011
3306
  if (isNull(data)) {
4012
3307
  return;
4013
3308
  }
4014
3309
  super.load(data);
4015
- if (data.sync !== undefined) {
4016
- this.sync = data.sync;
4017
- }
3310
+ loadProperty(this, "sync", data.sync);
4018
3311
  }
4019
3312
  }
4020
3313
 
4021
3314
  class Life {
4022
- count;
4023
- delay;
4024
- duration;
4025
- constructor() {
4026
- this.count = 0;
4027
- this.delay = new LifeDelay();
4028
- this.duration = new LifeDuration();
4029
- }
3315
+ count = 0;
3316
+ delay = new LifeDelay();
3317
+ duration = new LifeDuration();
4030
3318
  load(data) {
4031
3319
  if (isNull(data)) {
4032
3320
  return;
4033
3321
  }
4034
- if (data.count !== undefined) {
4035
- this.count = data.count;
4036
- }
3322
+ loadProperty(this, "count", data.count);
4037
3323
  this.delay.load(data.delay);
4038
3324
  this.duration.load(data.duration);
4039
3325
  }
@@ -4092,7 +3378,7 @@
4092
3378
  }
4093
3379
  }
4094
3380
 
4095
- const noTime = 0, identity$2 = 1, infiniteValue = -1;
3381
+ const noTime = 0, identity$1 = 1, infiniteValue = -1;
4096
3382
  class LifeUpdater {
4097
3383
  #container;
4098
3384
  constructor(container) {
@@ -4103,7 +3389,7 @@
4103
3389
  if (!lifeOptions) {
4104
3390
  return;
4105
3391
  }
4106
- const delayFactor = lifeOptions.delay.sync ? identity$2 : getRandom(), durationFactor = lifeOptions.duration.sync ? identity$2 : getRandom();
3392
+ const delayFactor = lifeOptions.delay.sync ? identity$1 : getRandom(), durationFactor = lifeOptions.duration.sync ? identity$1 : getRandom();
4107
3393
  particle.life = {
4108
3394
  delay: container.retina.reduceFactor
4109
3395
  ? ((getRangeValue(lifeOptions.delay.value) * delayFactor) / container.retina.reduceFactor) *
@@ -4129,10 +3415,7 @@
4129
3415
  return !particle.destroyed;
4130
3416
  }
4131
3417
  loadOptions(options, ...sources) {
4132
- options.life ??= new Life();
4133
- for (const source of sources) {
4134
- options.life.load(source?.life);
4135
- }
3418
+ loadOptionProperty(options, "life", Life, ...sources);
4136
3419
  }
4137
3420
  update(particle, delta) {
4138
3421
  if (!this.isEnabled(particle) || !particle.life) {
@@ -4143,7 +3426,7 @@
4143
3426
  }
4144
3427
 
4145
3428
  async function loadLifeUpdater(engine) {
4146
- engine.checkVersion("4.1.2");
3429
+ engine.checkVersion("4.2.0");
4147
3430
  await engine.pluginManager.register(e => {
4148
3431
  e.pluginManager.addParticleUpdater("life", container => {
4149
3432
  return Promise.resolve(new LifeUpdater(container));
@@ -4152,39 +3435,25 @@
4152
3435
  }
4153
3436
 
4154
3437
  class MotionReduce {
4155
- factor;
4156
- value;
4157
- constructor() {
4158
- this.factor = 4;
4159
- this.value = true;
4160
- }
3438
+ factor = 4;
3439
+ value = true;
4161
3440
  load(data) {
4162
3441
  if (isNull(data)) {
4163
3442
  return;
4164
3443
  }
4165
- if (data.factor !== undefined) {
4166
- this.factor = data.factor;
4167
- }
4168
- if (data.value !== undefined) {
4169
- this.value = data.value;
4170
- }
3444
+ loadProperty(this, "factor", data.factor);
3445
+ loadProperty(this, "value", data.value);
4171
3446
  }
4172
3447
  }
4173
3448
 
4174
3449
  class Motion {
4175
- disable;
4176
- reduce;
4177
- constructor() {
4178
- this.disable = true;
4179
- this.reduce = new MotionReduce();
4180
- }
3450
+ disable = true;
3451
+ reduce = new MotionReduce();
4181
3452
  load(data) {
4182
3453
  if (isNull(data)) {
4183
3454
  return;
4184
3455
  }
4185
- if (data.disable !== undefined) {
4186
- this.disable = data.disable;
4187
- }
3456
+ loadProperty(this, "disable", data.disable);
4188
3457
  this.reduce.load(data.reduce);
4189
3458
  }
4190
3459
  }
@@ -4211,7 +3480,7 @@
4211
3480
  }
4212
3481
 
4213
3482
  async function loadMotionPlugin(engine) {
4214
- engine.checkVersion("4.1.2");
3483
+ engine.checkVersion("4.2.0");
4215
3484
  await engine.pluginManager.register(e => {
4216
3485
  e.pluginManager.addPlugin(new MotionPlugin());
4217
3486
  });
@@ -4280,39 +3549,24 @@
4280
3549
  }
4281
3550
 
4282
3551
  class RollLight {
4283
- enable;
4284
- value;
4285
- constructor() {
4286
- this.enable = false;
4287
- this.value = 0;
4288
- }
3552
+ enable = false;
3553
+ value = 0;
4289
3554
  load(data) {
4290
3555
  if (isNull(data)) {
4291
3556
  return;
4292
3557
  }
4293
- if (data.enable !== undefined) {
4294
- this.enable = data.enable;
4295
- }
4296
- if (data.value !== undefined) {
4297
- this.value = setRangeValue(data.value);
4298
- }
3558
+ loadProperty(this, "enable", data.enable);
3559
+ loadRangeProperty(this, "value", data.value);
4299
3560
  }
4300
3561
  }
4301
3562
 
4302
3563
  class Roll {
4303
3564
  backColor;
4304
- darken;
4305
- enable;
4306
- enlighten;
4307
- mode;
4308
- speed;
4309
- constructor() {
4310
- this.darken = new RollLight();
4311
- this.enable = false;
4312
- this.enlighten = new RollLight();
4313
- this.mode = RollMode.vertical;
4314
- this.speed = 25;
4315
- }
3565
+ darken = new RollLight();
3566
+ enable = false;
3567
+ enlighten = new RollLight();
3568
+ mode = RollMode.vertical;
3569
+ speed = 25;
4316
3570
  load(data) {
4317
3571
  if (isNull(data)) {
4318
3572
  return;
@@ -4321,16 +3575,10 @@
4321
3575
  this.backColor = OptionsColor.create(this.backColor, data.backColor);
4322
3576
  }
4323
3577
  this.darken.load(data.darken);
4324
- if (data.enable !== undefined) {
4325
- this.enable = data.enable;
4326
- }
3578
+ loadProperty(this, "enable", data.enable);
4327
3579
  this.enlighten.load(data.enlighten);
4328
- if (data.mode !== undefined) {
4329
- this.mode = data.mode;
4330
- }
4331
- if (data.speed !== undefined) {
4332
- this.speed = setRangeValue(data.speed);
4333
- }
3580
+ loadProperty(this, "mode", data.mode);
3581
+ loadRangeProperty(this, "speed", data.speed);
4334
3582
  }
4335
3583
  }
4336
3584
 
@@ -4354,10 +3602,7 @@
4354
3602
  return !particle.destroyed && !particle.spawning && !!roll?.enable;
4355
3603
  }
4356
3604
  loadOptions(options, ...sources) {
4357
- options.roll ??= new Roll();
4358
- for (const source of sources) {
4359
- options.roll.load(source?.roll);
4360
- }
3605
+ loadOptionProperty(options, "roll", Roll, ...sources);
4361
3606
  }
4362
3607
  update(particle, delta) {
4363
3608
  if (!this.isEnabled(particle)) {
@@ -4368,7 +3613,7 @@
4368
3613
  }
4369
3614
 
4370
3615
  async function loadRollUpdater(engine) {
4371
- engine.checkVersion("4.1.2");
3616
+ engine.checkVersion("4.2.0");
4372
3617
  await engine.pluginManager.register(e => {
4373
3618
  e.pluginManager.addParticleUpdater("roll", () => {
4374
3619
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -4377,58 +3622,33 @@
4377
3622
  }
4378
3623
 
4379
3624
  class RotateAnimation {
4380
- decay;
4381
- enable;
4382
- speed;
4383
- sync;
4384
- constructor() {
4385
- this.enable = false;
4386
- this.speed = 0;
4387
- this.decay = 0;
4388
- this.sync = false;
4389
- }
3625
+ decay = 0;
3626
+ enable = false;
3627
+ speed = 0;
3628
+ sync = false;
4390
3629
  load(data) {
4391
3630
  if (isNull(data)) {
4392
3631
  return;
4393
3632
  }
4394
- if (data.enable !== undefined) {
4395
- this.enable = data.enable;
4396
- }
4397
- if (data.speed !== undefined) {
4398
- this.speed = setRangeValue(data.speed);
4399
- }
4400
- if (data.decay !== undefined) {
4401
- this.decay = setRangeValue(data.decay);
4402
- }
4403
- if (data.sync !== undefined) {
4404
- this.sync = data.sync;
4405
- }
3633
+ loadProperty(this, "enable", data.enable);
3634
+ loadRangeProperty(this, "speed", data.speed);
3635
+ loadRangeProperty(this, "decay", data.decay);
3636
+ loadProperty(this, "sync", data.sync);
4406
3637
  }
4407
3638
  }
4408
3639
 
4409
3640
  class Rotate extends ValueWithRandom {
4410
- animation;
4411
- direction;
4412
- path;
4413
- constructor() {
4414
- super();
4415
- this.animation = new RotateAnimation();
4416
- this.direction = RotateDirection.clockwise;
4417
- this.path = false;
4418
- this.value = 0;
4419
- }
3641
+ animation = new RotateAnimation();
3642
+ direction = RotateDirection.clockwise;
3643
+ path = false;
4420
3644
  load(data) {
4421
3645
  if (isNull(data)) {
4422
3646
  return;
4423
3647
  }
4424
3648
  super.load(data);
4425
- if (data.direction !== undefined) {
4426
- this.direction = data.direction;
4427
- }
3649
+ loadProperty(this, "direction", data.direction);
4428
3650
  this.animation.load(data.animation);
4429
- if (data.path !== undefined) {
4430
- this.path = data.path;
4431
- }
3651
+ loadProperty(this, "path", data.path);
4432
3652
  }
4433
3653
  }
4434
3654
 
@@ -4466,7 +3686,7 @@
4466
3686
  }
4467
3687
  const rotateAnimation = rotateOptions.animation;
4468
3688
  if (rotateAnimation.enable) {
4469
- particle.rotate.decay = identity$3 - getRangeValue(rotateAnimation.decay);
3689
+ particle.rotate.decay = identity$2 - getRangeValue(rotateAnimation.decay);
4470
3690
  particle.rotate.velocity =
4471
3691
  (getRangeValue(rotateAnimation.speed) / doublePIDeg) * this.#container.retina.reduceFactor;
4472
3692
  if (!rotateAnimation.sync) {
@@ -4483,10 +3703,7 @@
4483
3703
  return !particle.destroyed && !particle.spawning && (!!rotate.value || rotate.animation.enable || rotate.path);
4484
3704
  }
4485
3705
  loadOptions(options, ...sources) {
4486
- options.rotate ??= new Rotate();
4487
- for (const source of sources) {
4488
- options.rotate.load(source?.rotate);
4489
- }
3706
+ loadOptionProperty(options, "rotate", Rotate, ...sources);
4490
3707
  }
4491
3708
  update(particle, delta) {
4492
3709
  if (!this.isEnabled(particle)) {
@@ -4502,7 +3719,7 @@
4502
3719
  }
4503
3720
 
4504
3721
  async function loadRotateUpdater(engine) {
4505
- engine.checkVersion("4.1.2");
3722
+ engine.checkVersion("4.2.0");
4506
3723
  await engine.pluginManager.register(e => {
4507
3724
  e.pluginManager.addParticleUpdater("rotate", container => {
4508
3725
  return Promise.resolve(new RotateUpdater(container));
@@ -4526,7 +3743,7 @@
4526
3743
  }
4527
3744
 
4528
3745
  async function loadSquareShape(engine) {
4529
- engine.checkVersion("4.1.2");
3746
+ engine.checkVersion("4.2.0");
4530
3747
  await engine.pluginManager.register(e => {
4531
3748
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
4532
3749
  });
@@ -4540,58 +3757,33 @@
4540
3757
  })(TiltDirection || (TiltDirection = {}));
4541
3758
 
4542
3759
  class TiltAnimation {
4543
- decay;
4544
- enable;
4545
- speed;
4546
- sync;
4547
- constructor() {
4548
- this.enable = false;
4549
- this.speed = 0;
4550
- this.decay = 0;
4551
- this.sync = false;
4552
- }
3760
+ decay = 0;
3761
+ enable = false;
3762
+ speed = 0;
3763
+ sync = false;
4553
3764
  load(data) {
4554
3765
  if (isNull(data)) {
4555
3766
  return;
4556
3767
  }
4557
- if (data.enable !== undefined) {
4558
- this.enable = data.enable;
4559
- }
4560
- if (data.speed !== undefined) {
4561
- this.speed = setRangeValue(data.speed);
4562
- }
4563
- if (data.decay !== undefined) {
4564
- this.decay = setRangeValue(data.decay);
4565
- }
4566
- if (data.sync !== undefined) {
4567
- this.sync = data.sync;
4568
- }
3768
+ loadProperty(this, "enable", data.enable);
3769
+ loadRangeProperty(this, "speed", data.speed);
3770
+ loadRangeProperty(this, "decay", data.decay);
3771
+ loadProperty(this, "sync", data.sync);
4569
3772
  }
4570
3773
  }
4571
3774
 
4572
3775
  class Tilt extends ValueWithRandom {
4573
- animation;
4574
- direction;
4575
- enable;
4576
- constructor() {
4577
- super();
4578
- this.animation = new TiltAnimation();
4579
- this.direction = TiltDirection.clockwise;
4580
- this.enable = false;
4581
- this.value = 0;
4582
- }
3776
+ animation = new TiltAnimation();
3777
+ direction = TiltDirection.clockwise;
3778
+ enable = false;
4583
3779
  load(data) {
4584
3780
  super.load(data);
4585
3781
  if (isNull(data)) {
4586
3782
  return;
4587
3783
  }
4588
3784
  this.animation.load(data.animation);
4589
- if (data.direction !== undefined) {
4590
- this.direction = data.direction;
4591
- }
4592
- if (data.enable !== undefined) {
4593
- this.enable = data.enable;
4594
- }
3785
+ loadProperty(this, "direction", data.direction);
3786
+ loadProperty(this, "enable", data.enable);
4595
3787
  }
4596
3788
  }
4597
3789
 
@@ -4616,8 +3808,8 @@
4616
3808
  particle.tilt = {
4617
3809
  enable: tiltOptions.enable,
4618
3810
  value: degToRad(getRangeValue(tiltOptions.value)),
4619
- sinDirection: getRandom() >= half ? identity$3 : -identity$3,
4620
- cosDirection: getRandom() >= half ? identity$3 : -identity$3,
3811
+ sinDirection: getRandom() >= half ? identity$2 : -identity$2,
3812
+ cosDirection: getRandom() >= half ? identity$2 : -identity$2,
4621
3813
  min: 0,
4622
3814
  max: doublePI,
4623
3815
  };
@@ -4637,7 +3829,7 @@
4637
3829
  }
4638
3830
  const tiltAnimation = particle.options.tilt?.animation;
4639
3831
  if (tiltAnimation?.enable) {
4640
- particle.tilt.decay = identity$3 - getRangeValue(tiltAnimation.decay);
3832
+ particle.tilt.decay = identity$2 - getRangeValue(tiltAnimation.decay);
4641
3833
  particle.tilt.velocity = (getRangeValue(tiltAnimation.speed) / maxAngle$1) * this.#container.retina.reduceFactor;
4642
3834
  if (!tiltAnimation.sync) {
4643
3835
  particle.tilt.velocity *= getRandom();
@@ -4649,10 +3841,7 @@
4649
3841
  return !particle.destroyed && !particle.spawning && !!tiltAnimation?.enable;
4650
3842
  }
4651
3843
  loadOptions(options, ...sources) {
4652
- options.tilt ??= new Tilt();
4653
- for (const source of sources) {
4654
- options.tilt.load(source?.tilt);
4655
- }
3844
+ loadOptionProperty(options, "tilt", Tilt, ...sources);
4656
3845
  }
4657
3846
  update(particle, delta) {
4658
3847
  if (!this.isEnabled(particle) || !particle.tilt) {
@@ -4663,7 +3852,7 @@
4663
3852
  }
4664
3853
 
4665
3854
  async function loadTiltUpdater(engine) {
4666
- engine.checkVersion("4.1.2");
3855
+ engine.checkVersion("4.2.0");
4667
3856
  await engine.pluginManager.register(e => {
4668
3857
  e.pluginManager.addParticleUpdater("tilt", container => {
4669
3858
  return Promise.resolve(new TiltUpdater(container));
@@ -4672,44 +3861,27 @@
4672
3861
  }
4673
3862
 
4674
3863
  class WobbleSpeed {
4675
- angle;
4676
- move;
4677
- constructor() {
4678
- this.angle = 50;
4679
- this.move = 10;
4680
- }
3864
+ angle = 50;
3865
+ move = 10;
4681
3866
  load(data) {
4682
3867
  if (isNull(data)) {
4683
3868
  return;
4684
3869
  }
4685
- if (data.angle !== undefined) {
4686
- this.angle = setRangeValue(data.angle);
4687
- }
4688
- if (data.move !== undefined) {
4689
- this.move = setRangeValue(data.move);
4690
- }
3870
+ loadRangeProperty(this, "angle", data.angle);
3871
+ loadRangeProperty(this, "move", data.move);
4691
3872
  }
4692
3873
  }
4693
3874
 
4694
3875
  class Wobble {
4695
- distance;
4696
- enable;
4697
- speed;
4698
- constructor() {
4699
- this.distance = 5;
4700
- this.enable = false;
4701
- this.speed = new WobbleSpeed();
4702
- }
3876
+ distance = 5;
3877
+ enable = false;
3878
+ speed = new WobbleSpeed();
4703
3879
  load(data) {
4704
3880
  if (isNull(data)) {
4705
3881
  return;
4706
3882
  }
4707
- if (data.distance !== undefined) {
4708
- this.distance = setRangeValue(data.distance);
4709
- }
4710
- if (data.enable !== undefined) {
4711
- this.enable = data.enable;
4712
- }
3883
+ loadRangeProperty(this, "distance", data.distance);
3884
+ loadProperty(this, "enable", data.enable);
4713
3885
  if (data.speed !== undefined) {
4714
3886
  if (isNumber(data.speed)) {
4715
3887
  this.speed.load({ angle: data.speed });
@@ -4771,10 +3943,7 @@
4771
3943
  return !particle.destroyed && !particle.spawning && !!particle.options.wobble?.enable;
4772
3944
  }
4773
3945
  loadOptions(options, ...sources) {
4774
- options.wobble ??= new Wobble();
4775
- for (const source of sources) {
4776
- options.wobble.load(source?.wobble);
4777
- }
3946
+ loadOptionProperty(options, "wobble", Wobble, ...sources);
4778
3947
  }
4779
3948
  update(particle, delta) {
4780
3949
  if (!this.isEnabled(particle)) {
@@ -4785,7 +3954,7 @@
4785
3954
  }
4786
3955
 
4787
3956
  async function loadWobbleUpdater(engine) {
4788
- engine.checkVersion("4.1.2");
3957
+ engine.checkVersion("4.2.0");
4789
3958
  await engine.pluginManager.register(e => {
4790
3959
  e.pluginManager.addParticleUpdater("wobble", container => {
4791
3960
  return Promise.resolve(new WobbleUpdater(container));
@@ -5000,7 +4169,7 @@
5000
4169
  return;
5001
4170
  }
5002
4171
  this.draw(ctx => {
5003
- clear(ctx, this.#canvasManager.size);
4172
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
5004
4173
  });
5005
4174
  }
5006
4175
  clear() {
@@ -5062,7 +4231,7 @@
5062
4231
  plugin.drawParticleSetup?.(context, particle, delta);
5063
4232
  }
5064
4233
  this.#applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
5065
- drawParticle({
4234
+ this.#drawParticle({
5066
4235
  container,
5067
4236
  context,
5068
4237
  particle,
@@ -5081,7 +4250,7 @@
5081
4250
  drawParticlePlugins(particle, delta) {
5082
4251
  this.draw(ctx => {
5083
4252
  for (const plugin of this.#drawParticlePlugins) {
5084
- drawParticlePlugin(ctx, plugin, particle, delta);
4253
+ this.#drawParticlePlugin(ctx, plugin, particle, delta);
5085
4254
  }
5086
4255
  });
5087
4256
  }
@@ -5181,12 +4350,19 @@
5181
4350
  }
5182
4351
  paintBase(baseColor) {
5183
4352
  this.draw(ctx => {
5184
- paintBase(ctx, this.#canvasManager.size, baseColor);
4353
+ ctx.fillStyle = baseColor ?? "rgba(0,0,0,0)";
4354
+ ctx.fillRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
5185
4355
  });
5186
4356
  }
5187
4357
  paintImage(image, opacity) {
5188
4358
  this.draw(ctx => {
5189
- paintImage(ctx, this.#canvasManager.size, image, opacity);
4359
+ if (!image) {
4360
+ return;
4361
+ }
4362
+ const prevAlpha = ctx.globalAlpha;
4363
+ ctx.globalAlpha = opacity;
4364
+ ctx.drawImage(image, originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4365
+ ctx.globalAlpha = prevAlpha;
5190
4366
  });
5191
4367
  }
5192
4368
  setContext(context) {
@@ -5200,15 +4376,15 @@
5200
4376
  }
5201
4377
  stop() {
5202
4378
  this.draw(ctx => {
5203
- clear(ctx, this.#canvasManager.size);
4379
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
5204
4380
  });
5205
4381
  }
5206
- #applyPostDrawUpdaters = particle => {
4382
+ #applyPostDrawUpdaters(particle) {
5207
4383
  for (const updater of this.#postDrawUpdaters) {
5208
4384
  updater.afterDraw?.(particle);
5209
4385
  }
5210
- };
5211
- #applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
4386
+ }
4387
+ #applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
5212
4388
  for (const updater of this.#preDrawUpdaters) {
5213
4389
  if (updater.getColorStyles) {
5214
4390
  const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
@@ -5227,8 +4403,114 @@
5227
4403
  }
5228
4404
  updater.beforeDraw?.(particle);
5229
4405
  }
5230
- };
5231
- #getPluginParticleColors = particle => {
4406
+ }
4407
+ #drawAfterEffect(drawer, data) {
4408
+ if (!drawer?.drawAfter) {
4409
+ return;
4410
+ }
4411
+ const { particle } = data;
4412
+ if (!particle.effect) {
4413
+ return;
4414
+ }
4415
+ drawer.drawAfter(data);
4416
+ }
4417
+ #drawBeforeEffect(drawer, data) {
4418
+ if (!drawer?.drawBefore) {
4419
+ return;
4420
+ }
4421
+ const { particle } = data;
4422
+ if (!particle.effect) {
4423
+ return;
4424
+ }
4425
+ drawer.drawBefore(data);
4426
+ }
4427
+ #drawParticle(data) {
4428
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
4429
+ x: pos.x,
4430
+ y: pos.y,
4431
+ };
4432
+ context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
4433
+ if (colorStyles.fill) {
4434
+ context.fillStyle = colorStyles.fill;
4435
+ }
4436
+ const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
4437
+ context.lineWidth = strokeWidth;
4438
+ if (colorStyles.stroke) {
4439
+ context.strokeStyle = colorStyles.stroke;
4440
+ }
4441
+ const drawData = {
4442
+ context,
4443
+ particle,
4444
+ radius,
4445
+ drawRadius: radius * drawScale,
4446
+ opacity,
4447
+ delta,
4448
+ pixelRatio: container.retina.pixelRatio,
4449
+ fill: fillEnabled,
4450
+ stroke: strokeWidth > minStrokeWidth,
4451
+ transformData,
4452
+ position: { ...pos },
4453
+ drawPosition,
4454
+ drawScale,
4455
+ };
4456
+ for (const plugin of container.plugins) {
4457
+ plugin.drawParticleTransform?.(drawData);
4458
+ }
4459
+ const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
4460
+ this.#drawBeforeEffect(effect, drawData);
4461
+ this.#drawShapeBeforeDraw(shape, drawData);
4462
+ this.#drawShape(shape, drawData);
4463
+ this.#drawShapeAfterDraw(shape, drawData);
4464
+ this.#drawAfterEffect(effect, drawData);
4465
+ context.resetTransform();
4466
+ }
4467
+ #drawParticlePlugin(context, plugin, particle, delta) {
4468
+ if (!plugin.drawParticle) {
4469
+ return;
4470
+ }
4471
+ plugin.drawParticle(context, particle, delta);
4472
+ }
4473
+ #drawShape(drawer, data) {
4474
+ if (!drawer) {
4475
+ return;
4476
+ }
4477
+ const { context, fill, particle, stroke } = data;
4478
+ if (!particle.shape) {
4479
+ return;
4480
+ }
4481
+ context.beginPath();
4482
+ drawer.draw(data);
4483
+ if (particle.shapeClose) {
4484
+ context.closePath();
4485
+ }
4486
+ if (fill) {
4487
+ context.fill();
4488
+ }
4489
+ if (stroke) {
4490
+ context.stroke();
4491
+ }
4492
+ }
4493
+ #drawShapeAfterDraw(drawer, data) {
4494
+ if (!drawer?.afterDraw) {
4495
+ return;
4496
+ }
4497
+ const { particle } = data;
4498
+ if (!particle.shape) {
4499
+ return;
4500
+ }
4501
+ drawer.afterDraw(data);
4502
+ }
4503
+ #drawShapeBeforeDraw(drawer, data) {
4504
+ if (!drawer?.beforeDraw) {
4505
+ return;
4506
+ }
4507
+ const { particle } = data;
4508
+ if (!particle.shape) {
4509
+ return;
4510
+ }
4511
+ drawer.beforeDraw(data);
4512
+ }
4513
+ #getPluginParticleColors(particle) {
5232
4514
  let fColor, sColor;
5233
4515
  for (const plugin of this.#colorPlugins) {
5234
4516
  if (!fColor && plugin.particleFillColor) {
@@ -5244,7 +4526,7 @@
5244
4526
  this.#reusablePluginColors[fColorIndex] = fColor;
5245
4527
  this.#reusablePluginColors[sColorIndex] = sColor;
5246
4528
  return this.#reusablePluginColors;
5247
- };
4529
+ }
5248
4530
  }
5249
4531
 
5250
4532
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -5376,6 +4658,7 @@
5376
4658
  obs.observe(element, { attributes: true });
5377
4659
  });
5378
4660
  this.initPlugins();
4661
+ this.#initContext();
5379
4662
  this.render.init();
5380
4663
  }
5381
4664
  initBackground() {
@@ -5385,7 +4668,7 @@
5385
4668
  }
5386
4669
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
5387
4670
  if (color) {
5388
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity);
4671
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
5389
4672
  }
5390
4673
  else {
5391
4674
  elementStyle.backgroundColor = "";
@@ -5407,7 +4690,7 @@
5407
4690
  if (this.#generated && this.domElement) {
5408
4691
  this.domElement.remove();
5409
4692
  }
5410
- const container = this.#container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4693
+ const domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
5411
4694
  this.domElement = domCanvas;
5412
4695
  this.#generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
5413
4696
  this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
@@ -5428,26 +4711,6 @@
5428
4711
  const pxRatio = this.#container.retina.pixelRatio, retinaSize = this.size;
5429
4712
  renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
5430
4713
  renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
5431
- const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
5432
- this.render.setContextSettings({
5433
- alpha: true,
5434
- colorSpace: canSupportHdrQuery?.matches && container.hdr ? "display-p3" : "srgb",
5435
- desynchronized: true,
5436
- willReadFrequently: false,
5437
- });
5438
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
5439
- this.#safeMutationObserver(obs => {
5440
- obs.disconnect();
5441
- });
5442
- container.retina.init();
5443
- this.initBackground();
5444
- this.#safeMutationObserver(obs => {
5445
- const element = this.domElement;
5446
- if (!element || !(element instanceof Node)) {
5447
- return;
5448
- }
5449
- obs.observe(element, { attributes: true });
5450
- });
5451
4714
  }
5452
4715
  resize() {
5453
4716
  const element = this.domElement;
@@ -5515,12 +4778,30 @@
5515
4778
  await container.refresh();
5516
4779
  }
5517
4780
  }
5518
- #applyResizePlugins = () => {
4781
+ #applyResizePlugins() {
5519
4782
  for (const plugin of this.#resizePlugins) {
5520
4783
  plugin.resize?.();
5521
4784
  }
5522
- };
5523
- #initStyle = () => {
4785
+ }
4786
+ #initContext() {
4787
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4788
+ safeMatchMedia("(color-gamut: p3)")?.matches &&
4789
+ safeMatchMedia("(dynamic-range: high)")?.matches;
4790
+ this.render.setContextSettings({
4791
+ alpha: true,
4792
+ desynchronized: true,
4793
+ willReadFrequently: false,
4794
+ ...(canSupportHdr
4795
+ ? { colorSpace: "display-p3", colorType: "float16" }
4796
+ : { colorSpace: "srgb" }),
4797
+ });
4798
+ const renderCanvas = this.renderCanvas;
4799
+ if (!renderCanvas) {
4800
+ return;
4801
+ }
4802
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4803
+ }
4804
+ #initStyle() {
5524
4805
  const element = this.domElement, options = this.#container.actualOptions;
5525
4806
  if (!element) {
5526
4807
  return;
@@ -5541,8 +4822,8 @@
5541
4822
  }
5542
4823
  element.style.setProperty(key, value, "important");
5543
4824
  }
5544
- };
5545
- #repairStyle = () => {
4825
+ }
4826
+ #repairStyle() {
5546
4827
  const element = this.domElement;
5547
4828
  if (!element) {
5548
4829
  return;
@@ -5561,27 +4842,27 @@
5561
4842
  }
5562
4843
  observer.observe(element, { attributes: true });
5563
4844
  });
5564
- };
5565
- #resetOriginalStyle = () => {
4845
+ }
4846
+ #resetOriginalStyle() {
5566
4847
  const element = this.domElement, originalStyle = this.#originalStyle;
5567
4848
  if (!element || !originalStyle) {
5568
4849
  return;
5569
4850
  }
5570
4851
  setStyle(element, originalStyle, true);
5571
- };
5572
- #safeMutationObserver = callback => {
4852
+ }
4853
+ #safeMutationObserver(callback) {
5573
4854
  if (!this.#mutationObserver) {
5574
4855
  return;
5575
4856
  }
5576
4857
  callback(this.#mutationObserver);
5577
- };
5578
- #setFullScreenStyle = () => {
4858
+ }
4859
+ #setFullScreenStyle() {
5579
4860
  const element = this.domElement;
5580
4861
  if (!element) {
5581
4862
  return;
5582
4863
  }
5583
4864
  setStyle(element, getFullScreenStyle(this.#container.actualOptions.fullScreen.zIndex), true);
5584
- };
4865
+ }
5585
4866
  }
5586
4867
 
5587
4868
  class EventListeners {
@@ -5606,7 +4887,7 @@
5606
4887
  removeListeners() {
5607
4888
  this.#manageListeners(false);
5608
4889
  }
5609
- #handleVisibilityChange = () => {
4890
+ #handleVisibilityChange() {
5610
4891
  const container = this.#container, options = container.actualOptions;
5611
4892
  if (!options.pauseOnBlur) {
5612
4893
  return;
@@ -5624,8 +4905,8 @@
5624
4905
  container.draw(true);
5625
4906
  }
5626
4907
  }
5627
- };
5628
- #handleWindowResize = () => {
4908
+ }
4909
+ #handleWindowResize() {
5629
4910
  if (this.#resizeTimeout) {
5630
4911
  clearTimeout(this.#resizeTimeout);
5631
4912
  this.#resizeTimeout = undefined;
@@ -5635,13 +4916,13 @@
5635
4916
  await canvas.windowResize();
5636
4917
  };
5637
4918
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
5638
- };
5639
- #manageListeners = add => {
4919
+ }
4920
+ #manageListeners(add) {
5640
4921
  const handlers = this.#handlers;
5641
4922
  this.#manageResize(add);
5642
4923
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
5643
- };
5644
- #manageResize = add => {
4924
+ }
4925
+ #manageResize(add) {
5645
4926
  const handlers = this.#handlers, container = this.#container, options = container.actualOptions;
5646
4927
  if (!options.resize.enable) {
5647
4928
  return;
@@ -5668,7 +4949,7 @@
5668
4949
  });
5669
4950
  this.#resizeObserver.observe(canvasEl);
5670
4951
  }
5671
- };
4952
+ }
5672
4953
  }
5673
4954
 
5674
4955
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
@@ -5695,6 +4976,131 @@
5695
4976
  data.setCb(data.radius);
5696
4977
  }
5697
4978
  }
4979
+ function normalizeAngle(angle, modulus) {
4980
+ const normalized = angle % modulus;
4981
+ return normalized < defaultAngle ? normalized + modulus : normalized;
4982
+ }
4983
+ function initParticleState(particle, id, group) {
4984
+ particle.id = id;
4985
+ particle.group = group;
4986
+ particle.justWarped = false;
4987
+ particle.effectClose = true;
4988
+ particle.shapeClose = true;
4989
+ particle.pathRotation = false;
4990
+ particle.lastPathTime = 0;
4991
+ particle.destroyed = false;
4992
+ particle.unbreakable = false;
4993
+ particle.isRotating = false;
4994
+ particle.rotation = 0;
4995
+ particle.misplaced = false;
4996
+ particle.retina = {
4997
+ maxDistance: {},
4998
+ maxSpeed: 0,
4999
+ moveDrift: 0,
5000
+ moveSpeed: 0,
5001
+ sizeAnimationSpeed: 0,
5002
+ };
5003
+ particle.size = {
5004
+ value: 1,
5005
+ max: 1,
5006
+ min: 1,
5007
+ enable: false,
5008
+ };
5009
+ particle.outType = ParticleOutType.normal;
5010
+ particle.ignoresResizeRatio = true;
5011
+ }
5012
+ function resolveParticleOptions(particle, container, pluginManager, overrideOptions) {
5013
+ const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates;
5014
+ particle.effect = itemFromSingleOrMultiple(particlesOptions.effect.type, particle.id, reduceDuplicates);
5015
+ particle.shape = itemFromSingleOrMultiple(particlesOptions.shape.type, particle.id, reduceDuplicates);
5016
+ const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
5017
+ if (overrideOptions) {
5018
+ if (overrideOptions.effect) {
5019
+ const overrideEffectType = overrideOptions.effect.type;
5020
+ if (overrideEffectType && overrideEffectType !== particle.effect) {
5021
+ const effect = itemFromSingleOrMultiple(overrideEffectType, particle.id, reduceDuplicates);
5022
+ if (effect) {
5023
+ particle.effect = effect;
5024
+ }
5025
+ }
5026
+ effectOptions.load(overrideOptions.effect);
5027
+ }
5028
+ if (overrideOptions.shape) {
5029
+ const overrideShapeType = overrideOptions.shape.type;
5030
+ if (overrideShapeType && overrideShapeType !== particle.shape) {
5031
+ const shape = itemFromSingleOrMultiple(overrideShapeType, particle.id, reduceDuplicates);
5032
+ if (shape) {
5033
+ particle.shape = shape;
5034
+ }
5035
+ }
5036
+ shapeOptions.load(overrideOptions.shape);
5037
+ }
5038
+ }
5039
+ if (particle.effect === randomColorValue) {
5040
+ const availableEffects = [...container.effectDrawers.keys()];
5041
+ particle.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
5042
+ }
5043
+ if (particle.shape === randomColorValue) {
5044
+ const availableShapes = [...container.shapeDrawers.keys()];
5045
+ particle.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
5046
+ }
5047
+ particle.effectData = particle.effect
5048
+ ? loadEffectData(particle.effect, effectOptions, particle.id, reduceDuplicates)
5049
+ : undefined;
5050
+ particle.shapeData = particle.shape
5051
+ ? loadShapeData(particle.shape, shapeOptions, particle.id, reduceDuplicates)
5052
+ : undefined;
5053
+ particlesOptions.load(overrideOptions);
5054
+ const effectData = particle.effectData, shapeData = particle.shapeData;
5055
+ if (effectData) {
5056
+ particlesOptions.load(effectData.particles);
5057
+ }
5058
+ if (shapeData) {
5059
+ particlesOptions.load(shapeData.particles);
5060
+ }
5061
+ particle.effectClose = effectData?.close ?? particlesOptions.effect.close;
5062
+ particle.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
5063
+ return particlesOptions;
5064
+ }
5065
+ function initParticleDrawers(particle, container) {
5066
+ let effectDrawer, shapeDrawer;
5067
+ if (particle.effect) {
5068
+ effectDrawer = container.effectDrawers.get(particle.effect);
5069
+ }
5070
+ if (effectDrawer?.loadEffect) {
5071
+ effectDrawer.loadEffect(particle);
5072
+ }
5073
+ if (particle.shape) {
5074
+ shapeDrawer = container.shapeDrawers.get(particle.shape);
5075
+ }
5076
+ if (shapeDrawer?.loadShape) {
5077
+ shapeDrawer.loadShape(particle);
5078
+ }
5079
+ const sideCountFunc = shapeDrawer?.getSidesCount;
5080
+ if (sideCountFunc) {
5081
+ particle.sides = sideCountFunc(particle);
5082
+ }
5083
+ }
5084
+ function runUpdaterPreInit(updaters, particle) {
5085
+ for (const updater of updaters) {
5086
+ updater.preInit?.(particle);
5087
+ }
5088
+ }
5089
+ function runUpdaterInit(updaters, particle) {
5090
+ for (const updater of updaters) {
5091
+ updater.init(particle);
5092
+ }
5093
+ }
5094
+ function runDrawerInit(container, particle) {
5095
+ const shapeDrawer = particle.shape ? container.shapeDrawers.get(particle.shape) : undefined, effectDrawer = particle.effect ? container.effectDrawers.get(particle.effect) : undefined;
5096
+ effectDrawer?.particleInit?.(container, particle);
5097
+ shapeDrawer?.particleInit?.(container, particle);
5098
+ }
5099
+ function runParticleCreatedPlugins(container, particle) {
5100
+ for (const plugin of container.particleCreatedPlugins) {
5101
+ plugin.particleCreated?.(particle);
5102
+ }
5103
+ }
5698
5104
  class Particle {
5699
5105
  backColor;
5700
5106
  bubble;
@@ -5820,88 +5226,20 @@
5820
5226
  const rotateData = this.getRotateData(), rotating = this.isRotating;
5821
5227
  this.#cachedTransform.a = rotateData.cos * (externalTransform.a ?? defaultTransform.a);
5822
5228
  this.#cachedTransform.b = rotating
5823
- ? rotateData.sin * (externalTransform.b ?? identity$3)
5229
+ ? rotateData.sin * (externalTransform.b ?? identity$2)
5824
5230
  : (externalTransform.b ?? defaultTransform.b);
5825
5231
  this.#cachedTransform.c = rotating
5826
- ? -rotateData.sin * (externalTransform.c ?? identity$3)
5232
+ ? -rotateData.sin * (externalTransform.c ?? identity$2)
5827
5233
  : (externalTransform.c ?? defaultTransform.c);
5828
5234
  this.#cachedTransform.d = rotateData.cos * (externalTransform.d ?? defaultTransform.d);
5829
5235
  return this.#cachedTransform;
5830
5236
  }
5831
5237
  init(id, position, overrideOptions, group) {
5832
5238
  const container = this.#container;
5833
- this.id = id;
5834
- this.group = group;
5835
- this.justWarped = false;
5836
- this.effectClose = true;
5837
- this.shapeClose = true;
5838
- this.pathRotation = false;
5839
- this.lastPathTime = 0;
5840
- this.destroyed = false;
5841
- this.unbreakable = false;
5842
- this.isRotating = false;
5843
- this.rotation = 0;
5844
- this.misplaced = false;
5845
- this.retina = {
5846
- maxDistance: {},
5847
- maxSpeed: 0,
5848
- moveDrift: 0,
5849
- moveSpeed: 0,
5850
- sizeAnimationSpeed: 0,
5851
- };
5852
- this.size = {
5853
- value: 1,
5854
- max: 1,
5855
- min: 1,
5856
- enable: false,
5857
- };
5858
- this.outType = ParticleOutType.normal;
5859
- this.ignoresResizeRatio = true;
5860
- const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
5861
- this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
5862
- this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
5863
- const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
5864
- if (overrideOptions) {
5865
- if (overrideOptions.effect?.type && overrideOptions.effect.type !== this.effect) {
5866
- const overrideEffectType = overrideOptions.effect.type, effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
5867
- if (effect) {
5868
- this.effect = effect;
5869
- effectOptions.load(overrideOptions.effect);
5870
- }
5871
- }
5872
- if (overrideOptions.shape?.type && overrideOptions.shape.type !== this.shape) {
5873
- const overrideShapeType = overrideOptions.shape.type, shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
5874
- if (shape) {
5875
- this.shape = shape;
5876
- shapeOptions.load(overrideOptions.shape);
5877
- }
5878
- }
5879
- }
5880
- if (this.effect === randomColorValue) {
5881
- const availableEffects = [...this.#container.effectDrawers.keys()];
5882
- this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
5883
- }
5884
- if (this.shape === randomColorValue) {
5885
- const availableShapes = [...this.#container.shapeDrawers.keys()];
5886
- this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
5887
- }
5888
- this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
5889
- this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
5890
- particlesOptions.load(overrideOptions);
5891
- const effectData = this.effectData, shapeData = this.shapeData;
5892
- if (effectData) {
5893
- particlesOptions.load(effectData.particles);
5894
- }
5895
- if (shapeData) {
5896
- particlesOptions.load(shapeData.particles);
5897
- }
5898
- this.effectClose = effectData?.close ?? particlesOptions.effect.close;
5899
- this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
5900
- this.options = particlesOptions;
5239
+ initParticleState(this, id, group);
5240
+ this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
5901
5241
  container.retina.initParticle(this);
5902
- for (const updater of container.particleUpdaters) {
5903
- updater.preInit?.(this);
5904
- }
5242
+ runUpdaterPreInit(container.particleUpdaters, this);
5905
5243
  this.bubble = {
5906
5244
  inRange: false,
5907
5245
  };
@@ -5914,32 +5252,11 @@
5914
5252
  this.velocity = this.initialVelocity.copy();
5915
5253
  this.zIndexFactor = this.position.z / container.zLayers;
5916
5254
  this.sides = 24;
5917
- let effectDrawer, shapeDrawer;
5918
- if (this.effect) {
5919
- effectDrawer = container.effectDrawers.get(this.effect);
5920
- }
5921
- if (effectDrawer?.loadEffect) {
5922
- effectDrawer.loadEffect(this);
5923
- }
5924
- if (this.shape) {
5925
- shapeDrawer = container.shapeDrawers.get(this.shape);
5926
- }
5927
- if (shapeDrawer?.loadShape) {
5928
- shapeDrawer.loadShape(this);
5929
- }
5930
- const sideCountFunc = shapeDrawer?.getSidesCount;
5931
- if (sideCountFunc) {
5932
- this.sides = sideCountFunc(this);
5933
- }
5255
+ initParticleDrawers(this, container);
5934
5256
  this.spawning = false;
5935
- for (const updater of container.particleUpdaters) {
5936
- updater.init(this);
5937
- }
5938
- effectDrawer?.particleInit?.(container, this);
5939
- shapeDrawer?.particleInit?.(container, this);
5940
- for (const plugin of container.particleCreatedPlugins) {
5941
- plugin.particleCreated?.(this);
5942
- }
5257
+ runUpdaterInit(container.particleUpdaters, this);
5258
+ runDrawerInit(container, this);
5259
+ runParticleCreatedPlugins(container, this);
5943
5260
  }
5944
5261
  isInsideCanvas(direction) {
5945
5262
  return this.#getInsideCanvasResult({ direction }).inside;
@@ -5953,15 +5270,15 @@
5953
5270
  }
5954
5271
  const angle = this.roll.angle;
5955
5272
  if (this.roll.horizontal && this.roll.vertical) {
5956
- const normalizedAngle = angle % doublePI, adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + doublePI : normalizedAngle;
5273
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5957
5274
  return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
5958
5275
  }
5959
5276
  if (this.roll.horizontal) {
5960
- const normalizedAngle = (angle + Math.PI * half) % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
5277
+ const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
5961
5278
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5962
5279
  }
5963
5280
  if (this.roll.vertical) {
5964
- const normalizedAngle = angle % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
5281
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5965
5282
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5966
5283
  }
5967
5284
  return false;
@@ -5974,10 +5291,10 @@
5974
5291
  updater.reset?.(this);
5975
5292
  }
5976
5293
  }
5977
- #calcPosition = (position, zIndex) => {
5294
+ #calcPosition(position, zIndex) {
5978
5295
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
5979
- const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
5980
- while (!signal.aborted) {
5296
+ const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
5297
+ for (;;) {
5981
5298
  for (const plugin of plugins) {
5982
5299
  const pluginPos = plugin.particlePosition?.(posVec, this);
5983
5300
  if (pluginPos) {
@@ -6005,9 +5322,8 @@
6005
5322
  tryCount += tryCountIncrement;
6006
5323
  posVec = undefined;
6007
5324
  }
6008
- return posVec;
6009
- };
6010
- #calculateVelocity = () => {
5325
+ }
5326
+ #calculateVelocity() {
6011
5327
  const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
6012
5328
  if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
6013
5329
  return res;
@@ -6023,8 +5339,8 @@
6023
5339
  res.length *= getRandom();
6024
5340
  }
6025
5341
  return res;
6026
- };
6027
- #fixHorizontal = (pos, radius, outMode) => {
5342
+ }
5343
+ #fixHorizontal(pos, radius, outMode) {
6028
5344
  fixOutMode({
6029
5345
  outMode,
6030
5346
  checkModes: [OutMode.bounce],
@@ -6033,8 +5349,8 @@
6033
5349
  setCb: (value) => (pos.x += value),
6034
5350
  radius,
6035
5351
  });
6036
- };
6037
- #fixVertical = (pos, radius, outMode) => {
5352
+ }
5353
+ #fixVertical(pos, radius, outMode) {
6038
5354
  fixOutMode({
6039
5355
  outMode,
6040
5356
  checkModes: [OutMode.bounce],
@@ -6043,8 +5359,8 @@
6043
5359
  setCb: (value) => (pos.y += value),
6044
5360
  radius,
6045
5361
  });
6046
- };
6047
- #getDefaultInsideCanvasResult = (direction, outMode) => {
5362
+ }
5363
+ #getDefaultInsideCanvasResult(direction, outMode) {
6048
5364
  const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
6049
5365
  if (direction === OutModeDirection.bottom) {
6050
5366
  return {
@@ -6077,8 +5393,8 @@
6077
5393
  position.x <= canvasSize.width + radius,
6078
5394
  reason: "default",
6079
5395
  };
6080
- };
6081
- #getInsideCanvasCallbackData = (direction, outMode) => {
5396
+ }
5397
+ #getInsideCanvasCallbackData(direction, outMode) {
6082
5398
  return {
6083
5399
  canvasSize: this.#container.canvas.size,
6084
5400
  direction,
@@ -6086,8 +5402,8 @@
6086
5402
  particle: this,
6087
5403
  radius: this.getRadius(),
6088
5404
  };
6089
- };
6090
- #getInsideCanvasResult = (data) => {
5405
+ }
5406
+ #getInsideCanvasResult(data) {
6091
5407
  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;
6092
5408
  if (!shapeCheck && !effectCheck) {
6093
5409
  return defaultResult;
@@ -6102,8 +5418,8 @@
6102
5418
  };
6103
5419
  }
6104
5420
  return shapeResult ?? effectResult ?? defaultResult;
6105
- };
6106
- #getRollColor = color => {
5421
+ }
5422
+ #getRollColor(color) {
6107
5423
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
6108
5424
  return color;
6109
5425
  }
@@ -6117,8 +5433,8 @@
6117
5433
  return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
6118
5434
  }
6119
5435
  return color;
6120
- };
6121
- #initPosition = position => {
5436
+ }
5437
+ #initPosition(position) {
6122
5438
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
6123
5439
  if (!initialPosition) {
6124
5440
  throw new Error("a valid position cannot be found for particle");
@@ -6141,8 +5457,8 @@
6141
5457
  break;
6142
5458
  }
6143
5459
  this.offset = Vector.origin;
6144
- };
6145
- #normalizeInsideCanvasResult = (result, reason) => {
5460
+ }
5461
+ #normalizeInsideCanvasResult(result, reason) {
6146
5462
  if (typeof result === "boolean") {
6147
5463
  return {
6148
5464
  inside: result,
@@ -6154,7 +5470,7 @@
6154
5470
  margin: result.margin,
6155
5471
  reason: result.reason ?? reason,
6156
5472
  };
6157
- };
5473
+ }
6158
5474
  }
6159
5475
 
6160
5476
  class SpatialHashGrid {
@@ -6507,10 +5823,10 @@
6507
5823
  }
6508
5824
  this.#resizeFactor = undefined;
6509
5825
  }
6510
- #addToPool = (...particles) => {
5826
+ #addToPool(...particles) {
6511
5827
  this.#pool.push(...particles);
6512
- };
6513
- #applyDensity = (options, pluginsCount, group, groupOptions) => {
5828
+ }
5829
+ #applyDensity(options, pluginsCount, group, groupOptions) {
6514
5830
  const numberOptions = options.number;
6515
5831
  if (!numberOptions.density.enable) {
6516
5832
  if (group === undefined) {
@@ -6534,36 +5850,19 @@
6534
5850
  else if (particlesCount > particlesNumber) {
6535
5851
  this.removeQuantity(particlesCount - particlesNumber, group);
6536
5852
  }
6537
- };
6538
- #createBuckets = (zLayers) => {
5853
+ }
5854
+ #createBuckets(zLayers) {
6539
5855
  const bucketCount = Math.max(Math.floor(zLayers), one);
6540
5856
  return Array.from({ length: bucketCount }, () => []);
6541
- };
6542
- #getBucketIndex = (zIndex) => {
5857
+ }
5858
+ #getBucketIndex(zIndex) {
6543
5859
  const maxBucketIndex = this.#zBuckets.length - one;
6544
5860
  if (maxBucketIndex <= minIndex) {
6545
5861
  return minIndex;
6546
5862
  }
6547
5863
  return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
6548
- };
6549
- #getParticleInsertIndex = (bucket, particleId) => {
6550
- let start = minIndex, end = bucket.length;
6551
- while (start < end) {
6552
- const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
6553
- if (!middleParticle) {
6554
- end = middle;
6555
- continue;
6556
- }
6557
- if (middleParticle.id < particleId) {
6558
- start = middle + one;
6559
- }
6560
- else {
6561
- end = middle;
6562
- }
6563
- }
6564
- return start;
6565
- };
6566
- #initDensityFactor = densityOptions => {
5864
+ }
5865
+ #initDensityFactor(densityOptions) {
6567
5866
  const container = this.#container;
6568
5867
  if (!densityOptions.enable) {
6569
5868
  return defaultDensityFactor;
@@ -6573,16 +5872,16 @@
6573
5872
  return defaultDensityFactor;
6574
5873
  }
6575
5874
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
6576
- };
6577
- #insertParticleIntoBucket = (particle) => {
5875
+ }
5876
+ #insertParticleIntoBucket(particle) {
6578
5877
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6579
5878
  if (!bucket) {
6580
5879
  return;
6581
5880
  }
6582
- bucket.splice(this.#getParticleInsertIndex(bucket, particle.id), empty, particle);
5881
+ bucket.push(particle);
6583
5882
  this.#particleBuckets.set(particle.id, bucketIndex);
6584
- };
6585
- #removeParticle = (index, group, override) => {
5883
+ }
5884
+ #removeParticle(index, group, override) {
6586
5885
  const particle = this.#array[index];
6587
5886
  if (!particle) {
6588
5887
  return false;
@@ -6598,22 +5897,20 @@
6598
5897
  });
6599
5898
  this.#addToPool(particle);
6600
5899
  return true;
6601
- };
6602
- #removeParticleFromBucket = (particle) => {
5900
+ }
5901
+ #removeParticleFromBucket(particle) {
6603
5902
  const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6604
5903
  if (!bucket) {
6605
5904
  this.#particleBuckets.delete(particle.id);
6606
5905
  return;
6607
5906
  }
6608
- const particleIndex = this.#getParticleInsertIndex(bucket, particle.id);
6609
- if (bucket[particleIndex]?.id !== particle.id) {
6610
- this.#particleBuckets.delete(particle.id);
6611
- return;
5907
+ const idx = bucket.findIndex(p => p.id === particle.id);
5908
+ if (idx >= minIndex) {
5909
+ bucket.splice(idx, deleteCount);
6612
5910
  }
6613
- bucket.splice(particleIndex, deleteCount);
6614
5911
  this.#particleBuckets.delete(particle.id);
6615
- };
6616
- #resetBuckets = (zLayers) => {
5912
+ }
5913
+ #resetBuckets(zLayers) {
6617
5914
  const bucketCount = Math.max(Math.floor(zLayers), one);
6618
5915
  if (this.#zBuckets.length !== bucketCount) {
6619
5916
  this.#zBuckets = this.#createBuckets(bucketCount);
@@ -6622,8 +5919,8 @@
6622
5919
  for (const bucket of this.#zBuckets) {
6623
5920
  bucket.length = minIndex;
6624
5921
  }
6625
- };
6626
- #updateParticleBucket = (particle) => {
5922
+ }
5923
+ #updateParticleBucket(particle) {
6627
5924
  const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
6628
5925
  if (currentBucketIndex === undefined) {
6629
5926
  this.#insertParticleIntoBucket(particle);
@@ -6634,9 +5931,9 @@
6634
5931
  }
6635
5932
  const currentBucket = this.#zBuckets[currentBucketIndex];
6636
5933
  if (currentBucket) {
6637
- const particleIndex = this.#getParticleInsertIndex(currentBucket, particle.id);
6638
- if (currentBucket[particleIndex]?.id === particle.id) {
6639
- currentBucket.splice(particleIndex, deleteCount);
5934
+ const idx = currentBucket.findIndex(p => p.id === particle.id);
5935
+ if (idx >= minIndex) {
5936
+ currentBucket.splice(idx, deleteCount);
6640
5937
  }
6641
5938
  }
6642
5939
  const newBucket = this.#zBuckets[newBucketIndex];
@@ -6644,10 +5941,16 @@
6644
5941
  this.#particleBuckets.set(particle.id, newBucketIndex);
6645
5942
  return;
6646
5943
  }
6647
- newBucket.splice(this.#getParticleInsertIndex(newBucket, particle.id), empty, particle);
5944
+ newBucket.push(particle);
5945
+ if (newBucket.length >= double) {
5946
+ const prev = newBucket[newBucket.length - double];
5947
+ if (prev && particle.id < prev.id) {
5948
+ newBucket.sort((a, b) => a.id - b.id);
5949
+ }
5950
+ }
6648
5951
  this.#particleBuckets.set(particle.id, newBucketIndex);
6649
- };
6650
- #updateParticlesPhase1 = (delta) => {
5952
+ }
5953
+ #updateParticlesPhase1(delta) {
6651
5954
  const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
6652
5955
  for (const particle of this.#array) {
6653
5956
  if (resizeFactor && !particle.ignoresResizeRatio) {
@@ -6673,8 +5976,8 @@
6673
5976
  this.grid.insert(particle);
6674
5977
  }
6675
5978
  return particlesToDelete;
6676
- };
6677
- #updateParticlesPhase2 = (delta, particlesToDelete) => {
5979
+ }
5980
+ #updateParticlesPhase2(delta, particlesToDelete) {
6678
5981
  for (const particle of this.#array) {
6679
5982
  if (particle.destroyed) {
6680
5983
  particlesToDelete.add(particle);
@@ -6690,7 +5993,7 @@
6690
5993
  }
6691
5994
  this.#updateParticleBucket(particle);
6692
5995
  }
6693
- };
5996
+ }
6694
5997
  }
6695
5998
 
6696
5999
  class Retina {
@@ -7052,7 +6355,7 @@
7052
6355
  }
7053
6356
  return refresh;
7054
6357
  }
7055
- #nextFrame = (timestamp) => {
6358
+ #nextFrame(timestamp) {
7056
6359
  try {
7057
6360
  if (!this.#smooth &&
7058
6361
  this.#lastFrameTime !== undefined &&
@@ -7080,7 +6383,7 @@
7080
6383
  catch (e) {
7081
6384
  getLogger().error("error in animation loop", e);
7082
6385
  }
7083
- };
6386
+ }
7084
6387
  }
7085
6388
 
7086
6389
  var Container$1 = /*#__PURE__*/Object.freeze({
@@ -7126,7 +6429,7 @@
7126
6429
  BlendPluginInstance: BlendPluginInstance
7127
6430
  });
7128
6431
 
7129
- const minVelocity = 0, identity$1 = 1, moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
6432
+ const moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
7130
6433
  function applyDistance(particle) {
7131
6434
  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;
7132
6435
  if (!hDistance && !vDistance) {
@@ -7159,7 +6462,7 @@
7159
6462
  }
7160
6463
  function move(particle, moveOptions, moveSpeed, maxSpeed, moveDrift, reduceFactor, delta) {
7161
6464
  applyPath(particle, delta);
7162
- const gravityOptions = particle.gravity, gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity$1 : identity$1;
6465
+ const gravityOptions = particle.gravity, gravityFactor = gravityOptions?.enable && gravityOptions.inverse ? -identity$2 : identity$2;
7163
6466
  if (moveDrift && moveSpeed) {
7164
6467
  particle.velocity.x += (moveDrift * delta.factor) / (moveSpeedFactor * moveSpeed);
7165
6468
  }
@@ -7179,7 +6482,7 @@
7179
6482
  particle.velocity.y = velocity.y / moveSpeed;
7180
6483
  }
7181
6484
  }
7182
- const zIndexOptions = particle.options.zIndex, zVelocityFactor = (identity$1 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
6485
+ const zIndexOptions = particle.options.zIndex, zVelocityFactor = (identity$2 - particle.zIndexFactor) ** zIndexOptions.velocityRate;
7183
6486
  velocity.multTo(zVelocityFactor);
7184
6487
  velocity.multTo(reduceFactor);
7185
6488
  const { position } = particle;
@@ -7205,13 +6508,13 @@
7205
6508
  const maxCanvasSize = Math.max(container.canvas.size.width, container.canvas.size.height), halfMaxSize = maxCanvasSize * half;
7206
6509
  if (particle.spin.radius > halfMaxSize) {
7207
6510
  particle.spin.radius = halfMaxSize;
7208
- particle.spin.acceleration *= -identity$1;
6511
+ particle.spin.acceleration *= -identity$2;
7209
6512
  }
7210
6513
  else if (particle.spin.radius < minSpinRadius) {
7211
6514
  particle.spin.radius = minSpinRadius;
7212
- particle.spin.acceleration *= -identity$1;
6515
+ particle.spin.acceleration *= -identity$2;
7213
6516
  }
7214
- particle.spin.angle += moveSpeed * spinFactor * (identity$1 - particle.spin.radius / maxCanvasSize);
6517
+ particle.spin.angle += moveSpeed * spinFactor * (identity$2 - particle.spin.radius / maxCanvasSize);
7215
6518
  }
7216
6519
  function applyPath(particle, delta) {
7217
6520
  const particlesOptions = particle.options, pathOptions = particlesOptions.move.path, pathEnabled = pathOptions.enable;
@@ -7228,13 +6531,13 @@
7228
6531
  particle.velocity.addTo(path);
7229
6532
  }
7230
6533
  if (pathOptions.clamp) {
7231
- particle.velocity.x = clamp(particle.velocity.x, -identity$1, identity$1);
7232
- particle.velocity.y = clamp(particle.velocity.y, -identity$1, identity$1);
6534
+ particle.velocity.x = clamp(particle.velocity.x, -identity$2, identity$2);
6535
+ particle.velocity.y = clamp(particle.velocity.y, -identity$2, identity$2);
7233
6536
  }
7234
6537
  particle.lastPathTime -= pathDelay;
7235
6538
  }
7236
6539
  function getProximitySpeedFactor(particle) {
7237
- return particle.slow.inRange ? particle.slow.factor : identity$1;
6540
+ return particle.slow.inRange ? particle.slow.factor : identity$2;
7238
6541
  }
7239
6542
  function initSpin(container, particle) {
7240
6543
  const options = particle.options, spinOptions = options.move.spin;
@@ -7518,7 +6821,7 @@
7518
6821
  mediaQuery.addEventListener("change", handleChange);
7519
6822
  await Promise.resolve();
7520
6823
  }
7521
- #handleMotionChange = mediaQuery => {
6824
+ #handleMotionChange(mediaQuery) {
7522
6825
  const container = this.#container, motion = container.actualOptions.motion;
7523
6826
  if (!motion) {
7524
6827
  return;
@@ -7534,7 +6837,7 @@
7534
6837
  else {
7535
6838
  container.retina.reduceFactor = defaultReduce;
7536
6839
  }
7537
- };
6840
+ }
7538
6841
  }
7539
6842
 
7540
6843
  var MotionPluginInstance$1 = /*#__PURE__*/Object.freeze({
@@ -7627,7 +6930,13 @@
7627
6930
  this.#paused = !this.options.autoPlay;
7628
6931
  this.#particlesOptions = particlesOptions;
7629
6932
  this.#size = this.#calcSize();
7630
- this.size = getSize(this.#size, this.#container.canvas.size);
6933
+ this.size =
6934
+ this.#size.mode === PixelMode.percent
6935
+ ? {
6936
+ width: (this.#size.width / percentDenominator) * this.#container.canvas.size.width,
6937
+ height: (this.#size.height / percentDenominator) * this.#container.canvas.size.height,
6938
+ }
6939
+ : { width: this.#size.width, height: this.#size.height };
7631
6940
  this.#lifeCount = this.options.life.count ?? defaultLifeCount;
7632
6941
  this.#immortal = this.#lifeCount <= minLifeCount;
7633
6942
  if (this.options.domId) {
@@ -7698,7 +7007,13 @@
7698
7007
  ? initialPosition
7699
7008
  : this.#calcPosition();
7700
7009
  this.#size = this.#calcSize();
7701
- this.size = getSize(this.#size, container.canvas.size);
7010
+ this.size =
7011
+ this.#size.mode === PixelMode.percent
7012
+ ? {
7013
+ width: (this.#size.width / percentDenominator) * container.canvas.size.width,
7014
+ height: (this.#size.height / percentDenominator) * container.canvas.size.height,
7015
+ }
7016
+ : { width: this.#size.width, height: this.#size.height };
7702
7017
  this.#shape?.resize(this.position, this.size);
7703
7018
  }
7704
7019
  update(delta) {
@@ -7798,7 +7113,7 @@
7798
7113
  return size;
7799
7114
  })());
7800
7115
  }
7801
- #destroy = () => {
7116
+ #destroy() {
7802
7117
  this.#mutationObserver?.disconnect();
7803
7118
  this.#mutationObserver = undefined;
7804
7119
  this.#resizeObserver?.disconnect();
@@ -7807,7 +7122,7 @@
7807
7122
  this.#container.dispatchEvent("emitterDestroyed", {
7808
7123
  emitter: this,
7809
7124
  });
7810
- };
7125
+ }
7811
7126
  #emit() {
7812
7127
  if (this.#paused) {
7813
7128
  return;
@@ -7867,7 +7182,7 @@
7867
7182
  }
7868
7183
  }
7869
7184
  }
7870
- #prepareToDie = () => {
7185
+ #prepareToDie() {
7871
7186
  if (this.#paused) {
7872
7187
  return;
7873
7188
  }
@@ -7875,8 +7190,8 @@
7875
7190
  if ((this.#lifeCount > minLifeCount || this.#immortal) && duration !== undefined && duration > minDuration) {
7876
7191
  this.#duration = duration * millisecondsToSeconds;
7877
7192
  }
7878
- };
7879
- #setColorAnimation = (animation, initValue, maxValue, factor = defaultColorAnimationFactor) => {
7193
+ }
7194
+ #setColorAnimation(animation, initValue, maxValue, factor = defaultColorAnimationFactor) {
7880
7195
  const container = this.#container;
7881
7196
  if (!animation.enable) {
7882
7197
  return initValue;
@@ -7885,7 +7200,7 @@
7885
7200
  ? (delay * millisecondsToSeconds) / container.retina.reduceFactor
7886
7201
  : Infinity, colorSpeed = getRangeValue(animation.speed);
7887
7202
  return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * factor) % maxValue;
7888
- };
7203
+ }
7889
7204
  }
7890
7205
 
7891
7206
  var EmitterInstance$1 = /*#__PURE__*/Object.freeze({