@tsparticles/fireworks 4.4.0 → 4.5.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,21 +1,58 @@
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
- /* tsParticles v4.4.0 */
3
- (function (global, factory) {
4
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
5
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
6
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.__tsParticlesInternals = global.__tsParticlesInternals || {}, global.__tsParticlesInternals.bundles = global.__tsParticlesInternals.bundles || {}, global.__tsParticlesInternals.bundles.fireworks = global.__tsParticlesInternals.bundles.fireworks || {})));
7
- })(this, (function (exports) { 'use strict';
8
-
9
- const generatedAttribute = "generated", defaultCompositeValue = "source-over", resizeEvent = "resize", visibilityChangeEvent = "visibilitychange", percentDenominator = 100, half = 0.5, millisecondsToSeconds = 1000, originPoint = {
10
- x: 0,
11
- y: 0,
12
- z: 0,
13
- }, defaultTransform = {
14
- a: 1,
15
- b: 0,
16
- c: 0,
17
- d: 1,
18
- }, randomColorValue = "random", midColorValue = "mid", double = 2, doublePI = Math.PI * double, defaultFps = 60, defaultAlpha$1 = 1, 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, minRadius$1 = 0, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$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;
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);})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
+ (function (g) {
3
+ /* tsParticles v4.5.0 */
4
+ g.__tsParticlesInternals = g.__tsParticlesInternals || {};
5
+ g.__tsParticlesInternals.bundles = g.__tsParticlesInternals.bundles || {};
6
+ (function (exports) {
7
+ 'use strict';
8
+
9
+ const errorPrefix = "tsParticles - Error", codedErrorPattern = /^\[tsParticles Error (TSP-\d+)\]\s*/, fullMatchIndex = 0, codeIndex = 1;
10
+ const wrap = (fn) => (...args) => {
11
+ fn(...args);
12
+ }, _logger = {
13
+ debug: wrap(console.debug),
14
+ error: (message, ...optionalParams) => {
15
+ if (typeof message === "string") {
16
+ const match = codedErrorPattern.exec(message);
17
+ if (match?.[codeIndex]) {
18
+ console.error(`tsParticles - ${match[codeIndex]} - ${message.slice(match[fullMatchIndex].length)}`, ...optionalParams);
19
+ return;
20
+ }
21
+ }
22
+ console.error(`${errorPrefix} - ${message}`, ...optionalParams);
23
+ },
24
+ info: wrap(console.info),
25
+ log: wrap(console.log),
26
+ trace: wrap(console.trace),
27
+ verbose: wrap(console.log),
28
+ warning: wrap(console.warn),
29
+ };
30
+ function setLogger(logger) {
31
+ if (logger.debug) {
32
+ _logger.debug = wrap(logger.debug);
33
+ }
34
+ if (logger.error) {
35
+ _logger.error = wrap(logger.error);
36
+ }
37
+ if (logger.info) {
38
+ _logger.info = wrap(logger.info);
39
+ }
40
+ if (logger.log) {
41
+ _logger.log = wrap(logger.log);
42
+ }
43
+ if (logger.trace) {
44
+ _logger.trace = wrap(logger.trace);
45
+ }
46
+ if (logger.verbose) {
47
+ _logger.verbose = wrap(logger.verbose);
48
+ }
49
+ if (logger.warning) {
50
+ _logger.warning = wrap(logger.warning);
51
+ }
52
+ }
53
+ function getLogger() {
54
+ return _logger;
55
+ }
19
56
 
20
57
  exports.MoveDirection = void 0;
21
58
  (function (MoveDirection) {
@@ -32,6 +69,17 @@
32
69
  MoveDirection["inside"] = "inside";
33
70
  })(exports.MoveDirection || (exports.MoveDirection = {}));
34
71
 
72
+ const generatedAttribute = "generated", fullPercent = "100%", defaultCompositeValue = "source-over", resizeEvent = "resize", visibilityChangeEvent = "visibilitychange", percentDenominator = 100, half = 0.5, millisecondsToSeconds = 1000, originPoint = {
73
+ x: 0,
74
+ y: 0,
75
+ z: 0,
76
+ }, defaultTransform = {
77
+ a: 1,
78
+ b: 0,
79
+ c: 0,
80
+ d: 1,
81
+ }, randomColorValue = "random", midColorValue = "mid", double = 2, doublePI = Math.PI * double, defaultFps = 60, defaultAlpha = 1, 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, minRadius = 0, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 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;
82
+
35
83
  function getZ(source) {
36
84
  return "z" in source ? source.z : originPoint.z;
37
85
  }
@@ -150,6 +198,12 @@
150
198
  function isFunction(arg) {
151
199
  return typeof arg === "function";
152
200
  }
201
+ function isEnumValue(enumObject, arg) {
202
+ return Object.values(enumObject).some(enumValue => enumValue === arg);
203
+ }
204
+ function toEnumValue(enumObject, arg, defaultValue) {
205
+ return isEnumValue(enumObject, arg) ? arg : defaultValue;
206
+ }
153
207
  function isObject(arg) {
154
208
  return typeof arg === "object" && arg !== null;
155
209
  }
@@ -310,11 +364,61 @@
310
364
  };
311
365
  }
312
366
  function parseAlpha(input) {
313
- const defaultAlpha = 1;
314
367
  if (!input) {
315
368
  return defaultAlpha;
316
369
  }
317
- return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
370
+ return input.endsWith("%") ? Number.parseFloat(input) / percentDenominator : Number.parseFloat(input);
371
+ }
372
+
373
+ const ErrorCodes$2 = {
374
+ engineVersionMismatch: "TSP-1001",
375
+ particlePositionNotFound: "TSP-1002",
376
+ pluginRegisterAfterLoad: "TSP-1003",
377
+ offscreenCanvasUnsupported: "TSP-1101",
378
+ offscreenCanvasTransferFailed: "TSP-1102",
379
+ hdrEnableInvalid: "TSP-1201",
380
+ hdrModeInvalid: "TSP-1202",
381
+ hdrPeakNitsInvalid: "TSP-1203",
382
+ };
383
+
384
+ const messages = {
385
+ [ErrorCodes$2.engineVersionMismatch]: "The tsParticles version is different from the loaded plugins version. Engine version: {0}. Plugin version: {1}",
386
+ [ErrorCodes$2.particlePositionNotFound]: "a valid position cannot be found for particle",
387
+ [ErrorCodes$2.pluginRegisterAfterLoad]: "Register plugins can only be done before calling tsParticles.load()",
388
+ [ErrorCodes$2.offscreenCanvasUnsupported]: "OffscreenCanvas is required but not supported by this browser",
389
+ [ErrorCodes$2.offscreenCanvasTransferFailed]: "OffscreenCanvas transfer failed",
390
+ [ErrorCodes$2.hdrEnableInvalid]: 'Invalid HDR "enable" value: expected a boolean, got "{0}"',
391
+ [ErrorCodes$2.hdrModeInvalid]: 'Invalid HDR "mode" value: expected one of {0}, got "{1}"',
392
+ [ErrorCodes$2.hdrPeakNitsInvalid]: 'Invalid HDR "peakNits" value: expected a positive number, got "{0}"',
393
+ };
394
+
395
+ let registeredMessages;
396
+ const ensureRegisteredMessages = () => {
397
+ registeredMessages ??= new Map(Object.entries(messages));
398
+ return registeredMessages;
399
+ }, toStringValue$1 = (value) => String(value), format = (template, args) => {
400
+ return template.replace(/\{(\d+)\}/g, (match, index) => {
401
+ const arg = args[Number(index)];
402
+ return arg === undefined ? match : toStringValue$1(arg);
403
+ });
404
+ };
405
+ function addErrorMessages(extraMessages) {
406
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "production") {
407
+ return;
408
+ }
409
+ const catalog = ensureRegisteredMessages();
410
+ for (const [code, message] of Object.entries(extraMessages)) {
411
+ if (message !== undefined) {
412
+ catalog.set(code, message);
413
+ }
414
+ }
415
+ }
416
+ function getErrorMessage(code, ...args) {
417
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "production") {
418
+ return `[tsParticles Error ${code}] https://particles.js.org/errors/#${code}`;
419
+ }
420
+ const template = ensureRegisteredMessages().get(code) ?? `Unknown error code ${code}`;
421
+ return format(template, args);
318
422
  }
319
423
 
320
424
  exports.OutModeDirection = void 0;
@@ -331,7 +435,6 @@
331
435
  PixelMode["percent"] = "percent";
332
436
  })(exports.PixelMode || (exports.PixelMode = {}));
333
437
 
334
- const minRadius = 0;
335
438
  function isForbiddenKey(key) {
336
439
  return key === "__proto__" || key === "constructor" || key === "prototype";
337
440
  }
@@ -547,22 +650,84 @@
547
650
  element.removeEventListener(event, handler, removeOptions);
548
651
  }
549
652
  }
