@tsparticles/preset-confetti-falling 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$2 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
18
+ }, randomColorValue = "random", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, minVelocity = 0, minDistance = 0, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, maxNits = 400, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
19
19
 
20
20
  var MoveDirection;
21
21
  (function (MoveDirection) {
@@ -82,11 +82,6 @@
82
82
  div(n) {
83
83
  return Vector3d.create(this.x / n, this.y / n, this.z / n);
84
84
  }
85
- divTo(n) {
86
- this.x /= n;
87
- this.y /= n;
88
- this.z /= n;
89
- }
90
85
  getLengthSq() {
91
86
  return this.x ** squareExp + this.y ** squareExp;
92
87
  }
@@ -282,27 +277,6 @@
282
277
  return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
283
278
  }
284
279
 
285
- var AnimationMode;
286
- (function (AnimationMode) {
287
- AnimationMode["auto"] = "auto";
288
- AnimationMode["increase"] = "increase";
289
- AnimationMode["decrease"] = "decrease";
290
- AnimationMode["random"] = "random";
291
- })(AnimationMode || (AnimationMode = {}));
292
-
293
- var AnimationStatus;
294
- (function (AnimationStatus) {
295
- AnimationStatus["increasing"] = "increasing";
296
- AnimationStatus["decreasing"] = "decreasing";
297
- })(AnimationStatus || (AnimationStatus = {}));
298
-
299
- var DestroyType;
300
- (function (DestroyType) {
301
- DestroyType["none"] = "none";
302
- DestroyType["max"] = "max";
303
- DestroyType["min"] = "min";
304
- })(DestroyType || (DestroyType = {}));
305
-
306
280
  var OutModeDirection;
307
281
  (function (OutModeDirection) {
308
282
  OutModeDirection["bottom"] = "bottom";
@@ -317,67 +291,7 @@
317
291
  PixelMode["percent"] = "percent";
318
292
  })(PixelMode || (PixelMode = {}));
319
293
 
320
- var StartValueType;
321
- (function (StartValueType) {
322
- StartValueType["max"] = "max";
323
- StartValueType["min"] = "min";
324
- StartValueType["random"] = "random";
325
- })(StartValueType || (StartValueType = {}));
326
-
327
294
  const minRadius = 0;
328
- function memoize(fn, options) {
329
- const cache = new Map(), stableStringify = (obj, seen = new WeakSet()) => {
330
- if (obj === null) {
331
- return "null";
332
- }
333
- const t = typeof obj;
334
- if (t === "undefined") {
335
- return "undefined";
336
- }
337
- if (t === "number" || t === "boolean" || t === "string") {
338
- return JSON.stringify(obj);
339
- }
340
- if (t === "function") {
341
- try {
342
- const fn = obj;
343
- return fn.toString();
344
- }
345
- catch {
346
- return '"[Function]"';
347
- }
348
- }
349
- if (t === "symbol") {
350
- try {
351
- return obj.toString();
352
- }
353
- catch {
354
- return '"[Symbol]"';
355
- }
356
- }
357
- if (Array.isArray(obj)) {
358
- return `[${obj.map(i => stableStringify(i, seen)).join(",")}]`;
359
- }
360
- if (seen.has(obj)) {
361
- return '"[Circular]"';
362
- }
363
- seen.add(obj);
364
- const keys = Object.keys(obj).sort();
365
- return `{${keys.map(k => `${JSON.stringify(k)}:${stableStringify(obj[k], seen)}`).join(",")}}`;
366
- }, defaultKeyer = (args) => stableStringify(args), makeKey = (args) => (defaultKeyer(args));
367
- return (...args) => {
368
- const key = makeKey(args), now = Date.now(), entry = cache.get(key);
369
- if (entry !== undefined) {
370
- {
371
- cache.delete(key);
372
- cache.set(key, { value: entry.value, ts: entry.ts });
373
- return entry.value;
374
- }
375
- }
376
- const result = fn(...args);
377
- cache.set(key, { value: result, ts: now });
378
- return result;
379
- };
380
- }
381
295
  function hasMatchMedia() {
382
296
  return typeof matchMedia !== "undefined";
383
297
  }
@@ -399,11 +313,8 @@
399
313
  function isInArray(value, array) {
400
314
  return value === array || (isArray(array) && array.includes(value));
401
315
  }
402
- function arrayRandomIndex(array) {
403
- return Math.floor(getRandom() * array.length);
404
- }
405
316
  function itemFromArray(array, index, useIndex = true) {
406
- return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)];
317
+ return array[index !== undefined && useIndex ? index % array.length : Math.floor(getRandom() * array.length)];
407
318
  }