550
- async function getItemsFromInitializer(container, map, initializers, force = false) {
551
- let res = map.get(container);
552
- if (!res || force) {
553
- res = await Promise.all([...initializers.values()].map(t => t(container)));
554
- map.set(container, res);
653
+ async function getItemsFromInitializer(container, initializers) {
654
+ return await Promise.all([...initializers.values()].map(t => t(container)));
655
+ }
656
+ async function getItemMapFromInitializer(container, initializers) {
657
+ const entries = await Promise.all([...initializers.entries()].map(([key, initializer]) => initializer(container).then(item => [key, item])));
658
+ return new Map(entries);
659
+ }
660
+ async function getDataFromUrl(data) {
661
+ const url = itemFromSingleOrMultiple(data.url, data.index);
662
+ if (!url) {
663
+ return data.fallback;
555
664
  }
556
- return res;
665
+ try {
666
+ const response = await fetch(url);
667
+ if (response.ok) {
668
+ const current = (await response.json());
669
+ if (isSourceOptionsValue(current)) {
670
+ return current;
671
+ }
672
+ getLogger().error("invalid configuration data while retrieving config file");
673
+ }
674
+ else {
675
+ getLogger().error(`${response.status.toString()} while retrieving config file`);
676
+ }
677
+ }
678
+ catch (error) {
679
+ getLogger().error(`error while retrieving config file: ${error}`);
680
+ }
681
+ return data.fallback;
557
682
  }
558
- async function getItemMapFromInitializer(container, map, initializers, force = false) {
559
- let res = map.get(container);
560
- if (!res || force) {
561
- const entries = await Promise.all([...initializers.entries()].map(([key, initializer]) => initializer(container).then(item => [key, item])));
562
- res = new Map(entries);
563
- map.set(container, res);
683
+ function isSourceOptionsValue(value) {
684
+ if (isArray(value)) {
685
+ return value.every((entry) => isObject(entry) && !isArray(entry));
564
686
  }
565
- return res;
687
+ return isObject(value) && !isArray(value);
688
+ }
689
+ function getCanvasFromContainer(domContainer) {
690
+ let canvasEl;
691
+ const documentSafe = safeDocument(), isCanvas = domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag;
692
+ if (isCanvas) {
693
+ canvasEl = domContainer;
694
+ canvasEl.dataset[generatedAttribute] ??= generatedFalse;
695
+ if (canvasEl.dataset[generatedAttribute] === generatedTrue) {
696
+ canvasEl.style.width ||= fullPercent;
697
+ canvasEl.style.height ||= fullPercent;
698
+ canvasEl.style.pointerEvents = "none";
699
+ canvasEl.style.setProperty("pointer-events", "none");
700
+ }
701
+ }
702
+ else {
703
+ const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
704
+ if (foundCanvas) {
705
+ canvasEl = foundCanvas;
706
+ canvasEl.dataset[generatedAttribute] = generatedFalse;
707
+ }
708
+ else {
709
+ canvasEl = documentSafe.createElement(canvasTag);
710
+ canvasEl.dataset[generatedAttribute] = generatedTrue;
711
+ domContainer.appendChild(canvasEl);
712
+ }
713
+ canvasEl.style.width ||= fullPercent;
714
+ canvasEl.style.height ||= fullPercent;
715
+ canvasEl.style.pointerEvents = "none";
716
+ canvasEl.style.setProperty("pointer-events", "none");
717
+ }
718
+ return canvasEl;
719
+ }
720
+ function getDomContainer(id, source) {
721
+ const documentSafe = safeDocument();
722
+ let domContainer = source ?? documentSafe.getElementById(id);
723
+ if (domContainer) {
724
+ return domContainer;
725
+ }
726
+ domContainer = documentSafe.createElement("canvas");
727
+ domContainer.id = id;
728
+ domContainer.dataset[generatedAttribute] = generatedTrue;
729
+ documentSafe.body.append(domContainer);
730
+ return domContainer;
566
731
  }
567
732
 
568
733
  class EventDispatcher {
@@ -633,7 +798,6 @@
633
798
  class PluginManager {
634
799
  colorManagers = new Map();
635
800
  easingFunctions = new Map();
636
- effectDrawers = new Map();
637
801
  initializers = {
638
802
  effects: new Map(),
639
803
  shapes: new Map(),
@@ -642,8 +806,6 @@
642
806
  palettes = new Map();
643
807
  plugins = [];
644
808
  presets = new Map();
645
- shapeDrawers = new Map();
646
- updaters = new Map();
647
809
  #allLoadersSet = new Set();
648
810
  #configs = new Map();
649
811
  #engine;
@@ -661,57 +823,79 @@
661
823
  }
662
824
  return res;
663
825
  }
826
+ get initialized() {
827
+ return this.#initialized;
828
+ }
664
829
  addColorManager(name, manager) {
830
+ if (this.#initialized) {
831
+ return;
832
+ }
665
833
  this.colorManagers.set(name, manager);
666
834
  }
667
835
  addConfig(config) {
836
+ if (this.#initialized) {
837
+ return;
838
+ }
668
839
  const key = config.key ?? config.name ?? "default";
669
840
  this.#configs.set(key, config);
670
841
  this.#engine.dispatchEvent(exports.EventType.configAdded, { data: { name: key, config } });
671
842
  }
672
843
  addEasing(name, easing) {
844
+ if (this.#initialized) {
845
+ return;
846
+ }
673
847
  if (this.easingFunctions.get(name)) {
674
848
  return;
675
849
  }
676
850
  this.easingFunctions.set(name, easing);
677
851
  }
678
852
  addEffect(effect, drawer) {
853
+ if (this.#initialized) {
854
+ return;
855
+ }
679
856
  this.initializers.effects.set(effect, drawer);
680
857
  }
681
858
  addPalette(name, palette) {
859
+ if (this.#initialized) {
860
+ return;
861
+ }
682
862
  this.palettes.set(name, palette);
683
863
  }
684
864
  addParticleUpdater(name, updaterInitializer) {
865
+ if (this.#initialized) {
866
+ return;
867
+ }
685
868
  this.initializers.updaters.set(name, updaterInitializer);
686
869
  }
687
870
  addPlugin(plugin) {
871
+ if (this.#initialized) {
872
+ return;
873
+ }
688
874
  if (this.getPlugin(plugin.id)) {
689
875
  return;
690
876
  }
691
877
  this.plugins.push(plugin);
692
878
  }
693
879
  addPreset(preset, options, override = false) {
880
+ if (this.#initialized) {
881
+ return;
882
+ }
694
883
  if (!(override || !this.getPreset(preset))) {
695
884
  return;
696
885
  }
697
886
  this.presets.set(preset, options);
698
887
  }
699
888
  addShape(shapes, drawer) {
889
+ if (this.#initialized) {
890
+ return;
891
+ }
700
892
  for (const shape of shapes) {
701
893
  this.initializers.shapes.set(shape, drawer);
702
894
  }
703
895
  }
704
- clearPlugins(container) {
705
- this.effectDrawers.delete(container);
706
- this.shapeDrawers.delete(container);
707
- this.updaters.delete(container);
708
- }
709
896
  getEasing(name) {
710
897
  return this.easingFunctions.get(name) ?? ((value) => value);
711
898
  }
712
- getEffectDrawers(container, force = false) {
713
- return getItemMapFromInitializer(container, this.effectDrawers, this.initializers.effects, force);
714
- }
715
899
  getPalette(name) {
716
900
  return this.palettes.get(name);
717
901
  }
@@ -721,12 +905,6 @@
721
905
  getPreset(preset) {
722
906
  return this.presets.get(preset);
723
907
  }
724
- async getShapeDrawers(container, force = false) {
725
- return getItemMapFromInitializer(container, this.shapeDrawers, this.initializers.shapes, force);
726
- }
727
- async getUpdaters(container, force = false) {
728
- return getItemsFromInitializer(container, this.updaters, this.initializers.updaters, force);
729
- }
730
908
  async init() {
731
909
  if (this.#initialized || this.#isRunningLoaders) {
732
910
  return;
@@ -745,16 +923,9 @@
745
923
  this.#initialized = true;
746
924
  }
747
925
  }
748
- loadParticlesOptions(container, options, ...sourceOptions) {
749
- const updaters = this.updaters.get(container);
750
- if (!updaters) {
751
- return;
752
- }
753
- updaters.forEach(updater => updater.loadOptions?.(options, ...sourceOptions));
754
- }
755
926
  async register(...loaders) {
756
927
  if (this.#initialized) {
757
- throw new Error("Register plugins can only be done before calling tsParticles.load()");
928
+ throw new Error(getErrorMessage(ErrorCodes$2.pluginRegisterAfterLoad));
758
929
  }
759
930
  for (const loader of loaders) {
760
931
  if (this.#isRunningLoaders) {
@@ -766,111 +937,15 @@
766
937
  }
767
938
  }
768
939
  async #runLoader(loader, executed, allLoaders) {
769
- if (executed.has(loader))
940
+ if (executed.has(loader)) {
770
941
  return;
942
+ }
771
943
  executed.add(loader);
772
944
  allLoaders.add(loader);
773
945
  await loader(this.#engine);
774
946
  }
775
947
  }
776
948
 
777
- const errorPrefix = "tsParticles - Error";
778
- const wrap = (fn) => (...args) => {
779
- fn(...args);
780
- }, _logger = {
781
- debug: wrap(console.debug),
782
- error: (message, ...optionalParams) => {
783
- console.error(`${errorPrefix} - ${message}`, ...optionalParams);
784
- },
785
- info: wrap(console.info),
786
- log: wrap(console.log),
787
- trace: wrap(console.trace),
788
- verbose: wrap(console.log),
789
- warning: wrap(console.warn),
790
- };
791
- function setLogger(logger) {
792
- if (logger.debug) {
793
- _logger.debug = wrap(logger.debug);
794
- }
795
- if (logger.error) {
796
- _logger.error = wrap(logger.error);
797
- }
798
- if (logger.info) {
799
- _logger.info = wrap(logger.info);
800
- }
801
- if (logger.log) {
802
- _logger.log = wrap(logger.log);
803
- }
804
- if (logger.trace) {
805
- _logger.trace = wrap(logger.trace);
806
- }
807
- if (logger.verbose) {
808
- _logger.verbose = wrap(logger.verbose);
809
- }
810
- if (logger.warning) {
811
- _logger.warning = wrap(logger.warning);
812
- }
813
- }
814
- function getLogger() {
815
- return _logger;
816
- }
817
-
818
- const fullPercent = "100%";
819
- async function getDataFromUrl(data) {
820
- const url = itemFromSingleOrMultiple(data.url, data.index);
821
- if (!url) {
822
- return data.fallback;
823
- }
824
- const response = await fetch(url);
825
- if (response.ok) {
826
- return (await response.json());
827
- }
828
- getLogger().error(`${response.status.toString()} while retrieving config file`);
829
- return data.fallback;
830
- }
831
- const getCanvasFromContainer = (domContainer) => {
832
- const documentSafe = safeDocument();
833
- let canvasEl;
834
- const isCanvas = domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag;
835
- if (isCanvas) {
836
- canvasEl = domContainer;
837
- canvasEl.dataset[generatedAttribute] ??= generatedFalse;
838
- if (canvasEl.dataset[generatedAttribute] === generatedTrue) {
839
- canvasEl.style.width ||= fullPercent;
840
- canvasEl.style.height ||= fullPercent;
841
- canvasEl.style.pointerEvents = "none";
842
- canvasEl.style.setProperty("pointer-events", "none");
843
- }
844
- }
845
- else {
846
- const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
847
- if (foundCanvas) {
848
- canvasEl = foundCanvas;
849
- canvasEl.dataset[generatedAttribute] = generatedFalse;
850
- }
851
- else {
852
- canvasEl = documentSafe.createElement(canvasTag);
853
- canvasEl.dataset[generatedAttribute] = generatedTrue;
854
- domContainer.appendChild(canvasEl);
855
- }
856
- canvasEl.style.width ||= fullPercent;
857
- canvasEl.style.height ||= fullPercent;
858
- canvasEl.style.pointerEvents = "none";
859
- canvasEl.style.setProperty("pointer-events", "none");
860
- }
861
- return canvasEl;
862
- }, getDomContainer = (id, source) => {
863
- const documentSafe = safeDocument();
864
- let domContainer = source ?? documentSafe.getElementById(id);
865
- if (domContainer) {
866
- return domContainer;
867
- }
868
- domContainer = documentSafe.createElement("canvas");
869
- domContainer.id = id;
870
- domContainer.dataset[generatedAttribute] = generatedTrue;
871
- documentSafe.body.append(domContainer);
872
- return domContainer;
873
- };
874
949
  class Engine {
875
950
  pluginManager = new PluginManager(this);
876
951
  #domArray = [];
@@ -880,7 +955,7 @@
880
955
  return this.#domArray;
881
956
  }
882
957
  get version() {
883
- return "4.4.0";
958
+ return "4.5.0";
884
959
  }
885
960
  addEventListener(type, listener) {
886
961
  this.#eventDispatcher.addEventListener(type, listener);
@@ -889,7 +964,7 @@
889
964
  if (this.version === pluginVersion) {
890
965
  return;
891
966
  }
892
- throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${this.version}. Plugin version: ${pluginVersion}`);
967
+ throw new Error(getErrorMessage(ErrorCodes$2.engineVersionMismatch, this.version, pluginVersion));
893
968
  }
894
969
  dispatchEvent(type, args) {
895
970
  this.#eventDispatcher.dispatchEvent(type, args);
@@ -1138,20 +1213,6 @@
1138
1213
  DrawLayer[DrawLayer["Foreground"] = 7] = "Foreground";
1139
1214
  })(exports.DrawLayer || (exports.DrawLayer = {}));
1140
1215
 
1141
- class OptionLoader {
1142
- load(data) {
1143
- if (isNull(data)) {
1144
- return;
1145
- }
1146
- this.doLoad(data);
1147
- }
1148
- }
1149
- function loadOptions(options, ...sourceOptionsArr) {
1150
- for (const sourceOptions of sourceOptionsArr) {
1151
- options.load(sourceOptions);
1152
- }
1153
- }
1154
-
1155
1216
  function loadProperty(obj, key, value) {
1156
1217
  if (value !== undefined) {
1157
1218
  obj[key] = value;
@@ -1180,7 +1241,7 @@
1180
1241
  if (keyStr === "__proto__" || keyStr === "constructor" || keyStr === "prototype") {
1181
1242
  return;
1182
1243
  }
1183
- const objRecord = obj, currentValue = Object.prototype.hasOwnProperty.call(objRecord, keyStr) ? objRecord[keyStr] : {};
1244
+ const objRecord = obj, currentValue = Object.hasOwn(objRecord, keyStr) ? objRecord[keyStr] : {};
1184
1245
  objRecord[keyStr] = deepExtend(currentValue, value);
1185
1246
  }
1186
1247
  }
@@ -1193,6 +1254,20 @@
1193
1254
  }
1194
1255
  }
1195
1256
 
1257
+ class OptionLoader {
1258
+ load(data) {
1259
+ if (isNull(data)) {
1260
+ return;
1261
+ }
1262
+ this.doLoad(data);
1263
+ }
1264
+ }
1265
+ function loadOptions(options, ...sourceOptionsArr) {
1266
+ for (const sourceOptions of sourceOptionsArr) {
1267
+ options.load(sourceOptions);
1268
+ }
1269
+ }
1270
+
1196
1271
  class AnimationOptions extends OptionLoader {
1197
1272
  count = 0;
1198
1273
  decay = 0;
@@ -1343,15 +1418,14 @@
1343
1418
  peakNits = defaultPeakNits;
1344
1419
  doLoad(data) {
1345
1420
  if (data.enable !== undefined && !isBoolean(data.enable)) {
1346
- throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1421
+ throw new Error(getErrorMessage(ErrorCodes$2.hdrEnableInvalid, String(data.enable)));
1347
1422
  }
1348
- if (data.mode !== undefined &&
1349
- (typeof data.mode !== "string" || !Object.values(exports.HdrMode).includes(data.mode))) {
1350
- throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(exports.HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1423
+ if (data.mode !== undefined && !isEnumValue(exports.HdrMode, data.mode)) {
1424
+ throw new Error(getErrorMessage(ErrorCodes$2.hdrModeInvalid, Object.values(exports.HdrMode).join(", "), toStringValue(data.mode)));
1351
1425
  }
1352
1426
  if (data.peakNits !== undefined &&
1353
1427
  (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1354
- throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1428
+ throw new Error(getErrorMessage(ErrorCodes$2.hdrPeakNitsInvalid, String(data.peakNits)));
1355
1429
  }
1356
1430
  loadProperty(this, "enable", data.enable);
1357
1431
  loadProperty(this, "mode", data.mode);
@@ -1729,12 +1803,10 @@
1729
1803
  plugin.loadParticlesOptions(this.#container, this, data);
1730
1804
  }
1731
1805
  }
1732
- const updaters = this.#pluginManager.updaters.get(this.#container);
1733
- if (updaters) {
1734
- for (const updater of updaters) {
1735
- if (updater.loadOptions) {
1736
- updater.loadOptions(this, data);
1737
- }
1806
+ const updaters = this.#container.particleUpdaters;
1807
+ for (const updater of updaters) {
1808
+ if (updater.loadOptions) {
1809
+ updater.loadOptions(this, data);
1738
1810
  }
1739
1811
  }
1740
1812
  }
@@ -2076,9 +2148,9 @@
2076
2148
  const grayscaleValue = Math.round(lNormalized * rgbMax);
2077
2149
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
2078
2150
  }
2079
- const temp1 = lNormalized < half
2151
+ const temp2 = lNormalized < half
2080
2152
  ? lNormalized * (sNormalizedOffset + sNormalized)
2081
- : 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));
2153
+ : lNormalized + sNormalized - lNormalized * sNormalized, temp1 = double * lNormalized - temp2, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * hslChannel(temp1, temp2, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * hslChannel(temp1, temp2, hNormalized)), blue = Math.min(rgbMax, rgbMax * hslChannel(temp1, temp2, hNormalized - phaseThird));
2082
2154
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
2083
2155
  }
2084
2156
  function hslToRgbFloat(hsl) {
@@ -2087,9 +2159,9 @@
2087
2159
  const grayscaleValue = lNormalized * rgbMax;
2088
2160
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
2089
2161
  }
2090
- const temp1 = lNormalized < half
2162
+ const temp2 = lNormalized < half
2091
2163
  ? lNormalized * (sNormalizedOffset + sNormalized)
2092
- : 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));
2164
+ : lNormalized + sNormalized - lNormalized * sNormalized, temp1 = double * lNormalized - temp2, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * hslChannel(temp1, temp2, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * hslChannel(temp1, temp2, hNormalized)), blue = Math.min(rgbMax, rgbMax * hslChannel(temp1, temp2, hNormalized - phaseThird));
2093
2165
  return { r: red, g: green, b: blue };
2094
2166
  }
2095
2167
  function hslaToRgba(hsla) {
@@ -2676,7 +2748,7 @@
2676
2748
  }
2677
2749
 
2678
2750
  async function loadBlendPlugin(engine) {
2679
- engine.checkVersion("4.4.0");
2751
+ engine.checkVersion("4.5.0");
2680
2752
  await engine.pluginManager.register(e => {
2681
2753
  e.pluginManager.addPlugin(new BlendPlugin());
2682
2754
  });
@@ -2713,7 +2785,7 @@
2713
2785
  }
2714
2786
 
2715
2787
  async function loadCircleShape(engine) {
2716
- engine.checkVersion("4.4.0");
2788
+ engine.checkVersion("4.5.0");
2717
2789
  await engine.pluginManager.register(e => {
2718
2790
  e.pluginManager.addShape(["circle"], () => {
2719
2791
  return Promise.resolve(new CircleDrawer());
@@ -2728,7 +2800,7 @@
2728
2800
  RgbIndexes[RgbIndexes["b"] = 3] = "b";
2729
2801
  RgbIndexes[RgbIndexes["a"] = 4] = "a";
2730
2802
  })(RgbIndexes$1 || (RgbIndexes$1 = {}));
2731
- const shorthandHexRegex = /^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i, hexRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i, hexRadix = 16, defaultAlpha = 1, alphaFactor = 0xff;
2803
+ const shorthandHexRegex = /^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i, hexRegex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i, hexRadix = 16, alphaFactor = 0xff;
2732
2804
  class HexColorManager {
2733
2805
  accepts(input) {
2734
2806
  return input.startsWith("#");
@@ -2761,7 +2833,7 @@
2761
2833
  }
2762
2834
 
2763
2835
  async function loadHexColorPlugin(engine) {
2764
- engine.checkVersion("4.4.0");
2836
+ engine.checkVersion("4.5.0");
2765
2837
  await engine.pluginManager.register(e => {
2766
2838
  e.pluginManager.addColorManager("hex", new HexColorManager());
2767
2839
  });
@@ -2801,7 +2873,7 @@
2801
2873
  if (!this.accepts(input)) {
2802
2874
  return;
2803
2875
  }
2804
- const result = hslRegex.exec(input), minLength = 4, defaultAlpha = 1, radix = 10;
2876
+ const result = hslRegex.exec(input), minLength = 4, radix = 10;
2805
2877
  return result
2806
2878
  ? hslaToRgba({
2807
2879
  a: result.length > minLength ? parseAlpha(result[HslIndexes.a]) : defaultAlpha,
@@ -2814,12 +2886,20 @@
2814
2886
  }
2815
2887
 
2816
2888
  async function loadHslColorPlugin(engine) {
2817
- engine.checkVersion("4.4.0");
2889
+ engine.checkVersion("4.5.0");
2818
2890
  await engine.pluginManager.register(e => {
2819
2891
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2820
2892
  });
2821
2893
  }
2822
2894
 
2895
+ const ErrorCodes$1 = {
2896
+ baseMoverNotLoaded: "TSP-3203",
2897
+ };
2898
+
2899
+ const ErrorMessages$1 = {
2900
+ [ErrorCodes$1.baseMoverNotLoaded]: "tsParticles Base Mover is not loaded",
2901
+ };
2902
+
2823
2903
  class MovePlugin {
2824
2904
  id = "move";
2825
2905
  #pluginManager;
@@ -2838,20 +2918,20 @@
2838
2918
  }
2839
2919
 
2840
2920
  async function loadMovePlugin(engine) {
2841
- engine.checkVersion("4.4.0");
2921
+ engine.checkVersion("4.5.0");
2922
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
2923
+ addErrorMessages(ErrorMessages$1);
2924
+ }
2842
2925
  await engine.pluginManager.register(e => {
2843
2926
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2844
2927
  movePluginManager.initializers.pathGenerators ??= new Map();
2845
- movePluginManager.pathGenerators ??= new Map();
2846
2928
  movePluginManager.addPathGenerator = (name, generator) => {
2929
+ if (movePluginManager.initialized) {
2930
+ return;
2931
+ }
2847
2932
  movePluginManager.initializers.pathGenerators ??= new Map();
2848
2933
  movePluginManager.initializers.pathGenerators.set(name, generator);
2849
2934
  };
2850
- movePluginManager.getPathGenerators = async (container, force = false) => {
2851
- movePluginManager.initializers.pathGenerators ??= new Map();
2852
- movePluginManager.pathGenerators ??= new Map();
2853
- return getItemMapFromInitializer(container, movePluginManager.pathGenerators, movePluginManager.initializers.pathGenerators, force);
2854
- };
2855
2935
  e.pluginManager.addPlugin(new MovePlugin(e.pluginManager));
2856
2936
  });
2857
2937
  }
@@ -3054,7 +3134,7 @@
3054
3134
  }
3055
3135
 
3056
3136
  async function loadOpacityUpdater(engine) {
3057
- engine.checkVersion("4.4.0");
3137
+ engine.checkVersion("4.5.0");
3058
3138
  await engine.pluginManager.register(e => {
3059
3139
  e.pluginManager.addParticleUpdater("opacity", container => {
3060
3140
  return Promise.resolve(new OpacityUpdater(container));
@@ -3063,70 +3143,60 @@
3063
3143
  }
3064
3144
 
3065
3145
  const boundsMin = 0;
3066
- function bounceHorizontal(data) {
3067
- if ((data.outMode !== exports.OutMode.bounce && data.outMode !== exports.OutMode.split) ||
3068
- (data.direction !== exports.OutModeDirection.left && data.direction !== exports.OutModeDirection.right)) {
3069
- return;
3070
- }
3071
- if (data.bounds.right < boundsMin && data.direction === exports.OutModeDirection.left) {
3072
- data.particle.position.x = data.size + data.offset.x;
3073
- }
3074
- else if (data.bounds.left > data.canvasSize.width && data.direction === exports.OutModeDirection.right) {
3075
- data.particle.position.x = data.canvasSize.width - data.size - data.offset.x;
3076
- }
3077
- const velocity = data.particle.velocity.x;
3078
- let bounced = false;
3079
- if (data.outOfCanvas &&
3080
- ((data.direction === exports.OutModeDirection.right && velocity > minVelocity) ||
3081
- (data.direction === exports.OutModeDirection.left && velocity < minVelocity))) {
3082
- const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
3083
- data.particle.velocity.x *= -newVelocity;
3084
- bounced = true;
3085
- }
3086
- if (!bounced) {
3087
- return;
3088
- }
3089
- const minPos = data.offset.x + data.size;
3090
- if (data.outOfCanvas && data.direction === exports.OutModeDirection.right) {
3091
- data.particle.position.x = data.canvasSize.width - minPos;
3092
- }
3093
- else if (data.outOfCanvas && data.direction === exports.OutModeDirection.left) {
3094
- data.particle.position.x = minPos;
3095
- }
3096
- if (data.outMode === exports.OutMode.split) {
3097
- data.particle.destroy();
3098
- }
3099
- }
3100
- function bounceVertical(data) {
3101
- if ((data.outMode !== exports.OutMode.bounce && data.outMode !== exports.OutMode.split) ||
3102
- (data.direction !== exports.OutModeDirection.bottom && data.direction !== exports.OutModeDirection.top)) {
3146
+ const bounceAxisConfigs = {
3147
+ [exports.OutModeDirection.left]: {
3148
+ axis: "x",
3149
+ canvas: "width",
3150
+ bounce: "horizontal",
3151
+ negativeEdge: "right",
3152
+ positiveEdge: "left",
3153
+ negative: true,
3154
+ },
3155
+ [exports.OutModeDirection.right]: {
3156
+ axis: "x",
3157
+ canvas: "width",
3158
+ bounce: "horizontal",
3159
+ negativeEdge: "right",
3160
+ positiveEdge: "left",
3161
+ negative: false,
3162
+ },
3163
+ [exports.OutModeDirection.top]: {
3164
+ axis: "y",
3165
+ canvas: "height",
3166
+ bounce: "vertical",
3167
+ negativeEdge: "bottom",
3168
+ positiveEdge: "top",
3169
+ negative: true,
3170
+ },
3171
+ [exports.OutModeDirection.bottom]: {
3172
+ axis: "y",
3173
+ canvas: "height",
3174
+ bounce: "vertical",
3175
+ negativeEdge: "bottom",
3176
+ positiveEdge: "top",
3177
+ negative: false,
3178
+ },
3179
+ };
3180
+ function bounce(data) {
3181
+ if ((data.outMode !== exports.OutMode.bounce && data.outMode !== exports.OutMode.split) || !(data.direction in bounceAxisConfigs)) {
3103
3182
  return;
3104
3183
  }
3105
- if (data.bounds.bottom < boundsMin && data.direction === exports.OutModeDirection.top) {
3106
- data.particle.position.y = data.size + data.offset.y;
3184
+ const config = bounceAxisConfigs[data.direction], bounds = data.bounds, canvasDim = data.canvasSize[config.canvas], position = data.particle.position, velocity = data.particle.velocity[config.axis];
3185
+ if (config.negative && bounds[config.negativeEdge] < boundsMin) {
3186
+ position[config.axis] = data.size + data.offset[config.axis];
3107
3187
  }
3108
- else if (data.bounds.top > data.canvasSize.height && data.direction === exports.OutModeDirection.bottom) {
3109
- data.particle.position.y = data.canvasSize.height - data.size - data.offset.y;
3188
+ else if (!config.negative && bounds[config.positiveEdge] > canvasDim) {
3189
+ position[config.axis] = canvasDim - data.size - data.offset[config.axis];
3110
3190
  }
3111
- const velocity = data.particle.velocity.y;
3112
- let bounced = false;
3113
3191
  if (data.outOfCanvas &&
3114
- ((data.direction === exports.OutModeDirection.bottom && velocity > minVelocity) ||
3115
- (data.direction === exports.OutModeDirection.top && velocity < minVelocity))) {
3116
- const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
3117
- data.particle.velocity.y *= -newVelocity;
3118
- bounced = true;
3192
+ ((config.negative && velocity < minVelocity) || (!config.negative && velocity > minVelocity))) {
3193
+ data.particle.velocity[config.axis] *= -getRangeValue(data.particle.options.bounce[config.bounce].value);
3119
3194
  }
3120
- if (!bounced) {
3195
+ else {
3121
3196
  return;
3122
3197
  }
3123
- const minPos = data.offset.y + data.size;
3124
- if (data.outOfCanvas && data.direction === exports.OutModeDirection.bottom) {
3125
- data.particle.position.y = data.canvasSize.height - minPos;
3126
- }
3127
- else if (data.outOfCanvas && data.direction === exports.OutModeDirection.top) {
3128
- data.particle.position.y = minPos;
3129
- }
3198
+ const minPos = data.offset[config.axis] + data.size;
3199
+ position[config.axis] = config.negative ? minPos : canvasDim - minPos;
3130
3200
  if (data.outMode === exports.OutMode.split) {
3131
3201
  data.particle.destroy();
3132
3202
  }
@@ -3142,26 +3212,19 @@
3142
3212
  exports.OutMode.bounce,
3143
3213
  exports.OutMode.split,
3144
3214
  ];
3145
- this.#particleBouncePlugins = container.plugins.filter(p => p.particleBounce !== undefined);
3215
+ this.#particleBouncePlugins = container.plugins.filter(p => !!p.particleBounce);
3146
3216
  }
3147
3217
  update(particle, direction, delta, outMode) {
3148
3218
  if (!this.modes.includes(outMode)) {
3149
3219
  return;
3150
3220
  }
3151
- const container = this.#container;
3152
- let handled = false;
3153
3221
  for (const plugin of this.#particleBouncePlugins) {
3154
- handled = plugin.particleBounce?.(particle, delta, direction) ?? false;
3155
- if (handled) {
3156
- break;
3222
+ if (plugin.particleBounce?.(particle, delta, direction)) {
3223
+ return;
3157
3224
  }
3158
3225
  }
3159
- if (handled) {
3160
- return;
3161
- }
3162
- const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = container.canvas.size, outOfCanvas = !particle.isInsideCanvasForOutMode(outMode, direction);
3163
- bounceHorizontal({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
3164
- bounceVertical({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
3226
+ const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = this.#container.canvas.size, outOfCanvas = !particle.isInsideCanvasForOutMode(outMode, direction);
3227
+ bounce({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
3165
3228
  }
3166
3229
  }
3167
3230
 
@@ -3250,107 +3313,108 @@
3250
3313
  return;
3251
3314
  }
3252
3315
  const container = this.#container;
3253
- switch (particle.outType) {
3254
- case exports.ParticleOutType.inside: {
3255
- const { x: vx, y: vy } = particle.velocity;
3256
- updateVector.setTo(originPoint);
3257
- updateVector.length = particle.moveCenter.radius;
3258
- updateVector.angle = particle.velocity.angle + Math.PI;
3259
- updateVector.addTo(particle.moveCenter);
3260
- const { dx, dy } = getDistances(particle.position, updateVector);
3261
- if ((vx <= minVelocity && dx >= minDistance) ||
3262
- (vy <= minVelocity && dy >= minDistance) ||
3263
- (vx >= minVelocity && dx <= minDistance) ||
3264
- (vy >= minVelocity && dy <= minDistance)) {
3265
- return;
3266
- }
3267
- particle.position.x = Math.floor(randomInRangeValue({
3268
- min: 0,
3269
- max: container.canvas.size.width,
3270
- }));
3271
- particle.position.y = Math.floor(randomInRangeValue({
3272
- min: 0,
3273
- max: container.canvas.size.height,
3274
- }));
3275
- const { dx: newDx, dy: newDy } = getDistances(particle.position, particle.moveCenter);
3276
- particle.direction = Math.atan2(-newDy, -newDx);
3277
- particle.velocity.angle = particle.direction;
3278
- particle.justWarped = true;
3279
- break;
3316
+ if (particle.outType === exports.ParticleOutType.inside) {
3317
+ this.#applyOutModeInside(particle, container);
3318
+ }
3319
+ else {
3320
+ if (particle.isInsideCanvasForOutMode(outMode, direction)) {
3321
+ return;
3280
3322
  }
3281
- default: {
3282
- if (particle.isInsideCanvasForOutMode(outMode, direction)) {
3283
- return;
3284
- }
3285
- switch (particle.outType) {
3286
- case exports.ParticleOutType.outside: {
3287
- particle.position.x =
3288
- Math.floor(randomInRangeValue({
3289
- min: -particle.moveCenter.radius,
3290
- max: particle.moveCenter.radius,
3291
- })) + particle.moveCenter.x;
3292
- particle.position.y =
3293
- Math.floor(randomInRangeValue({
3294
- min: -particle.moveCenter.radius,
3295
- max: particle.moveCenter.radius,
3296
- })) + particle.moveCenter.y;
3297
- const { dx, dy } = getDistances(particle.position, particle.moveCenter);
3298
- if (particle.moveCenter.radius) {
3299
- particle.direction = Math.atan2(dy, dx);
3300
- particle.velocity.angle = particle.direction;
3301
- }
3302
- particle.justWarped = true;
3303
- break;
3304
- }
3305
- case exports.ParticleOutType.normal: {
3306
- const warp = particle.options.move.warp, canvasSize = container.canvas.size, newPos = {
3307
- bottom: canvasSize.height + particle.getRadius() + particle.offset.y,
3308
- left: -particle.getRadius() - particle.offset.x,
3309
- right: canvasSize.width + particle.getRadius() + particle.offset.x,
3310
- top: -particle.getRadius() - particle.offset.y,
3311
- }, sizeValue = particle.getRadius(), nextBounds = calculateBounds(particle.position, sizeValue);
3312
- if (direction === exports.OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) {
3313
- particle.position.x = newPos.left;
3314
- particle.initialPosition.x = particle.position.x;
3315
- if (!warp) {
3316
- particle.position.y = getRandom() * canvasSize.height;
3317
- particle.initialPosition.y = particle.position.y;
3318
- }
3319
- particle.justWarped = true;
3320
- }
3321
- else if (direction === exports.OutModeDirection.left && nextBounds.right < -particle.offset.x) {
3322
- particle.position.x = newPos.right;
3323
- particle.initialPosition.x = particle.position.x;
3324
- if (!warp) {
3325
- particle.position.y = getRandom() * canvasSize.height;
3326
- particle.initialPosition.y = particle.position.y;
3327
- }
3328
- particle.justWarped = true;
3329
- }
3330
- if (direction === exports.OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) {
3331
- if (!warp) {
3332
- particle.position.x = getRandom() * canvasSize.width;
3333
- particle.initialPosition.x = particle.position.x;
3334
- }
3335
- particle.position.y = newPos.top;
3336
- particle.initialPosition.y = particle.position.y;
3337
- particle.justWarped = true;
3338
- }
3339
- else if (direction === exports.OutModeDirection.top && nextBounds.bottom < -particle.offset.y) {
3340
- if (!warp) {
3341
- particle.position.x = getRandom() * canvasSize.width;
3342
- particle.initialPosition.x = particle.position.x;
3343
- }
3344
- particle.position.y = newPos.bottom;
3345
- particle.initialPosition.y = particle.position.y;
3346
- particle.justWarped = true;
3347
- }
3348
- break;
3349
- }
3350
- }
3351
- break;
3323
+ if (particle.outType === exports.ParticleOutType.outside) {
3324
+ this.#applyParticleModeOutside(particle);
3352
3325
  }
3326
+ else {
3327
+ this.#applyOutModeNormal(particle, container, direction);
3328
+ }
3329
+ }
3330
+ }
3331
+ #applyOutModeInside(particle, container) {
3332
+ const { x: vx, y: vy } = particle.velocity;
3333
+ updateVector.setTo(originPoint);
3334
+ updateVector.length = particle.moveCenter.radius;
3335
+ updateVector.angle = particle.velocity.angle + Math.PI;
3336
+ updateVector.addTo(particle.moveCenter);
3337
+ const { dx, dy } = getDistances(particle.position, updateVector);
3338
+ if ((vx <= minVelocity && dx >= minDistance) ||
3339
+ (vy <= minVelocity && dy >= minDistance) ||
3340
+ (vx >= minVelocity && dx <= minDistance) ||
3341
+ (vy >= minVelocity && dy <= minDistance)) {
3342
+ return;
3353
3343
  }
3344
+ particle.position.x = Math.floor(randomInRangeValue({
3345
+ min: 0,
3346
+ max: container.canvas.size.width,
3347
+ }));
3348
+ particle.position.y = Math.floor(randomInRangeValue({
3349
+ min: 0,
3350
+ max: container.canvas.size.height,
3351
+ }));
3352
+ const { dx: newDx, dy: newDy } = getDistances(particle.position, particle.moveCenter);
3353
+ particle.direction = Math.atan2(-newDy, -newDx);
3354
+ particle.velocity.angle = particle.direction;
3355
+ particle.justWarped = true;
3356
+ }
3357
+ #applyOutModeNormal(particle, container, direction) {
3358
+ const warp = particle.options.move.warp, canvasSize = container.canvas.size, sizeValue = particle.getRadius(), newPos = {
3359
+ bottom: canvasSize.height + sizeValue + particle.offset.y,
3360
+ left: -sizeValue - particle.offset.x,
3361
+ right: canvasSize.width + sizeValue + particle.offset.x,
3362
+ top: -sizeValue - particle.offset.y,
3363
+ }, nextBounds = calculateBounds(particle.position, sizeValue);
3364
+ if (direction === exports.OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) {
3365
+ particle.position.x = newPos.left;
3366
+ particle.initialPosition.x = particle.position.x;
3367
+ if (!warp) {
3368
+ particle.position.y = getRandom() * canvasSize.height;
3369
+ particle.initialPosition.y = particle.position.y;
3370
+ }
3371
+ particle.justWarped = true;
3372
+ }
3373
+ else if (direction === exports.OutModeDirection.left && nextBounds.right < -particle.offset.x) {
3374
+ particle.position.x = newPos.right;
3375
+ particle.initialPosition.x = particle.position.x;
3376
+ if (!warp) {
3377
+ particle.position.y = getRandom() * canvasSize.height;
3378
+ particle.initialPosition.y = particle.position.y;
3379
+ }
3380
+ particle.justWarped = true;
3381
+ }
3382
+ if (direction === exports.OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) {
3383
+ if (!warp) {
3384
+ particle.position.x = getRandom() * canvasSize.width;
3385
+ particle.initialPosition.x = particle.position.x;
3386
+ }
3387
+ particle.position.y = newPos.top;
3388
+ particle.initialPosition.y = particle.position.y;
3389
+ particle.justWarped = true;
3390
+ }
3391
+ else if (direction === exports.OutModeDirection.top && nextBounds.bottom < -particle.offset.y) {
3392
+ if (!warp) {
3393
+ particle.position.x = getRandom() * canvasSize.width;
3394
+ particle.initialPosition.x = particle.position.x;
3395
+ }
3396
+ particle.position.y = newPos.bottom;
3397
+ particle.initialPosition.y = particle.position.y;
3398
+ particle.justWarped = true;
3399
+ }
3400
+ }
3401
+ #applyParticleModeOutside(particle) {
3402
+ particle.position.x =
3403
+ Math.floor(randomInRangeValue({
3404
+ min: -particle.moveCenter.radius,
3405
+ max: particle.moveCenter.radius,
3406
+ })) + particle.moveCenter.x;
3407
+ particle.position.y =
3408
+ Math.floor(randomInRangeValue({
3409
+ min: -particle.moveCenter.radius,
3410
+ max: particle.moveCenter.radius,
3411
+ })) + particle.moveCenter.y;
3412
+ const { dx, dy } = getDistances(particle.position, particle.moveCenter);
3413
+ if (particle.moveCenter.radius) {
3414
+ particle.direction = Math.atan2(dy, dx);
3415
+ particle.velocity.angle = particle.direction;
3416
+ }
3417
+ particle.justWarped = true;
3354
3418
  }
3355
3419
  }
3356
3420
 
@@ -3399,7 +3463,7 @@
3399
3463
  }
3400
3464
 
3401
3465
  async function loadOutModesUpdater(engine) {
3402
- engine.checkVersion("4.4.0");
3466
+ engine.checkVersion("4.5.0");
3403
3467
  await engine.pluginManager.register(e => {
3404
3468
  e.pluginManager.addParticleUpdater("outModes", container => {
3405
3469
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3416,39 +3480,9 @@
3416
3480
  this.#pluginManager = pluginManager;
3417
3481
  }
3418
3482
  init(particle) {
3419
- const container = this.#container, options = particle.options, paint = itemFromSingleOrMultiple(options.paint, particle.id, options.reduceDuplicates), color = paint?.color, paintColor = color ?? undefined, fill = paint?.fill, stroke = paint?.stroke;
3420
- if (fill) {
3421
- const fillColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), fill.color);
3422
- particle.fillEnabled = fill.enable;
3423
- particle.fillOpacity = getRangeValue(fill.opacity);
3424
- particle.fillAnimation = fillColor.animation;
3425
- const fillHslColor = rangeColorToHsl(this.#pluginManager, fillColor);
3426
- if (fillHslColor) {
3427
- particle.fillColor = getHslAnimationFromHsl(fillHslColor, particle.fillAnimation, container.retina.reduceFactor);
3428
- }
3429
- }
3430
- else {
3431
- particle.fillEnabled = false;
3432
- particle.fillAnimation = undefined;
3433
- particle.fillColor = undefined;
3434
- particle.fillOpacity = defaultOpacity;
3435
- }
3436
- if (stroke) {
3437
- const strokeColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), stroke.color);
3438
- particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
3439
- particle.strokeOpacity = getRangeValue(stroke.opacity ?? defaultOpacity);
3440
- particle.strokeAnimation = strokeColor.animation;
3441
- const strokeHslColor = rangeColorToHsl(this.#pluginManager, strokeColor) ?? particle.getFillColor();
3442
- if (strokeHslColor) {
3443
- particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, particle.strokeAnimation, container.retina.reduceFactor);
3444
- }
3445
- }
3446
- else {
3447
- particle.strokeAnimation = undefined;
3448
- particle.strokeColor = undefined;
3449
- particle.strokeOpacity = defaultOpacity;
3450
- particle.strokeWidth = 0;
3451
- }
3483
+ const container = this.#container, options = particle.options, paint = itemFromSingleOrMultiple(options.paint, particle.id, options.reduceDuplicates);
3484
+ this.#initFill(paint, particle, container);
3485
+ this.#initStroke(paint, particle, container);
3452
3486
  }
3453
3487
  isEnabled(particle) {
3454
3488
  const { fillAnimation, fillColor, strokeAnimation, strokeColor } = particle, fillEnabled = !!fillAnimation &&
@@ -3467,10 +3501,48 @@
3467
3501
  updateColor(particle.fillColor, delta, this.#container.hdr);
3468
3502
  updateColor(particle.strokeColor, delta, this.#container.hdr);
3469
3503
  }
3504
+ #initFill(paint, particle, container) {
3505
+ const fill = paint?.fill, color = paint?.color, paintColor = color ?? undefined;
3506
+ if (!fill) {
3507
+ particle.fillEnabled = false;
3508
+ particle.fillAnimation = undefined;
3509
+ particle.fillColor = undefined;
3510
+ particle.fillOpacity = defaultOpacity;
3511
+ return;
3512
+ }
3513
+ const fillColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), fill.color);
3514
+ particle.fillEnabled = fill.enable;
3515
+ particle.fillOpacity = getRangeValue(fill.opacity);
3516
+ particle.fillAnimation = fillColor.animation;
3517
+ const fillHslColor = rangeColorToHsl(this.#pluginManager, fillColor);
3518
+ if (!fillHslColor) {
3519
+ return;
3520
+ }
3521
+ particle.fillColor = getHslAnimationFromHsl(fillHslColor, particle.fillAnimation, container.retina.reduceFactor);
3522
+ }
3523
+ #initStroke(paint, particle, container) {
3524
+ const stroke = paint?.stroke, color = paint?.color, paintColor = color ?? undefined;
3525
+ if (!stroke) {
3526
+ particle.strokeAnimation = undefined;
3527
+ particle.strokeColor = undefined;
3528
+ particle.strokeOpacity = defaultOpacity;
3529
+ particle.strokeWidth = 0;
3530
+ return;
3531
+ }
3532
+ const strokeColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), stroke.color);
3533
+ particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
3534
+ particle.strokeOpacity = getRangeValue(stroke.opacity ?? defaultOpacity);
3535
+ particle.strokeAnimation = strokeColor.animation;
3536
+ const strokeHslColor = rangeColorToHsl(this.#pluginManager, strokeColor) ?? particle.getFillColor();
3537
+ if (!strokeHslColor) {
3538
+ return;
3539
+ }
3540
+ particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, particle.strokeAnimation, container.retina.reduceFactor);
3541
+ }
3470
3542
  }
3471
3543
 
3472
3544
  async function loadPaintUpdater(engine) {
3473
- engine.checkVersion("4.4.0");
3545
+ engine.checkVersion("4.5.0");
3474
3546
  await engine.pluginManager.register(e => {
3475
3547
  e.pluginManager.addParticleUpdater("paint", container => {
3476
3548
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3512,7 +3584,7 @@
3512
3584
  if (!this.accepts(input)) {
3513
3585
  return;
3514
3586
  }
3515
- const result = rgbRegex.exec(input), radix = 10, minLength = 4, defaultAlpha = 1;
3587
+ const result = rgbRegex.exec(input), radix = 10, minLength = 4;
3516
3588
  return result
3517
3589
  ? {
3518
3590
  a: result.length > minLength ? parseAlpha(result[RgbIndexes.a]) : defaultAlpha,
@@ -3525,7 +3597,7 @@
3525
3597
  }
3526
3598
 
3527
3599
  async function loadRgbColorPlugin(engine) {
3528
- engine.checkVersion("4.4.0");
3600
+ engine.checkVersion("4.5.0");
3529
3601
  await engine.pluginManager.register(e => {
3530
3602
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3531
3603
  });
@@ -3610,7 +3682,7 @@
3610
3682
  }
3611
3683
 
3612
3684
  async function loadSizeUpdater(engine) {
3613
- engine.checkVersion("4.4.0");
3685
+ engine.checkVersion("4.5.0");
3614
3686
  await engine.pluginManager.register(e => {
3615
3687
  e.pluginManager.addParticleUpdater("size", container => {
3616
3688
  return Promise.resolve(new SizeUpdater(container));
@@ -3619,7 +3691,7 @@
3619
3691
  }
3620
3692
 
3621
3693
  async function loadBasic(engine) {
3622
- engine.checkVersion("4.4.0");
3694
+ engine.checkVersion("4.5.0");
3623
3695
  await engine.pluginManager.register(async (e) => {
3624
3696
  await Promise.all([
3625
3697
  loadBlendPlugin(e),
@@ -3950,7 +4022,7 @@
3950
4022
  }
3951
4023
 
3952
4024
  async function loadDestroyUpdater(engine) {
3953
- engine.checkVersion("4.4.0");
4025
+ engine.checkVersion("4.5.0");
3954
4026
  await engine.pluginManager.register(e => {
3955
4027
  e.pluginManager.addParticleUpdater("destroy", container => {
3956
4028
  return Promise.resolve(new DestroyUpdater(e.pluginManager, container));
@@ -4050,6 +4122,8 @@
4050
4122
  autoPlay = true;
4051
4123
  direction;
4052
4124
  domId;
4125
+ draggable = false;
4126
+ draw = true;
4053
4127
  fill = true;
4054
4128
  life = new EmitterLife();
4055
4129
  name;
@@ -4073,6 +4147,8 @@
4073
4147
  }
4074
4148
  loadProperty(this, "direction", data.direction);
4075
4149
  loadProperty(this, "domId", data.domId);
4150
+ loadProperty(this, "draggable", data.draggable);
4151
+ loadProperty(this, "draw", data.draw);
4076
4152
  loadProperty(this, "fill", data.fill);
4077
4153
  this.life.load(data.life);
4078
4154
  loadProperty(this, "name", data.name);
@@ -4134,6 +4210,14 @@
4134
4210
  }
4135
4211
  }
4136
4212
 
4213
+ const ErrorCodes = {
4214
+ emittersPluginNotLoaded: "TSP-3101",
4215
+ };
4216
+
4217
+ const ErrorMessages = {
4218
+ [ErrorCodes.emittersPluginNotLoaded]: "tsParticles Emitters Plugin is not loaded",
4219
+ };
4220
+
4137
4221
  async function addEmittersShapesManager(e) {
4138
4222
  const { ShapeManager } = await Promise.resolve().then(function () { return ShapeManager$1; }), pluginManager = e.pluginManager;
4139
4223
  pluginManager.emitterShapeManager ??= new ShapeManager();
@@ -4169,6 +4253,8 @@
4169
4253
  this.fill = fill;
4170
4254
  this.options = options;
4171
4255
  }
4256
+ draw(_context) {
4257
+ }
4172
4258
  resize(position, size) {
4173
4259
  this.position = position;
4174
4260
  this.size = size;
@@ -4181,7 +4267,10 @@
4181
4267
  })(EmitterClickMode || (EmitterClickMode = {}));
4182
4268
 
4183
4269
  async function loadEmittersPluginSimple(engine) {
4184
- engine.checkVersion("4.4.0");
4270
+ engine.checkVersion("4.5.0");
4271
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
4272
+ addErrorMessages(ErrorMessages);
4273
+ }
4185
4274
  await engine.pluginManager.register(async (e) => {
4186
4275
  const instancesManager = await getEmittersInstancesManager(e);
4187
4276
  await addEmittersShapesManager(e);
@@ -4189,9 +4278,63 @@
4189
4278
  });
4190
4279
  }
4191
4280
 
4281
+ class EmittersPluginInstance {
4282
+ #container;
4283
+ #instancesManager;
4284
+ constructor(instancesManager, container) {
4285
+ this.#instancesManager = instancesManager;
4286
+ this.#container = container;
4287
+ this.#instancesManager.initContainer(container);
4288
+ }
4289
+ draw(context, _delta) {
4290
+ for (const emitter of this.#instancesManager.getArray(this.#container)) {
4291
+ emitter.draw(context);
4292
+ }
4293
+ }
4294
+ async init() {
4295
+ const emittersOptions = this.#container.actualOptions.emitters;
4296
+ if (isArray(emittersOptions)) {
4297
+ for (const emitterOptions of emittersOptions) {
4298
+ await this.#instancesManager.addEmitter(this.#container, emitterOptions);
4299
+ }
4300
+ }
4301
+ else {
4302
+ await this.#instancesManager.addEmitter(this.#container, emittersOptions);
4303
+ }
4304
+ }
4305
+ pause() {
4306
+ for (const emitter of this.#instancesManager.getArray(this.#container)) {
4307
+ emitter.pause();
4308
+ }
4309
+ }
4310
+ play() {
4311
+ for (const emitter of this.#instancesManager.getArray(this.#container)) {
4312
+ emitter.play();
4313
+ }
4314
+ }
4315
+ resize() {
4316
+ for (const emitter of this.#instancesManager.getArray(this.#container)) {
4317
+ emitter.resize();
4318
+ }
4319
+ }
4320
+ stop() {
4321
+ this.#instancesManager.clear(this.#container);
4322
+ }
4323
+ update(delta) {
4324
+ this.#instancesManager.getArray(this.#container).forEach(emitter => {
4325
+ emitter.update(delta);
4326
+ });
4327
+ }
4328
+ }
4329
+
4330
+ var EmittersPluginInstance$1 = /*#__PURE__*/Object.freeze({
4331
+ __proto__: null,
4332
+ EmittersPluginInstance: EmittersPluginInstance
4333
+ });
4334
+
4192
4335
  function ensureEmittersPluginLoaded(e) {
4193
4336
  if (!e.pluginManager.addEmitterShapeGenerator) {
4194
- throw new Error("tsParticles Emitters Plugin is not loaded");
4337
+ throw new Error(getErrorMessage(ErrorCodes.emittersPluginNotLoaded));
4195
4338
  }
4196
4339
  }
4197
4340
 
@@ -4207,12 +4350,16 @@
4207
4350
  return position + offset * (getRandom() - half);
4208
4351
  }
4209
4352
  function getRandomSize(sides) {
4210
- return Math.floor(getRandom() * sides);
4353
+ return toEnumValue(Sides, Math.floor(getRandom() * sides), Sides.BottomLeft);
4211
4354
  }
4212
4355
  class EmittersSquareShape extends EmitterShapeBase {
4213
4356
  constructor(position, size, fill, options) {
4214
4357
  super(position, size, fill, options);
4215
4358
  }
4359
+ draw(context) {
4360
+ const position = this.position, size = this.size, halfW = size.width * half, halfH = size.height * half;
4361
+ context.rect(position.x - halfW, position.y - halfH, size.width, size.height);
4362
+ }
4216
4363
  async init() {
4217
4364
  }
4218
4365
  randomPosition() {
@@ -4269,7 +4416,7 @@
4269
4416
  }
4270
4417
 
4271
4418
  async function loadEmittersShapeSquare(engine) {
4272
- engine.checkVersion("4.4.0");
4419
+ engine.checkVersion("4.5.0");
4273
4420
  await engine.pluginManager.register((e) => {
4274
4421
  ensureEmittersPluginLoaded(e);
4275
4422
  e.pluginManager.addEmitterShapeGenerator?.("square", new EmittersSquareShapeGenerator());
@@ -4413,7 +4560,7 @@
4413
4560
  }
4414
4561
 
4415
4562
  async function loadLifeUpdater(engine) {
4416
- engine.checkVersion("4.4.0");
4563
+ engine.checkVersion("4.5.0");
4417
4564
  await engine.pluginManager.register(e => {
4418
4565
  e.pluginManager.addParticleUpdater("life", container => {
4419
4566
  return Promise.resolve(new LifeUpdater(container));
@@ -4439,7 +4586,7 @@
4439
4586
  }
4440
4587
 
4441
4588
  async function loadLineShape(engine) {
4442
- engine.checkVersion("4.4.0");
4589
+ engine.checkVersion("4.5.0");
4443
4590
  await engine.pluginManager.register(e => {
4444
4591
  e.pluginManager.addShape(["line"], () => Promise.resolve(new LineDrawer()));
4445
4592
  });
@@ -4496,7 +4643,7 @@
4496
4643
  particle.pathRotation = rotateOptions.path;
4497
4644
  let rotateDirection = rotateOptions.direction;
4498
4645
  if (rotateDirection === exports.RotateDirection.random) {
4499
- const index = Math.floor(getRandom() * double), minIndex = 0;
4646
+ const index = Math.floor(getRandom() * double);
4500
4647
  rotateDirection = index > minIndex ? exports.RotateDirection.counterClockwise : exports.RotateDirection.clockwise;
4501
4648
  }
4502
4649
  switch (rotateDirection) {
@@ -4543,7 +4690,7 @@
4543
4690
  }
4544
4691
 
4545
4692
  async function loadRotateUpdater(engine) {
4546
- engine.checkVersion("4.4.0");
4693
+ engine.checkVersion("4.5.0");
4547
4694
  await engine.pluginManager.register(e => {
4548
4695
  e.pluginManager.addParticleUpdater("rotate", container => {
4549
4696
  return Promise.resolve(new RotateUpdater(container));
@@ -4859,7 +5006,7 @@
4859
5006
  }
4860
5007
 
4861
5008
  async function loadSoundsPlugin(engine) {
4862
- engine.checkVersion("4.4.0");
5009
+ engine.checkVersion("4.5.0");
4863
5010
  await engine.pluginManager.register(e => {
4864
5011
  e.pluginManager.addPlugin(new SoundsPlugin(e));
4865
5012
  });
@@ -4867,7 +5014,7 @@
4867
5014
 
4868
5015
  let initPromise = null;
4869
5016
  async function doInitPlugins(engine) {
4870
- engine.checkVersion("4.4.0");
5017
+ engine.checkVersion("4.5.0");
4871
5018
  await engine.pluginManager.register(async (e) => {
4872
5019
  const loadEmittersForFireworks = async (e) => {
4873
5020
  await loadEmittersPluginSimple(e);
@@ -4914,7 +5061,7 @@
4914
5061
  fireworks.init = async () => {
4915
5062
  await initPlugins(tsParticles);
4916
5063
  };
4917
- fireworks.version = "4.4.0";
5064
+ fireworks.version = "4.5.0";
4918
5065
  globalThis.fireworks = fireworks;
4919
5066
 
4920
5067
  const globalObject = globalThis;
@@ -4984,21 +5131,28 @@
4984
5131
  });
4985
5132
  }
4986
5133
  clear() {
5134
+ const visited = new Set();
4987
5135
  for (const plugin of this.#canvasClearPlugins) {
5136
+ visited.add(plugin);
4988
5137
  if (plugin.canvasClear?.() ?? false) {
4989
- return;
5138
+ return plugin;
4990
5139
  }
4991
5140
  }
4992
5141
  for (const layer of Object.values(exports.DrawLayer)) {
4993
5142
  if (typeof layer === "number") {
4994
5143
  for (const plugin of this.#getLayerPlugins(layer)) {
5144
+ if (visited.has(plugin)) {
5145
+ continue;
5146
+ }
5147
+ visited.add(plugin);
4995
5148
  if (plugin.canvasClear?.() ?? false) {
4996
- return;
5149
+ return plugin;
4997
5150
  }
4998
5151
  }
4999
5152
  }
5000
5153
  }
5001
5154
  this.canvasClear();
5155
+ return undefined;
5002
5156
  }
5003
5157
  destroy() {
5004
5158
  this.stop();
@@ -5076,8 +5230,7 @@
5076
5230
  });
5077
5231
  }
5078
5232
  drawParticles(delta) {
5079
- const { particles, actualOptions } = this.#container;
5080
- this.clear();
5233
+ const { particles, actualOptions } = this.#container, clearedPlugin = this.clear();
5081
5234
  particles.update(delta);
5082
5235
  this.draw(ctx => {
5083
5236
  const width = this.#canvasManager.size.width, height = this.#canvasManager.size.height;
@@ -5099,7 +5252,9 @@
5099
5252
  }
5100
5253
  }
5101
5254
  for (const plugin of this.#getLayerPlugins(exports.DrawLayer.BackgroundMask)) {
5102
- plugin.canvasPaint?.();
5255
+ if (plugin !== clearedPlugin) {
5256
+ plugin.canvasPaint?.();
5257
+ }
5103
5258
  }
5104
5259
  for (const plugin of this.#getLayerPlugins(exports.DrawLayer.CanvasSetup)) {
5105
5260
  plugin.drawSettingsSetup?.(ctx, delta);
@@ -5131,35 +5286,7 @@
5131
5286
  this.#layers[layer] = [];
5132
5287
  }
5133
5288
  }
5134
- for (const plugin of this.#container.plugins) {
5135
- if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
5136
- this.#colorPlugins.push(plugin);
5137
- }
5138
- if (plugin.drawParticle) {
5139
- this.#drawParticlePlugins.push(plugin);
5140
- }
5141
- if (plugin.drawParticleSetup) {
5142
- this.#drawParticlesSetupPlugins.push(plugin);
5143
- }
5144
- if (plugin.drawParticleCleanup) {
5145
- this.#drawParticlesCleanupPlugins.push(plugin);
5146
- }
5147
- if (plugin.canvasClear) {
5148
- this.#canvasClearPlugins.push(plugin);
5149
- }
5150
- if (plugin.canvasPaint) {
5151
- this.#getLayerPlugins(exports.DrawLayer.BackgroundMask).push(plugin);
5152
- }
5153
- if (plugin.drawSettingsSetup) {
5154
- this.#getLayerPlugins(exports.DrawLayer.CanvasSetup).push(plugin);
5155
- }
5156
- if (plugin.draw) {
5157
- this.#getLayerPlugins(exports.DrawLayer.PluginContent).push(plugin);
5158
- }
5159
- if (plugin.clearDraw ?? plugin.drawSettingsCleanup) {
5160
- this.#getLayerPlugins(exports.DrawLayer.CanvasCleanup).push(plugin);
5161
- }
5162
- }
5289
+ this.#initPluginsArray();
5163
5290
  }
5164
5291
  initUpdaters() {
5165
5292
  this.#preDrawUpdaters = [];
@@ -5357,16 +5484,55 @@
5357
5484
  if (!fColor && plugin.particleFillColor) {
5358
5485
  fColor = rangeColorToHsl(this.#pluginManager, plugin.particleFillColor(particle));
5359
5486
  }
5360
- if (!sColor && plugin.particleStrokeColor) {
5361
- sColor = rangeColorToHsl(this.#pluginManager, plugin.particleStrokeColor(particle));
5487
+ if (!sColor && plugin.particleStrokeColor) {
5488
+ sColor = rangeColorToHsl(this.#pluginManager, plugin.particleStrokeColor(particle));
5489
+ }
5490
+ if (fColor && sColor) {
5491
+ break;
5492
+ }
5493
+ }
5494
+ this.#reusablePluginColors[fColorIndex] = fColor;
5495
+ this.#reusablePluginColors[sColorIndex] = sColor;
5496
+ return this.#reusablePluginColors;
5497
+ }
5498
+ #initLayerPlugin(plugin) {
5499
+ const layerMap = [
5500
+ [exports.DrawLayer.BackgroundMask, !!plugin.canvasPaint],
5501
+ [exports.DrawLayer.CanvasSetup, !!plugin.drawSettingsSetup],
5502
+ [exports.DrawLayer.PluginContent, !!plugin.draw],
5503
+ [exports.DrawLayer.CanvasCleanup, !!(plugin.clearDraw ?? plugin.drawSettingsCleanup)],
5504
+ ];
5505
+ for (const [layer, active] of layerMap) {
5506
+ if (active) {
5507
+ this.#layers[layer].push(plugin);
5508
+ }
5509
+ }
5510
+ }
5511
+ #initPluginsArray() {
5512
+ for (const plugin of this.#container.plugins) {
5513
+ if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
5514
+ this.#colorPlugins.push(plugin);
5515
+ }
5516
+ if (plugin.drawParticle) {
5517
+ this.#drawParticlePlugins.push(plugin);
5518
+ }
5519
+ if (plugin.drawParticleSetup) {
5520
+ this.#drawParticlesSetupPlugins.push(plugin);
5521
+ }
5522
+ if (plugin.drawParticleCleanup) {
5523
+ this.#drawParticlesCleanupPlugins.push(plugin);
5362
5524
  }
5363
- if (fColor && sColor) {
5364
- break;
5525
+ if (plugin.canvasClear) {
5526
+ this.#canvasClearPlugins.push(plugin);
5365
5527
  }
5528
+ this.#initLayerPlugin(plugin);
5366
5529
  }
5367
- this.#reusablePluginColors[fColorIndex] = fColor;
5368
- this.#reusablePluginColors[sColorIndex] = sColor;
5369
- return this.#reusablePluginColors;
5530
+ }
5531
+ #isSupportedElement(element) {
5532
+ return ((typeof HTMLCanvasElement !== "undefined" && element instanceof HTMLCanvasElement) ||
5533
+ (typeof OffscreenCanvas !== "undefined" && element instanceof OffscreenCanvas) ||
5534
+ (typeof HTMLVideoElement !== "undefined" && element instanceof HTMLVideoElement) ||
5535
+ (typeof HTMLImageElement !== "undefined" && element instanceof HTMLImageElement));
5370
5536
  }
5371
5537
  #resolveBackgroundElement() {
5372
5538
  const background = this.#container.actualOptions.background;
@@ -5377,9 +5543,7 @@
5377
5543
  if (typeof background.element === "string") {
5378
5544
  if (typeof document !== "undefined") {
5379
5545
  const node = document.querySelector(background.element);
5380
- if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
5381
- (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
5382
- (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
5546
+ if (node && this.#isSupportedElement(node)) {
5383
5547
  this.#backgroundElement = node;
5384
5548
  }
5385
5549
  else if (node) {
@@ -5390,10 +5554,7 @@
5390
5554
  }
5391
5555
  }
5392
5556
  }
5393
- else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
5394
- (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
5395
- (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
5396
- (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
5557
+ else if (this.#isSupportedElement(background.element)) {
5397
5558
  this.#backgroundElement = background.element;
5398
5559
  }
5399
5560
  }
@@ -5411,7 +5572,7 @@
5411
5572
  return transferredCanvas;
5412
5573
  }
5413
5574
  if (typeof canvas.transferControlToOffscreen !== "function") {
5414
- throw new TypeError("OffscreenCanvas is required but not supported by this browser");
5575
+ throw new TypeError(getErrorMessage(ErrorCodes$2.offscreenCanvasUnsupported));
5415
5576
  }
5416
5577
  try {
5417
5578
  const offscreenCanvas = canvas.transferControlToOffscreen();
@@ -5419,10 +5580,16 @@
5419
5580
  return offscreenCanvas;
5420
5581
  }
5421
5582
  catch {
5422
- throw new TypeError("OffscreenCanvas transfer failed");
5583
+ throw new TypeError(getErrorMessage(ErrorCodes$2.offscreenCanvasTransferFailed));
5423
5584
  }
5424
5585
  }, isHtmlCanvasElement = (canvas) => {
5425
5586
  return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
5587
+ }, getEffectiveColorSpace = (context) => {
5588
+ if (!context) {
5589
+ return undefined;
5590
+ }
5591
+ const colorInfo = context;
5592
+ return colorInfo.getContextAttributes?.().colorSpace ?? undefined;
5426
5593
  };
5427
5594
  function setStyle(canvas, style, important = false) {
5428
5595
  if (!style) {
@@ -5547,7 +5714,7 @@
5547
5714
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
5548
5715
  if (color) {
5549
5716
  const hdrOptions = container.actualOptions.hdr;
5550
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
5717
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, toEnumValue(exports.HdrMode, hdrOptions.mode, exports.HdrMode.standard));
5551
5718
  }
5552
5719
  else {
5553
5720
  elementStyle.backgroundColor = "";
@@ -5667,11 +5834,11 @@
5667
5834
  const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
5668
5835
  safeMatchMedia("(color-gamut: p3)")?.matches &&
5669
5836
  safeMatchMedia("(dynamic-range: high)")?.matches;
5670
- container.hdr = canSupportHdr ?? false;
5671
- container.hdrMode = container.actualOptions.hdr.mode;
5837
+ container.hdrMode = toEnumValue(exports.HdrMode, container.actualOptions.hdr.mode, exports.HdrMode.standard);
5672
5838
  container.peakNits = container.actualOptions.hdr.peakNits;
5673
5839
  const renderCanvas = this.renderCanvas;
5674
5840
  if (!renderCanvas) {
5841
+ container.hdr = canSupportHdr ?? false;
5675
5842
  return;
5676
5843
  }
5677
5844
  this.render.setContextSettings({
@@ -5690,7 +5857,6 @@
5690
5857
  context = null;
5691
5858
  }
5692
5859
  if (canSupportHdr && !context) {
5693
- container.hdr = false;
5694
5860
  const sdrSettings = {
5695
5861
  alpha: true,
5696
5862
  desynchronized: true,
@@ -5706,11 +5872,16 @@
5706
5872
  }
5707
5873
  }
5708
5874
  this.render.setContext(context);
5875
+ if (context) {
5876
+ const effectiveColorSpace = getEffectiveColorSpace(context);
5877
+ if (effectiveColorSpace !== undefined) {
5878
+ container.hdr = effectiveColorSpace === "display-p3";
5879
+ }
5880
+ }
5709
5881
  }
5710
5882
  #initHdrListeners() {
5711
5883
  this.#removeHdrListeners();
5712
5884
  const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
5713
- this.#recreateRenderCanvas();
5714
5885
  this.#initContext();
5715
5886
  this.initBackground();
5716
5887
  }, listeners = [];
@@ -5746,16 +5917,6 @@
5746
5917
  element.style.setProperty(key, value, "important");
5747
5918
  }
5748
5919
  }
5749
- #recreateRenderCanvas() {
5750
- const renderCanvas = this.renderCanvas;
5751
- if (!renderCanvas) {
5752
- return;
5753
- }
5754
- if (this.domElement) {
5755
- return;
5756
- }
5757
- this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
5758
- }
5759
5920
  #removeHdrListeners() {
5760
5921
  if (!this.#hdrMediaListeners) {
5761
5922
  return;
@@ -5854,8 +6015,7 @@
5854
6015
  this.#resizeTimeout = undefined;
5855
6016
  }
5856
6017
  const handleResize = async () => {
5857
- const canvas = this.#container.canvas;
5858
- await canvas.windowResize();
6018
+ await this.#container.canvas.windowResize();
5859
6019
  };
5860
6020
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
5861
6021
  }
@@ -5883,8 +6043,8 @@
5883
6043
  }
5884
6044
  else if (!this.#resizeObserver && add && canvasEl) {
5885
6045
  this.#resizeObserver = new ResizeObserver((entries) => {
5886
- const entry = entries.find(e => e.target === canvasEl);
5887
- if (!entry) {
6046
+ const res = entries.some(e => e.target === canvasEl);
6047
+ if (!res) {
5888
6048
  return;
5889
6049
  }
5890
6050
  this.#handleWindowResize();
@@ -6148,10 +6308,10 @@
6148
6308
  return this.#modifiers.find(m => m.id === id);
6149
6309
  }
6150
6310
  getOpacity() {
6151
- const zIndexOptions = this.options.zIndex, zIndexFactor = zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, baseOpacity = getRangeValue(this.opacity?.value ?? defaultOpacity$1), modifierOpacity = this.#applyModifiers(undefined, m => m.opacity), opacity = modifierOpacity ?? baseOpacity, fillOpacity = this.fillOpacity ?? defaultOpacity$1, strokeOpacity = this.strokeOpacity ?? defaultOpacity$1;
6152
- this.#cachedOpacityData.fillOpacity = fillOpacity;
6311
+ const zIndexOptions = this.options.zIndex, zIndexFactor = zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, baseOpacity = getRangeValue(this.opacity?.value ?? defaultOpacity$1), modifierOpacity = this.#applyModifiers(undefined, m => m.opacity), opacity = modifierOpacity ?? baseOpacity;
6312
+ this.#cachedOpacityData.fillOpacity = this.fillOpacity ?? defaultOpacity$1;
6153
6313
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
6154
- this.#cachedOpacityData.strokeOpacity = strokeOpacity;
6314
+ this.#cachedOpacityData.strokeOpacity = this.strokeOpacity ?? defaultOpacity$1;
6155
6315
  return this.#cachedOpacityData;
6156
6316
  }
6157
6317
  getPosition() {
@@ -6398,7 +6558,7 @@
6398
6558
  #initPosition(position) {
6399
6559
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
6400
6560
  if (!initialPosition) {
6401
- throw new Error("a valid position cannot be found for particle");
6561
+ throw new Error(getErrorMessage(ErrorCodes$2.particlePositionNotFound));
6402
6562
  }
6403
6563
  this.position = initialPosition;
6404
6564
  this.initialPosition = this.position.copy();
@@ -6447,6 +6607,12 @@
6447
6607
  this.#circlePoolIdx = 0;
6448
6608
  this.#rectanglePoolIdx = 0;
6449
6609
  }
6610
+ get cellSize() {
6611
+ return this.#cellSize;
6612
+ }
6613
+ set cellSize(value) {
6614
+ this.#pendingCellSize = value;
6615
+ }
6450
6616
  clear() {
6451
6617
  this.#cells.clear();
6452
6618
  const pendingCellSize = this.#pendingCellSize;
@@ -6470,18 +6636,7 @@
6470
6636
  const minCellX = Math.floor(bounds.minX / this.#cellSize), maxCellX = Math.floor(bounds.maxX / this.#cellSize), minCellY = Math.floor(bounds.minY / this.#cellSize), maxCellY = Math.floor(bounds.maxY / this.#cellSize);
6471
6637
  for (let cx = minCellX; cx <= maxCellX; cx++) {
6472
6638
  for (let cy = minCellY; cy <= maxCellY; cy++) {
6473
- const key = `${cx}_${cy}`, cellParticles = this.#cells.get(key);
6474
- if (!cellParticles) {
6475
- continue;
6476
- }
6477
- for (const p of cellParticles) {
6478
- if (check && !check(p)) {
6479
- continue;
6480
- }
6481
- if (range.contains(p.getPosition())) {
6482
- out.push(p);
6483
- }
6484
- }
6639
+ this.#queryCell(cx, cy, range, check, out);
6485
6640
  }
6486
6641
  }
6487
6642
  return out;
@@ -6496,14 +6651,23 @@
6496
6651
  this.#releaseShapes();
6497
6652
  return result;
6498
6653
  }
6499
- setCellSize(cellSize) {
6500
- this.#pendingCellSize = cellSize;
6501
- }
6502
6654
  #acquireCircle(x, y, r) {
6503
- return (this.#circlePool[this.#circlePoolIdx++] ??= new Circle(x, y, r)).reset(x, y, r);
6655
+ const idx = this.#circlePoolIdx++;
6656
+ let circle = this.#circlePool[idx];
6657
+ if (!circle) {
6658
+ circle = new Circle(x, y, r);
6659
+ this.#circlePool[idx] = circle;
6660
+ }
6661
+ return circle.reset(x, y, r);
6504
6662
  }
6505
6663
  #acquireRectangle(x, y, w, h) {
6506
- return (this.#rectanglePool[this.#rectanglePoolIdx++] ??= new Rectangle(x, y, w, h)).reset(x, y, w, h);
6664
+ const idx = this.#rectanglePoolIdx++;
6665
+ let rectangle = this.#rectanglePool[idx];
6666
+ if (!rectangle) {
6667
+ rectangle = new Rectangle(x, y, w, h);
6668
+ this.#rectanglePool[idx] = rectangle;
6669
+ }
6670
+ return rectangle.reset(x, y, w, h);
6507
6671
  }
6508
6672
  #cellKeyFromCoords(x, y) {
6509
6673
  const cellX = Math.floor(x / this.#cellSize), cellY = Math.floor(y / this.#cellSize);
@@ -6530,6 +6694,20 @@
6530
6694
  }
6531
6695
  return null;
6532
6696
  }
6697
+ #queryCell(cx, cy, range, check, out) {
6698
+ const cellParticles = this.#cells.get(`${cx}_${cy}`);
6699
+ if (!cellParticles) {
6700
+ return;
6701
+ }
6702
+ for (const p of cellParticles) {
6703
+ if (check && !check(p)) {
6704
+ continue;
6705
+ }
6706
+ if (range.contains(p.getPosition())) {
6707
+ out.push(p);
6708
+ }
6709
+ }
6710
+ }
6533
6711
  #releaseShapes() {
6534
6712
  this.#circlePoolIdx = 0;
6535
6713
  this.#rectanglePoolIdx = 0;
@@ -6538,9 +6716,9 @@
6538
6716
 
6539
6717
  class ParticlesManager {
6540
6718
  checkParticlePositionPlugins;
6541
- grid;
6542
6719
  #array;
6543
6720
  #container;
6721
+ #grid;
6544
6722
  #groupLimits;
6545
6723
  #limit;
6546
6724
  #nextId;
@@ -6564,7 +6742,7 @@
6564
6742
  this.#groupLimits = new Map();
6565
6743
  this.#particleBuckets = new Map();
6566
6744
  this.#zBuckets = this.#createBuckets(this.#container.zLayers);
6567
- this.grid = new SpatialHashGrid(spatialHashGridCellSize);
6745
+ this.#grid = new SpatialHashGrid(spatialHashGridCellSize);
6568
6746
  this.checkParticlePositionPlugins = [];
6569
6747
  this.#particleResetPlugins = [];
6570
6748
  this.#particleUpdatePlugins = [];
@@ -6575,23 +6753,12 @@
6575
6753
  get count() {
6576
6754
  return this.#array.length;
6577
6755
  }
6756
+ get grid() {
6757
+ return this.#grid;
6758
+ }
6578
6759
  addParticle(position, overrideOptions, group, initializer) {
6579
- const limitMode = this.#container.actualOptions.particles.number.limit.mode, limit = group === undefined ? this.#limit : (this.#groupLimits.get(group) ?? this.#limit), currentCount = this.count;
6580
- if (limit > minLimit) {
6581
- switch (limitMode) {
6582
- case exports.LimitMode.delete: {
6583
- const countToRemove = currentCount + countOffset - limit;
6584
- if (countToRemove > minCount) {
6585
- this.removeQuantity(countToRemove);
6586
- }
6587
- break;
6588
- }
6589
- case exports.LimitMode.wait:
6590
- if (currentCount >= limit) {
6591
- return;
6592
- }
6593
- break;
6594
- }
6760
+ if (this.#checkAndApplyLimits(group, this.count)) {
6761
+ return;
6595
6762
  }
6596
6763
  try {
6597
6764
  const particle = this.#pool.pop() ?? new Particle(this.#pluginManager, this.#container);
@@ -6655,7 +6822,7 @@
6655
6822
  return this.#array[index];
6656
6823
  }
6657
6824
  async init() {
6658
- const container = this.#container, options = container.actualOptions;
6825
+ const container = this.#container;
6659
6826
  this.checkParticlePositionPlugins = [];
6660
6827
  this.#updatePlugins = [];
6661
6828
  this.#particleUpdatePlugins = [];
@@ -6664,59 +6831,16 @@
6664
6831
  this.#postParticleUpdatePlugins = [];
6665
6832
  this.#particleBuckets.clear();
6666
6833
  this.#resetBuckets(container.zLayers);
6667
- this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
6668
- for (const plugin of container.plugins) {
6669
- if (plugin.redrawInit) {
6670
- await plugin.redrawInit();
6671
- }
6672
- if (plugin.checkParticlePosition) {
6673
- this.checkParticlePositionPlugins.push(plugin);
6674
- }
6675
- if (plugin.update) {
6676
- this.#updatePlugins.push(plugin);
6677
- }
6678
- if (plugin.particleUpdate) {
6679
- this.#particleUpdatePlugins.push(plugin);
6680
- }
6681
- if (plugin.postUpdate) {
6682
- this.#postUpdatePlugins.push(plugin);
6683
- }
6684
- if (plugin.particleReset) {
6685
- this.#particleResetPlugins.push(plugin);
6686
- }
6687
- if (plugin.postParticleUpdate) {
6688
- this.#postParticleUpdatePlugins.push(plugin);
6689
- }
6690
- }
6691
- await this.#container.initDrawersAndUpdaters();
6692
- for (const drawer of this.#container.effectDrawers.values()) {
6693
- await drawer.init?.(container);
6694
- }
6695
- for (const drawer of this.#container.shapeDrawers.values()) {
6696
- await drawer.init?.(container);
6697
- }
6698
- let handled = false;
6699
- for (const plugin of container.plugins) {
6700
- handled = plugin.particlesInitialization?.() ?? handled;
6701
- if (handled) {
6702
- break;
6703
- }
6704
- }
6705
- if (!handled) {
6706
- const particlesOptions = options.particles, groups = particlesOptions.groups;
6707
- for (const group in groups) {
6708
- const groupOptions = groups[group];
6709
- if (!groupOptions) {
6710
- continue;
6711
- }
6712
- for (let i = this.count, j = 0; j < groupOptions.number.value && i < particlesOptions.number.value; i++, j++) {
6713
- this.addParticle(undefined, groupOptions, group);
6714
- }
6715
- }
6716
- for (let i = this.count; i < particlesOptions.number.value; i++) {
6717
- this.addParticle();
6834
+ this.#grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
6835
+ this.#applyLimits(container.actualOptions.particles);
6836
+ const particlesOptions = container.actualOptions.particles, groups = particlesOptions.groups;
6837
+ for (const group in groups) {
6838
+ const groupData = groups[group];
6839
+ if (groupData) {
6840
+ this.#applyLimits(loadParticlesOptions(this.#pluginManager, this.#container, groupData), group, groupData);
6718
6841
  }
6719
6842
  }
6843
+ await this.#initPlugins();
6720
6844
  }
6721
6845
  push(nb, position, overrideOptions, group) {
6722
6846
  for (let i = 0; i < nb; i++) {
@@ -6731,13 +6855,13 @@
6731
6855
  remove(particle, group, override) {
6732
6856
  this.removeAt(this.#array.indexOf(particle), undefined, group, override);
6733
6857
  }
6734
- removeAt(index, quantity = defaultRemoveQuantity, group, override) {
6858
+ removeAt(index, quantity = defaultRemoveQuantity, group, override, matchGroup = true) {
6735
6859
  if (index < minIndex || index > this.count) {
6736
6860
  return;
6737
6861
  }
6738
6862
  let deleted = 0;
6739
6863
  for (let i = index; deleted < quantity && i < this.count; i++) {
6740
- if (this.#removeParticle(i, group, override)) {
6864
+ if (this.#removeParticle(i, group, override, matchGroup)) {
6741
6865
  i--;
6742
6866
  deleted++;
6743
6867
  }
@@ -6768,7 +6892,7 @@
6768
6892
  this.#resizeFactor = factor;
6769
6893
  }
6770
6894
  update(delta) {
6771
- this.grid.clear();
6895
+ this.#grid.clear();
6772
6896
  for (const plugin of this.#updatePlugins) {
6773
6897
  plugin.update?.(delta);
6774
6898
  }
@@ -6779,7 +6903,7 @@
6779
6903
  this.#updateParticlesPhase2(delta, particlesToDelete);
6780
6904
  if (particlesToDelete.size) {
6781
6905
  for (const particle of particlesToDelete) {
6782
- this.remove(particle);
6906
+ this.remove(particle, particle.group);
6783
6907
  }
6784
6908
  }
6785
6909
  this.#resizeFactor = undefined;
@@ -6790,12 +6914,7 @@
6790
6914
  #applyDensity(options, pluginsCount, group, groupOptions) {
6791
6915
  const numberOptions = options.number;
6792
6916
  if (!numberOptions.density.enable) {
6793
- if (group === undefined) {
6794
- this.#limit = numberOptions.limit.value;
6795
- }
6796
- else if (groupOptions?.number.limit.value ?? numberOptions.limit.value) {
6797
- this.#groupLimits.set(group, groupOptions?.number.limit.value ?? numberOptions.limit.value);
6798
- }
6917
+ this.#applyLimits(options, group, groupOptions);
6799
6918
  return;
6800
6919
  }
6801
6920
  const densityFactor = this.#initDensityFactor(numberOptions.density), optParticlesNumber = numberOptions.value, optParticlesLimit = numberOptions.limit.value > minLimit ? numberOptions.limit.value : optParticlesNumber, particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + pluginsCount, particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
@@ -6803,7 +6922,10 @@
6803
6922
  this.#limit = numberOptions.limit.value * densityFactor;
6804
6923
  }
6805
6924
  else {
6806
- this.#groupLimits.set(group, numberOptions.limit.value * densityFactor);
6925
+ this.#groupLimits.set(group, {
6926
+ limit: numberOptions.limit.value * densityFactor,
6927
+ mode: toEnumValue(exports.LimitMode, numberOptions.limit.mode, exports.LimitMode.delete),
6928
+ });
6807
6929
  }
6808
6930
  if (particlesCount < particlesNumber) {
6809
6931
  this.push(Math.abs(particlesNumber - particlesCount), undefined, options, group);
@@ -6812,6 +6934,55 @@
6812
6934
  this.removeQuantity(particlesCount - particlesNumber, group);
6813
6935
  }
6814
6936
  }
6937
+ #applyLimits(options, group, groupOptions) {
6938
+ if (group === undefined) {
6939
+ this.#limit = options.number.limit.value;
6940
+ const groups = this.#container.actualOptions.particles.groups;
6941
+ for (const existingGroup of this.#groupLimits.keys()) {
6942
+ if (!(existingGroup in groups)) {
6943
+ this.#groupLimits.delete(existingGroup);
6944
+ }
6945
+ }
6946
+ }
6947
+ else {
6948
+ const limitValue = groupOptions?.number?.limit?.value ?? options.number.limit.value;
6949
+ if (limitValue > minLimit) {
6950
+ this.#groupLimits.set(group, {
6951
+ limit: limitValue,
6952
+ mode: toEnumValue(exports.LimitMode, groupOptions?.number?.limit?.mode ?? options.number.limit.mode, exports.LimitMode.delete),
6953
+ });
6954
+ }
6955
+ else {
6956
+ this.#groupLimits.delete(group);
6957
+ }
6958
+ }
6959
+ }
6960
+ #checkAndApplyLimits(group, currentCount) {
6961
+ const globalLimit = this.#limit, globalMode = this.#container.actualOptions.particles.number.limit.mode;
6962
+ if (globalLimit > minLimit && globalMode === exports.LimitMode.wait && currentCount >= globalLimit) {
6963
+ return true;
6964
+ }
6965
+ const groupLimitEntry = group === undefined ? undefined : this.#groupLimits.get(group);
6966
+ if (groupLimitEntry && groupLimitEntry.limit > minLimit && groupLimitEntry.mode === exports.LimitMode.wait) {
6967
+ const groupCount = this.filter(t => t.group === group).length;
6968
+ if (groupCount >= groupLimitEntry.limit) {
6969
+ return true;
6970
+ }
6971
+ }
6972
+ if (groupLimitEntry && groupLimitEntry.limit > minLimit && groupLimitEntry.mode === exports.LimitMode.delete) {
6973
+ const groupCountToRemove = this.filter(t => t.group === group).length + countOffset - groupLimitEntry.limit;
6974
+ if (groupCountToRemove > minCount) {
6975
+ this.removeQuantity(groupCountToRemove, group);
6976
+ }
6977
+ }
6978
+ if (globalLimit > minLimit && globalMode === exports.LimitMode.delete) {
6979
+ const globalCountToRemove = this.count + countOffset - globalLimit;
6980
+ if (globalCountToRemove > minCount) {
6981
+ this.#removeAny(globalCountToRemove);
6982
+ }
6983
+ }
6984
+ return false;
6985
+ }
6815
6986
  #createBuckets(zLayers) {
6816
6987
  const bucketCount = Math.max(Math.floor(zLayers), one);
6817
6988
  return Array.from({ length: bucketCount }, () => []);
@@ -6834,6 +7005,70 @@
6834
7005
  }
6835
7006
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
6836
7007
  }
7008
+ async #initDrawersAndUpdaters() {
7009
+ const container = this.#container;
7010
+ await container.initDrawersAndUpdaters();
7011
+ for (const drawer of container.effectDrawers.values()) {
7012
+ await drawer.init?.(container);
7013
+ }
7014
+ for (const drawer of container.shapeDrawers.values()) {
7015
+ await drawer.init?.(container);
7016
+ }
7017
+ }
7018
+ async #initPlugins() {
7019
+ await this.#initPluginsArrays();
7020
+ await this.#initDrawersAndUpdaters();
7021
+ let handled = false;
7022
+ const container = this.#container;
7023
+ for (const plugin of container.plugins) {
7024
+ handled = plugin.particlesInitialization?.() ?? handled;
7025
+ if (handled) {
7026
+ break;
7027
+ }
7028
+ }
7029
+ if (handled) {
7030
+ return;
7031
+ }
7032
+ const particlesOptions = container.actualOptions.particles, groups = particlesOptions.groups;
7033
+ for (const group in groups) {
7034
+ const groupOptions = groups[group];
7035
+ if (!groupOptions) {
7036
+ continue;
7037
+ }
7038
+ for (let i = this.count, j = 0; j < groupOptions.number.value && i < particlesOptions.number.value; i++, j++) {
7039
+ this.addParticle(undefined, groupOptions, group);
7040
+ }
7041
+ }
7042
+ for (let i = this.count; i < particlesOptions.number.value; i++) {
7043
+ this.addParticle();
7044
+ }
7045
+ }
7046
+ async #initPluginsArrays() {
7047
+ const container = this.#container;
7048
+ for (const plugin of container.plugins) {
7049
+ if (plugin.redrawInit) {
7050
+ await plugin.redrawInit();
7051
+ }
7052
+ if (plugin.checkParticlePosition) {
7053
+ this.checkParticlePositionPlugins.push(plugin);
7054
+ }
7055
+ if (plugin.update) {
7056
+ this.#updatePlugins.push(plugin);
7057
+ }
7058
+ if (plugin.particleUpdate) {
7059
+ this.#particleUpdatePlugins.push(plugin);
7060
+ }
7061
+ if (plugin.postUpdate) {
7062
+ this.#postUpdatePlugins.push(plugin);
7063
+ }
7064
+ if (plugin.particleReset) {
7065
+ this.#particleResetPlugins.push(plugin);
7066
+ }
7067
+ if (plugin.postParticleUpdate) {
7068
+ this.#postParticleUpdatePlugins.push(plugin);
7069
+ }
7070
+ }
7071
+ }
6837
7072
  #insertParticleIntoBucket(particle) {
6838
7073
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
6839
7074
  if (!bucket) {
@@ -6842,12 +7077,15 @@
6842
7077
  bucket.push(particle);
6843
7078
  this.#particleBuckets.set(particle.id, bucketIndex);
6844
7079
  }
6845
- #removeParticle(index, group, override) {
7080
+ #removeAny(quantity) {
7081
+ this.removeAt(minIndex, quantity, undefined, undefined, false);
7082
+ }
7083
+ #removeParticle(index, group, override, matchGroup = true) {
6846
7084
  const particle = this.#array[index];
6847
7085
  if (!particle) {
6848
7086
  return false;
6849
7087
  }
6850
- if (particle.group !== group) {
7088
+ if (matchGroup && particle.group !== group) {
6851
7089
  return false;
6852
7090
  }
6853
7091
  this.#array.splice(index, deleteCount);
@@ -6934,7 +7172,7 @@
6934
7172
  particlesToDelete.add(particle);
6935
7173
  continue;
6936
7174
  }
6937
- this.grid.insert(particle);
7175
+ this.#grid.insert(particle);
6938
7176
  }
6939
7177
  return particlesToDelete;
6940
7178
  }
@@ -7110,7 +7348,6 @@
7110
7348
  this.shapeDrawers = new Map();
7111
7349
  this.particleUpdaters = [];
7112
7350
  this.plugins.length = 0;
7113
- this.#pluginManager.clearPlugins(this);
7114
7351
  this.destroyed = true;
7115
7352
  this.#onDestroy(remove);
7116
7353
  this.dispatchEvent(exports.EventType.containerDestroyed);
@@ -7163,31 +7400,14 @@
7163
7400
  await this.initDrawersAndUpdaters();
7164
7401
  this.#options = loadContainerOptions(this.#pluginManager, this, this.#initialSourceOptions, this.sourceOptions);
7165
7402
  this.actualOptions = loadContainerOptions(this.#pluginManager, this, this.#options);
7166
- this.plugins.length = 0;
7167
- this.particleDestroyedPlugins.length = 0;
7168
- this.particleCreatedPlugins.length = 0;
7169
- this.particlePositionPlugins.length = 0;
7170
- for (const [plugin, containerPlugin] of allContainerPlugins) {
7171
- if (plugin.needsPlugin(this.actualOptions)) {
7172
- this.plugins.push(containerPlugin);
7173
- if (containerPlugin.particleCreated) {
7174
- this.particleCreatedPlugins.push(containerPlugin);
7175
- }
7176
- if (containerPlugin.particleDestroyed) {
7177
- this.particleDestroyedPlugins.push(containerPlugin);
7178
- }
7179
- if (containerPlugin.particlePosition) {
7180
- this.particlePositionPlugins.push(containerPlugin);
7181
- }
7182
- }
7183
- }
7403
+ this.#initPlugins(allContainerPlugins);
7184
7404
  this.retina.init();
7185
7405
  this.canvas.init();
7186
7406
  this.updateActualOptions();
7187
7407
  this.canvas.initBackground();
7188
7408
  this.canvas.resize();
7189
7409
  const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
7190
- this.hdrMode = hdrOptions.mode;
7410
+ this.hdrMode = toEnumValue(exports.HdrMode, hdrOptions.mode, exports.HdrMode.standard);
7191
7411
  this.peakNits = hdrOptions.peakNits;
7192
7412
  this.zLayers = zLayers;
7193
7413
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
@@ -7208,9 +7428,9 @@
7208
7428
  }
7209
7429
  async initDrawersAndUpdaters() {
7210
7430
  const pluginManager = this.#pluginManager;
7211
- this.effectDrawers = await pluginManager.getEffectDrawers(this, true);
7212
- this.shapeDrawers = await pluginManager.getShapeDrawers(this, true);
7213
- this.particleUpdaters = await pluginManager.getUpdaters(this, true);
7431
+ this.effectDrawers = await getItemMapFromInitializer(this, pluginManager.initializers.effects);
7432
+ this.shapeDrawers = await getItemMapFromInitializer(this, pluginManager.initializers.shapes);
7433
+ this.particleUpdaters = await getItemsFromInitializer(this, pluginManager.initializers.updaters);
7214
7434
  }
7215
7435
  pause() {
7216
7436
  if (!guardCheck(this)) {
@@ -7321,6 +7541,27 @@
7321
7541
  }
7322
7542
  return refresh;
7323
7543
  }
7544
+ #initPlugins(allContainerPlugins) {
7545
+ this.plugins.length = 0;
7546
+ this.particleDestroyedPlugins.length = 0;
7547
+ this.particleCreatedPlugins.length = 0;
7548
+ this.particlePositionPlugins.length = 0;
7549
+ for (const [plugin, containerPlugin] of allContainerPlugins) {
7550
+ if (!plugin.needsPlugin(this.actualOptions)) {
7551
+ continue;
7552
+ }
7553
+ this.plugins.push(containerPlugin);
7554
+ if (containerPlugin.particleCreated) {
7555
+ this.particleCreatedPlugins.push(containerPlugin);
7556
+ }
7557
+ if (containerPlugin.particleDestroyed) {
7558
+ this.particleDestroyedPlugins.push(containerPlugin);
7559
+ }
7560
+ if (containerPlugin.particlePosition) {
7561
+ this.particlePositionPlugins.push(containerPlugin);
7562
+ }
7563
+ }
7564
+ }
7324
7565
  #nextFrame(timestamp) {
7325
7566
  try {
7326
7567
  if (!this.#smooth &&
@@ -7627,11 +7868,11 @@
7627
7868
  }
7628
7869
  }
7629
7870
  async #init() {
7630
- const availablePathGenerators = await this.#pluginManager.getPathGenerators?.(this.#container, true);
7631
- if (!availablePathGenerators) {
7871
+ const pluginManager = this.#pluginManager;
7872
+ if (!pluginManager.initializers.pathGenerators) {
7632
7873
  return;
7633
7874
  }
7634
- this.availablePathGenerators = availablePathGenerators;
7875
+ this.availablePathGenerators = await getItemMapFromInitializer(this.#container, pluginManager.initializers.pathGenerators);
7635
7876
  this.pathGenerators = new Map();
7636
7877
  for (const pathGenerator of this.pathGenerators.values()) {
7637
7878
  pathGenerator.init();
@@ -7644,55 +7885,6 @@
7644
7885
  MovePluginInstance: MovePluginInstance
7645
7886
  });
7646
7887
 
7647
- class EmittersPluginInstance {
7648
- #container;
7649
- #instancesManager;
7650
- constructor(instancesManager, container) {
7651
- this.#instancesManager = instancesManager;
7652
- this.#container = container;
7653
- this.#instancesManager.initContainer(container);
7654
- }
7655
- async init() {
7656
- const emittersOptions = this.#container.actualOptions.emitters;
7657
- if (isArray(emittersOptions)) {
7658
- for (const emitterOptions of emittersOptions) {
7659
- await this.#instancesManager.addEmitter(this.#container, emitterOptions);
7660
- }
7661
- }
7662
- else {
7663
- await this.#instancesManager.addEmitter(this.#container, emittersOptions);
7664
- }
7665
- }
7666
- pause() {
7667
- for (const emitter of this.#instancesManager.getArray(this.#container)) {
7668
- emitter.pause();
7669
- }
7670
- }
7671
- play() {
7672
- for (const emitter of this.#instancesManager.getArray(this.#container)) {
7673
- emitter.play();
7674
- }
7675
- }
7676
- resize() {
7677
- for (const emitter of this.#instancesManager.getArray(this.#container)) {
7678
- emitter.resize();
7679
- }
7680
- }
7681
- stop() {
7682
- this.#instancesManager.clear(this.#container);
7683
- }
7684
- update(delta) {
7685
- this.#instancesManager.getArray(this.#container).forEach(emitter => {
7686
- emitter.update(delta);
7687
- });
7688
- }
7689
- }
7690
-
7691
- var EmittersPluginInstance$1 = /*#__PURE__*/Object.freeze({
7692
- __proto__: null,
7693
- EmittersPluginInstance: EmittersPluginInstance
7694
- });
7695
-
7696
7888
  const shapeGenerators = new Map();
7697
7889
  class ShapeManager {
7698
7890
  addShapeGenerator(name, generator) {
@@ -7722,14 +7914,21 @@
7722
7914
  this.#pluginManager = pluginManager;
7723
7915
  }
7724
7916
  async addEmitter(container, options, position) {
7725
- const emitterOptions = new Emitter();
7726
- emitterOptions.load(options);
7727
- const { EmitterInstance } = await Promise.resolve().then(function () { return EmitterInstance$1; }), emitter = new EmitterInstance(this.#pluginManager, container, (emitter) => {
7728
- this.removeEmitter(container, emitter);
7729
- }, emitterOptions, position);
7730
- await emitter.init();
7731
- this.getArray(container).push(emitter);
7732
- return emitter;
7917
+ return this.addEmitters(container, [{ options, position }]).then(t => t[defaultIndex]);
7918
+ }
7919
+ async addEmitters(container, emitters) {
7920
+ const { EmitterInstance } = await Promise.resolve().then(function () { return EmitterInstance$1; }), res = [];
7921
+ for (const { options, position } of emitters) {
7922
+ const emitterOptions = new Emitter();
7923
+ emitterOptions.load(options);
7924
+ const emitter = new EmitterInstance(this.#pluginManager, container, (emitter) => {
7925
+ this.removeEmitter(container, emitter);
7926
+ }, emitterOptions, position);
7927
+ await emitter.init();
7928
+ this.getArray(container).push(emitter);
7929
+ res.push(emitter);
7930
+ }
7931
+ return res;
7733
7932
  }
7734
7933
  clear(container) {
7735
7934
  this.initContainer(container);
@@ -7756,6 +7955,7 @@
7756
7955
  : array.find(t => t.name === idxOrName);
7757
7956
  };
7758
7957
  container.addEmitter = async (options, position) => this.addEmitter(container, options, position);
7958
+ container.addEmitters = async (emitters) => this.addEmitters(container, emitters);
7759
7959
  container.removeEmitter = (idxOrName) => {
7760
7960
  const emitter = container.getEmitter?.(idxOrName);
7761
7961
  if (emitter) {
@@ -7776,7 +7976,7 @@
7776
7976
  };
7777
7977
  }
7778
7978
  removeEmitter(container, emitter) {
7779
- const index = this.getArray(container).indexOf(emitter), minIndex = 0, deleteCount = 1;
7979
+ const index = this.getArray(container).indexOf(emitter), deleteCount = 1;
7780
7980
  if (index >= minIndex) {
7781
7981
  this.getArray(container).splice(index, deleteCount);
7782
7982
  }
@@ -8281,6 +8481,7 @@
8281
8481
  #particlesOptions;
8282
8482
  #paused;
8283
8483
  #pluginManager;
8484
+ #positionOverride = false;
8284
8485
  #removeCallback;
8285
8486
  #resizeObserver;
8286
8487
  #shape;
@@ -8357,6 +8558,31 @@
8357
8558
  });
8358
8559
  this.play();
8359
8560
  }
8561
+ draw(context) {
8562
+ if (!this.options.draw || !this.#shape) {
8563
+ return;
8564
+ }
8565
+ const container = this.#container, fillEnabled = this.options.spawn.fill?.enable ?? true;
8566
+ context.save();
8567
+ context.beginPath();
8568
+ if (fillEnabled) {
8569
+ context.fillStyle = this.spawnFillColor
8570
+ ? getStyleFromHsl(this.spawnFillColor, container.hdr, this.spawnFillOpacity ?? defaultOpacity$1, container.peakNits, container.hdrMode)
8571
+ : getStyleFromRgb({ r: 0, g: 0, b: 0 }, container.hdr, defaultOpacity$1, container.peakNits, container.hdrMode);
8572
+ }
8573
+ if (this.spawnStrokeColor) {
8574
+ context.strokeStyle = getStyleFromHsl(this.spawnStrokeColor, container.hdr, this.spawnStrokeOpacity ?? defaultOpacity$1, container.peakNits, container.hdrMode);
8575
+ context.lineWidth = this.spawnStrokeWidth ?? defaultStrokeWidth;
8576
+ }
8577
+ this.#shape.draw?.(context);
8578
+ if (fillEnabled) {
8579
+ context.fill();
8580
+ }
8581
+ if (this.spawnStrokeColor) {
8582
+ context.stroke();
8583
+ }
8584
+ context.restore();
8585
+ }
8360
8586
  externalPause() {
8361
8587
  this.#paused = true;
8362
8588
  this.pause();
@@ -8394,11 +8620,14 @@
8394
8620
  }
8395
8621
  }
8396
8622
  resize() {
8397
- const initialPosition = this.#initialPosition, container = this.#container;
8398
- this.position =
8399
- initialPosition && isPointInside(initialPosition, container.canvas.size, Vector.origin)
8400
- ? initialPosition
8401
- : this.#calcPosition();
8623
+ const container = this.#container;
8624
+ if (!this.#positionOverride) {
8625
+ const initialPosition = this.#initialPosition;
8626
+ this.position =
8627
+ initialPosition && isPointInside(initialPosition, container.canvas.size, Vector.origin)
8628
+ ? initialPosition
8629
+ : this.#calcPosition();
8630
+ }
8402
8631
  this.#size = this.#calcSize();
8403
8632
  this.size =
8404
8633
  this.#size.mode === exports.PixelMode.percent
@@ -8409,6 +8638,11 @@
8409
8638
  : { width: this.#size.width, height: this.#size.height };
8410
8639
  this.#shape?.resize(this.position, this.size);
8411
8640
  }
8641
+ setPosition(position) {
8642
+ this.#positionOverride = true;
8643
+ this.position = { ...position };
8644
+ this.#shape?.resize(this.position, this.size);
8645
+ }
8412
8646
  update(delta) {
8413
8647
  if (this.#paused) {
8414
8648
  return;
@@ -8608,6 +8842,7 @@
8608
8842
  exports.BaseRange = BaseRange;
8609
8843
  exports.Circle = Circle;
8610
8844
  exports.ColorAnimation = ColorAnimation;
8845
+ exports.ErrorCodes = ErrorCodes$2;
8611
8846
  exports.Fill = Fill;
8612
8847
  exports.FullScreen = FullScreen;
8613
8848
  exports.HDROptions = HDROptions;
@@ -8639,6 +8874,7 @@
8639
8874
  exports.Vector = Vector;
8640
8875
  exports.Vector3d = Vector3d;
8641
8876
  exports.ZIndex = ZIndex;
8877
+ exports.addErrorMessages = addErrorMessages;
8642
8878
  exports.alterHsl = alterHsl;
8643
8879
  exports.animate = animate;
8644
8880
  exports.areBoundsInside = areBoundsInside;
@@ -8661,7 +8897,7 @@
8661
8897
  exports.countOffset = countOffset;
8662
8898
  exports.decayOffset = decayOffset;
8663
8899
  exports.deepExtend = deepExtend;
8664
- exports.defaultAlpha = defaultAlpha$1;
8900
+ exports.defaultAlpha = defaultAlpha;
8665
8901
  exports.defaultAngle = defaultAngle;
8666
8902
  exports.defaultCompositeValue = defaultCompositeValue;
8667
8903
  exports.defaultDensityFactor = defaultDensityFactor;
@@ -8686,12 +8922,17 @@
8686
8922
  exports.empty = empty;
8687
8923
  exports.executeOnSingleOrMultiple = executeOnSingleOrMultiple;
8688
8924
  exports.fireworks = fireworks;
8925
+ exports.fullPercent = fullPercent;
8689
8926
  exports.generatedAttribute = generatedAttribute;
8690
8927
  exports.generatedFalse = generatedFalse;
8691
8928
  exports.generatedTrue = generatedTrue;
8929
+ exports.getCanvasFromContainer = getCanvasFromContainer;
8930
+ exports.getDataFromUrl = getDataFromUrl;
8692
8931
  exports.getDistance = getDistance;
8693
8932
  exports.getDistanceSq = getDistanceSq;
8694
8933
  exports.getDistances = getDistances;
8934
+ exports.getDomContainer = getDomContainer;
8935
+ exports.getErrorMessage = getErrorMessage;
8695
8936
  exports.getFullScreenStyle = getFullScreenStyle;
8696
8937
  exports.getHslAnimationFromHsl = getHslAnimationFromHsl;
8697
8938
  exports.getHslFromAnimation = getHslFromAnimation;
@@ -8723,6 +8964,7 @@
8723
8964
  exports.inverseFactorNumerator = inverseFactorNumerator;
8724
8965
  exports.isArray = isArray;
8725
8966
  exports.isBoolean = isBoolean;
8967
+ exports.isEnumValue = isEnumValue;
8726
8968
  exports.isFunction = isFunction;
8727
8969
  exports.isInArray = isInArray;
8728
8970
  exports.isNull = isNull;
@@ -8755,7 +8997,7 @@
8755
8997
  exports.minFpsLimit = minFpsLimit;
8756
8998
  exports.minIndex = minIndex;
8757
8999
  exports.minLimit = minLimit;
8758
- exports.minRadius = minRadius$1;
9000
+ exports.minRadius = minRadius;
8759
9001
  exports.minStrokeWidth = minStrokeWidth;
8760
9002
  exports.minVelocity = minVelocity;
8761
9003
  exports.minZ = minZ;
@@ -8793,6 +9035,7 @@
8793
9035
  exports.stringToAlpha = stringToAlpha;
8794
9036
  exports.stringToRgb = stringToRgb;
8795
9037
  exports.threeQuarter = threeQuarter;
9038
+ exports.toEnumValue = toEnumValue;
8796
9039
  exports.triple = triple;
8797
9040
  exports.tryCountIncrement = tryCountIncrement;
8798
9041
  exports.tsParticles = tsParticles;
@@ -8801,6 +9044,7 @@
8801
9044
  exports.visibilityChangeEvent = visibilityChangeEvent;
8802
9045
  exports.zIndexFactorOffset = zIndexFactorOffset;
8803
9046
 
8804
- }));
9047
+ })(g.__tsParticlesInternals.bundles.fireworks = g.__tsParticlesInternals.bundles.fireworks || {});
9048
+ })(typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : self);
9049
+
8805
9050
  Object.assign(globalThis.window || globalThis, { fireworks: (globalThis.__tsParticlesInternals.bundles.fireworks || {}).fireworks });
8806
- delete (globalThis.window || globalThis).tsparticlesInternalExports;