408
319
  function isPointInside(point, size, offset, radius, direction) {
409
320
  return areBoundsInside(calculateBounds(point, radius ?? minRadius), size, offset, direction);
@@ -487,56 +398,6 @@
487
398
  function itemFromSingleOrMultiple(obj, index, useIndex) {
488
399
  return isArray(obj) ? itemFromArray(obj, index, useIndex) : obj;
489
400
  }
490
- function initParticleNumericAnimationValue(options, pxRatio) {
491
- const valueRange = options.value, animationOptions = options.animation, res = {
492
- delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
493
- enable: animationOptions.enable,
494
- value: getRangeValue(options.value) * pxRatio,
495
- max: getRangeMax(valueRange) * pxRatio,
496
- min: getRangeMin(valueRange) * pxRatio,
497
- loops: 0,
498
- maxLoops: getRangeValue(animationOptions.count),
499
- time: 0,
500
- }, decayOffset = 1;
501
- if (animationOptions.enable) {
502
- res.decay = decayOffset - getRangeValue(animationOptions.decay);
503
- switch (animationOptions.mode) {
504
- case AnimationMode.increase:
505
- res.status = AnimationStatus.increasing;
506
- break;
507
- case AnimationMode.decrease:
508
- res.status = AnimationStatus.decreasing;
509
- break;
510
- case AnimationMode.random:
511
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
512
- break;
513
- }
514
- const autoStatus = animationOptions.mode === AnimationMode.auto;
515
- switch (animationOptions.startValue) {
516
- case StartValueType.min:
517
- res.value = res.min;
518
- if (autoStatus) {
519
- res.status = AnimationStatus.increasing;
520
- }
521
- break;
522
- case StartValueType.max:
523
- res.value = res.max;
524
- if (autoStatus) {
525
- res.status = AnimationStatus.decreasing;
526
- }
527
- break;
528
- case StartValueType.random:
529
- default:
530
- res.value = randomInRangeValue(res);
531
- if (autoStatus) {
532
- res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
533
- }
534
- break;
535
- }
536
- }
537
- res.initialValue = res.value;
538
- return res;
539
- }
540
401
  function getPositionOrSize(positionOrSize, canvasSize) {
541
402
  const isPercent = positionOrSize.mode === PixelMode.percent;
542
403
  if (!isPercent) {
@@ -560,77 +421,6 @@
560
421
  function getPosition(position, canvasSize) {
561
422
  return getPositionOrSize(position, canvasSize);
562
423
  }
563
- function checkDestroy(particle, destroyType, value, minValue, maxValue) {
564
- switch (destroyType) {
565
- case DestroyType.max:
566
- if (value >= maxValue) {
567
- particle.destroy();
568
- }
569
- break;
570
- case DestroyType.min:
571
- if (value <= minValue) {
572
- particle.destroy();
573
- }
574
- break;
575
- }
576
- }
577
- function updateAnimation(particle, data, changeDirection, destroyType, delta) {
578
- const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
579
- if (particle.destroyed ||
580
- !data.enable ||
581
- ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
582
- return;
583
- }
584
- const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
585
- data.time ??= 0;
586
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
587
- data.time += delta.value;
588
- }
589
- if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
590
- return;
591
- }
592
- switch (data.status) {
593
- case AnimationStatus.increasing:
594
- data.value += velocity;
595
- break;
596
- case AnimationStatus.decreasing:
597
- data.value -= velocity;
598
- break;
599
- }
600
- if (data.velocity && decay !== identity) {
601
- data.velocity *= decay;
602
- }
603
- switch (data.status) {
604
- case AnimationStatus.increasing:
605
- if (data.value >= maxValue) {
606
- if (changeDirection) {
607
- data.status = AnimationStatus.decreasing;
608
- }
609
- else {
610
- data.value -= maxValue;
611
- }
612
- data.loops ??= minLoops;
613
- data.loops++;
614
- }
615
- break;
616
- case AnimationStatus.decreasing:
617
- if (data.value <= minValue) {
618
- if (changeDirection) {
619
- data.status = AnimationStatus.increasing;
620
- }
621
- else {
622
- data.value += maxValue;
623
- }
624
- data.loops ??= minLoops;
625
- data.loops++;
626
- }
627
- break;
628
- }
629
- checkDestroy(particle, destroyType, data.value, minValue, maxValue);
630
- if (!particle.destroyed) {
631
- data.value = clamp(data.value, minValue, maxValue);
632
- }
633
- }
634
424
  function cloneStyle(style) {
635
425
  const clonedStyle = safeDocument().createElement("div").style;
636
426
  for (const key in style) {
@@ -652,30 +442,34 @@
652
442
  }
653
443
  return clonedStyle;
654
444
  }
655
- function computeFullScreenStyle(zIndex) {
656
- const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
657
- width: "100%",
658
- height: "100%",
659
- margin: "0",
660
- padding: "0",
661
- borderWidth: "0",
662
- position: "fixed",
663
- zIndex: zIndex.toString(radix),
664
- "z-index": zIndex.toString(radix),
665
- top: "0",
666
- left: "0",
667
- "pointer-events": "none",
668
- };
669
- for (const key in style) {
670
- const value = style[key];
671
- if (value === undefined) {
672
- continue;
445
+ let _cachedZIndex, _cachedStyle;
446
+ function getFullScreenStyle(zIndex) {
447
+ if (_cachedZIndex !== zIndex || !_cachedStyle) {
448
+ _cachedZIndex = zIndex;
449
+ const fullScreenStyle = safeDocument().createElement("div").style, radix = 10, style = {
450
+ width: "100%",
451
+ height: "100%",
452
+ margin: "0",
453
+ padding: "0",
454
+ borderWidth: "0",
455
+ position: "fixed",
456
+ zIndex: zIndex.toString(radix),
457
+ "z-index": zIndex.toString(radix),
458
+ top: "0",
459
+ left: "0",
460
+ "pointer-events": "none",
461
+ };
462
+ for (const key in style) {
463
+ const value = style[key];
464
+ if (value === undefined) {
465
+ continue;
466
+ }
467
+ fullScreenStyle.setProperty(key, value);
673
468
  }
674
- fullScreenStyle.setProperty(key, value);
469
+ _cachedStyle = fullScreenStyle;
675
470
  }
676
- return fullScreenStyle;
471
+ return _cachedStyle;
677
472
  }
678
- const getFullScreenStyle = memoize(computeFullScreenStyle);
679
473
  function manageListener(element, event, handler, add, options) {
680
474
  if (add) {
681
475
  let addOptions = { passive: true };
@@ -1002,7 +796,7 @@
1002
796
  return this.#domArray;
1003
797
  }
1004
798
  get version() {
1005
- return "4.1.2";
799
+ return "4.2.0";
1006
800
  }
1007
801
  addEventListener(type, listener) {
1008
802
  this.#eventDispatcher.addEventListener(type, listener);
@@ -1172,6 +966,14 @@
1172
966
  RotateDirection["random"] = "random";
1173
967
  })(RotateDirection || (RotateDirection = {}));
1174
968
 
969
+ var AnimationMode;
970
+ (function (AnimationMode) {
971
+ AnimationMode["auto"] = "auto";
972
+ AnimationMode["increase"] = "increase";
973
+ AnimationMode["decrease"] = "decrease";
974
+ AnimationMode["random"] = "random";
975
+ })(AnimationMode || (AnimationMode = {}));
976
+
1175
977
  var LimitMode;
1176
978
  (function (LimitMode) {
1177
979
  LimitMode["delete"] = "delete";
@@ -1193,6 +995,13 @@
1193
995
  AlterType["enlighten"] = "enlighten";
1194
996
  })(AlterType || (AlterType = {}));
1195
997
 
998
+ var DestroyType;
999
+ (function (DestroyType) {
1000
+ DestroyType["none"] = "none";
1001
+ DestroyType["max"] = "max";
1002
+ DestroyType["min"] = "min";
1003
+ })(DestroyType || (DestroyType = {}));
1004
+
1196
1005
  var GradientType;
1197
1006
  (function (GradientType) {
1198
1007
  GradientType["linear"] = "linear";
@@ -1207,160 +1016,121 @@
1207
1016
  ParticleOutType["outside"] = "outside";
1208
1017
  })(ParticleOutType || (ParticleOutType = {}));
1209
1018
 
1210
- var EasingType;
1211
- (function (EasingType) {
1212
- EasingType["easeInBack"] = "ease-in-back";
1213
- EasingType["easeInBounce"] = "ease-in-bounce";
1214
- EasingType["easeInCirc"] = "ease-in-circ";
1215
- EasingType["easeInCubic"] = "ease-in-cubic";
1216
- EasingType["easeInElastic"] = "ease-in-elastic";
1217
- EasingType["easeInExpo"] = "ease-in-expo";
1218
- EasingType["easeInGaussian"] = "ease-in-gaussian";
1219
- EasingType["easeInLinear"] = "ease-in-linear";
1220
- EasingType["easeInQuad"] = "ease-in-quad";
1221
- EasingType["easeInQuart"] = "ease-in-quart";
1222
- EasingType["easeInQuint"] = "ease-in-quint";
1223
- EasingType["easeInSigmoid"] = "ease-in-sigmoid";
1224
- EasingType["easeInSine"] = "ease-in-sine";
1225
- EasingType["easeInSmoothstep"] = "ease-in-smoothstep";
1226
- EasingType["easeOutBack"] = "ease-out-back";
1227
- EasingType["easeOutBounce"] = "ease-out-bounce";
1228
- EasingType["easeOutCirc"] = "ease-out-circ";
1229
- EasingType["easeOutCubic"] = "ease-out-cubic";
1230
- EasingType["easeOutElastic"] = "ease-out-elastic";
1231
- EasingType["easeOutExpo"] = "ease-out-expo";
1232
- EasingType["easeOutGaussian"] = "ease-out-gaussian";
1233
- EasingType["easeOutLinear"] = "ease-out-linear";
1234
- EasingType["easeOutQuad"] = "ease-out-quad";
1235
- EasingType["easeOutQuart"] = "ease-out-quart";
1236
- EasingType["easeOutQuint"] = "ease-out-quint";
1237
- EasingType["easeOutSigmoid"] = "ease-out-sigmoid";
1238
- EasingType["easeOutSine"] = "ease-out-sine";
1239
- EasingType["easeOutSmoothstep"] = "ease-out-smoothstep";
1240
- EasingType["easeInOutBack"] = "ease-in-out-back";
1241
- EasingType["easeInOutBounce"] = "ease-in-out-bounce";
1242
- EasingType["easeInOutCirc"] = "ease-in-out-circ";
1243
- EasingType["easeInOutCubic"] = "ease-in-out-cubic";
1244
- EasingType["easeInOutElastic"] = "ease-in-out-elastic";
1245
- EasingType["easeInOutExpo"] = "ease-in-out-expo";
1246
- EasingType["easeInOutGaussian"] = "ease-in-out-gaussian";
1247
- EasingType["easeInOutLinear"] = "ease-in-out-linear";
1248
- EasingType["easeInOutQuad"] = "ease-in-out-quad";
1249
- EasingType["easeInOutQuart"] = "ease-in-out-quart";
1250
- EasingType["easeInOutQuint"] = "ease-in-out-quint";
1251
- EasingType["easeInOutSigmoid"] = "ease-in-out-sigmoid";
1252
- EasingType["easeInOutSine"] = "ease-in-out-sine";
1253
- EasingType["easeInOutSmoothstep"] = "ease-in-out-smoothstep";
1254
- })(EasingType || (EasingType = {}));
1255
-
1256
- class AnimationOptions {
1257
- count;
1258
- decay;
1259
- delay;
1260
- enable;
1261
- speed;
1262
- sync;
1263
- constructor() {
1264
- this.count = 0;
1265
- this.enable = false;
1266
- this.speed = 1;
1267
- this.decay = 0;
1268
- this.delay = 0;
1269
- this.sync = false;
1270
- }
1019
+ var StartValueType;
1020
+ (function (StartValueType) {
1021
+ StartValueType["max"] = "max";
1022
+ StartValueType["min"] = "min";
1023
+ StartValueType["random"] = "random";
1024
+ })(StartValueType || (StartValueType = {}));
1025
+
1026
+ var AnimationStatus;
1027
+ (function (AnimationStatus) {
1028
+ AnimationStatus["increasing"] = "increasing";
1029
+ AnimationStatus["decreasing"] = "decreasing";
1030
+ })(AnimationStatus || (AnimationStatus = {}));
1031
+
1032
+ class OptionLoader {
1271
1033
  load(data) {
1272
1034
  if (isNull(data)) {
1273
1035
  return;
1274
1036
  }
1275
- if (data.count !== undefined) {
1276
- this.count = setRangeValue(data.count);
1277
- }
1278
- if (data.enable !== undefined) {
1279
- this.enable = data.enable;
1280
- }
1281
- if (data.speed !== undefined) {
1282
- this.speed = setRangeValue(data.speed);
1283
- }
1284
- if (data.decay !== undefined) {
1285
- this.decay = setRangeValue(data.decay);
1286
- }
1287
- if (data.delay !== undefined) {
1288
- this.delay = setRangeValue(data.delay);
1289
- }
1290
- if (data.sync !== undefined) {
1291
- this.sync = data.sync;
1292
- }
1037
+ this.doLoad(data);
1293
1038
  }
1294
1039
  }
1295
- class RangedAnimationOptions extends AnimationOptions {
1296
- mode;
1297
- startValue;
1298
- constructor() {
1299
- super();
1300
- this.mode = AnimationMode.auto;
1301
- this.startValue = StartValueType.random;
1040
+ function loadOptions(options, ...sourceOptionsArr) {
1041
+ for (const sourceOptions of sourceOptionsArr) {
1042
+ options.load(sourceOptions);
1302
1043
  }
1303
- load(data) {
1304
- super.load(data);
1305
- if (isNull(data)) {
1306
- return;
1307
- }
1308
- if (data.mode !== undefined) {
1309
- this.mode = data.mode;
1310
- }
1311
- if (data.startValue !== undefined) {
1312
- this.startValue = data.startValue;
1313
- }
1044
+ }
1045
+
1046
+ function loadProperty(obj, key, value) {
1047
+ if (value !== undefined) {
1048
+ obj[key] = value;
1049
+ }
1050
+ }
1051
+ function loadRangeProperty(obj, key, value) {
1052
+ if (value !== undefined) {
1053
+ obj[key] = setRangeValue(value);
1054
+ }
1055
+ }
1056
+ function loadNestedProperty(obj, key, value) {
1057
+ if (value !== undefined) {
1058
+ obj[key].load(value);
1059
+ }
1060
+ }
1061
+ function loadLazyProperty(obj, key, value, factory) {
1062
+ if (value !== undefined) {
1063
+ const objRecord = obj;
1064
+ objRecord[key] ??= factory();
1065
+ objRecord[key].load(value);
1066
+ }
1067
+ }
1068
+ function loadOptionProperty(obj, key, optionClass, ...sources) {
1069
+ const objRecord = obj;
1070
+ objRecord[key] ??= new optionClass();
1071
+ const target = objRecord[key];
1072
+ for (const source of sources) {
1073
+ target.load(source?.[key]);
1074
+ }
1075
+ }
1076
+
1077
+ class AnimationOptions extends OptionLoader {
1078
+ count = 0;
1079
+ decay = 0;
1080
+ delay = 0;
1081
+ enable = false;
1082
+ speed = 1;
1083
+ sync = false;
1084
+ doLoad(data) {
1085
+ loadRangeProperty(this, "count", data.count);
1086
+ loadProperty(this, "enable", data.enable);
1087
+ loadRangeProperty(this, "speed", data.speed);
1088
+ loadRangeProperty(this, "decay", data.decay);
1089
+ loadRangeProperty(this, "delay", data.delay);
1090
+ loadProperty(this, "sync", data.sync);
1091
+ }
1092
+ }
1093
+ class RangedAnimationOptions extends AnimationOptions {
1094
+ mode = AnimationMode.auto;
1095
+ startValue = StartValueType.random;
1096
+ doLoad(data) {
1097
+ super.doLoad(data);
1098
+ loadProperty(this, "mode", data.mode);
1099
+ loadProperty(this, "startValue", data.startValue);
1314
1100
  }
1315
1101
  }
1316
1102
 
1317
1103
  class ColorAnimation extends AnimationOptions {
1318
1104
  max;
1319
1105
  min;
1320
- offset;
1106
+ offset = 0;
1107
+ sync = true;
1321
1108
  constructor(min, max) {
1322
1109
  super();
1323
1110
  this.min = min;
1324
1111
  this.max = max;
1325
- this.offset = 0;
1326
- this.sync = true;
1327
1112
  }
1328
- load(data) {
1329
- super.load(data);
1330
- if (isNull(data)) {
1331
- return;
1332
- }
1333
- if (data.max !== undefined) {
1334
- this.max = data.max;
1335
- }
1336
- if (data.min !== undefined) {
1337
- this.min = data.min;
1338
- }
1339
- if (data.offset !== undefined) {
1340
- this.offset = setRangeValue(data.offset);
1341
- }
1113
+ doLoad(data) {
1114
+ super.doLoad(data);
1115
+ loadProperty(this, "max", data.max);
1116
+ loadProperty(this, "min", data.min);
1117
+ loadRangeProperty(this, "offset", data.offset);
1342
1118
  }
1343
1119
  }
1344
1120
 
1345
- class HslAnimation {
1121
+ class HslAnimation extends OptionLoader {
1346
1122
  h = new ColorAnimation(hMin, hMax);
1347
1123
  l = new ColorAnimation(lMin, lMax);
1348
1124
  s = new ColorAnimation(sMin, sMax);
1349
- load(data) {
1350
- if (isNull(data)) {
1351
- return;
1352
- }
1125
+ doLoad(data) {
1353
1126
  this.h.load(data.h);
1354
1127
  this.s.load(data.s);
1355
1128
  this.l.load(data.l);
1356
1129
  }
1357
1130
  }
1358
1131
 
1359
- class OptionsColor {
1360
- value;
1361
- constructor() {
1362
- this.value = "";
1363
- }
1132
+ class OptionsColor extends OptionLoader {
1133
+ value = "";
1364
1134
  static create(source, data) {
1365
1135
  const color = new OptionsColor();
1366
1136
  color.load(source);
@@ -1374,10 +1144,7 @@
1374
1144
  }
1375
1145
  return color;
1376
1146
  }
1377
- load(data) {
1378
- if (isNull(data)) {
1379
- return;
1380
- }
1147
+ doLoad(data) {
1381
1148
  if (!isNull(data.value)) {
1382
1149
  this.value = data.value;
1383
1150
  }
@@ -1385,11 +1152,7 @@
1385
1152
  }
1386
1153
 
1387
1154
  class AnimatableColor extends OptionsColor {
1388
- animation;
1389
- constructor() {
1390
- super();
1391
- this.animation = new HslAnimation();
1392
- }
1155
+ animation = new HslAnimation();
1393
1156
  static create(source, data) {
1394
1157
  const color = new AnimatableColor();
1395
1158
  color.load(source);
@@ -1403,11 +1166,8 @@
1403
1166
  }
1404
1167
  return color;
1405
1168
  }
1406
- load(data) {
1407
- super.load(data);
1408
- if (isNull(data)) {
1409
- return;
1410
- }
1169
+ doLoad(data) {
1170
+ super.doLoad(data);
1411
1171
  const colorAnimation = data.animation;
1412
1172
  if (colorAnimation !== undefined) {
1413
1173
  if (colorAnimation.enable === undefined) {
@@ -1420,100 +1180,53 @@
1420
1180
  }
1421
1181
  }
1422
1182
 
1423
- class Background {
1183
+ class Background extends OptionLoader {
1424
1184
  color;
1425
- image;
1426
- opacity;
1427
- position;
1428
- repeat;
1429
- size;
1185
+ image = "";
1186
+ opacity = 1;
1187
+ position = "";
1188
+ repeat = "";
1189
+ size = "";
1430
1190
  constructor() {
1191
+ super();
1431
1192
  this.color = new OptionsColor();
1432
1193
  this.color.value = "";
1433
- this.image = "";
1434
- this.position = "";
1435
- this.repeat = "";
1436
- this.size = "";
1437
- this.opacity = 1;
1438
1194
  }
1439
- load(data) {
1440
- if (isNull(data)) {
1441
- return;
1442
- }
1195
+ doLoad(data) {
1443
1196
  if (data.color !== undefined) {
1444
1197
  this.color = OptionsColor.create(this.color, data.color);
1445
1198
  }
1446
- if (data.image !== undefined) {
1447
- this.image = data.image;
1448
- }
1449
- if (data.position !== undefined) {
1450
- this.position = data.position;
1451
- }
1452
- if (data.repeat !== undefined) {
1453
- this.repeat = data.repeat;
1454
- }
1455
- if (data.size !== undefined) {
1456
- this.size = data.size;
1457
- }
1458
- if (data.opacity !== undefined) {
1459
- this.opacity = data.opacity;
1460
- }
1199
+ loadProperty(this, "image", data.image);
1200
+ loadProperty(this, "position", data.position);
1201
+ loadProperty(this, "repeat", data.repeat);
1202
+ loadProperty(this, "size", data.size);
1203
+ loadProperty(this, "opacity", data.opacity);
1461
1204
  }
1462
1205
  }
1463
1206
 
1464
- class FullScreen {
1465
- enable;
1466
- zIndex;
1467
- constructor() {
1468
- this.enable = true;
1469
- this.zIndex = 0;
1470
- }
1471
- load(data) {
1472
- if (isNull(data)) {
1473
- return;
1474
- }
1475
- if (data.enable !== undefined) {
1476
- this.enable = data.enable;
1477
- }
1478
- if (data.zIndex !== undefined) {
1479
- this.zIndex = data.zIndex;
1480
- }
1207
+ class FullScreen extends OptionLoader {
1208
+ enable = true;
1209
+ zIndex = 0;
1210
+ doLoad(data) {
1211
+ loadProperty(this, "enable", data.enable);
1212
+ loadProperty(this, "zIndex", data.zIndex);
1481
1213
  }
1482
1214
  }
1483
1215
 
1484
- class ResizeEvent {
1485
- delay;
1486
- enable;
1487
- constructor() {
1488
- this.delay = 0.5;
1489
- this.enable = true;
1490
- }
1491
- load(data) {
1492
- if (isNull(data)) {
1493
- return;
1494
- }
1495
- if (data.delay !== undefined) {
1496
- this.delay = data.delay;
1497
- }
1498
- if (data.enable !== undefined) {
1499
- this.enable = data.enable;
1500
- }
1216
+ class ResizeEvent extends OptionLoader {
1217
+ delay = 0.5;
1218
+ enable = true;
1219
+ doLoad(data) {
1220
+ loadProperty(this, "delay", data.delay);
1221
+ loadProperty(this, "enable", data.enable);
1501
1222
  }
1502
1223
  }
1503
1224
 
1504
- class Effect {
1505
- close;
1506
- options;
1507
- type;
1508
- constructor() {
1509
- this.close = true;
1510
- this.options = {};
1511
- this.type = [];
1512
- }
1513
- load(data) {
1514
- if (isNull(data)) {
1515
- return;
1516
- }
1225
+ class Effect extends OptionLoader {
1226
+ close = true;
1227
+ options = {};
1228
+ type = [];
1229
+ doLoad(data) {
1517
1230
  const options = data.options;
1518
1231
  if (options !== undefined) {
1519
1232
  for (const effect in options) {
@@ -1523,128 +1236,62 @@
1523
1236
  }
1524
1237
  }
1525
1238
  }
1526
- if (data.close !== undefined) {
1527
- this.close = data.close;
1528
- }
1529
- if (data.type !== undefined) {
1530
- this.type = data.type;
1531
- }
1239
+ loadProperty(this, "close", data.close);
1240
+ loadProperty(this, "type", data.type);
1532
1241
  }
1533
1242
  }
1534
1243
 
1535
- class Fill {
1244
+ class Fill extends OptionLoader {
1536
1245
  color;
1537
- enable;
1538
- opacity;
1539
- constructor() {
1540
- this.enable = true;
1541
- this.opacity = 1;
1542
- }
1543
- load(data) {
1544
- if (isNull(data)) {
1545
- return;
1546
- }
1246
+ enable = true;
1247
+ opacity = 1;
1248
+ doLoad(data) {
1547
1249
  if (data.color !== undefined) {
1548
1250
  this.color = AnimatableColor.create(this.color, data.color);
1549
1251
  }
1550
- if (data.enable !== undefined) {
1551
- this.enable = data.enable;
1552
- }
1553
- if (data.opacity !== undefined) {
1554
- this.opacity = setRangeValue(data.opacity);
1555
- }
1252
+ loadProperty(this, "enable", data.enable);
1253
+ loadRangeProperty(this, "opacity", data.opacity);
1556
1254
  }
1557
1255
  }
1558
1256
 
1559
- class MoveAngle {
1560
- offset;
1561
- value;
1562
- constructor() {
1563
- this.offset = 0;
1564
- this.value = 90;
1565
- }
1566
- load(data) {
1567
- if (isNull(data)) {
1568
- return;
1569
- }
1570
- if (data.offset !== undefined) {
1571
- this.offset = setRangeValue(data.offset);
1572
- }
1573
- if (data.value !== undefined) {
1574
- this.value = setRangeValue(data.value);
1575
- }
1257
+ class MoveAngle extends OptionLoader {
1258
+ offset = 0;
1259
+ value = 90;
1260
+ doLoad(data) {
1261
+ loadRangeProperty(this, "offset", data.offset);
1262
+ loadRangeProperty(this, "value", data.value);
1576
1263
  }
1577
1264
  }
1578
1265
 
1579
- class MoveCenter {
1580
- mode;
1581
- radius;
1582
- x;
1583
- y;
1584
- constructor() {
1585
- this.x = 50;
1586
- this.y = 50;
1587
- this.mode = PixelMode.percent;
1588
- this.radius = 0;
1589
- }
1590
- load(data) {
1591
- if (isNull(data)) {
1592
- return;
1593
- }
1594
- if (data.x !== undefined) {
1595
- this.x = data.x;
1596
- }
1597
- if (data.y !== undefined) {
1598
- this.y = data.y;
1599
- }
1600
- if (data.mode !== undefined) {
1601
- this.mode = data.mode;
1602
- }
1603
- if (data.radius !== undefined) {
1604
- this.radius = data.radius;
1605
- }
1266
+ class MoveCenter extends OptionLoader {
1267
+ mode = PixelMode.percent;
1268
+ radius = 0;
1269
+ x = 50;
1270
+ y = 50;
1271
+ doLoad(data) {
1272
+ loadProperty(this, "x", data.x);
1273
+ loadProperty(this, "y", data.y);
1274
+ loadProperty(this, "mode", data.mode);
1275
+ loadProperty(this, "radius", data.radius);
1606
1276
  }
1607
1277
  }
1608
1278
 
1609
- class MoveGravity {
1610
- acceleration;
1611
- enable;
1612
- inverse;
1613
- maxSpeed;
1614
- constructor() {
1615
- this.acceleration = 9.81;
1616
- this.enable = false;
1617
- this.inverse = false;
1618
- this.maxSpeed = 50;
1619
- }
1620
- load(data) {
1621
- if (isNull(data)) {
1622
- return;
1623
- }
1624
- if (data.acceleration !== undefined) {
1625
- this.acceleration = setRangeValue(data.acceleration);
1626
- }
1627
- if (data.enable !== undefined) {
1628
- this.enable = data.enable;
1629
- }
1630
- if (data.inverse !== undefined) {
1631
- this.inverse = data.inverse;
1632
- }
1633
- if (data.maxSpeed !== undefined) {
1634
- this.maxSpeed = setRangeValue(data.maxSpeed);
1635
- }
1279
+ class MoveGravity extends OptionLoader {
1280
+ acceleration = 9.81;
1281
+ enable = false;
1282
+ inverse = false;
1283
+ maxSpeed = 50;
1284
+ doLoad(data) {
1285
+ loadRangeProperty(this, "acceleration", data.acceleration);
1286
+ loadProperty(this, "enable", data.enable);
1287
+ loadProperty(this, "inverse", data.inverse);
1288
+ loadRangeProperty(this, "maxSpeed", data.maxSpeed);
1636
1289
  }
1637
1290
  }
1638
1291
 
1639
- class ValueWithRandom {
1640
- value;
1641
- constructor() {
1642
- this.value = 0;
1643
- }
1644
- load(data) {
1645
- if (isNull(data)) {
1646
- return;
1647
- }
1292
+ class ValueWithRandom extends OptionLoader {
1293
+ value = 0;
1294
+ doLoad(data) {
1648
1295
  if (!isNull(data.value)) {
1649
1296
  this.value = setRangeValue(data.value);
1650
1297
  }
@@ -1652,51 +1299,25 @@
1652
1299
  }
1653
1300
  class AnimationValueWithRandom extends ValueWithRandom {
1654
1301
  animation = new AnimationOptions();
1655
- load(data) {
1656
- super.load(data);
1657
- if (isNull(data)) {
1658
- return;
1659
- }
1660
- const animation = data.animation;
1661
- if (animation !== undefined) {
1662
- this.animation.load(animation);
1663
- }
1302
+ doLoad(data) {
1303
+ super.doLoad(data);
1304
+ loadNestedProperty(this, "animation", data.animation);
1664
1305
  }
1665
1306
  }
1666
1307
  class RangedAnimationValueWithRandom extends AnimationValueWithRandom {
1667
- animation;
1668
- constructor() {
1669
- super();
1670
- this.animation = new RangedAnimationOptions();
1671
- }
1672
- load(data) {
1673
- super.load(data);
1674
- }
1308
+ animation = new RangedAnimationOptions();
1675
1309
  }
1676
1310
 
1677
- class MovePath {
1678
- clamp;
1679
- delay;
1680
- enable;
1311
+ class MovePath extends OptionLoader {
1312
+ clamp = true;
1313
+ delay = new ValueWithRandom();
1314
+ enable = false;
1681
1315
  generator;
1682
- options;
1683
- constructor() {
1684
- this.clamp = true;
1685
- this.delay = new ValueWithRandom();
1686
- this.enable = false;
1687
- this.options = {};
1688
- }
1689
- load(data) {
1690
- if (isNull(data)) {
1691
- return;
1692
- }
1693
- if (data.clamp !== undefined) {
1694
- this.clamp = data.clamp;
1695
- }
1316
+ options = {};
1317
+ doLoad(data) {
1318
+ loadProperty(this, "clamp", data.clamp);
1696
1319
  this.delay.load(data.delay);
1697
- if (data.enable !== undefined) {
1698
- this.enable = data.enable;
1699
- }
1320
+ loadProperty(this, "enable", data.enable);
1700
1321
  this.generator = data.generator;
1701
1322
  if (data.options) {
1702
1323
  this.options = deepExtend(this.options, data.options);
@@ -1704,19 +1325,13 @@
1704
1325
  }
1705
1326
  }
1706
1327
 
1707
- class OutModes {
1328
+ class OutModes extends OptionLoader {
1708
1329
  bottom;
1709
- default;
1330
+ default = OutMode.out;
1710
1331
  left;
1711
1332
  right;
1712
1333
  top;
1713
- constructor() {
1714
- this.default = OutMode.out;
1715
- }
1716
- load(data) {
1717
- if (isNull(data)) {
1718
- return;
1719
- }
1334
+ doLoad(data) {
1720
1335
  if (data.default !== undefined) {
1721
1336
  this.default = data.default;
1722
1337
  }
@@ -1727,79 +1342,42 @@
1727
1342
  }
1728
1343
  }
1729
1344
 
1730
- class Spin {
1731
- acceleration;
1732
- enable;
1345
+ class Spin extends OptionLoader {
1346
+ acceleration = 0;
1347
+ enable = false;
1733
1348
  position;
1734
- constructor() {
1735
- this.acceleration = 0;
1736
- this.enable = false;
1737
- }
1738
- load(data) {
1739
- if (isNull(data)) {
1740
- return;
1741
- }
1742
- if (data.acceleration !== undefined) {
1743
- this.acceleration = setRangeValue(data.acceleration);
1744
- }
1745
- if (data.enable !== undefined) {
1746
- this.enable = data.enable;
1747
- }
1349
+ doLoad(data) {
1350
+ loadRangeProperty(this, "acceleration", data.acceleration);
1351
+ loadProperty(this, "enable", data.enable);
1748
1352
  if (data.position) {
1749
1353
  this.position = deepExtend({}, data.position);
1750
1354
  }
1751
1355
  }
1752
1356
  }
1753
1357
 
1754
- class Move {
1755
- angle;
1756
- center;
1757
- decay;
1758
- direction;
1759
- distance;
1760
- drift;
1761
- enable;
1762
- gravity;
1763
- outModes;
1764
- path;
1765
- random;
1766
- size;
1767
- speed;
1768
- spin;
1769
- straight;
1770
- vibrate;
1771
- warp;
1772
- constructor() {
1773
- this.angle = new MoveAngle();
1774
- this.center = new MoveCenter();
1775
- this.decay = 0;
1776
- this.distance = {};
1777
- this.direction = MoveDirection.none;
1778
- this.drift = 0;
1779
- this.enable = false;
1780
- this.gravity = new MoveGravity();
1781
- this.path = new MovePath();
1782
- this.outModes = new OutModes();
1783
- this.random = false;
1784
- this.size = false;
1785
- this.speed = 2;
1786
- this.spin = new Spin();
1787
- this.straight = false;
1788
- this.vibrate = false;
1789
- this.warp = false;
1790
- }
1791
- load(data) {
1792
- if (isNull(data)) {
1793
- return;
1794
- }
1358
+ class Move extends OptionLoader {
1359
+ angle = new MoveAngle();
1360
+ center = new MoveCenter();
1361
+ decay = 0;
1362
+ direction = MoveDirection.none;
1363
+ distance = {};
1364
+ drift = 0;
1365
+ enable = false;
1366
+ gravity = new MoveGravity();
1367
+ outModes = new OutModes();
1368
+ path = new MovePath();
1369
+ random = false;
1370
+ size = false;
1371
+ speed = 2;
1372
+ spin = new Spin();
1373
+ straight = false;
1374
+ vibrate = false;
1375
+ warp = false;
1376
+ doLoad(data) {
1795
1377
  this.angle.load(isNumber(data.angle) ? { value: data.angle } : data.angle);
1796
1378
  this.center.load(data.center);
1797
- if (data.decay !== undefined) {
1798
- this.decay = setRangeValue(data.decay);
1799
- }
1800
- if (data.direction !== undefined) {
1801
- this.direction = data.direction;
1802
- }
1379
+ loadRangeProperty(this, "decay", data.decay);
1380
+ loadProperty(this, "direction", data.direction);
1803
1381
  if (data.distance !== undefined) {
1804
1382
  this.distance = isNumber(data.distance)
1805
1383
  ? {
@@ -1808,12 +1386,8 @@
1808
1386
  }
1809
1387
  : { ...data.distance };
1810
1388
  }
1811
- if (data.drift !== undefined) {
1812
- this.drift = setRangeValue(data.drift);
1813
- }
1814
- if (data.enable !== undefined) {
1815
- this.enable = data.enable;
1816
- }
1389
+ loadRangeProperty(this, "drift", data.drift);
1390
+ loadProperty(this, "enable", data.enable);
1817
1391
  this.gravity.load(data.gravity);
1818
1392
  const outModes = data.outModes;
1819
1393
  if (outModes !== undefined) {
@@ -1827,256 +1401,141 @@
1827
1401
  }
1828
1402
  }
1829
1403
  this.path.load(data.path);
1830
- if (data.random !== undefined) {
1831
- this.random = data.random;
1832
- }
1833
- if (data.size !== undefined) {
1834
- this.size = data.size;
1835
- }
1836
- if (data.speed !== undefined) {
1837
- this.speed = setRangeValue(data.speed);
1838
- }
1404
+ loadProperty(this, "random", data.random);
1405
+ loadProperty(this, "size", data.size);
1406
+ loadRangeProperty(this, "speed", data.speed);
1839
1407
  this.spin.load(data.spin);
1840
- if (data.straight !== undefined) {
1841
- this.straight = data.straight;
1842
- }
1843
- if (data.vibrate !== undefined) {
1844
- this.vibrate = data.vibrate;
1845
- }
1846
- if (data.warp !== undefined) {
1847
- this.warp = data.warp;
1848
- }
1408
+ loadProperty(this, "straight", data.straight);
1409
+ loadProperty(this, "vibrate", data.vibrate);
1410
+ loadProperty(this, "warp", data.warp);
1849
1411
  }
1850
1412
  }
1851
1413
 
1852
- class Stroke {
1414
+ class Stroke extends OptionLoader {
1853
1415
  color;
1854
1416
  opacity;
1855
- width;
1856
- constructor() {
1857
- this.width = 0;
1858
- }
1859
- load(data) {
1860
- if (isNull(data)) {
1861
- return;
1862
- }
1417
+ width = 0;
1418
+ doLoad(data) {
1863
1419
  if (data.color !== undefined) {
1864
1420
  this.color = AnimatableColor.create(this.color, data.color);
1865
1421
  }
1866
- if (data.width !== undefined) {
1867
- this.width = setRangeValue(data.width);
1868
- }
1869
- if (data.opacity !== undefined) {
1870
- this.opacity = setRangeValue(data.opacity);
1871
- }
1422
+ loadRangeProperty(this, "width", data.width);
1423
+ loadRangeProperty(this, "opacity", data.opacity);
1872
1424
  }
1873
1425
  }
1874
1426
 
1875
- class Paint {
1427
+ class Paint extends OptionLoader {
1876
1428
  color;
1877
1429
  fill;
1878
1430
  stroke;
1879
- load(data) {
1880
- if (isNull(data)) {
1881
- return;
1882
- }
1431
+ doLoad(data) {
1883
1432
  if (data.color !== undefined) {
1884
1433
  this.color = AnimatableColor.create(this.color, data.color);
1885
1434
  }
1886
- if (data.fill !== undefined) {
1887
- this.fill ??= new Fill();
1888
- this.fill.load(data.fill);
1889
- }
1890
- if (data.stroke !== undefined) {
1891
- this.stroke ??= new Stroke();
1892
- this.stroke.load(data.stroke);
1893
- }
1435
+ loadLazyProperty(this, "fill", data.fill, () => new Fill());
1436
+ loadLazyProperty(this, "stroke", data.stroke, () => new Stroke());
1894
1437
  }
1895
1438
  }
1896
1439
 
1897
1440
  class ParticlesBounceFactor extends ValueWithRandom {
1898
- constructor() {
1899
- super();
1900
- this.value = 1;
1901
- }
1441
+ value = 1;
1902
1442
  }
1903
1443
 
1904
- class ParticlesBounce {
1905
- horizontal;
1906
- vertical;
1907
- constructor() {
1908
- this.horizontal = new ParticlesBounceFactor();
1909
- this.vertical = new ParticlesBounceFactor();
1910
- }
1911
- load(data) {
1912
- if (isNull(data)) {
1913
- return;
1914
- }
1444
+ class ParticlesBounce extends OptionLoader {
1445
+ horizontal = new ParticlesBounceFactor();
1446
+ vertical = new ParticlesBounceFactor();
1447
+ doLoad(data) {
1915
1448
  this.horizontal.load(data.horizontal);
1916
1449
  this.vertical.load(data.vertical);
1917
1450
  }
1918
1451
  }
1919
1452
 
1920
- class ParticlesDensity {
1921
- enable;
1922
- height;
1923
- width;
1924
- constructor() {
1925
- this.enable = false;
1926
- this.width = 1920;
1927
- this.height = 1080;
1928
- }
1929
- load(data) {
1930
- if (isNull(data)) {
1931
- return;
1932
- }
1933
- if (data.enable !== undefined) {
1934
- this.enable = data.enable;
1935
- }
1936
- const width = data.width;
1937
- if (width !== undefined) {
1938
- this.width = width;
1939
- }
1940
- const height = data.height;
1941
- if (height !== undefined) {
1942
- this.height = height;
1943
- }
1453
+ class ParticlesDensity extends OptionLoader {
1454
+ enable = false;
1455
+ height = 1080;
1456
+ width = 1920;
1457
+ doLoad(data) {
1458
+ loadProperty(this, "enable", data.enable);
1459
+ loadProperty(this, "width", data.width);
1460
+ loadProperty(this, "height", data.height);
1944
1461
  }
1945
1462
  }
1946
1463
 
1947
- class ParticlesNumberLimit {
1948
- mode;
1949
- value;
1950
- constructor() {
1951
- this.mode = LimitMode.delete;
1952
- this.value = 0;
1953
- }
1954
- load(data) {
1955
- if (isNull(data)) {
1956
- return;
1957
- }
1958
- if (data.mode !== undefined) {
1959
- this.mode = data.mode;
1960
- }
1961
- if (data.value !== undefined) {
1962
- this.value = data.value;
1963
- }
1464
+ class ParticlesNumberLimit extends OptionLoader {
1465
+ mode = LimitMode.delete;
1466
+ value = 0;
1467
+ doLoad(data) {
1468
+ loadProperty(this, "mode", data.mode);
1469
+ loadProperty(this, "value", data.value);
1964
1470
  }
1965
1471
  }
1966
1472
 
1967
- class ParticlesNumber {
1968
- density;
1969
- limit;
1970
- value;
1971
- constructor() {
1972
- this.density = new ParticlesDensity();
1973
- this.limit = new ParticlesNumberLimit();
1974
- this.value = 0;
1975
- }
1976
- load(data) {
1977
- if (isNull(data)) {
1978
- return;
1979
- }
1473
+ class ParticlesNumber extends OptionLoader {
1474
+ density = new ParticlesDensity();
1475
+ limit = new ParticlesNumberLimit();
1476
+ value = 0;
1477
+ doLoad(data) {
1980
1478
  this.density.load(data.density);
1981
1479
  this.limit.load(data.limit);
1982
- if (data.value !== undefined) {
1983
- this.value = data.value;
1984
- }
1480
+ loadProperty(this, "value", data.value);
1985
1481
  }
1986
1482
  }
1987
1483
 
1988
- class Shape {
1989
- close;
1990
- options;
1991
- type;
1992
- constructor() {
1993
- this.close = true;
1994
- this.options = {};
1995
- this.type = "circle";
1996
- }
1997
- load(data) {
1998
- if (isNull(data)) {
1999
- return;
2000
- }
1484
+ class Shape extends OptionLoader {
1485
+ close = true;
1486
+ options = {};
1487
+ type = "circle";
1488
+ doLoad(data) {
2001
1489
  const options = data.options;
2002
1490
  if (options !== undefined) {
2003
- for (const shape in options) {
2004
- const item = options[shape];
2005
- if (item) {
2006
- this.options[shape] = deepExtend(this.options[shape] ?? {}, item);
2007
- }
2008
- }
2009
- }
2010
- if (data.close !== undefined) {
2011
- this.close = data.close;
2012
- }
2013
- if (data.type !== undefined) {
2014
- this.type = data.type;
2015
- }
2016
- }
2017
- }
2018
-
2019
- class ZIndex extends ValueWithRandom {
2020
- opacityRate;
2021
- sizeRate;
2022
- velocityRate;
2023
- constructor() {
2024
- super();
2025
- this.opacityRate = 1;
2026
- this.sizeRate = 1;
2027
- this.velocityRate = 1;
2028
- }
2029
- load(data) {
2030
- super.load(data);
2031
- if (isNull(data)) {
2032
- return;
2033
- }
2034
- if (data.opacityRate !== undefined) {
2035
- this.opacityRate = data.opacityRate;
2036
- }
2037
- if (data.sizeRate !== undefined) {
2038
- this.sizeRate = data.sizeRate;
2039
- }
2040
- if (data.velocityRate !== undefined) {
2041
- this.velocityRate = data.velocityRate;
1491
+ for (const shape in options) {
1492
+ const item = options[shape];
1493
+ if (item) {
1494
+ this.options[shape] = deepExtend(this.options[shape] ?? {}, item);
1495
+ }
1496
+ }
2042
1497
  }
1498
+ loadProperty(this, "close", data.close);
1499
+ loadProperty(this, "type", data.type);
2043
1500
  }
2044
1501
  }
2045
1502
 
2046
- class ParticlesOptions {
2047
- bounce;
2048
- effect;
2049
- groups;
2050
- move;
2051
- number;
1503
+ class ZIndex extends ValueWithRandom {
1504
+ opacityRate = 1;
1505
+ sizeRate = 1;
1506
+ velocityRate = 1;
1507
+ doLoad(data) {
1508
+ super.doLoad(data);
1509
+ loadProperty(this, "opacityRate", data.opacityRate);
1510
+ loadProperty(this, "sizeRate", data.sizeRate);
1511
+ loadProperty(this, "velocityRate", data.velocityRate);
1512
+ }
1513
+ }
1514
+
1515
+ class ParticlesOptions extends OptionLoader {
1516
+ bounce = new ParticlesBounce();
1517
+ effect = new Effect();
1518
+ groups = {};
1519
+ move = new Move();
1520
+ number = new ParticlesNumber();
2052
1521
  paint;
2053
1522
  palette;
2054
- reduceDuplicates;
2055
- shape;
2056
- zIndex;
1523
+ reduceDuplicates = false;
1524
+ shape = new Shape();
1525
+ zIndex = new ZIndex();
2057
1526
  #container;
2058
1527
  #pluginManager;
2059
1528
  constructor(pluginManager, container) {
1529
+ super();
2060
1530
  this.#pluginManager = pluginManager;
2061
1531
  this.#container = container;
2062
- this.bounce = new ParticlesBounce();
2063
- this.effect = new Effect();
2064
- this.groups = {};
2065
- this.move = new Move();
2066
- this.number = new ParticlesNumber();
2067
1532
  this.paint = new Paint();
2068
1533
  this.paint.color = new AnimatableColor();
2069
1534
  this.paint.color.value = "#fff";
2070
1535
  this.paint.fill = new Fill();
2071
1536
  this.paint.fill.enable = true;
2072
- this.reduceDuplicates = false;
2073
- this.shape = new Shape();
2074
- this.zIndex = new ZIndex();
2075
1537
  }
2076
- load(data) {
2077
- if (isNull(data)) {
2078
- return;
2079
- }
1538
+ doLoad(data) {
2080
1539
  if (data.palette) {
2081
1540
  this.palette = data.palette;
2082
1541
  this.#importPalette(this.palette);
@@ -2134,7 +1593,7 @@
2134
1593
  }
2135
1594
  }
2136
1595
  }
2137
- #importPalette = (palette) => {
1596
+ #importPalette(palette) {
2138
1597
  const paletteData = this.#pluginManager.getPalette(palette);
2139
1598
  if (!paletteData) {
2140
1599
  return;
@@ -2178,69 +1637,49 @@
2178
1637
  mode: paletteData.blendMode,
2179
1638
  },
2180
1639
  });
2181
- };
2182
- }
2183
-
2184
- function loadOptions(options, ...sourceOptionsArr) {
2185
- for (const sourceOptions of sourceOptionsArr) {
2186
- options.load(sourceOptions);
2187
1640
  }
2188
1641
  }
1642
+
2189
1643
  function loadParticlesOptions(pluginManager, container, ...sourceOptionsArr) {
2190
1644
  const options = new ParticlesOptions(pluginManager, container);
2191
1645
  loadOptions(options, ...sourceOptionsArr);
2192
1646
  return options;
2193
1647
  }
2194
1648
 
2195
- class Options {
2196
- autoPlay;
1649
+ class Options extends OptionLoader {
1650
+ autoPlay = true;
2197
1651
  background;
2198
- clear;
2199
- defaultThemes;
2200
- delay;
2201
- detectRetina;
2202
- duration;
2203
- fpsLimit;
1652
+ clear = true;
1653
+ defaultThemes = {};
1654
+ delay = 0;
1655
+ detectRetina = true;
1656
+ duration = 0;
1657
+ fpsLimit = 120;
2204
1658
  fullScreen;
2205
- hdr;
1659
+ hdr = true;
2206
1660
  key;
2207
1661
  name;
2208
1662
  palette;
2209
1663
  particles;
2210
- pauseOnBlur;
2211
- pauseOnOutsideViewport;
1664
+ pauseOnBlur = true;
1665
+ pauseOnOutsideViewport = true;
2212
1666
  preset;
2213
1667
  resize;
2214
- smooth;
2215
- style;
2216
- zLayers;
1668
+ smooth = false;
1669
+ style = {};
1670
+ zLayers = 100;
2217
1671
  #container;
2218
1672
  #pluginManager;
2219
1673
  constructor(pluginManager, container) {
1674
+ super();
2220
1675
  this.#pluginManager = pluginManager;
2221
1676
  this.#container = container;
2222
- this.autoPlay = true;
2223
1677
  this.background = new Background();
2224
- this.clear = true;
2225
- this.defaultThemes = {};
2226
- this.delay = 0;
2227
1678
  this.fullScreen = new FullScreen();
2228
- this.detectRetina = true;
2229
- this.duration = 0;
2230
- this.fpsLimit = 120;
2231
- this.hdr = true;
2232
1679
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
2233
- this.pauseOnBlur = true;
2234
- this.pauseOnOutsideViewport = true;
2235
1680
  this.resize = new ResizeEvent();
2236
- this.smooth = false;
2237
- this.style = {};
2238
- this.zLayers = 100;
2239
1681
  }
2240
- load(data) {
2241
- if (isNull(data)) {
2242
- return;
2243
- }
1682
+ doLoad(data) {
2244
1683
  if (data.preset !== undefined) {
2245
1684
  this.preset = data.preset;
2246
1685
  executeOnSingleOrMultiple(this.preset, preset => {
@@ -2251,44 +1690,18 @@
2251
1690
  this.palette = data.palette;
2252
1691
  this.#importPalette(this.palette);
2253
1692
  }
2254
- if (data.autoPlay !== undefined) {
2255
- this.autoPlay = data.autoPlay;
2256
- }
2257
- if (data.clear !== undefined) {
2258
- this.clear = data.clear;
2259
- }
2260
- if (data.key !== undefined) {
2261
- this.key = data.key;
2262
- }
2263
- if (data.name !== undefined) {
2264
- this.name = data.name;
2265
- }
2266
- if (data.delay !== undefined) {
2267
- this.delay = setRangeValue(data.delay);
2268
- }
2269
- const detectRetina = data.detectRetina;
2270
- if (detectRetina !== undefined) {
2271
- this.detectRetina = detectRetina;
2272
- }
2273
- if (data.duration !== undefined) {
2274
- this.duration = setRangeValue(data.duration);
2275
- }
2276
- const fpsLimit = data.fpsLimit;
2277
- if (fpsLimit !== undefined) {
2278
- this.fpsLimit = fpsLimit;
2279
- }
2280
- if (data.hdr !== undefined) {
2281
- this.hdr = data.hdr;
2282
- }
2283
- if (data.pauseOnBlur !== undefined) {
2284
- this.pauseOnBlur = data.pauseOnBlur;
2285
- }
2286
- if (data.pauseOnOutsideViewport !== undefined) {
2287
- this.pauseOnOutsideViewport = data.pauseOnOutsideViewport;
2288
- }
2289
- if (data.zLayers !== undefined) {
2290
- this.zLayers = data.zLayers;
2291
- }
1693
+ loadProperty(this, "autoPlay", data.autoPlay);
1694
+ loadProperty(this, "clear", data.clear);
1695
+ loadProperty(this, "key", data.key);
1696
+ loadProperty(this, "name", data.name);
1697
+ loadRangeProperty(this, "delay", data.delay);
1698
+ loadProperty(this, "detectRetina", data.detectRetina);
1699
+ loadRangeProperty(this, "duration", data.duration);
1700
+ loadProperty(this, "fpsLimit", data.fpsLimit);
1701
+ loadProperty(this, "hdr", data.hdr);
1702
+ loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1703
+ loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1704
+ loadProperty(this, "zLayers", data.zLayers);
2292
1705
  this.background.load(data.background);
2293
1706
  const fullScreen = data.fullScreen;
2294
1707
  if (isBoolean(fullScreen)) {
@@ -2300,14 +1713,12 @@
2300
1713
  this.particles.load(data.particles);
2301
1714
  this.resize.load(data.resize);
2302
1715
  this.style = deepExtend(this.style, data.style);
2303
- if (data.smooth !== undefined) {
2304
- this.smooth = data.smooth;
2305
- }
1716
+ loadProperty(this, "smooth", data.smooth);
2306
1717
  this.#pluginManager.plugins.forEach(plugin => {
2307
1718
  plugin.loadOptions(this.#container, this, data);
2308
1719
  });
2309
1720
  }
2310
- #importPalette = palette => {
1721
+ #importPalette(palette) {
2311
1722
  const paletteData = this.#pluginManager.getPalette(palette);
2312
1723
  if (!paletteData) {
2313
1724
  return;
@@ -2324,143 +1735,19 @@
2324
1735
  palette,
2325
1736
  },
2326
1737
  });
2327
- };
2328
- #importPreset = preset => {
2329
- this.load(this.#pluginManager.getPreset(preset));
2330
- };
2331
- }
2332
-
2333
- function paintBase(context, dimension, baseColor) {
2334
- context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
2335
- context.fillRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2336
- }
2337
- function paintImage(context, dimension, image, opacity) {
2338
- if (!image) {
2339
- return;
2340
- }
2341
- const prevAlpha = context.globalAlpha;
2342
- context.globalAlpha = opacity;
2343
- context.drawImage(image, originPoint.x, originPoint.y, dimension.width, dimension.height);
2344
- context.globalAlpha = prevAlpha;
2345
- }
2346
- function clear(context, dimension) {
2347
- context.clearRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
2348
- }
2349
- function drawParticle(data) {
2350
- const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
2351
- x: pos.x,
2352
- y: pos.y,
2353
- };
2354
- context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
2355
- if (colorStyles.fill) {
2356
- context.fillStyle = colorStyles.fill;
2357
- }
2358
- const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
2359
- context.lineWidth = strokeWidth;
2360
- if (colorStyles.stroke) {
2361
- context.strokeStyle = colorStyles.stroke;
2362
- }
2363
- const drawData = {
2364
- context,
2365
- particle,
2366
- radius,
2367
- drawRadius: radius * drawScale,
2368
- opacity,
2369
- delta,
2370
- pixelRatio: container.retina.pixelRatio,
2371
- fill: fillEnabled,
2372
- stroke: strokeWidth > minStrokeWidth,
2373
- transformData,
2374
- position: { ...pos },
2375
- drawPosition,
2376
- drawScale,
2377
- };
2378
- for (const plugin of container.plugins) {
2379
- plugin.drawParticleTransform?.(drawData);
2380
- }
2381
- const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
2382
- drawBeforeEffect(effect, drawData);
2383
- drawShapeBeforeDraw(shape, drawData);
2384
- drawShape(shape, drawData);
2385
- drawShapeAfterDraw(shape, drawData);
2386
- drawAfterEffect(effect, drawData);
2387
- context.resetTransform();
2388
- }
2389
- function drawAfterEffect(drawer, data) {
2390
- if (!drawer?.drawAfter) {
2391
- return;
2392
- }
2393
- const { particle } = data;
2394
- if (!particle.effect) {
2395
- return;
2396
- }
2397
- drawer.drawAfter(data);
2398
- }
2399
- function drawBeforeEffect(drawer, data) {
2400
- if (!drawer?.drawBefore) {
2401
- return;
2402
- }
2403
- const { particle } = data;
2404
- if (!particle.effect) {
2405
- return;
2406
1738
  }
2407
- drawer.drawBefore(data);
2408
- }
2409
- function drawShape(drawer, data) {
2410
- if (!drawer) {
2411
- return;
2412
- }
2413
- const { context, fill, particle, stroke } = data;
2414
- if (!particle.shape) {
2415
- return;
2416
- }
2417
- context.beginPath();
2418
- drawer.draw(data);
2419
- if (particle.shapeClose) {
2420
- context.closePath();
2421
- }
2422
- if (fill) {
2423
- context.fill();
2424
- }
2425
- if (stroke) {
2426
- context.stroke();
2427
- }
2428
- }
2429
- function drawShapeAfterDraw(drawer, data) {
2430
- if (!drawer?.afterDraw) {
2431
- return;
2432
- }
2433
- const { particle } = data;
2434
- if (!particle.shape) {
2435
- return;
2436
- }
2437
- drawer.afterDraw(data);
2438
- }
2439
- function drawShapeBeforeDraw(drawer, data) {
2440
- if (!drawer?.beforeDraw) {
2441
- return;
2442
- }
2443
- const { particle } = data;
2444
- if (!particle.shape) {
2445
- return;
2446
- }
2447
- drawer.beforeDraw(data);
2448
- }
2449
- function drawParticlePlugin(context, plugin, particle, delta) {
2450
- if (!plugin.drawParticle) {
2451
- return;
1739
+ #importPreset(preset) {
1740
+ this.load(this.#pluginManager.getPreset(preset));
2452
1741
  }
2453
- plugin.drawParticle(context, particle, delta);
2454
1742
  }
2455
1743
 
2456
- const styleCache = new Map(), maxCacheSize = 1000, firstIndex = 0, rgbFixedPrecision = 2, hslFixedPrecision = 2;
1744
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
2457
1745
  function getCachedStyle(key, generator) {
2458
1746
  let cached = styleCache.get(key);
2459
1747
  if (!cached) {
2460
1748
  cached = generator();
2461
- if (styleCache.size >= maxCacheSize) {
2462
- const keysToDelete = [...styleCache.keys()].slice(firstIndex, maxCacheSize * half);
2463
- keysToDelete.forEach(k => styleCache.delete(k));
1749
+ if (styleCache.size > maxStyleCacheSize) {
1750
+ styleCache.clear();
2464
1751
  }
2465
1752
  styleCache.set(key, cached);
2466
1753
  }
@@ -2563,34 +1850,35 @@
2563
1850
  function stringToRgb(pluginManager, input) {
2564
1851
  return stringToRgba(pluginManager, input);
2565
1852
  }
1853
+ function hslChannel(temp1, temp2, temp3) {
1854
+ const temp3Min = 0, temp3Max = 1;
1855
+ if (temp3 < temp3Min) {
1856
+ temp3++;
1857
+ }
1858
+ if (temp3 > temp3Max) {
1859
+ temp3--;
1860
+ }
1861
+ if (temp3 * sextuple < temp3Max) {
1862
+ return temp1 + (temp2 - temp1) * sextuple * temp3;
1863
+ }
1864
+ if (temp3 * double < temp3Max) {
1865
+ return temp2;
1866
+ }
1867
+ if (temp3 * triple < temp3Max * double) {
1868
+ const temp3Offset = double / triple;
1869
+ return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
1870
+ }
1871
+ return temp1;
1872
+ }
2566
1873
  function hslToRgb(hsl) {
2567
1874
  const h = ((hsl.h % hMax) + hMax) % hMax, s = Math.max(sMin, Math.min(sMax, hsl.s)), l = Math.max(lMin, Math.min(lMax, hsl.l)), hNormalized = h / hMax, sNormalized = s / sMax, lNormalized = l / lMax;
2568
1875
  if (s === sMin) {
2569
1876
  const grayscaleValue = Math.round(lNormalized * rgbMax);
2570
1877
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
2571
1878
  }
2572
- const channel = (temp1, temp2, temp3) => {
2573
- const temp3Min = 0, temp3Max = 1;
2574
- if (temp3 < temp3Min) {
2575
- temp3++;
2576
- }
2577
- if (temp3 > temp3Max) {
2578
- temp3--;
2579
- }
2580
- if (temp3 * sextuple < temp3Max) {
2581
- return temp1 + (temp2 - temp1) * sextuple * temp3;
2582
- }
2583
- if (temp3 * double < temp3Max) {
2584
- return temp2;
2585
- }
2586
- if (temp3 * triple < temp3Max * double) {
2587
- const temp3Offset = double / triple;
2588
- return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
2589
- }
2590
- return temp1;
2591
- }, temp1 = lNormalized < half
1879
+ const temp1 = lNormalized < half
2592
1880
  ? lNormalized * (sNormalizedOffset + sNormalized)
2593
- : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * channel(temp2, temp1, hNormalized - phaseThird));
1881
+ : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized - phaseThird));
2594
1882
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
2595
1883
  }
2596
1884
  function hslaToRgba(hsla) {
@@ -2603,7 +1891,7 @@
2603
1891
  };
2604
1892
  }
2605
1893
  function getRandomRgbColor(min) {
2606
- const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$2, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1894
+ const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$1, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
2607
1895
  return {
2608
1896
  b: getRgbInRangeValue(),
2609
1897
  g: getRgbInRangeValue(),
@@ -2614,21 +1902,18 @@
2614
1902
  const op = opacity ?? defaultOpacity$1, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2615
1903
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2616
1904
  }
2617
- function getHdrStyleFromRgb(color, opacity) {
2618
- return `color(display-p3 ${(color.r / rgbMax).toString()} ${(color.g / rgbMax).toString()} ${(color.b / rgbMax).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1905
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1906
+ const headroom = peakNits / sdrReferenceWhiteNits;
1907
+ return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2619
1908
  }
2620
1909
  function getSdrStyleFromRgb(color, opacity) {
2621
1910
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
2622
1911
  }
2623
1912
  function getStyleFromHsl(color, hdr, opacity) {
2624
1913
  const op = opacity ?? defaultOpacity$1, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2625
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromHsl(color, opacity) : getSdrStyleFromHsl(color, opacity)));
2626
- }
2627
- function getHdrStyleFromHsl(color, opacity) {
2628
- return getHdrStyleFromRgb(hslToRgb(color), opacity);
2629
- }
2630
- function getSdrStyleFromHsl(color, opacity) {
2631
- return `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${(opacity ?? defaultOpacity$1).toString()})`;
1914
+ return getCachedStyle(key, () => hdr
1915
+ ? getStyleFromRgb(hslToRgb(color), true, opacity)
1916
+ : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
2632
1917
  }
2633
1918
  function getHslFromAnimation(animation) {
2634
1919
  return animation === undefined
@@ -2750,22 +2035,14 @@
2750
2035
  const tsParticles = initEngine();
2751
2036
 
2752
2037
  class Blend {
2753
- enable;
2754
- mode;
2755
- constructor() {
2756
- this.mode = "destination-out";
2757
- this.enable = false;
2758
- }
2038
+ enable = false;
2039
+ mode = "destination-out";
2759
2040
  load(data) {
2760
2041
  if (isNull(data)) {
2761
2042
  return;
2762
2043
  }
2763
- if (data.mode !== undefined) {
2764
- this.mode = data.mode;
2765
- }
2766
- if (data.enable !== undefined) {
2767
- this.enable = data.enable;
2768
- }
2044
+ loadProperty(this, "mode", data.mode);
2045
+ loadProperty(this, "enable", data.enable);
2769
2046
  }
2770
2047
  }
2771
2048
 
@@ -2795,7 +2072,7 @@
2795
2072
  }
2796
2073
 
2797
2074
  async function loadBlendPlugin(engine) {
2798
- engine.checkVersion("4.1.2");
2075
+ engine.checkVersion("4.2.0");
2799
2076
  await engine.pluginManager.register(e => {
2800
2077
  e.pluginManager.addPlugin(new BlendPlugin());
2801
2078
  });
@@ -2832,7 +2109,7 @@
2832
2109
  }
2833
2110
 
2834
2111
  async function loadCircleShape(engine) {
2835
- engine.checkVersion("4.1.2");
2112
+ engine.checkVersion("4.2.0");
2836
2113
  await engine.pluginManager.register(e => {
2837
2114
  e.pluginManager.addShape(["circle"], () => {
2838
2115
  return Promise.resolve(new CircleDrawer());
@@ -2880,7 +2157,7 @@
2880
2157
  }
2881
2158
 
2882
2159
  async function loadHexColorPlugin(engine) {
2883
- engine.checkVersion("4.1.2");
2160
+ engine.checkVersion("4.2.0");
2884
2161
  await engine.pluginManager.register(e => {
2885
2162
  e.pluginManager.addColorManager("hex", new HexColorManager());
2886
2163
  });
@@ -2933,7 +2210,7 @@
2933
2210
  }
2934
2211
 
2935
2212
  async function loadHslColorPlugin(engine) {
2936
- engine.checkVersion("4.1.2");
2213
+ engine.checkVersion("4.2.0");
2937
2214
  await engine.pluginManager.register(e => {
2938
2215
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2939
2216
  });
@@ -2957,7 +2234,7 @@
2957
2234
  }
2958
2235
 
2959
2236
  async function loadMovePlugin(engine) {
2960
- engine.checkVersion("4.1.2");
2237
+ engine.checkVersion("4.2.0");
2961
2238
  await engine.pluginManager.register(e => {
2962
2239
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2963
2240
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2975,31 +2252,143 @@
2975
2252
  });
2976
2253
  }
2977
2254
 
2978
- class OpacityAnimation extends RangedAnimationOptions {
2979
- destroy;
2980
- constructor() {
2981
- super();
2982
- this.destroy = DestroyType.none;
2983
- this.speed = 2;
2255
+ function checkDestroy(particle, destroyType, value, minValue, maxValue) {
2256
+ switch (destroyType) {
2257
+ case DestroyType.max:
2258
+ if (value >= maxValue) {
2259
+ particle.destroy();
2260
+ }
2261
+ break;
2262
+ case DestroyType.min:
2263
+ if (value <= minValue) {
2264
+ particle.destroy();
2265
+ }
2266
+ break;
2267
+ }
2268
+ }
2269
+ function initParticleNumericAnimationValue(options, pxRatio) {
2270
+ const valueRange = options.value, animationOptions = options.animation, res = {
2271
+ delayTime: getRangeValue(animationOptions.delay) * millisecondsToSeconds,
2272
+ enable: animationOptions.enable,
2273
+ value: getRangeValue(options.value) * pxRatio,
2274
+ max: getRangeMax(valueRange) * pxRatio,
2275
+ min: getRangeMin(valueRange) * pxRatio,
2276
+ loops: 0,
2277
+ maxLoops: getRangeValue(animationOptions.count),
2278
+ time: 0,
2279
+ }, decayOffset = 1;
2280
+ if (animationOptions.enable) {
2281
+ res.decay = decayOffset - getRangeValue(animationOptions.decay);
2282
+ switch (animationOptions.mode) {
2283
+ case AnimationMode.increase:
2284
+ res.status = AnimationStatus.increasing;
2285
+ break;
2286
+ case AnimationMode.decrease:
2287
+ res.status = AnimationStatus.decreasing;
2288
+ break;
2289
+ case AnimationMode.random:
2290
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2291
+ break;
2292
+ }
2293
+ const autoStatus = animationOptions.mode === AnimationMode.auto;
2294
+ switch (animationOptions.startValue) {
2295
+ case StartValueType.min:
2296
+ res.value = res.min;
2297
+ if (autoStatus) {
2298
+ res.status = AnimationStatus.increasing;
2299
+ }
2300
+ break;
2301
+ case StartValueType.max:
2302
+ res.value = res.max;
2303
+ if (autoStatus) {
2304
+ res.status = AnimationStatus.decreasing;
2305
+ }
2306
+ break;
2307
+ case StartValueType.random:
2308
+ default:
2309
+ res.value = randomInRangeValue(res);
2310
+ if (autoStatus) {
2311
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
2312
+ }
2313
+ break;
2314
+ }
2315
+ }
2316
+ res.initialValue = res.value;
2317
+ return res;
2318
+ }
2319
+ function updateAnimation(particle, data, changeDirection, destroyType, delta) {
2320
+ const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minDecay = 1;
2321
+ if (particle.destroyed ||
2322
+ !data.enable ||
2323
+ ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
2324
+ return;
2325
+ }
2326
+ const velocity = (data.velocity ?? minVelocity) * delta.factor, minValue = data.min, maxValue = data.max, decay = data.decay ?? minDecay;
2327
+ data.time ??= 0;
2328
+ const delayTime = data.delayTime ?? minDelay;
2329
+ if (delayTime > minDelay && data.time < delayTime) {
2330
+ data.time += delta.value;
2331
+ if (data.time < delayTime) {
2332
+ return;
2333
+ }
2334
+ }
2335
+ switch (data.status) {
2336
+ case AnimationStatus.increasing:
2337
+ data.value += velocity;
2338
+ break;
2339
+ case AnimationStatus.decreasing:
2340
+ data.value -= velocity;
2341
+ break;
2342
+ }
2343
+ if (data.velocity && decay !== identity) {
2344
+ data.velocity *= decay;
2984
2345
  }
2346
+ switch (data.status) {
2347
+ case AnimationStatus.increasing:
2348
+ if (data.value >= maxValue) {
2349
+ if (changeDirection) {
2350
+ data.status = AnimationStatus.decreasing;
2351
+ }
2352
+ else {
2353
+ data.value -= maxValue;
2354
+ }
2355
+ data.loops ??= minLoops;
2356
+ data.loops++;
2357
+ }
2358
+ break;
2359
+ case AnimationStatus.decreasing:
2360
+ if (data.value <= minValue) {
2361
+ if (changeDirection) {
2362
+ data.status = AnimationStatus.increasing;
2363
+ }
2364
+ else {
2365
+ data.value += maxValue;
2366
+ }
2367
+ data.loops ??= minLoops;
2368
+ data.loops++;
2369
+ }
2370
+ break;
2371
+ }
2372
+ checkDestroy(particle, destroyType, data.value, minValue, maxValue);
2373
+ if (!particle.destroyed) {
2374
+ data.value = clamp(data.value, minValue, maxValue);
2375
+ }
2376
+ }
2377
+
2378
+ class OpacityAnimation extends RangedAnimationOptions {
2379
+ destroy = DestroyType.none;
2985
2380
  load(data) {
2986
2381
  super.load(data);
2987
2382
  if (isNull(data)) {
2988
2383
  return;
2989
2384
  }
2990
- if (data.destroy !== undefined) {
2991
- this.destroy = data.destroy;
2992
- }
2385
+ loadProperty(this, "destroy", data.destroy);
2993
2386
  }
2994
2387
  }
2995
2388
 
2996
2389
  class Opacity extends RangedAnimationValueWithRandom {
2997
- animation;
2998
- constructor() {
2999
- super();
3000
- this.animation = new OpacityAnimation();
3001
- this.value = 1;
3002
- }
2390
+ animation = new OpacityAnimation();
2391
+ value = 1;
3003
2392
  load(data) {
3004
2393
  if (isNull(data)) {
3005
2394
  return;
@@ -3043,10 +2432,7 @@
3043
2432
  (particle.opacity.loops ?? none) < (particle.opacity.maxLoops ?? none))));
3044
2433
  }
3045
2434
  loadOptions(options, ...sources) {
3046
- options.opacity ??= new Opacity();
3047
- for (const source of sources) {
3048
- options.opacity.load(source?.opacity);
3049
- }
2435
+ loadOptionProperty(options, "opacity", Opacity, ...sources);
3050
2436
  }
3051
2437
  reset(particle) {
3052
2438
  if (!particle.opacity) {
@@ -3064,7 +2450,7 @@
3064
2450
  }
3065
2451
 
3066
2452
  async function loadOpacityUpdater(engine) {
3067
- engine.checkVersion("4.1.2");
2453
+ engine.checkVersion("4.2.0");
3068
2454
  await engine.pluginManager.register(e => {
3069
2455
  e.pluginManager.addParticleUpdater("opacity", container => {
3070
2456
  return Promise.resolve(new OpacityUpdater(container));
@@ -3072,7 +2458,7 @@
3072
2458
  });
3073
2459
  }
3074
2460
 
3075
- const minVelocity$4 = 0, boundsMin = 0;
2461
+ const boundsMin = 0;
3076
2462
  function bounceHorizontal(data) {
3077
2463
  if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
3078
2464
  (data.direction !== OutModeDirection.left && data.direction !== OutModeDirection.right)) {
@@ -3087,8 +2473,8 @@
3087
2473
  const velocity = data.particle.velocity.x;
3088
2474
  let bounced = false;
3089
2475
  if (data.outOfCanvas &&
3090
- ((data.direction === OutModeDirection.right && velocity > minVelocity$4) ||
3091
- (data.direction === OutModeDirection.left && velocity < minVelocity$4))) {
2476
+ ((data.direction === OutModeDirection.right && velocity > minVelocity) ||
2477
+ (data.direction === OutModeDirection.left && velocity < minVelocity))) {
3092
2478
  const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
3093
2479
  data.particle.velocity.x *= -newVelocity;
3094
2480
  bounced = true;
@@ -3121,8 +2507,8 @@
3121
2507
  const velocity = data.particle.velocity.y;
3122
2508
  let bounced = false;
3123
2509
  if (data.outOfCanvas &&
3124
- ((data.direction === OutModeDirection.bottom && velocity > minVelocity$4) ||
3125
- (data.direction === OutModeDirection.top && velocity < minVelocity$4))) {
2510
+ ((data.direction === OutModeDirection.bottom && velocity > minVelocity) ||
2511
+ (data.direction === OutModeDirection.top && velocity < minVelocity))) {
3126
2512
  const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
3127
2513
  data.particle.velocity.y *= -newVelocity;
3128
2514
  bounced = true;
@@ -3175,7 +2561,6 @@
3175
2561
  }
3176
2562
  }
3177
2563
 
3178
- const minVelocity$3 = 0;
3179
2564
  class DestroyOutMode {
3180
2565
  modes;
3181
2566
  constructor(_container) {
@@ -3194,10 +2579,10 @@
3194
2579
  break;
3195
2580
  case ParticleOutType.inside: {
3196
2581
  const { dx, dy } = getDistances(particle.position, particle.moveCenter), { x: vx, y: vy } = particle.velocity;
3197
- if ((vx < minVelocity$3 && dx > particle.moveCenter.radius) ||
3198
- (vy < minVelocity$3 && dy > particle.moveCenter.radius) ||
3199
- (vx >= minVelocity$3 && dx < -particle.moveCenter.radius) ||
3200
- (vy >= minVelocity$3 && dy < -particle.moveCenter.radius)) {
2582
+ if ((vx < minVelocity && dx > particle.moveCenter.radius) ||
2583
+ (vy < minVelocity && dy > particle.moveCenter.radius) ||
2584
+ (vx >= minVelocity && dx < -particle.moveCenter.radius) ||
2585
+ (vy >= minVelocity && dy < -particle.moveCenter.radius)) {
3201
2586
  return;
3202
2587
  }
3203
2588
  break;
@@ -3207,7 +2592,6 @@
3207
2592
  }
3208
2593
  }
3209
2594
 
3210
- const minVelocity$2 = 0;
3211
2595
  class NoneOutMode {
3212
2596
  modes;
3213
2597
  #container;
@@ -3227,10 +2611,10 @@
3227
2611
  }
3228
2612
  const gravityOptions = particle.options.move.gravity, container = this.#container, canvasSize = container.canvas.size, pRadius = particle.getRadius();
3229
2613
  if (!gravityOptions.enable) {
3230
- if ((particle.velocity.y > minVelocity$2 && particle.position.y <= canvasSize.height + pRadius) ||
3231
- (particle.velocity.y < minVelocity$2 && particle.position.y >= -pRadius) ||
3232
- (particle.velocity.x > minVelocity$2 && particle.position.x <= canvasSize.width + pRadius) ||
3233
- (particle.velocity.x < minVelocity$2 && particle.position.x >= -pRadius)) {
2614
+ if ((particle.velocity.y > minVelocity && particle.position.y <= canvasSize.height + pRadius) ||
2615
+ (particle.velocity.y < minVelocity && particle.position.y >= -pRadius) ||
2616
+ (particle.velocity.x > minVelocity && particle.position.x <= canvasSize.width + pRadius) ||
2617
+ (particle.velocity.x < minVelocity && particle.position.x >= -pRadius)) {
3234
2618
  return;
3235
2619
  }
3236
2620
  if (!isPointInside(particle.position, container.canvas.size, originPoint, pRadius, direction)) {
@@ -3249,7 +2633,7 @@
3249
2633
  }
3250
2634
  }
3251
2635
 
3252
- const minVelocity$1 = 0, minDistance = 0, updateVector = Vector.origin;
2636
+ const updateVector = Vector.origin;
3253
2637
  class OutOutMode {
3254
2638
  modes;
3255
2639
  #container;
@@ -3270,10 +2654,10 @@
3270
2654
  updateVector.angle = particle.velocity.angle + Math.PI;
3271
2655
  updateVector.addTo(particle.moveCenter);
3272
2656
  const { dx, dy } = getDistances(particle.position, updateVector);
3273
- if ((vx <= minVelocity$1 && dx >= minDistance) ||
3274
- (vy <= minVelocity$1 && dy >= minDistance) ||
3275
- (vx >= minVelocity$1 && dx <= minDistance) ||
3276
- (vy >= minVelocity$1 && dy <= minDistance)) {
2657
+ if ((vx <= minVelocity && dx >= minDistance) ||
2658
+ (vy <= minVelocity && dy >= minDistance) ||
2659
+ (vx >= minVelocity && dx <= minDistance) ||
2660
+ (vy >= minVelocity && dy <= minDistance)) {
3277
2661
  return;
3278
2662
  }
3279
2663
  particle.position.x = Math.floor(randomInRangeValue({
@@ -3397,21 +2781,21 @@
3397
2781
  this.#updateOutMode(particle, delta, outModes.right ?? outModes.default, OutModeDirection.right);
3398
2782
  this.#updateOutMode(particle, delta, outModes.top ?? outModes.default, OutModeDirection.top);
3399
2783
  }
3400
- #addUpdaterIfMissing = (particle, outMode, getUpdater) => {
2784
+ #addUpdaterIfMissing(particle, outMode, getUpdater) {
3401
2785
  const outModes = particle.options.move.outModes;
3402
2786
  if (!this.updaters.has(outMode) && checkOutMode(outModes, outMode)) {
3403
2787
  this.updaters.set(outMode, getUpdater(this.#container));
3404
2788
  }
3405
- };
3406
- #updateOutMode = (particle, delta, outMode, direction) => {
2789
+ }
2790
+ #updateOutMode(particle, delta, outMode, direction) {
3407
2791
  for (const updater of this.updaters.values()) {
3408
2792
  updater.update(particle, direction, delta, outMode);
3409
2793
  }
3410
- };
2794
+ }
3411
2795
  }
3412
2796
 
3413
2797
  async function loadOutModesUpdater(engine) {
3414
- engine.checkVersion("4.1.2");
2798
+ engine.checkVersion("4.2.0");
3415
2799
  await engine.pluginManager.register(e => {
3416
2800
  e.pluginManager.addParticleUpdater("outModes", container => {
3417
2801
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3482,7 +2866,7 @@
3482
2866
  }
3483
2867
 
3484
2868
  async function loadPaintUpdater(engine) {
3485
- engine.checkVersion("4.1.2");
2869
+ engine.checkVersion("4.2.0");
3486
2870
  await engine.pluginManager.register(e => {
3487
2871
  e.pluginManager.addParticleUpdater("paint", container => {
3488
2872
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3537,37 +2921,26 @@
3537
2921
  }
3538
2922
 
3539
2923
  async function loadRgbColorPlugin(engine) {
3540
- engine.checkVersion("4.1.2");
2924
+ engine.checkVersion("4.2.0");
3541
2925
  await engine.pluginManager.register(e => {
3542
2926
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3543
2927
  });
3544
2928
  }
3545
2929
 
3546
2930
  class SizeAnimation extends RangedAnimationOptions {
3547
- destroy;
3548
- constructor() {
3549
- super();
3550
- this.destroy = DestroyType.none;
3551
- this.speed = 5;
3552
- }
2931
+ destroy = DestroyType.none;
3553
2932
  load(data) {
3554
2933
  super.load(data);
3555
2934
  if (isNull(data)) {
3556
2935
  return;
3557
2936
  }
3558
- if (data.destroy !== undefined) {
3559
- this.destroy = data.destroy;
3560
- }
2937
+ loadProperty(this, "destroy", data.destroy);
3561
2938
  }
3562
2939
  }
3563
2940
 
3564
2941
  class Size extends RangedAnimationValueWithRandom {
3565
- animation;
3566
- constructor() {
3567
- super();
3568
- this.animation = new SizeAnimation();
3569
- this.value = 3;
3570
- }
2942
+ animation = new SizeAnimation();
2943
+ value = 3;
3571
2944
  load(data) {
3572
2945
  super.load(data);
3573
2946
  if (isNull(data)) {
@@ -3610,10 +2983,7 @@
3610
2983
  (particle.size.loops ?? minLoops) < (particle.size.maxLoops ?? minLoops))));
3611
2984
  }
3612
2985
  loadOptions(options, ...sources) {
3613
- options.size ??= new Size();
3614
- for (const source of sources) {
3615
- options.size.load(source?.size);
3616
- }
2986
+ loadOptionProperty(options, "size", Size, ...sources);
3617
2987
  }
3618
2988
  preInit(particle) {
3619
2989
  const pxRatio = this.#container.retina.pixelRatio, options = particle.options, sizeOptions = options.size;
@@ -3636,7 +3006,7 @@
3636
3006
  }
3637
3007
 
3638
3008
  async function loadSizeUpdater(engine) {
3639
- engine.checkVersion("4.1.2");
3009
+ engine.checkVersion("4.2.0");
3640
3010
  await engine.pluginManager.register(e => {
3641
3011
  e.pluginManager.addParticleUpdater("size", container => {
3642
3012
  return Promise.resolve(new SizeUpdater(container));
@@ -3645,7 +3015,7 @@
3645
3015
  }
3646
3016
 
3647
3017
  async function loadBasic(engine) {
3648
- engine.checkVersion("4.1.2");
3018
+ engine.checkVersion("4.2.0");
3649
3019
  await engine.pluginManager.register(async (e) => {
3650
3020
  await Promise.all([
3651
3021
  loadBlendPlugin(e),
@@ -3693,39 +3063,25 @@
3693
3063
  }
3694
3064
 
3695
3065
  class MotionReduce {
3696
- factor;
3697
- value;
3698
- constructor() {
3699
- this.factor = 4;
3700
- this.value = true;
3701
- }
3066
+ factor = 4;
3067
+ value = true;
3702
3068
  load(data) {
3703
3069
  if (isNull(data)) {
3704
3070
  return;
3705
3071
  }
3706
- if (data.factor !== undefined) {
3707
- this.factor = data.factor;
3708
- }
3709
- if (data.value !== undefined) {
3710
- this.value = data.value;
3711
- }
3072
+ loadProperty(this, "factor", data.factor);
3073
+ loadProperty(this, "value", data.value);
3712
3074
  }
3713
3075
  }
3714
3076
 
3715
3077
  class Motion {
3716
- disable;
3717
- reduce;
3718
- constructor() {
3719
- this.disable = true;
3720
- this.reduce = new MotionReduce();
3721
- }
3078
+ disable = true;
3079
+ reduce = new MotionReduce();
3722
3080
  load(data) {
3723
3081
  if (isNull(data)) {
3724
3082
  return;
3725
3083
  }
3726
- if (data.disable !== undefined) {
3727
- this.disable = data.disable;
3728
- }
3084
+ loadProperty(this, "disable", data.disable);
3729
3085
  this.reduce.load(data.reduce);
3730
3086
  }
3731
3087
  }
@@ -3752,7 +3108,7 @@
3752
3108
  }
3753
3109
 
3754
3110
  async function loadMotionPlugin(engine) {
3755
- engine.checkVersion("4.1.2");
3111
+ engine.checkVersion("4.2.0");
3756
3112
  await engine.pluginManager.register(e => {
3757
3113
  e.pluginManager.addPlugin(new MotionPlugin());
3758
3114
  });
@@ -3821,39 +3177,24 @@
3821
3177
  }
3822
3178
 
3823
3179
  class RollLight {
3824
- enable;
3825
- value;
3826
- constructor() {
3827
- this.enable = false;
3828
- this.value = 0;
3829
- }
3180
+ enable = false;
3181
+ value = 0;
3830
3182
  load(data) {
3831
3183
  if (isNull(data)) {
3832
- return;
3833
- }
3834
- if (data.enable !== undefined) {
3835
- this.enable = data.enable;
3836
- }
3837
- if (data.value !== undefined) {
3838
- this.value = setRangeValue(data.value);
3184
+ return;
3839
3185
  }
3186
+ loadProperty(this, "enable", data.enable);
3187
+ loadRangeProperty(this, "value", data.value);
3840
3188
  }
3841
3189
  }
3842
3190
 
3843
3191
  class Roll {
3844
3192
  backColor;
3845
- darken;
3846
- enable;
3847
- enlighten;
3848
- mode;
3849
- speed;
3850
- constructor() {
3851
- this.darken = new RollLight();
3852
- this.enable = false;
3853
- this.enlighten = new RollLight();
3854
- this.mode = RollMode.vertical;
3855
- this.speed = 25;
3856
- }
3193
+ darken = new RollLight();
3194
+ enable = false;
3195
+ enlighten = new RollLight();
3196
+ mode = RollMode.vertical;
3197
+ speed = 25;
3857
3198
  load(data) {
3858
3199
  if (isNull(data)) {
3859
3200
  return;
@@ -3862,16 +3203,10 @@
3862
3203
  this.backColor = OptionsColor.create(this.backColor, data.backColor);
3863
3204
  }
3864
3205
  this.darken.load(data.darken);
3865
- if (data.enable !== undefined) {
3866
- this.enable = data.enable;
3867
- }
3206
+ loadProperty(this, "enable", data.enable);
3868
3207
  this.enlighten.load(data.enlighten);
3869
- if (data.mode !== undefined) {
3870
- this.mode = data.mode;
3871
- }
3872
- if (data.speed !== undefined) {
3873
- this.speed = setRangeValue(data.speed);
3874
- }
3208
+ loadProperty(this, "mode", data.mode);
3209
+ loadRangeProperty(this, "speed", data.speed);
3875
3210
  }
3876
3211
  }
3877
3212
 
@@ -3895,10 +3230,7 @@
3895
3230
  return !particle.destroyed && !particle.spawning && !!roll?.enable;
3896
3231
  }
3897
3232
  loadOptions(options, ...sources) {
3898
- options.roll ??= new Roll();
3899
- for (const source of sources) {
3900
- options.roll.load(source?.roll);
3901
- }
3233
+ loadOptionProperty(options, "roll", Roll, ...sources);
3902
3234
  }
3903
3235
  update(particle, delta) {
3904
3236
  if (!this.isEnabled(particle)) {
@@ -3909,7 +3241,7 @@
3909
3241
  }
3910
3242
 
3911
3243
  async function loadRollUpdater(engine) {
3912
- engine.checkVersion("4.1.2");
3244
+ engine.checkVersion("4.2.0");
3913
3245
  await engine.pluginManager.register(e => {
3914
3246
  e.pluginManager.addParticleUpdater("roll", () => {
3915
3247
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -3918,58 +3250,33 @@
3918
3250
  }
3919
3251
 
3920
3252
  class RotateAnimation {
3921
- decay;
3922
- enable;
3923
- speed;
3924
- sync;
3925
- constructor() {
3926
- this.enable = false;
3927
- this.speed = 0;
3928
- this.decay = 0;
3929
- this.sync = false;
3930
- }
3253
+ decay = 0;
3254
+ enable = false;
3255
+ speed = 0;
3256
+ sync = false;
3931
3257
  load(data) {
3932
3258
  if (isNull(data)) {
3933
3259
  return;
3934
3260
  }
3935
- if (data.enable !== undefined) {
3936
- this.enable = data.enable;
3937
- }
3938
- if (data.speed !== undefined) {
3939
- this.speed = setRangeValue(data.speed);
3940
- }
3941
- if (data.decay !== undefined) {
3942
- this.decay = setRangeValue(data.decay);
3943
- }
3944
- if (data.sync !== undefined) {
3945
- this.sync = data.sync;
3946
- }
3261
+ loadProperty(this, "enable", data.enable);
3262
+ loadRangeProperty(this, "speed", data.speed);
3263
+ loadRangeProperty(this, "decay", data.decay);
3264
+ loadProperty(this, "sync", data.sync);
3947
3265
  }
3948
3266
  }
3949
3267
 
3950
3268
  class Rotate extends ValueWithRandom {
3951
- animation;
3952
- direction;
3953
- path;
3954
- constructor() {
3955
- super();
3956
- this.animation = new RotateAnimation();
3957
- this.direction = RotateDirection.clockwise;
3958
- this.path = false;
3959
- this.value = 0;
3960
- }
3269
+ animation = new RotateAnimation();
3270
+ direction = RotateDirection.clockwise;
3271
+ path = false;
3961
3272
  load(data) {
3962
3273
  if (isNull(data)) {
3963
3274
  return;
3964
3275
  }
3965
3276
  super.load(data);
3966
- if (data.direction !== undefined) {
3967
- this.direction = data.direction;
3968
- }
3277
+ loadProperty(this, "direction", data.direction);
3969
3278
  this.animation.load(data.animation);
3970
- if (data.path !== undefined) {
3971
- this.path = data.path;
3972
- }
3279
+ loadProperty(this, "path", data.path);
3973
3280
  }
3974
3281
  }
3975
3282
 
@@ -4007,7 +3314,7 @@
4007
3314
  }
4008
3315
  const rotateAnimation = rotateOptions.animation;
4009
3316
  if (rotateAnimation.enable) {
4010
- particle.rotate.decay = identity$2 - getRangeValue(rotateAnimation.decay);
3317
+ particle.rotate.decay = identity$1 - getRangeValue(rotateAnimation.decay);
4011
3318
  particle.rotate.velocity =
4012
3319
  (getRangeValue(rotateAnimation.speed) / doublePIDeg) * this.#container.retina.reduceFactor;
4013
3320
  if (!rotateAnimation.sync) {
@@ -4024,10 +3331,7 @@
4024
3331
  return !particle.destroyed && !particle.spawning && (!!rotate.value || rotate.animation.enable || rotate.path);
4025
3332
  }
4026
3333
  loadOptions(options, ...sources) {
4027
- options.rotate ??= new Rotate();
4028
- for (const source of sources) {
4029
- options.rotate.load(source?.rotate);
4030
- }
3334
+ loadOptionProperty(options, "rotate", Rotate, ...sources);
4031
3335
  }
4032
3336
  update(particle, delta) {
4033
3337
  if (!this.isEnabled(particle)) {
@@ -4043,7 +3347,7 @@
4043
3347
  }
4044
3348
 
4045
3349
  async function loadRotateUpdater(engine) {
4046
- engine.checkVersion("4.1.2");
3350
+ engine.checkVersion("4.2.0");
4047
3351
  await engine.pluginManager.register(e => {
4048
3352
  e.pluginManager.addParticleUpdater("rotate", container => {
4049
3353
  return Promise.resolve(new RotateUpdater(container));
@@ -4067,7 +3371,7 @@
4067
3371
  }
4068
3372
 
4069
3373
  async function loadSquareShape(engine) {
4070
- engine.checkVersion("4.1.2");
3374
+ engine.checkVersion("4.2.0");
4071
3375
  await engine.pluginManager.register(e => {
4072
3376
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
4073
3377
  });
@@ -4081,58 +3385,33 @@
4081
3385
  })(TiltDirection || (TiltDirection = {}));
4082
3386
 
4083
3387
  class TiltAnimation {
4084
- decay;
4085
- enable;
4086
- speed;
4087
- sync;
4088
- constructor() {
4089
- this.enable = false;
4090
- this.speed = 0;
4091
- this.decay = 0;
4092
- this.sync = false;
4093
- }
3388
+ decay = 0;
3389
+ enable = false;
3390
+ speed = 0;
3391
+ sync = false;
4094
3392
  load(data) {
4095
3393
  if (isNull(data)) {
4096
3394
  return;
4097
3395
  }
4098
- if (data.enable !== undefined) {
4099
- this.enable = data.enable;
4100
- }
4101
- if (data.speed !== undefined) {
4102
- this.speed = setRangeValue(data.speed);
4103
- }
4104
- if (data.decay !== undefined) {
4105
- this.decay = setRangeValue(data.decay);
4106
- }
4107
- if (data.sync !== undefined) {
4108
- this.sync = data.sync;
4109
- }
3396
+ loadProperty(this, "enable", data.enable);
3397
+ loadRangeProperty(this, "speed", data.speed);
3398
+ loadRangeProperty(this, "decay", data.decay);
3399
+ loadProperty(this, "sync", data.sync);
4110
3400
  }
4111
3401
  }
4112
3402
 
4113
3403
  class Tilt extends ValueWithRandom {
4114
- animation;
4115
- direction;
4116
- enable;
4117
- constructor() {
4118
- super();
4119
- this.animation = new TiltAnimation();
4120
- this.direction = TiltDirection.clockwise;
4121
- this.enable = false;
4122
- this.value = 0;
4123
- }
3404
+ animation = new TiltAnimation();
3405
+ direction = TiltDirection.clockwise;
3406
+ enable = false;
4124
3407
  load(data) {
4125
3408
  super.load(data);
4126
3409
  if (isNull(data)) {
4127
3410
  return;
4128
3411
  }
4129
3412
  this.animation.load(data.animation);
4130
- if (data.direction !== undefined) {
4131
- this.direction = data.direction;
4132
- }
4133
- if (data.enable !== undefined) {
4134
- this.enable = data.enable;
4135
- }
3413
+ loadProperty(this, "direction", data.direction);
3414
+ loadProperty(this, "enable", data.enable);
4136
3415
  }
4137
3416
  }
4138
3417
 
@@ -4157,8 +3436,8 @@
4157
3436
  particle.tilt = {
4158
3437
  enable: tiltOptions.enable,
4159
3438
  value: degToRad(getRangeValue(tiltOptions.value)),
4160
- sinDirection: getRandom() >= half ? identity$2 : -identity$2,
4161
- cosDirection: getRandom() >= half ? identity$2 : -identity$2,
3439
+ sinDirection: getRandom() >= half ? identity$1 : -identity$1,
3440
+ cosDirection: getRandom() >= half ? identity$1 : -identity$1,
4162
3441
  min: 0,
4163
3442
  max: doublePI,
4164
3443
  };
@@ -4178,7 +3457,7 @@
4178
3457
  }
4179
3458
  const tiltAnimation = particle.options.tilt?.animation;
4180
3459
  if (tiltAnimation?.enable) {
4181
- particle.tilt.decay = identity$2 - getRangeValue(tiltAnimation.decay);
3460
+ particle.tilt.decay = identity$1 - getRangeValue(tiltAnimation.decay);
4182
3461
  particle.tilt.velocity = (getRangeValue(tiltAnimation.speed) / maxAngle$1) * this.#container.retina.reduceFactor;
4183
3462
  if (!tiltAnimation.sync) {
4184
3463
  particle.tilt.velocity *= getRandom();
@@ -4190,10 +3469,7 @@
4190
3469
  return !particle.destroyed && !particle.spawning && !!tiltAnimation?.enable;
4191
3470
  }
4192
3471
  loadOptions(options, ...sources) {
4193
- options.tilt ??= new Tilt();
4194
- for (const source of sources) {
4195
- options.tilt.load(source?.tilt);
4196
- }
3472
+ loadOptionProperty(options, "tilt", Tilt, ...sources);
4197
3473
  }
4198
3474
  update(particle, delta) {
4199
3475
  if (!this.isEnabled(particle) || !particle.tilt) {
@@ -4204,7 +3480,7 @@
4204
3480
  }
4205
3481
 
4206
3482
  async function loadTiltUpdater(engine) {
4207
- engine.checkVersion("4.1.2");
3483
+ engine.checkVersion("4.2.0");
4208
3484
  await engine.pluginManager.register(e => {
4209
3485
  e.pluginManager.addParticleUpdater("tilt", container => {
4210
3486
  return Promise.resolve(new TiltUpdater(container));
@@ -4213,44 +3489,27 @@
4213
3489
  }
4214
3490
 
4215
3491
  class WobbleSpeed {
4216
- angle;
4217
- move;
4218
- constructor() {
4219
- this.angle = 50;
4220
- this.move = 10;
4221
- }
3492
+ angle = 50;
3493
+ move = 10;
4222
3494
  load(data) {
4223
3495
  if (isNull(data)) {
4224
3496
  return;
4225
3497
  }
4226
- if (data.angle !== undefined) {
4227
- this.angle = setRangeValue(data.angle);
4228
- }
4229
- if (data.move !== undefined) {
4230
- this.move = setRangeValue(data.move);
4231
- }
3498
+ loadRangeProperty(this, "angle", data.angle);
3499
+ loadRangeProperty(this, "move", data.move);
4232
3500
  }
4233
3501
  }
4234
3502
 
4235
3503
  class Wobble {
4236
- distance;
4237
- enable;
4238
- speed;
4239
- constructor() {
4240
- this.distance = 5;
4241
- this.enable = false;
4242
- this.speed = new WobbleSpeed();
4243
- }
3504
+ distance = 5;
3505
+ enable = false;
3506
+ speed = new WobbleSpeed();
4244
3507
  load(data) {
4245
3508
  if (isNull(data)) {
4246
3509
  return;
4247
3510
  }
4248
- if (data.distance !== undefined) {
4249
- this.distance = setRangeValue(data.distance);
4250
- }
4251
- if (data.enable !== undefined) {
4252
- this.enable = data.enable;
4253
- }
3511
+ loadRangeProperty(this, "distance", data.distance);
3512
+ loadProperty(this, "enable", data.enable);
4254
3513
  if (data.speed !== undefined) {
4255
3514
  if (isNumber(data.speed)) {
4256
3515
  this.speed.load({ angle: data.speed });
@@ -4312,10 +3571,7 @@
4312
3571
  return !particle.destroyed && !particle.spawning && !!particle.options.wobble?.enable;
4313
3572
  }
4314
3573
  loadOptions(options, ...sources) {
4315
- options.wobble ??= new Wobble();
4316
- for (const source of sources) {
4317
- options.wobble.load(source?.wobble);
4318
- }
3574
+ loadOptionProperty(options, "wobble", Wobble, ...sources);
4319
3575
  }
4320
3576
  update(particle, delta) {
4321
3577
  if (!this.isEnabled(particle)) {
@@ -4326,7 +3582,7 @@
4326
3582
  }
4327
3583
 
4328
3584
  async function loadWobbleUpdater(engine) {
4329
- engine.checkVersion("4.1.2");
3585
+ engine.checkVersion("4.2.0");
4330
3586
  await engine.pluginManager.register(e => {
4331
3587
  e.pluginManager.addParticleUpdater("wobble", container => {
4332
3588
  return Promise.resolve(new WobbleUpdater(container));
@@ -4499,7 +3755,7 @@
4499
3755
  return;
4500
3756
  }
4501
3757
  this.draw(ctx => {
4502
- clear(ctx, this.#canvasManager.size);
3758
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4503
3759
  });
4504
3760
  }
4505
3761
  clear() {
@@ -4561,7 +3817,7 @@
4561
3817
  plugin.drawParticleSetup?.(context, particle, delta);
4562
3818
  }
4563
3819
  this.#applyPreDrawUpdaters(context, particle, radius, opacity, colorStyles, transform);
4564
- drawParticle({
3820
+ this.#drawParticle({
4565
3821
  container,
4566
3822
  context,
4567
3823
  particle,
@@ -4580,7 +3836,7 @@
4580
3836
  drawParticlePlugins(particle, delta) {
4581
3837
  this.draw(ctx => {
4582
3838
  for (const plugin of this.#drawParticlePlugins) {
4583
- drawParticlePlugin(ctx, plugin, particle, delta);
3839
+ this.#drawParticlePlugin(ctx, plugin, particle, delta);
4584
3840
  }
4585
3841
  });
4586
3842
  }
@@ -4680,12 +3936,19 @@
4680
3936
  }
4681
3937
  paintBase(baseColor) {
4682
3938
  this.draw(ctx => {
4683
- paintBase(ctx, this.#canvasManager.size, baseColor);
3939
+ ctx.fillStyle = baseColor ?? "rgba(0,0,0,0)";
3940
+ ctx.fillRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4684
3941
  });
4685
3942
  }
4686
3943
  paintImage(image, opacity) {
4687
3944
  this.draw(ctx => {
4688
- paintImage(ctx, this.#canvasManager.size, image, opacity);
3945
+ if (!image) {
3946
+ return;
3947
+ }
3948
+ const prevAlpha = ctx.globalAlpha;
3949
+ ctx.globalAlpha = opacity;
3950
+ ctx.drawImage(image, originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
3951
+ ctx.globalAlpha = prevAlpha;
4689
3952
  });
4690
3953
  }
4691
3954
  setContext(context) {
@@ -4699,15 +3962,15 @@
4699
3962
  }
4700
3963
  stop() {
4701
3964
  this.draw(ctx => {
4702
- clear(ctx, this.#canvasManager.size);
3965
+ ctx.clearRect(originPoint.x, originPoint.y, this.#canvasManager.size.width, this.#canvasManager.size.height);
4703
3966
  });
4704
3967
  }
4705
- #applyPostDrawUpdaters = particle => {
3968
+ #applyPostDrawUpdaters(particle) {
4706
3969
  for (const updater of this.#postDrawUpdaters) {
4707
3970
  updater.afterDraw?.(particle);
4708
3971
  }
4709
- };
4710
- #applyPreDrawUpdaters = (ctx, particle, radius, zOpacity, colorStyles, transform) => {
3972
+ }
3973
+ #applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
4711
3974
  for (const updater of this.#preDrawUpdaters) {
4712
3975
  if (updater.getColorStyles) {
4713
3976
  const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
@@ -4726,8 +3989,114 @@
4726
3989
  }
4727
3990
  updater.beforeDraw?.(particle);
4728
3991
  }
4729
- };
4730
- #getPluginParticleColors = particle => {
3992
+ }
3993
+ #drawAfterEffect(drawer, data) {
3994
+ if (!drawer?.drawAfter) {
3995
+ return;
3996
+ }
3997
+ const { particle } = data;
3998
+ if (!particle.effect) {
3999
+ return;
4000
+ }
4001
+ drawer.drawAfter(data);
4002
+ }
4003
+ #drawBeforeEffect(drawer, data) {
4004
+ if (!drawer?.drawBefore) {
4005
+ return;
4006
+ }
4007
+ const { particle } = data;
4008
+ if (!particle.effect) {
4009
+ return;
4010
+ }
4011
+ drawer.drawBefore(data);
4012
+ }
4013
+ #drawParticle(data) {
4014
+ const { container, context, particle, delta, colorStyles, radius, opacity, transform } = data, { effectDrawers, shapeDrawers } = container, pos = particle.getPosition(), transformData = particle.getTransformData(transform), drawScale = defaultZoom, drawPosition = {
4015
+ x: pos.x,
4016
+ y: pos.y,
4017
+ };
4018
+ context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
4019
+ if (colorStyles.fill) {
4020
+ context.fillStyle = colorStyles.fill;
4021
+ }
4022
+ const fillEnabled = !!particle.fillEnabled, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
4023
+ context.lineWidth = strokeWidth;
4024
+ if (colorStyles.stroke) {
4025
+ context.strokeStyle = colorStyles.stroke;
4026
+ }
4027
+ const drawData = {
4028
+ context,
4029
+ particle,
4030
+ radius,
4031
+ drawRadius: radius * drawScale,
4032
+ opacity,
4033
+ delta,
4034
+ pixelRatio: container.retina.pixelRatio,
4035
+ fill: fillEnabled,
4036
+ stroke: strokeWidth > minStrokeWidth,
4037
+ transformData,
4038
+ position: { ...pos },
4039
+ drawPosition,
4040
+ drawScale,
4041
+ };
4042
+ for (const plugin of container.plugins) {
4043
+ plugin.drawParticleTransform?.(drawData);
4044
+ }
4045
+ const effect = particle.effect ? effectDrawers.get(particle.effect) : undefined, shape = particle.shape ? shapeDrawers.get(particle.shape) : undefined;
4046
+ this.#drawBeforeEffect(effect, drawData);
4047
+ this.#drawShapeBeforeDraw(shape, drawData);
4048
+ this.#drawShape(shape, drawData);
4049
+ this.#drawShapeAfterDraw(shape, drawData);
4050
+ this.#drawAfterEffect(effect, drawData);
4051
+ context.resetTransform();
4052
+ }
4053
+ #drawParticlePlugin(context, plugin, particle, delta) {
4054
+ if (!plugin.drawParticle) {
4055
+ return;
4056
+ }
4057
+ plugin.drawParticle(context, particle, delta);
4058
+ }
4059
+ #drawShape(drawer, data) {
4060
+ if (!drawer) {
4061
+ return;
4062
+ }
4063
+ const { context, fill, particle, stroke } = data;
4064
+ if (!particle.shape) {
4065
+ return;
4066
+ }
4067
+ context.beginPath();
4068
+ drawer.draw(data);
4069
+ if (particle.shapeClose) {
4070
+ context.closePath();
4071
+ }
4072
+ if (fill) {
4073
+ context.fill();
4074
+ }
4075
+ if (stroke) {
4076
+ context.stroke();
4077
+ }
4078
+ }
4079
+ #drawShapeAfterDraw(drawer, data) {
4080
+ if (!drawer?.afterDraw) {
4081
+ return;
4082
+ }
4083
+ const { particle } = data;
4084
+ if (!particle.shape) {
4085
+ return;
4086
+ }
4087
+ drawer.afterDraw(data);
4088
+ }
4089
+ #drawShapeBeforeDraw(drawer, data) {
4090
+ if (!drawer?.beforeDraw) {
4091
+ return;
4092
+ }
4093
+ const { particle } = data;
4094
+ if (!particle.shape) {
4095
+ return;
4096
+ }
4097
+ drawer.beforeDraw(data);
4098
+ }
4099
+ #getPluginParticleColors(particle) {
4731
4100
  let fColor, sColor;
4732
4101
  for (const plugin of this.#colorPlugins) {
4733
4102
  if (!fColor && plugin.particleFillColor) {
@@ -4743,7 +4112,7 @@
4743
4112
  this.#reusablePluginColors[fColorIndex] = fColor;
4744
4113
  this.#reusablePluginColors[sColorIndex] = sColor;
4745
4114
  return this.#reusablePluginColors;
4746
- };
4115
+ }
4747
4116
  }
4748
4117
 
4749
4118
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -4875,6 +4244,7 @@
4875
4244
  obs.observe(element, { attributes: true });
4876
4245
  });
4877
4246
  this.initPlugins();
4247
+ this.#initContext();
4878
4248
  this.render.init();
4879
4249
  }
4880
4250
  initBackground() {
@@ -4884,7 +4254,7 @@
4884
4254
  }
4885
4255
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4886
4256
  if (color) {
4887
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity);
4257
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
4888
4258
  }
4889
4259
  else {
4890
4260
  elementStyle.backgroundColor = "";
@@ -4906,7 +4276,7 @@
4906
4276
  if (this.#generated && this.domElement) {
4907
4277
  this.domElement.remove();
4908
4278
  }
4909
- const container = this.#container, domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4279
+ const domCanvas = isHtmlCanvasElement(canvas) ? canvas : undefined;
4910
4280
  this.domElement = domCanvas;
4911
4281
  this.#generated = domCanvas ? domCanvas.dataset[generatedAttribute] === "true" : false;
4912
4282
  this.renderCanvas = domCanvas ? getTransferredCanvas(domCanvas) : canvas;
@@ -4927,26 +4297,6 @@
4927
4297
  const pxRatio = this.#container.retina.pixelRatio, retinaSize = this.size;
4928
4298
  renderCanvas.height = retinaSize.height = standardSize.height * pxRatio;
4929
4299
  renderCanvas.width = retinaSize.width = standardSize.width * pxRatio;
4930
- const canSupportHdrQuery = safeMatchMedia("(color-gamut: p3)");
4931
- this.render.setContextSettings({
4932
- alpha: true,
4933
- colorSpace: canSupportHdrQuery?.matches && container.hdr ? "display-p3" : "srgb",
4934
- desynchronized: true,
4935
- willReadFrequently: false,
4936
- });
4937
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4938
- this.#safeMutationObserver(obs => {
4939
- obs.disconnect();
4940
- });
4941
- container.retina.init();
4942
- this.initBackground();
4943
- this.#safeMutationObserver(obs => {
4944
- const element = this.domElement;
4945
- if (!element || !(element instanceof Node)) {
4946
- return;
4947
- }
4948
- obs.observe(element, { attributes: true });
4949
- });
4950
4300
  }
4951
4301
  resize() {
4952
4302
  const element = this.domElement;
@@ -5014,12 +4364,30 @@
5014
4364
  await container.refresh();
5015
4365
  }
5016
4366
  }
5017
- #applyResizePlugins = () => {
4367
+ #applyResizePlugins() {
5018
4368
  for (const plugin of this.#resizePlugins) {
5019
4369
  plugin.resize?.();
5020
4370
  }
5021
- };
5022
- #initStyle = () => {
4371
+ }
4372
+ #initContext() {
4373
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4374
+ safeMatchMedia("(color-gamut: p3)")?.matches &&
4375
+ safeMatchMedia("(dynamic-range: high)")?.matches;
4376
+ this.render.setContextSettings({
4377
+ alpha: true,
4378
+ desynchronized: true,
4379
+ willReadFrequently: false,
4380
+ ...(canSupportHdr
4381
+ ? { colorSpace: "display-p3", colorType: "float16" }
4382
+ : { colorSpace: "srgb" }),
4383
+ });
4384
+ const renderCanvas = this.renderCanvas;
4385
+ if (!renderCanvas) {
4386
+ return;
4387
+ }
4388
+ this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4389
+ }
4390
+ #initStyle() {
5023
4391
  const element = this.domElement, options = this.#container.actualOptions;
5024
4392
  if (!element) {
5025
4393
  return;
@@ -5040,8 +4408,8 @@
5040
4408
  }
5041
4409
  element.style.setProperty(key, value, "important");
5042
4410
  }
5043
- };
5044
- #repairStyle = () => {
4411
+ }
4412
+ #repairStyle() {
5045
4413
  const element = this.domElement;
5046
4414
  if (!element) {
5047
4415
  return;
@@ -5060,27 +4428,27 @@
5060
4428
  }
5061
4429
  observer.observe(element, { attributes: true });
5062
4430
  });
5063
- };
5064
- #resetOriginalStyle = () => {
4431
+ }
4432
+ #resetOriginalStyle() {
5065
4433
  const element = this.domElement, originalStyle = this.#originalStyle;
5066
4434
  if (!element || !originalStyle) {
5067
4435
  return;
5068
4436
  }
5069
4437
  setStyle(element, originalStyle, true);
5070
- };
5071
- #safeMutationObserver = callback => {
4438
+ }
4439
+ #safeMutationObserver(callback) {
5072
4440
  if (!this.#mutationObserver) {
5073
4441
  return;
5074
4442
  }
5075
4443
  callback(this.#mutationObserver);
5076
- };
5077
- #setFullScreenStyle = () => {
4444
+ }
4445
+ #setFullScreenStyle() {
5078
4446
  const element = this.domElement;
5079
4447
  if (!element) {
5080
4448
  return;
5081
4449
  }
5082
4450
  setStyle(element, getFullScreenStyle(this.#container.actualOptions.fullScreen.zIndex), true);
5083
- };
4451
+ }
5084
4452
  }
5085
4453
 
5086
4454
  class EventListeners {
@@ -5105,7 +4473,7 @@
5105
4473
  removeListeners() {
5106
4474
  this.#manageListeners(false);
5107
4475
  }
5108
- #handleVisibilityChange = () => {
4476
+ #handleVisibilityChange() {
5109
4477
  const container = this.#container, options = container.actualOptions;
5110
4478
  if (!options.pauseOnBlur) {
5111
4479
  return;
@@ -5123,8 +4491,8 @@
5123
4491
  container.draw(true);
5124
4492
  }
5125
4493
  }
5126
- };
5127
- #handleWindowResize = () => {
4494
+ }
4495
+ #handleWindowResize() {
5128
4496
  if (this.#resizeTimeout) {
5129
4497
  clearTimeout(this.#resizeTimeout);
5130
4498
  this.#resizeTimeout = undefined;
@@ -5134,13 +4502,13 @@
5134
4502
  await canvas.windowResize();
5135
4503
  };
5136
4504
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
5137
- };
5138
- #manageListeners = add => {
4505
+ }
4506
+ #manageListeners(add) {
5139
4507
  const handlers = this.#handlers;
5140
4508
  this.#manageResize(add);
5141
4509
  manageListener(document, visibilityChangeEvent, handlers.visibilityChange, add, false);
5142
- };
5143
- #manageResize = add => {
4510
+ }
4511
+ #manageResize(add) {
5144
4512
  const handlers = this.#handlers, container = this.#container, options = container.actualOptions;
5145
4513
  if (!options.resize.enable) {
5146
4514
  return;
@@ -5167,7 +4535,7 @@
5167
4535
  });
5168
4536
  this.#resizeObserver.observe(canvasEl);
5169
4537
  }
5170
- };
4538
+ }
5171
4539
  }
5172
4540
 
5173
4541
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
@@ -5194,6 +4562,131 @@
5194
4562
  data.setCb(data.radius);
5195
4563
  }
5196
4564
  }
4565
+ function normalizeAngle(angle, modulus) {
4566
+ const normalized = angle % modulus;
4567
+ return normalized < defaultAngle ? normalized + modulus : normalized;
4568
+ }
4569
+ function initParticleState(particle, id, group) {
4570
+ particle.id = id;
4571
+ particle.group = group;
4572
+ particle.justWarped = false;
4573
+ particle.effectClose = true;
4574
+ particle.shapeClose = true;
4575
+ particle.pathRotation = false;
4576
+ particle.lastPathTime = 0;
4577
+ particle.destroyed = false;
4578
+ particle.unbreakable = false;
4579
+ particle.isRotating = false;
4580
+ particle.rotation = 0;
4581
+ particle.misplaced = false;
4582
+ particle.retina = {
4583
+ maxDistance: {},
4584
+ maxSpeed: 0,
4585
+ moveDrift: 0,
4586
+ moveSpeed: 0,
4587
+ sizeAnimationSpeed: 0,
4588
+ };
4589
+ particle.size = {
4590
+ value: 1,
4591
+ max: 1,
4592
+ min: 1,
4593
+ enable: false,
4594
+ };
4595
+ particle.outType = ParticleOutType.normal;
4596
+ particle.ignoresResizeRatio = true;
4597
+ }
4598
+ function resolveParticleOptions(particle, container, pluginManager, overrideOptions) {
4599
+ const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates;
4600
+ particle.effect = itemFromSingleOrMultiple(particlesOptions.effect.type, particle.id, reduceDuplicates);
4601
+ particle.shape = itemFromSingleOrMultiple(particlesOptions.shape.type, particle.id, reduceDuplicates);
4602
+ const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
4603
+ if (overrideOptions) {
4604
+ if (overrideOptions.effect) {
4605
+ const overrideEffectType = overrideOptions.effect.type;
4606
+ if (overrideEffectType && overrideEffectType !== particle.effect) {
4607
+ const effect = itemFromSingleOrMultiple(overrideEffectType, particle.id, reduceDuplicates);
4608
+ if (effect) {
4609
+ particle.effect = effect;
4610
+ }
4611
+ }
4612
+ effectOptions.load(overrideOptions.effect);
4613
+ }
4614
+ if (overrideOptions.shape) {
4615
+ const overrideShapeType = overrideOptions.shape.type;
4616
+ if (overrideShapeType && overrideShapeType !== particle.shape) {
4617
+ const shape = itemFromSingleOrMultiple(overrideShapeType, particle.id, reduceDuplicates);
4618
+ if (shape) {
4619
+ particle.shape = shape;
4620
+ }
4621
+ }
4622
+ shapeOptions.load(overrideOptions.shape);
4623
+ }
4624
+ }
4625
+ if (particle.effect === randomColorValue) {
4626
+ const availableEffects = [...container.effectDrawers.keys()];
4627
+ particle.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
4628
+ }
4629
+ if (particle.shape === randomColorValue) {
4630
+ const availableShapes = [...container.shapeDrawers.keys()];
4631
+ particle.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
4632
+ }
4633
+ particle.effectData = particle.effect
4634
+ ? loadEffectData(particle.effect, effectOptions, particle.id, reduceDuplicates)
4635
+ : undefined;
4636
+ particle.shapeData = particle.shape
4637
+ ? loadShapeData(particle.shape, shapeOptions, particle.id, reduceDuplicates)
4638
+ : undefined;
4639
+ particlesOptions.load(overrideOptions);
4640
+ const effectData = particle.effectData, shapeData = particle.shapeData;
4641
+ if (effectData) {
4642
+ particlesOptions.load(effectData.particles);
4643
+ }
4644
+ if (shapeData) {
4645
+ particlesOptions.load(shapeData.particles);
4646
+ }
4647
+ particle.effectClose = effectData?.close ?? particlesOptions.effect.close;
4648
+ particle.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
4649
+ return particlesOptions;
4650
+ }
4651
+ function initParticleDrawers(particle, container) {
4652
+ let effectDrawer, shapeDrawer;
4653
+ if (particle.effect) {
4654
+ effectDrawer = container.effectDrawers.get(particle.effect);
4655
+ }
4656
+ if (effectDrawer?.loadEffect) {
4657
+ effectDrawer.loadEffect(particle);
4658
+ }
4659
+ if (particle.shape) {
4660
+ shapeDrawer = container.shapeDrawers.get(particle.shape);
4661
+ }
4662
+ if (shapeDrawer?.loadShape) {
4663
+ shapeDrawer.loadShape(particle);
4664
+ }
4665
+ const sideCountFunc = shapeDrawer?.getSidesCount;
4666
+ if (sideCountFunc) {
4667
+ particle.sides = sideCountFunc(particle);
4668
+ }
4669
+ }
4670
+ function runUpdaterPreInit(updaters, particle) {
4671
+ for (const updater of updaters) {
4672
+ updater.preInit?.(particle);
4673
+ }
4674
+ }
4675
+ function runUpdaterInit(updaters, particle) {
4676
+ for (const updater of updaters) {
4677
+ updater.init(particle);
4678
+ }
4679
+ }
4680
+ function runDrawerInit(container, particle) {
4681
+ const shapeDrawer = particle.shape ? container.shapeDrawers.get(particle.shape) : undefined, effectDrawer = particle.effect ? container.effectDrawers.get(particle.effect) : undefined;
4682
+ effectDrawer?.particleInit?.(container, particle);
4683
+ shapeDrawer?.particleInit?.(container, particle);
4684
+ }
4685
+ function runParticleCreatedPlugins(container, particle) {
4686
+ for (const plugin of container.particleCreatedPlugins) {
4687
+ plugin.particleCreated?.(particle);
4688
+ }
4689
+ }
5197
4690
  class Particle {
5198
4691
  backColor;
5199
4692
  bubble;
@@ -5319,88 +4812,20 @@
5319
4812
  const rotateData = this.getRotateData(), rotating = this.isRotating;
5320
4813
  this.#cachedTransform.a = rotateData.cos * (externalTransform.a ?? defaultTransform.a);
5321
4814
  this.#cachedTransform.b = rotating
5322
- ? rotateData.sin * (externalTransform.b ?? identity$2)
4815
+ ? rotateData.sin * (externalTransform.b ?? identity$1)
5323
4816
  : (externalTransform.b ?? defaultTransform.b);
5324
4817
  this.#cachedTransform.c = rotating
5325
- ? -rotateData.sin * (externalTransform.c ?? identity$2)
4818
+ ? -rotateData.sin * (externalTransform.c ?? identity$1)
5326
4819
  : (externalTransform.c ?? defaultTransform.c);
5327
4820
  this.#cachedTransform.d = rotateData.cos * (externalTransform.d ?? defaultTransform.d);
5328
4821
  return this.#cachedTransform;
5329
4822
  }
5330
4823
  init(id, position, overrideOptions, group) {
5331
4824
  const container = this.#container;
5332
- this.id = id;
5333
- this.group = group;
5334
- this.justWarped = false;
5335
- this.effectClose = true;
5336
- this.shapeClose = true;
5337
- this.pathRotation = false;
5338
- this.lastPathTime = 0;
5339
- this.destroyed = false;
5340
- this.unbreakable = false;
5341
- this.isRotating = false;
5342
- this.rotation = 0;
5343
- this.misplaced = false;
5344
- this.retina = {
5345
- maxDistance: {},
5346
- maxSpeed: 0,
5347
- moveDrift: 0,
5348
- moveSpeed: 0,
5349
- sizeAnimationSpeed: 0,
5350
- };
5351
- this.size = {
5352
- value: 1,
5353
- max: 1,
5354
- min: 1,
5355
- enable: false,
5356
- };
5357
- this.outType = ParticleOutType.normal;
5358
- this.ignoresResizeRatio = true;
5359
- const mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this.#pluginManager, container, mainOptions.particles), reduceDuplicates = particlesOptions.reduceDuplicates, effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type;
5360
- this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
5361
- this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
5362
- const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
5363
- if (overrideOptions) {
5364
- if (overrideOptions.effect?.type && overrideOptions.effect.type !== this.effect) {
5365
- const overrideEffectType = overrideOptions.effect.type, effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
5366
- if (effect) {
5367
- this.effect = effect;
5368
- effectOptions.load(overrideOptions.effect);
5369
- }
5370
- }
5371
- if (overrideOptions.shape?.type && overrideOptions.shape.type !== this.shape) {
5372
- const overrideShapeType = overrideOptions.shape.type, shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
5373
- if (shape) {
5374
- this.shape = shape;
5375
- shapeOptions.load(overrideOptions.shape);
5376
- }
5377
- }
5378
- }
5379
- if (this.effect === randomColorValue) {
5380
- const availableEffects = [...this.#container.effectDrawers.keys()];
5381
- this.effect = availableEffects[Math.floor(getRandom() * availableEffects.length)];
5382
- }
5383
- if (this.shape === randomColorValue) {
5384
- const availableShapes = [...this.#container.shapeDrawers.keys()];
5385
- this.shape = availableShapes[Math.floor(getRandom() * availableShapes.length)];
5386
- }
5387
- this.effectData = this.effect ? loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates) : undefined;
5388
- this.shapeData = this.shape ? loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates) : undefined;
5389
- particlesOptions.load(overrideOptions);
5390
- const effectData = this.effectData, shapeData = this.shapeData;
5391
- if (effectData) {
5392
- particlesOptions.load(effectData.particles);
5393
- }
5394
- if (shapeData) {
5395
- particlesOptions.load(shapeData.particles);
5396
- }
5397
- this.effectClose = effectData?.close ?? particlesOptions.effect.close;
5398
- this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
5399
- this.options = particlesOptions;
4825
+ initParticleState(this, id, group);
4826
+ this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
5400
4827
  container.retina.initParticle(this);
5401
- for (const updater of container.particleUpdaters) {
5402
- updater.preInit?.(this);
5403
- }
4828
+ runUpdaterPreInit(container.particleUpdaters, this);
5404
4829
  this.bubble = {
5405
4830
  inRange: false,
5406
4831
  };
@@ -5413,32 +4838,11 @@
5413
4838
  this.velocity = this.initialVelocity.copy();
5414
4839
  this.zIndexFactor = this.position.z / container.zLayers;
5415
4840
  this.sides = 24;
5416
- let effectDrawer, shapeDrawer;
5417
- if (this.effect) {
5418
- effectDrawer = container.effectDrawers.get(this.effect);
5419
- }
5420
- if (effectDrawer?.loadEffect) {
5421
- effectDrawer.loadEffect(this);
5422
- }
5423
- if (this.shape) {
5424
- shapeDrawer = container.shapeDrawers.get(this.shape);
5425
- }
5426
- if (shapeDrawer?.loadShape) {
5427
- shapeDrawer.loadShape(this);
5428
- }
5429
- const sideCountFunc = shapeDrawer?.getSidesCount;
5430
- if (sideCountFunc) {
5431
- this.sides = sideCountFunc(this);
5432
- }
4841
+ initParticleDrawers(this, container);
5433
4842
  this.spawning = false;
5434
- for (const updater of container.particleUpdaters) {
5435
- updater.init(this);
5436
- }
5437
- effectDrawer?.particleInit?.(container, this);
5438
- shapeDrawer?.particleInit?.(container, this);
5439
- for (const plugin of container.particleCreatedPlugins) {
5440
- plugin.particleCreated?.(this);
5441
- }
4843
+ runUpdaterInit(container.particleUpdaters, this);
4844
+ runDrawerInit(container, this);
4845
+ runParticleCreatedPlugins(container, this);
5442
4846
  }
5443
4847
  isInsideCanvas(direction) {
5444
4848
  return this.#getInsideCanvasResult({ direction }).inside;
@@ -5452,15 +4856,15 @@
5452
4856
  }
5453
4857
  const angle = this.roll.angle;
5454
4858
  if (this.roll.horizontal && this.roll.vertical) {
5455
- const normalizedAngle = angle % doublePI, adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + doublePI : normalizedAngle;
4859
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5456
4860
  return adjustedAngle >= Math.PI * half && adjustedAngle < Math.PI * triple * half;
5457
4861
  }
5458
4862
  if (this.roll.horizontal) {
5459
- const normalizedAngle = (angle + Math.PI * half) % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4863
+ const adjustedAngle = normalizeAngle(angle + Math.PI * half, doublePI);
5460
4864
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5461
4865
  }
5462
4866
  if (this.roll.vertical) {
5463
- const normalizedAngle = angle % (Math.PI * double), adjustedAngle = normalizedAngle < defaultAngle ? normalizedAngle + Math.PI * double : normalizedAngle;
4867
+ const adjustedAngle = normalizeAngle(angle, doublePI);
5464
4868
  return adjustedAngle >= Math.PI && adjustedAngle < Math.PI * double;
5465
4869
  }
5466
4870
  return false;
@@ -5473,10 +4877,10 @@
5473
4877
  updater.reset?.(this);
5474
4878
  }
5475
4879
  }
5476
- #calcPosition = (position, zIndex) => {
4880
+ #calcPosition(position, zIndex) {
5477
4881
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
5478
- const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size, abortController = new AbortController(), { signal } = abortController;
5479
- while (!signal.aborted) {
4882
+ const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
4883
+ for (;;) {
5480
4884
  for (const plugin of plugins) {
5481
4885
  const pluginPos = plugin.particlePosition?.(posVec, this);
5482
4886
  if (pluginPos) {
@@ -5504,9 +4908,8 @@
5504
4908
  tryCount += tryCountIncrement;
5505
4909
  posVec = undefined;
5506
4910
  }
5507
- return posVec;
5508
- };
5509
- #calculateVelocity = () => {
4911
+ }
4912
+ #calculateVelocity() {
5510
4913
  const moveOptions = this.options.move, baseVelocity = getParticleBaseVelocity(this.direction), res = baseVelocity.copy();
5511
4914
  if (moveOptions.direction === MoveDirection.inside || moveOptions.direction === MoveDirection.outside) {
5512
4915
  return res;
@@ -5522,8 +4925,8 @@
5522
4925
  res.length *= getRandom();
5523
4926
  }
5524
4927
  return res;
5525
- };
5526
- #fixHorizontal = (pos, radius, outMode) => {
4928
+ }
4929
+ #fixHorizontal(pos, radius, outMode) {
5527
4930
  fixOutMode({
5528
4931
  outMode,
5529
4932
  checkModes: [OutMode.bounce],
@@ -5532,8 +4935,8 @@
5532
4935
  setCb: (value) => (pos.x += value),
5533
4936
  radius,
5534
4937
  });
5535
- };
5536
- #fixVertical = (pos, radius, outMode) => {
4938
+ }
4939
+ #fixVertical(pos, radius, outMode) {
5537
4940
  fixOutMode({
5538
4941
  outMode,
5539
4942
  checkModes: [OutMode.bounce],
@@ -5542,8 +4945,8 @@
5542
4945
  setCb: (value) => (pos.y += value),
5543
4946
  radius,
5544
4947
  });
5545
- };
5546
- #getDefaultInsideCanvasResult = (direction, outMode) => {
4948
+ }
4949
+ #getDefaultInsideCanvasResult(direction, outMode) {
5547
4950
  const radius = this.getRadius(), canvasSize = this.#container.canvas.size, position = this.position, isBounce = outMode === OutMode.bounce;
5548
4951
  if (direction === OutModeDirection.bottom) {
5549
4952
  return {
@@ -5576,8 +4979,8 @@
5576
4979
  position.x <= canvasSize.width + radius,
5577
4980
  reason: "default",
5578
4981
  };
5579
- };
5580
- #getInsideCanvasCallbackData = (direction, outMode) => {
4982
+ }
4983
+ #getInsideCanvasCallbackData(direction, outMode) {
5581
4984
  return {
5582
4985
  canvasSize: this.#container.canvas.size,
5583
4986
  direction,
@@ -5585,8 +4988,8 @@
5585
4988
  particle: this,
5586
4989
  radius: this.getRadius(),
5587
4990
  };
5588
- };
5589
- #getInsideCanvasResult = (data) => {
4991
+ }
4992
+ #getInsideCanvasResult(data) {
5590
4993
  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;
5591
4994
  if (!shapeCheck && !effectCheck) {
5592
4995
  return defaultResult;
@@ -5601,8 +5004,8 @@
5601
5004
  };
5602
5005
  }
5603
5006
  return shapeResult ?? effectResult ?? defaultResult;
5604
- };
5605
- #getRollColor = color => {
5007
+ }
5008
+ #getRollColor(color) {
5606
5009
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
5607
5010
  return color;
5608
5011
  }
@@ -5616,8 +5019,8 @@
5616
5019
  return alterHsl(color, this.roll.alter.type, this.roll.alter.value);
5617
5020
  }
5618
5021
  return color;
5619
- };
5620
- #initPosition = position => {
5022
+ }
5023
+ #initPosition(position) {
5621
5024
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5622
5025
  if (!initialPosition) {
5623
5026
  throw new Error("a valid position cannot be found for particle");
@@ -5640,8 +5043,8 @@
5640
5043
  break;
5641
5044
  }
5642
5045
  this.offset = Vector.origin;
5643
- };
5644
- #normalizeInsideCanvasResult = (result, reason) => {
5046
+ }
5047
+ #normalizeInsideCanvasResult(result, reason) {
5645
5048
  if (typeof result === "boolean") {
5646
5049
  return {
5647
5050
  inside: result,
@@ -5653,7 +5056,7 @@
5653
5056
  margin: result.margin,
5654
5057
  reason: result.reason ?? reason,
5655
5058
  };
5656
- };
5059
+ }
5657
5060
  }
5658
5061
 
5659
5062
  class SpatialHashGrid {
@@ -6006,10 +5409,10 @@
6006
5409
  }
6007
5410
  this.#resizeFactor = undefined;
6008
5411
  }
6009
- #addToPool = (...particles) => {
5412
+ #addToPool(...particles) {
6010
5413
  this.#pool.push(...particles);
6011
- };
6012
- #applyDensity = (options, pluginsCount, group, groupOptions) => {
5414
+ }
5415
+ #applyDensity(options, pluginsCount, group, groupOptions) {
6013
5416
  const numberOptions = options.number;
6014
5417
  if (!numberOptions.density.enable) {
6015
5418
  if (group === undefined) {
@@ -6033,36 +5436,19 @@
6033
5436
  else if (particlesCount > particlesNumber) {
6034
5437
  this.removeQuantity(particlesCount - particlesNumber, group);
6035
5438
  }
6036
- };
6037
- #createBuckets = (zLayers) => {
5439
+ }
5440
+ #createBuckets(zLayers) {
6038
5441
  const bucketCount = Math.max(Math.floor(zLayers), one);
6039
5442
  return Array.from({ length: bucketCount }, () => []);
6040
- };
6041
- #getBucketIndex = (zIndex) => {
5443
+ }
5444
+ #getBucketIndex(zIndex) {
6042
5445
  const maxBucketIndex = this.#zBuckets.length - one;
6043
5446
  if (maxBucketIndex <= minIndex) {
6044
5447
  return minIndex;
6045
5448
  }
6046
5449
  return Math.min(Math.max(Math.floor(zIndex), minIndex), maxBucketIndex);
6047
- };
6048
- #getParticleInsertIndex = (bucket, particleId) => {
6049
- let start = minIndex, end = bucket.length;
6050
- while (start < end) {
6051
- const middle = Math.floor((start + end) / double), middleParticle = bucket[middle];
6052
- if (!middleParticle) {
6053
- end = middle;
6054
- continue;
6055
- }
6056
- if (middleParticle.id < particleId) {
6057
- start = middle + one;
6058
- }
6059
- else {
6060
- end = middle;
6061
- }
6062
- }
6063
- return start;
6064
- };
6065
- #initDensityFactor = densityOptions => {
5450
+ }
5451
+ #initDensityFactor(densityOptions) {
6066
5452
  const container = this.#container;
6067
5453
  if (!densityOptions.enable) {
6068
5454
  return defaultDensityFactor;
@@ -6072,16 +5458,16 @@
6072
5458
  return defaultDensityFactor;
6073
5459
  }
6074
5460
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
6075
- };
6076
- #insertParticleIntoBucket = (particle) => {
5461
+ }
5462
+ #insertParticleIntoBucket(particle) {
6077
5463
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6078
5464
  if (!bucket) {
6079
5465
  return;
6080
5466
  }
6081
- bucket.splice(this.#getParticleInsertIndex(bucket, particle.id), empty, particle);
5467
+ bucket.push(particle);
6082
5468
  this.#particleBuckets.set(particle.id, bucketIndex);
6083
- };
6084
- #removeParticle = (index, group, override) => {
5469
+ }
5470
+ #removeParticle(index, group, override) {
6085
5471
  const particle = this.#array[index];
6086
5472
  if (!particle) {
6087
5473
  return false;
@@ -6097,22 +5483,20 @@
6097
5483
  });
6098
5484
  this.#addToPool(particle);
6099
5485
  return true;
6100
- };
6101
- #removeParticleFromBucket = (particle) => {
5486
+ }
5487
+ #removeParticleFromBucket(particle) {
6102
5488
  const bucketIndex = this.#particleBuckets.get(particle.id) ?? this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6103
5489
  if (!bucket) {
6104
5490
  this.#particleBuckets.delete(particle.id);
6105
5491
  return;
6106
5492
  }
6107
- const particleIndex = this.#getParticleInsertIndex(bucket, particle.id);
6108
- if (bucket[particleIndex]?.id !== particle.id) {
6109
- this.#particleBuckets.delete(particle.id);
6110
- return;
5493
+ const idx = bucket.findIndex(p => p.id === particle.id);
5494
+ if (idx >= minIndex) {
5495
+ bucket.splice(idx, deleteCount);
6111
5496
  }
6112
- bucket.splice(particleIndex, deleteCount);
6113
5497
  this.#particleBuckets.delete(particle.id);
6114
- };
6115
- #resetBuckets = (zLayers) => {
5498
+ }
5499
+ #resetBuckets(zLayers) {
6116
5500
  const bucketCount = Math.max(Math.floor(zLayers), one);
6117
5501
  if (this.#zBuckets.length !== bucketCount) {
6118
5502
  this.#zBuckets = this.#createBuckets(bucketCount);
@@ -6121,8 +5505,8 @@
6121
5505
  for (const bucket of this.#zBuckets) {
6122
5506
  bucket.length = minIndex;
6123
5507
  }
6124
- };
6125
- #updateParticleBucket = (particle) => {
5508
+ }
5509
+ #updateParticleBucket(particle) {
6126
5510
  const newBucketIndex = this.#getBucketIndex(particle.position.z), currentBucketIndex = this.#particleBuckets.get(particle.id);
6127
5511
  if (currentBucketIndex === undefined) {
6128
5512
  this.#insertParticleIntoBucket(particle);
@@ -6133,9 +5517,9 @@
6133
5517
  }
6134
5518
  const currentBucket = this.#zBuckets[currentBucketIndex];
6135
5519
  if (currentBucket) {
6136
- const particleIndex = this.#getParticleInsertIndex(currentBucket, particle.id);
6137
- if (currentBucket[particleIndex]?.id === particle.id) {
6138
- currentBucket.splice(particleIndex, deleteCount);
5520
+ const idx = currentBucket.findIndex(p => p.id === particle.id);
5521
+ if (idx >= minIndex) {
5522
+ currentBucket.splice(idx, deleteCount);
6139
5523
  }
6140
5524
  }
6141
5525
  const newBucket = this.#zBuckets[newBucketIndex];
@@ -6143,10 +5527,16 @@
6143
5527
  this.#particleBuckets.set(particle.id, newBucketIndex);
6144
5528
  return;
6145
5529
  }
6146
- newBucket.splice(this.#getParticleInsertIndex(newBucket, particle.id), empty, particle);
5530
+ newBucket.push(particle);
5531
+ if (newBucket.length >= double) {
5532
+ const prev = newBucket[newBucket.length - double];
5533
+ if (prev && particle.id < prev.id) {
5534
+ newBucket.sort((a, b) => a.id - b.id);
5535
+ }
5536
+ }
6147
5537
  this.#particleBuckets.set(particle.id, newBucketIndex);
6148
- };
6149
- #updateParticlesPhase1 = (delta) => {
5538
+ }
5539
+ #updateParticlesPhase1(delta) {
6150
5540
  const particlesToDelete = new Set(), resizeFactor = this.#resizeFactor;
6151
5541
  for (const particle of this.#array) {
6152
5542
  if (resizeFactor && !particle.ignoresResizeRatio) {
@@ -6172,8 +5562,8 @@
6172
5562
  this.grid.insert(particle);
6173
5563
  }
6174
5564
  return particlesToDelete;
6175
- };
6176
- #updateParticlesPhase2 = (delta, particlesToDelete) => {
5565
+ }
5566
+ #updateParticlesPhase2(delta, particlesToDelete) {
6177
5567
  for (const particle of this.#array) {
6178
5568
  if (particle.destroyed) {
6179
5569
  particlesToDelete.add(particle);
@@ -6189,7 +5579,7 @@
6189
5579
  }
6190
5580
  this.#updateParticleBucket(particle);
6191
5581
  }
6192
- };
5582
+ }
6193
5583
  }
6194
5584
 
6195
5585
  class Retina {
@@ -6551,7 +5941,7 @@
6551
5941
  }
6552
5942
  return refresh;
6553
5943
  }
6554
- #nextFrame = (timestamp) => {
5944
+ #nextFrame(timestamp) {
6555
5945
  try {
6556
5946
  if (!this.#smooth &&
6557
5947
  this.#lastFrameTime !== undefined &&
@@ -6579,7 +5969,7 @@
6579
5969
  catch (e) {
6580
5970
  getLogger().error("error in animation loop", e);
6581
5971
  }
6582
- };
5972
+ }
6583
5973
  }
6584
5974
 
6585
5975
  var Container$1 = /*#__PURE__*/Object.freeze({
@@ -6625,7 +6015,7 @@
6625
6015
  BlendPluginInstance: BlendPluginInstance
6626
6016
  });
6627
6017
 
6628
- const minVelocity = 0, identity$1 = 1, moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
6018
+ const moveSpeedFactor = 60, minSpinRadius = 0, spinFactor = 0.01, defaultPathDelay = 0, noDecay = 1;
6629
6019
  function applyDistance(particle) {
6630
6020
  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;
6631
6021
  if (!hDistance && !vDistance) {
@@ -6873,7 +6263,7 @@
6873
6263
  mediaQuery.addEventListener("change", handleChange);
6874
6264
  await Promise.resolve();
6875
6265
  }
6876
- #handleMotionChange = mediaQuery => {
6266
+ #handleMotionChange(mediaQuery) {
6877
6267
  const container = this.#container, motion = container.actualOptions.motion;
6878
6268
  if (!motion) {
6879
6269
  return;
@@ -6889,7 +6279,7 @@
6889
6279
  else {
6890
6280
  container.retina.reduceFactor = defaultReduce;
6891
6281
  }
6892
- };
6282
+ }
6893
6283
  }
6894
6284
 
6895
6285
  var MotionPluginInstance$1 = /*#__PURE__*/Object.freeze({