@tsparticles/preset-hyperspace 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,35 @@
1
- (function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
- /* Preset v4.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.presets = global.__tsParticlesInternals.presets || {}, global.__tsParticlesInternals.presets.hyperspace = global.__tsParticlesInternals.presets.hyperspace || {})));
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", double = 2, doublePI = Math.PI * double, defaultFps = 60, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, spatialHashGridCellSize = 100, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, inverseFactorNumerator = 1, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, minVelocity = 0, minDistance = 0, defaultTransformValue = 1, minimumSize = 0, zIndexFactorOffset = 1, defaultOpacity$1 = 1, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minZ = 0, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, defaultDensityFactor = 1, deleteCount = 1, defaultAngle = 0, identity$1 = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, maxNits = 400, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0, defaultZoom = 1;
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
+ /* Preset v4.5.0 */
4
+ g.__tsParticlesInternals = g.__tsParticlesInternals || {};
5
+ g.__tsParticlesInternals.presets = g.__tsParticlesInternals.presets || {};
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 getLogger() {
31
+ return _logger;
32
+ }
19
33
 
20
34
  var MoveDirection;
21
35
  (function (MoveDirection) {
@@ -32,6 +46,17 @@
32
46
  MoveDirection["inside"] = "inside";
33
47
  })(MoveDirection || (MoveDirection = {}));
34
48
 
49
+ const generatedAttribute = "generated", fullPercent = "100%", defaultCompositeValue = "source-over", resizeEvent = "resize", visibilityChangeEvent = "visibilitychange", percentDenominator = 100, half = 0.5, millisecondsToSeconds = 1000, originPoint = {
50
+ x: 0,
51
+ y: 0,
52
+ z: 0,
53
+ }, defaultTransform = {
54
+ a: 1,
55
+ b: 0,
56
+ c: 0,
57
+ d: 1,
58
+ }, randomColorValue = "random", 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, 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;
59
+
35
60
  function getZ(source) {
36
61
  return "z" in source ? source.z : originPoint.z;
37
62
  }
@@ -147,6 +172,12 @@
147
172
  function isNumber(arg) {
148
173
  return typeof arg === "number";
149
174
  }
175
+ function isEnumValue(enumObject, arg) {
176
+ return Object.values(enumObject).some(enumValue => enumValue === arg);
177
+ }
178
+ function toEnumValue(enumObject, arg, defaultValue) {
179
+ return isEnumValue(enumObject, arg) ? arg : defaultValue;
180
+ }
150
181
  function isObject(arg) {
151
182
  return typeof arg === "object" && arg !== null;
152
183
  }
@@ -283,11 +314,61 @@
283
314
  };
284
315
  }
285
316
  function parseAlpha(input) {
286
- const defaultAlpha = 1;
287
317
  if (!input) {
288
318
  return defaultAlpha;
289
319
  }
290
- return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
320
+ return input.endsWith("%") ? Number.parseFloat(input) / percentDenominator : Number.parseFloat(input);
321
+ }
322
+
323
+ const ErrorCodes$2 = {
324
+ engineVersionMismatch: "TSP-1001",
325
+ particlePositionNotFound: "TSP-1002",
326
+ pluginRegisterAfterLoad: "TSP-1003",
327
+ offscreenCanvasUnsupported: "TSP-1101",
328
+ offscreenCanvasTransferFailed: "TSP-1102",
329
+ hdrEnableInvalid: "TSP-1201",
330
+ hdrModeInvalid: "TSP-1202",
331
+ hdrPeakNitsInvalid: "TSP-1203",
332
+ };
333
+
334
+ const messages = {
335
+ [ErrorCodes$2.engineVersionMismatch]: "The tsParticles version is different from the loaded plugins version. Engine version: {0}. Plugin version: {1}",
336
+ [ErrorCodes$2.particlePositionNotFound]: "a valid position cannot be found for particle",
337
+ [ErrorCodes$2.pluginRegisterAfterLoad]: "Register plugins can only be done before calling tsParticles.load()",
338
+ [ErrorCodes$2.offscreenCanvasUnsupported]: "OffscreenCanvas is required but not supported by this browser",
339
+ [ErrorCodes$2.offscreenCanvasTransferFailed]: "OffscreenCanvas transfer failed",
340
+ [ErrorCodes$2.hdrEnableInvalid]: 'Invalid HDR "enable" value: expected a boolean, got "{0}"',
341
+ [ErrorCodes$2.hdrModeInvalid]: 'Invalid HDR "mode" value: expected one of {0}, got "{1}"',
342
+ [ErrorCodes$2.hdrPeakNitsInvalid]: 'Invalid HDR "peakNits" value: expected a positive number, got "{0}"',
343
+ };
344
+
345
+ let registeredMessages;
346
+ const ensureRegisteredMessages = () => {
347
+ registeredMessages ??= new Map(Object.entries(messages));
348
+ return registeredMessages;
349
+ }, toStringValue$1 = (value) => String(value), format = (template, args) => {
350
+ return template.replace(/\{(\d+)\}/g, (match, index) => {
351
+ const arg = args[Number(index)];
352
+ return arg === undefined ? match : toStringValue$1(arg);
353
+ });
354
+ };
355
+ function addErrorMessages(extraMessages) {
356
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "production") {
357
+ return;
358
+ }
359
+ const catalog = ensureRegisteredMessages();
360
+ for (const [code, message] of Object.entries(extraMessages)) {
361
+ if (message !== undefined) {
362
+ catalog.set(code, message);
363
+ }
364
+ }
365
+ }
366
+ function getErrorMessage(code, ...args) {
367
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "production") {
368
+ return `[tsParticles Error ${code}] https://particles.js.org/errors/#${code}`;
369
+ }
370
+ const template = ensureRegisteredMessages().get(code) ?? `Unknown error code ${code}`;
371
+ return format(template, args);
291
372
  }
292
373
 
293
374
  var OutModeDirection;
@@ -304,7 +385,6 @@
304
385
  PixelMode["percent"] = "percent";
305
386
  })(PixelMode || (PixelMode = {}));
306
387
 
307
- const minRadius = 0;
308
388
  function isForbiddenKey(key) {
309
389
  return key === "__proto__" || key === "constructor" || key === "prototype";
310
390
  }
@@ -500,22 +580,84 @@
500
580
  element.removeEventListener(event, handler, removeOptions);
501
581
  }
502
582
  }
503
- async function getItemsFromInitializer(container, map, initializers, force = false) {
504
- let res = map.get(container);
505
- if (!res || force) {
506
- res = await Promise.all([...initializers.values()].map(t => t(container)));
507
- map.set(container, res);
583
+ async function getItemsFromInitializer(container, initializers) {
584
+ return await Promise.all([...initializers.values()].map(t => t(container)));
585
+ }
586
+ async function getItemMapFromInitializer(container, initializers) {
587
+ const entries = await Promise.all([...initializers.entries()].map(([key, initializer]) => initializer(container).then(item => [key, item])));
588
+ return new Map(entries);
589
+ }
590
+ async function getDataFromUrl(data) {
591
+ const url = itemFromSingleOrMultiple(data.url, data.index);
592
+ if (!url) {
593
+ return data.fallback;
594
+ }
595
+ try {
596
+ const response = await fetch(url);
597
+ if (response.ok) {
598
+ const current = (await response.json());
599
+ if (isSourceOptionsValue(current)) {
600
+ return current;
601
+ }
602
+ getLogger().error("invalid configuration data while retrieving config file");
603
+ }
604
+ else {
605
+ getLogger().error(`${response.status.toString()} while retrieving config file`);
606
+ }
607
+ }
608
+ catch (error) {
609
+ getLogger().error(`error while retrieving config file: ${error}`);
610
+ }
611
+ return data.fallback;
612
+ }
613
+ function isSourceOptionsValue(value) {
614
+ if (isArray(value)) {
615
+ return value.every((entry) => isObject(entry) && !isArray(entry));
508
616
  }
509
- return res;
617
+ return isObject(value) && !isArray(value);
510
618
  }
511
- async function getItemMapFromInitializer(container, map, initializers, force = false) {
512
- let res = map.get(container);
513
- if (!res || force) {
514
- const entries = await Promise.all([...initializers.entries()].map(([key, initializer]) => initializer(container).then(item => [key, item])));
515
- res = new Map(entries);
516
- map.set(container, res);
619
+ function getCanvasFromContainer(domContainer) {
620
+ let canvasEl;
621
+ const documentSafe = safeDocument(), isCanvas = domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag;
622
+ if (isCanvas) {
623
+ canvasEl = domContainer;
624
+ canvasEl.dataset[generatedAttribute] ??= generatedFalse;
625
+ if (canvasEl.dataset[generatedAttribute] === generatedTrue) {
626
+ canvasEl.style.width ||= fullPercent;
627
+ canvasEl.style.height ||= fullPercent;
628
+ canvasEl.style.pointerEvents = "none";
629
+ canvasEl.style.setProperty("pointer-events", "none");
630
+ }
517
631
  }
518
- return res;
632
+ else {
633
+ const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
634
+ if (foundCanvas) {
635
+ canvasEl = foundCanvas;
636
+ canvasEl.dataset[generatedAttribute] = generatedFalse;
637
+ }
638
+ else {
639
+ canvasEl = documentSafe.createElement(canvasTag);
640
+ canvasEl.dataset[generatedAttribute] = generatedTrue;
641
+ domContainer.appendChild(canvasEl);
642
+ }
643
+ canvasEl.style.width ||= fullPercent;
644
+ canvasEl.style.height ||= fullPercent;
645
+ canvasEl.style.pointerEvents = "none";
646
+ canvasEl.style.setProperty("pointer-events", "none");
647
+ }
648
+ return canvasEl;
649
+ }
650
+ function getDomContainer(id, source) {
651
+ const documentSafe = safeDocument();
652
+ let domContainer = source ?? documentSafe.getElementById(id);
653
+ if (domContainer) {
654
+ return domContainer;
655
+ }
656
+ domContainer = documentSafe.createElement("canvas");
657
+ domContainer.id = id;
658
+ domContainer.dataset[generatedAttribute] = generatedTrue;
659
+ documentSafe.body.append(domContainer);
660
+ return domContainer;
519
661
  }
520
662
 
521
663
  class EventDispatcher {
@@ -586,7 +728,6 @@
586
728
  class PluginManager {
587
729
  colorManagers = new Map();
588
730
  easingFunctions = new Map();
589
- effectDrawers = new Map();
590
731
  initializers = {
591
732
  effects: new Map(),
592
733
  shapes: new Map(),
@@ -595,8 +736,6 @@
595
736
  palettes = new Map();
596
737
  plugins = [];
597
738
  presets = new Map();
598
- shapeDrawers = new Map();
599
- updaters = new Map();
600
739
  #allLoadersSet = new Set();
601
740
  #configs = new Map();
602
741
  #engine;
@@ -614,57 +753,79 @@
614
753
  }
615
754
  return res;
616
755
  }
756
+ get initialized() {
757
+ return this.#initialized;
758
+ }
617
759
  addColorManager(name, manager) {
760
+ if (this.#initialized) {
761
+ return;
762
+ }
618
763
  this.colorManagers.set(name, manager);
619
764
  }
620
765
  addConfig(config) {
766
+ if (this.#initialized) {
767
+ return;
768
+ }
621
769
  const key = config.key ?? config.name ?? "default";
622
770
  this.#configs.set(key, config);
623
771
  this.#engine.dispatchEvent(EventType.configAdded, { data: { name: key, config } });
624
772
  }
625
773
  addEasing(name, easing) {
774
+ if (this.#initialized) {
775
+ return;
776
+ }
626
777
  if (this.easingFunctions.get(name)) {
627
778
  return;
628
779
  }
629
780
  this.easingFunctions.set(name, easing);
630
781
  }
631
782
  addEffect(effect, drawer) {
783
+ if (this.#initialized) {
784
+ return;
785
+ }
632
786
  this.initializers.effects.set(effect, drawer);
633
787
  }
634
788
  addPalette(name, palette) {
789
+ if (this.#initialized) {
790
+ return;
791
+ }
635
792
  this.palettes.set(name, palette);
636
793
  }
637
794
  addParticleUpdater(name, updaterInitializer) {
795
+ if (this.#initialized) {
796
+ return;
797
+ }
638
798
  this.initializers.updaters.set(name, updaterInitializer);
639
799
  }
640
800
  addPlugin(plugin) {
801
+ if (this.#initialized) {
802
+ return;
803
+ }
641
804
  if (this.getPlugin(plugin.id)) {
642
805
  return;
643
806
  }
644
807
  this.plugins.push(plugin);
645
808
  }
646
809
  addPreset(preset, options, override = false) {
810
+ if (this.#initialized) {
811
+ return;
812
+ }
647
813
  if (!(override || !this.getPreset(preset))) {
648
814
  return;
649
815
  }
650
816
  this.presets.set(preset, options);
651
817
  }
652
818
  addShape(shapes, drawer) {
819
+ if (this.#initialized) {
820
+ return;
821
+ }
653
822
  for (const shape of shapes) {
654
823
  this.initializers.shapes.set(shape, drawer);
655
824
  }
656
825
  }
657
- clearPlugins(container) {
658
- this.effectDrawers.delete(container);
659
- this.shapeDrawers.delete(container);
660
- this.updaters.delete(container);
661
- }
662
826
  getEasing(name) {
663
827
  return this.easingFunctions.get(name) ?? ((value) => value);
664
828
  }
665
- getEffectDrawers(container, force = false) {
666
- return getItemMapFromInitializer(container, this.effectDrawers, this.initializers.effects, force);
667
- }
668
829
  getPalette(name) {
669
830
  return this.palettes.get(name);
670
831
  }
@@ -674,12 +835,6 @@
674
835
  getPreset(preset) {
675
836
  return this.presets.get(preset);
676
837
  }
677
- async getShapeDrawers(container, force = false) {
678
- return getItemMapFromInitializer(container, this.shapeDrawers, this.initializers.shapes, force);
679
- }
680
- async getUpdaters(container, force = false) {
681
- return getItemsFromInitializer(container, this.updaters, this.initializers.updaters, force);
682
- }
683
838
  async init() {
684
839
  if (this.#initialized || this.#isRunningLoaders) {
685
840
  return;
@@ -698,16 +853,9 @@
698
853
  this.#initialized = true;
699
854
  }
700
855
  }
701
- loadParticlesOptions(container, options, ...sourceOptions) {
702
- const updaters = this.updaters.get(container);
703
- if (!updaters) {
704
- return;
705
- }
706
- updaters.forEach(updater => updater.loadOptions?.(options, ...sourceOptions));
707
- }
708
856
  async register(...loaders) {
709
857
  if (this.#initialized) {
710
- throw new Error("Register plugins can only be done before calling tsParticles.load()");
858
+ throw new Error(getErrorMessage(ErrorCodes$2.pluginRegisterAfterLoad));
711
859
  }
712
860
  for (const loader of loaders) {
713
861
  if (this.#isRunningLoaders) {
@@ -719,88 +867,15 @@
719
867
  }
720
868
  }
721
869
  async #runLoader(loader, executed, allLoaders) {
722
- if (executed.has(loader))
870
+ if (executed.has(loader)) {
723
871
  return;
872
+ }
724
873
  executed.add(loader);
725
874
  allLoaders.add(loader);
726
875
  await loader(this.#engine);
727
876
  }
728
877
  }
729
878
 
730
- const errorPrefix = "tsParticles - Error";
731
- const wrap = (fn) => (...args) => {
732
- fn(...args);
733
- }, _logger = {
734
- debug: wrap(console.debug),
735
- error: (message, ...optionalParams) => {
736
- console.error(`${errorPrefix} - ${message}`, ...optionalParams);
737
- },
738
- info: wrap(console.info),
739
- log: wrap(console.log),
740
- trace: wrap(console.trace),
741
- verbose: wrap(console.log),
742
- warning: wrap(console.warn),
743
- };
744
- function getLogger() {
745
- return _logger;
746
- }
747
-
748
- const fullPercent = "100%";
749
- async function getDataFromUrl(data) {
750
- const url = itemFromSingleOrMultiple(data.url, data.index);
751
- if (!url) {
752
- return data.fallback;
753
- }
754
- const response = await fetch(url);
755
- if (response.ok) {
756
- return (await response.json());
757
- }
758
- getLogger().error(`${response.status.toString()} while retrieving config file`);
759
- return data.fallback;
760
- }
761
- const getCanvasFromContainer = (domContainer) => {
762
- const documentSafe = safeDocument();
763
- let canvasEl;
764
- const isCanvas = domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag;
765
- if (isCanvas) {
766
- canvasEl = domContainer;
767
- canvasEl.dataset[generatedAttribute] ??= generatedFalse;
768
- if (canvasEl.dataset[generatedAttribute] === generatedTrue) {
769
- canvasEl.style.width ||= fullPercent;
770
- canvasEl.style.height ||= fullPercent;
771
- canvasEl.style.pointerEvents = "none";
772
- canvasEl.style.setProperty("pointer-events", "none");
773
- }
774
- }
775
- else {
776
- const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
777
- if (foundCanvas) {
778
- canvasEl = foundCanvas;
779
- canvasEl.dataset[generatedAttribute] = generatedFalse;
780
- }
781
- else {
782
- canvasEl = documentSafe.createElement(canvasTag);
783
- canvasEl.dataset[generatedAttribute] = generatedTrue;
784
- domContainer.appendChild(canvasEl);
785
- }
786
- canvasEl.style.width ||= fullPercent;
787
- canvasEl.style.height ||= fullPercent;
788
- canvasEl.style.pointerEvents = "none";
789
- canvasEl.style.setProperty("pointer-events", "none");
790
- }
791
- return canvasEl;
792
- }, getDomContainer = (id, source) => {
793
- const documentSafe = safeDocument();
794
- let domContainer = source ?? documentSafe.getElementById(id);
795
- if (domContainer) {
796
- return domContainer;
797
- }
798
- domContainer = documentSafe.createElement("canvas");
799
- domContainer.id = id;
800
- domContainer.dataset[generatedAttribute] = generatedTrue;
801
- documentSafe.body.append(domContainer);
802
- return domContainer;
803
- };
804
879
  class Engine {
805
880
  pluginManager = new PluginManager(this);
806
881
  #domArray = [];
@@ -810,7 +885,7 @@
810
885
  return this.#domArray;
811
886
  }
812
887
  get version() {
813
- return "4.4.0";
888
+ return "4.5.0";
814
889
  }
815
890
  addEventListener(type, listener) {
816
891
  this.#eventDispatcher.addEventListener(type, listener);
@@ -819,7 +894,7 @@
819
894
  if (this.version === pluginVersion) {
820
895
  return;
821
896
  }
822
- throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${this.version}. Plugin version: ${pluginVersion}`);
897
+ throw new Error(getErrorMessage(ErrorCodes$2.engineVersionMismatch, this.version, pluginVersion));
823
898
  }
824
899
  dispatchEvent(type, args) {
825
900
  this.#eventDispatcher.dispatchEvent(type, args);
@@ -1068,20 +1143,6 @@
1068
1143
  DrawLayer[DrawLayer["Foreground"] = 7] = "Foreground";
1069
1144
  })(DrawLayer || (DrawLayer = {}));
1070
1145
 
1071
- class OptionLoader {
1072
- load(data) {
1073
- if (isNull(data)) {
1074
- return;
1075
- }
1076
- this.doLoad(data);
1077
- }
1078
- }
1079
- function loadOptions(options, ...sourceOptionsArr) {
1080
- for (const sourceOptions of sourceOptionsArr) {
1081
- options.load(sourceOptions);
1082
- }
1083
- }
1084
-
1085
1146
  function loadProperty(obj, key, value) {
1086
1147
  if (value !== undefined) {
1087
1148
  obj[key] = value;
@@ -1113,6 +1174,20 @@
1113
1174
  }
1114
1175
  }
1115
1176
 
1177
+ class OptionLoader {
1178
+ load(data) {
1179
+ if (isNull(data)) {
1180
+ return;
1181
+ }
1182
+ this.doLoad(data);
1183
+ }
1184
+ }
1185
+ function loadOptions(options, ...sourceOptionsArr) {
1186
+ for (const sourceOptions of sourceOptionsArr) {
1187
+ options.load(sourceOptions);
1188
+ }
1189
+ }
1190
+
1116
1191
  class AnimationOptions extends OptionLoader {
1117
1192
  count = 0;
1118
1193
  decay = 0;
@@ -1263,15 +1338,14 @@
1263
1338
  peakNits = defaultPeakNits;
1264
1339
  doLoad(data) {
1265
1340
  if (data.enable !== undefined && !isBoolean(data.enable)) {
1266
- throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1341
+ throw new Error(getErrorMessage(ErrorCodes$2.hdrEnableInvalid, String(data.enable)));
1267
1342
  }
1268
- if (data.mode !== undefined &&
1269
- (typeof data.mode !== "string" || !Object.values(HdrMode).includes(data.mode))) {
1270
- throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1343
+ if (data.mode !== undefined && !isEnumValue(HdrMode, data.mode)) {
1344
+ throw new Error(getErrorMessage(ErrorCodes$2.hdrModeInvalid, Object.values(HdrMode).join(", "), toStringValue(data.mode)));
1271
1345
  }
1272
1346
  if (data.peakNits !== undefined &&
1273
1347
  (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1274
- throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1348
+ throw new Error(getErrorMessage(ErrorCodes$2.hdrPeakNitsInvalid, String(data.peakNits)));
1275
1349
  }
1276
1350
  loadProperty(this, "enable", data.enable);
1277
1351
  loadProperty(this, "mode", data.mode);
@@ -1649,12 +1723,10 @@
1649
1723
  plugin.loadParticlesOptions(this.#container, this, data);
1650
1724
  }
1651
1725
  }
1652
- const updaters = this.#pluginManager.updaters.get(this.#container);
1653
- if (updaters) {
1654
- for (const updater of updaters) {
1655
- if (updater.loadOptions) {
1656
- updater.loadOptions(this, data);
1657
- }
1726
+ const updaters = this.#container.particleUpdaters;
1727
+ for (const updater of updaters) {
1728
+ if (updater.loadOptions) {
1729
+ updater.loadOptions(this, data);
1658
1730
  }
1659
1731
  }
1660
1732
  }
@@ -1987,9 +2059,9 @@
1987
2059
  const grayscaleValue = Math.round(lNormalized * rgbMax);
1988
2060
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
1989
2061
  }
1990
- const temp1 = lNormalized < half
2062
+ const temp2 = lNormalized < half
1991
2063
  ? lNormalized * (sNormalizedOffset + sNormalized)
1992
- : 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));
2064
+ : 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));
1993
2065
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
1994
2066
  }
1995
2067
  function hslToRgbFloat(hsl) {
@@ -1998,9 +2070,9 @@
1998
2070
  const grayscaleValue = lNormalized * rgbMax;
1999
2071
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
2000
2072
  }
2001
- const temp1 = lNormalized < half
2073
+ const temp2 = lNormalized < half
2002
2074
  ? lNormalized * (sNormalizedOffset + sNormalized)
2003
- : 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));
2075
+ : 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));
2004
2076
  return { r: red, g: green, b: blue };
2005
2077
  }
2006
2078
  function hslaToRgba(hsla) {
@@ -2214,7 +2286,7 @@
2214
2286
  }
2215
2287
 
2216
2288
  async function loadBlendPlugin(engine) {
2217
- engine.checkVersion("4.4.0");
2289
+ engine.checkVersion("4.5.0");
2218
2290
  await engine.pluginManager.register(e => {
2219
2291
  e.pluginManager.addPlugin(new BlendPlugin());
2220
2292
  });
@@ -2251,7 +2323,7 @@
2251
2323
  }
2252
2324
 
2253
2325
  async function loadCircleShape(engine) {
2254
- engine.checkVersion("4.4.0");
2326
+ engine.checkVersion("4.5.0");
2255
2327
  await engine.pluginManager.register(e => {
2256
2328
  e.pluginManager.addShape(["circle"], () => {
2257
2329
  return Promise.resolve(new CircleDrawer());
@@ -2266,7 +2338,7 @@
2266
2338
  RgbIndexes[RgbIndexes["b"] = 3] = "b";
2267
2339
  RgbIndexes[RgbIndexes["a"] = 4] = "a";
2268
2340
  })(RgbIndexes$1 || (RgbIndexes$1 = {}));
2269
- 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;
2341
+ 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;
2270
2342
  class HexColorManager {
2271
2343
  accepts(input) {
2272
2344
  return input.startsWith("#");
@@ -2299,7 +2371,7 @@
2299
2371
  }
2300
2372
 
2301
2373
  async function loadHexColorPlugin(engine) {
2302
- engine.checkVersion("4.4.0");
2374
+ engine.checkVersion("4.5.0");
2303
2375
  await engine.pluginManager.register(e => {
2304
2376
  e.pluginManager.addColorManager("hex", new HexColorManager());
2305
2377
  });
@@ -2339,7 +2411,7 @@
2339
2411
  if (!this.accepts(input)) {
2340
2412
  return;
2341
2413
  }
2342
- const result = hslRegex.exec(input), minLength = 4, defaultAlpha = 1, radix = 10;
2414
+ const result = hslRegex.exec(input), minLength = 4, radix = 10;
2343
2415
  return result
2344
2416
  ? hslaToRgba({
2345
2417
  a: result.length > minLength ? parseAlpha(result[HslIndexes.a]) : defaultAlpha,
@@ -2352,12 +2424,20 @@
2352
2424
  }
2353
2425
 
2354
2426
  async function loadHslColorPlugin(engine) {
2355
- engine.checkVersion("4.4.0");
2427
+ engine.checkVersion("4.5.0");
2356
2428
  await engine.pluginManager.register(e => {
2357
2429
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2358
2430
  });
2359
2431
  }
2360
2432
 
2433
+ const ErrorCodes$1 = {
2434
+ baseMoverNotLoaded: "TSP-3203",
2435
+ };
2436
+
2437
+ const ErrorMessages$1 = {
2438
+ [ErrorCodes$1.baseMoverNotLoaded]: "tsParticles Base Mover is not loaded",
2439
+ };
2440
+
2361
2441
  class MovePlugin {
2362
2442
  id = "move";
2363
2443
  #pluginManager;
@@ -2376,20 +2456,20 @@
2376
2456
  }
2377
2457
 
2378
2458
  async function loadMovePlugin(engine) {
2379
- engine.checkVersion("4.4.0");
2459
+ engine.checkVersion("4.5.0");
2460
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
2461
+ addErrorMessages(ErrorMessages$1);
2462
+ }
2380
2463
  await engine.pluginManager.register(e => {
2381
2464
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2382
2465
  movePluginManager.initializers.pathGenerators ??= new Map();
2383
- movePluginManager.pathGenerators ??= new Map();
2384
2466
  movePluginManager.addPathGenerator = (name, generator) => {
2467
+ if (movePluginManager.initialized) {
2468
+ return;
2469
+ }
2385
2470
  movePluginManager.initializers.pathGenerators ??= new Map();
2386
2471
  movePluginManager.initializers.pathGenerators.set(name, generator);
2387
2472
  };
2388
- movePluginManager.getPathGenerators = async (container, force = false) => {
2389
- movePluginManager.initializers.pathGenerators ??= new Map();
2390
- movePluginManager.pathGenerators ??= new Map();
2391
- return getItemMapFromInitializer(container, movePluginManager.pathGenerators, movePluginManager.initializers.pathGenerators, force);
2392
- };
2393
2473
  e.pluginManager.addPlugin(new MovePlugin(e.pluginManager));
2394
2474
  });
2395
2475
  }
@@ -2586,7 +2666,7 @@
2586
2666
  }
2587
2667
 
2588
2668
  async function loadOpacityUpdater(engine) {
2589
- engine.checkVersion("4.4.0");
2669
+ engine.checkVersion("4.5.0");
2590
2670
  await engine.pluginManager.register(e => {
2591
2671
  e.pluginManager.addParticleUpdater("opacity", container => {
2592
2672
  return Promise.resolve(new OpacityUpdater(container));
@@ -2595,70 +2675,60 @@
2595
2675
  }
2596
2676
 
2597
2677
  const boundsMin = 0;
2598
- function bounceHorizontal(data) {
2599
- if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
2600
- (data.direction !== OutModeDirection.left && data.direction !== OutModeDirection.right)) {
2601
- return;
2602
- }
2603
- if (data.bounds.right < boundsMin && data.direction === OutModeDirection.left) {
2604
- data.particle.position.x = data.size + data.offset.x;
2605
- }
2606
- else if (data.bounds.left > data.canvasSize.width && data.direction === OutModeDirection.right) {
2607
- data.particle.position.x = data.canvasSize.width - data.size - data.offset.x;
2608
- }
2609
- const velocity = data.particle.velocity.x;
2610
- let bounced = false;
2611
- if (data.outOfCanvas &&
2612
- ((data.direction === OutModeDirection.right && velocity > minVelocity) ||
2613
- (data.direction === OutModeDirection.left && velocity < minVelocity))) {
2614
- const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
2615
- data.particle.velocity.x *= -newVelocity;
2616
- bounced = true;
2617
- }
2618
- if (!bounced) {
2619
- return;
2620
- }
2621
- const minPos = data.offset.x + data.size;
2622
- if (data.outOfCanvas && data.direction === OutModeDirection.right) {
2623
- data.particle.position.x = data.canvasSize.width - minPos;
2624
- }
2625
- else if (data.outOfCanvas && data.direction === OutModeDirection.left) {
2626
- data.particle.position.x = minPos;
2627
- }
2628
- if (data.outMode === OutMode.split) {
2629
- data.particle.destroy();
2630
- }
2631
- }
2632
- function bounceVertical(data) {
2633
- if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
2634
- (data.direction !== OutModeDirection.bottom && data.direction !== OutModeDirection.top)) {
2678
+ const bounceAxisConfigs = {
2679
+ [OutModeDirection.left]: {
2680
+ axis: "x",
2681
+ canvas: "width",
2682
+ bounce: "horizontal",
2683
+ negativeEdge: "right",
2684
+ positiveEdge: "left",
2685
+ negative: true,
2686
+ },
2687
+ [OutModeDirection.right]: {
2688
+ axis: "x",
2689
+ canvas: "width",
2690
+ bounce: "horizontal",
2691
+ negativeEdge: "right",
2692
+ positiveEdge: "left",
2693
+ negative: false,
2694
+ },
2695
+ [OutModeDirection.top]: {
2696
+ axis: "y",
2697
+ canvas: "height",
2698
+ bounce: "vertical",
2699
+ negativeEdge: "bottom",
2700
+ positiveEdge: "top",
2701
+ negative: true,
2702
+ },
2703
+ [OutModeDirection.bottom]: {
2704
+ axis: "y",
2705
+ canvas: "height",
2706
+ bounce: "vertical",
2707
+ negativeEdge: "bottom",
2708
+ positiveEdge: "top",
2709
+ negative: false,
2710
+ },
2711
+ };
2712
+ function bounce(data) {
2713
+ if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) || !(data.direction in bounceAxisConfigs)) {
2635
2714
  return;
2636
2715
  }
2637
- if (data.bounds.bottom < boundsMin && data.direction === OutModeDirection.top) {
2638
- data.particle.position.y = data.size + data.offset.y;
2716
+ const config = bounceAxisConfigs[data.direction], bounds = data.bounds, canvasDim = data.canvasSize[config.canvas], position = data.particle.position, velocity = data.particle.velocity[config.axis];
2717
+ if (config.negative && bounds[config.negativeEdge] < boundsMin) {
2718
+ position[config.axis] = data.size + data.offset[config.axis];
2639
2719
  }
2640
- else if (data.bounds.top > data.canvasSize.height && data.direction === OutModeDirection.bottom) {
2641
- data.particle.position.y = data.canvasSize.height - data.size - data.offset.y;
2720
+ else if (!config.negative && bounds[config.positiveEdge] > canvasDim) {
2721
+ position[config.axis] = canvasDim - data.size - data.offset[config.axis];
2642
2722
  }
2643
- const velocity = data.particle.velocity.y;
2644
- let bounced = false;
2645
2723
  if (data.outOfCanvas &&
2646
- ((data.direction === OutModeDirection.bottom && velocity > minVelocity) ||
2647
- (data.direction === OutModeDirection.top && velocity < minVelocity))) {
2648
- const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
2649
- data.particle.velocity.y *= -newVelocity;
2650
- bounced = true;
2724
+ ((config.negative && velocity < minVelocity) || (!config.negative && velocity > minVelocity))) {
2725
+ data.particle.velocity[config.axis] *= -getRangeValue(data.particle.options.bounce[config.bounce].value);
2651
2726
  }
2652
- if (!bounced) {
2727
+ else {
2653
2728
  return;
2654
2729
  }
2655
- const minPos = data.offset.y + data.size;
2656
- if (data.outOfCanvas && data.direction === OutModeDirection.bottom) {
2657
- data.particle.position.y = data.canvasSize.height - minPos;
2658
- }
2659
- else if (data.outOfCanvas && data.direction === OutModeDirection.top) {
2660
- data.particle.position.y = minPos;
2661
- }
2730
+ const minPos = data.offset[config.axis] + data.size;
2731
+ position[config.axis] = config.negative ? minPos : canvasDim - minPos;
2662
2732
  if (data.outMode === OutMode.split) {
2663
2733
  data.particle.destroy();
2664
2734
  }
@@ -2674,26 +2744,19 @@
2674
2744
  OutMode.bounce,
2675
2745
  OutMode.split,
2676
2746
  ];
2677
- this.#particleBouncePlugins = container.plugins.filter(p => p.particleBounce !== undefined);
2747
+ this.#particleBouncePlugins = container.plugins.filter(p => !!p.particleBounce);
2678
2748
  }
2679
2749
  update(particle, direction, delta, outMode) {
2680
2750
  if (!this.modes.includes(outMode)) {
2681
2751
  return;
2682
2752
  }
2683
- const container = this.#container;
2684
- let handled = false;
2685
2753
  for (const plugin of this.#particleBouncePlugins) {
2686
- handled = plugin.particleBounce?.(particle, delta, direction) ?? false;
2687
- if (handled) {
2688
- break;
2754
+ if (plugin.particleBounce?.(particle, delta, direction)) {
2755
+ return;
2689
2756
  }
2690
2757
  }
2691
- if (handled) {
2692
- return;
2693
- }
2694
- const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = container.canvas.size, outOfCanvas = !particle.isInsideCanvasForOutMode(outMode, direction);
2695
- bounceHorizontal({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
2696
- bounceVertical({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
2758
+ const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = this.#container.canvas.size, outOfCanvas = !particle.isInsideCanvasForOutMode(outMode, direction);
2759
+ bounce({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
2697
2760
  }
2698
2761
  }
2699
2762
 
@@ -2782,107 +2845,108 @@
2782
2845
  return;
2783
2846
  }
2784
2847
  const container = this.#container;
2785
- switch (particle.outType) {
2786
- case ParticleOutType.inside: {
2787
- const { x: vx, y: vy } = particle.velocity;
2788
- updateVector.setTo(originPoint);
2789
- updateVector.length = particle.moveCenter.radius;
2790
- updateVector.angle = particle.velocity.angle + Math.PI;
2791
- updateVector.addTo(particle.moveCenter);
2792
- const { dx, dy } = getDistances(particle.position, updateVector);
2793
- if ((vx <= minVelocity && dx >= minDistance) ||
2794
- (vy <= minVelocity && dy >= minDistance) ||
2795
- (vx >= minVelocity && dx <= minDistance) ||
2796
- (vy >= minVelocity && dy <= minDistance)) {
2797
- return;
2798
- }
2799
- particle.position.x = Math.floor(randomInRangeValue({
2800
- min: 0,
2801
- max: container.canvas.size.width,
2802
- }));
2803
- particle.position.y = Math.floor(randomInRangeValue({
2804
- min: 0,
2805
- max: container.canvas.size.height,
2806
- }));
2807
- const { dx: newDx, dy: newDy } = getDistances(particle.position, particle.moveCenter);
2808
- particle.direction = Math.atan2(-newDy, -newDx);
2809
- particle.velocity.angle = particle.direction;
2810
- particle.justWarped = true;
2811
- break;
2848
+ if (particle.outType === ParticleOutType.inside) {
2849
+ this.#applyOutModeInside(particle, container);
2850
+ }
2851
+ else {
2852
+ if (particle.isInsideCanvasForOutMode(outMode, direction)) {
2853
+ return;
2812
2854
  }
2813
- default: {
2814
- if (particle.isInsideCanvasForOutMode(outMode, direction)) {
2815
- return;
2816
- }
2817
- switch (particle.outType) {
2818
- case ParticleOutType.outside: {
2819
- particle.position.x =
2820
- Math.floor(randomInRangeValue({
2821
- min: -particle.moveCenter.radius,
2822
- max: particle.moveCenter.radius,
2823
- })) + particle.moveCenter.x;
2824
- particle.position.y =
2825
- Math.floor(randomInRangeValue({
2826
- min: -particle.moveCenter.radius,
2827
- max: particle.moveCenter.radius,
2828
- })) + particle.moveCenter.y;
2829
- const { dx, dy } = getDistances(particle.position, particle.moveCenter);
2830
- if (particle.moveCenter.radius) {
2831
- particle.direction = Math.atan2(dy, dx);
2832
- particle.velocity.angle = particle.direction;
2833
- }
2834
- particle.justWarped = true;
2835
- break;
2836
- }
2837
- case ParticleOutType.normal: {
2838
- const warp = particle.options.move.warp, canvasSize = container.canvas.size, newPos = {
2839
- bottom: canvasSize.height + particle.getRadius() + particle.offset.y,
2840
- left: -particle.getRadius() - particle.offset.x,
2841
- right: canvasSize.width + particle.getRadius() + particle.offset.x,
2842
- top: -particle.getRadius() - particle.offset.y,
2843
- }, sizeValue = particle.getRadius(), nextBounds = calculateBounds(particle.position, sizeValue);
2844
- if (direction === OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) {
2845
- particle.position.x = newPos.left;
2846
- particle.initialPosition.x = particle.position.x;
2847
- if (!warp) {
2848
- particle.position.y = getRandom() * canvasSize.height;
2849
- particle.initialPosition.y = particle.position.y;
2850
- }
2851
- particle.justWarped = true;
2852
- }
2853
- else if (direction === OutModeDirection.left && nextBounds.right < -particle.offset.x) {
2854
- particle.position.x = newPos.right;
2855
- particle.initialPosition.x = particle.position.x;
2856
- if (!warp) {
2857
- particle.position.y = getRandom() * canvasSize.height;
2858
- particle.initialPosition.y = particle.position.y;
2859
- }
2860
- particle.justWarped = true;
2861
- }
2862
- if (direction === OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) {
2863
- if (!warp) {
2864
- particle.position.x = getRandom() * canvasSize.width;
2865
- particle.initialPosition.x = particle.position.x;
2866
- }
2867
- particle.position.y = newPos.top;
2868
- particle.initialPosition.y = particle.position.y;
2869
- particle.justWarped = true;
2870
- }
2871
- else if (direction === OutModeDirection.top && nextBounds.bottom < -particle.offset.y) {
2872
- if (!warp) {
2873
- particle.position.x = getRandom() * canvasSize.width;
2874
- particle.initialPosition.x = particle.position.x;
2875
- }
2876
- particle.position.y = newPos.bottom;
2877
- particle.initialPosition.y = particle.position.y;
2878
- particle.justWarped = true;
2879
- }
2880
- break;
2881
- }
2882
- }
2883
- break;
2855
+ if (particle.outType === ParticleOutType.outside) {
2856
+ this.#applyParticleModeOutside(particle);
2884
2857
  }
2885
- }
2858
+ else {
2859
+ this.#applyOutModeNormal(particle, container, direction);
2860
+ }
2861
+ }
2862
+ }
2863
+ #applyOutModeInside(particle, container) {
2864
+ const { x: vx, y: vy } = particle.velocity;
2865
+ updateVector.setTo(originPoint);
2866
+ updateVector.length = particle.moveCenter.radius;
2867
+ updateVector.angle = particle.velocity.angle + Math.PI;
2868
+ updateVector.addTo(particle.moveCenter);
2869
+ const { dx, dy } = getDistances(particle.position, updateVector);
2870
+ if ((vx <= minVelocity && dx >= minDistance) ||
2871
+ (vy <= minVelocity && dy >= minDistance) ||
2872
+ (vx >= minVelocity && dx <= minDistance) ||
2873
+ (vy >= minVelocity && dy <= minDistance)) {
2874
+ return;
2875
+ }
2876
+ particle.position.x = Math.floor(randomInRangeValue({
2877
+ min: 0,
2878
+ max: container.canvas.size.width,
2879
+ }));
2880
+ particle.position.y = Math.floor(randomInRangeValue({
2881
+ min: 0,
2882
+ max: container.canvas.size.height,
2883
+ }));
2884
+ const { dx: newDx, dy: newDy } = getDistances(particle.position, particle.moveCenter);
2885
+ particle.direction = Math.atan2(-newDy, -newDx);
2886
+ particle.velocity.angle = particle.direction;
2887
+ particle.justWarped = true;
2888
+ }
2889
+ #applyOutModeNormal(particle, container, direction) {
2890
+ const warp = particle.options.move.warp, canvasSize = container.canvas.size, sizeValue = particle.getRadius(), newPos = {
2891
+ bottom: canvasSize.height + sizeValue + particle.offset.y,
2892
+ left: -sizeValue - particle.offset.x,
2893
+ right: canvasSize.width + sizeValue + particle.offset.x,
2894
+ top: -sizeValue - particle.offset.y,
2895
+ }, nextBounds = calculateBounds(particle.position, sizeValue);
2896
+ if (direction === OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) {
2897
+ particle.position.x = newPos.left;
2898
+ particle.initialPosition.x = particle.position.x;
2899
+ if (!warp) {
2900
+ particle.position.y = getRandom() * canvasSize.height;
2901
+ particle.initialPosition.y = particle.position.y;
2902
+ }
2903
+ particle.justWarped = true;
2904
+ }
2905
+ else if (direction === OutModeDirection.left && nextBounds.right < -particle.offset.x) {
2906
+ particle.position.x = newPos.right;
2907
+ particle.initialPosition.x = particle.position.x;
2908
+ if (!warp) {
2909
+ particle.position.y = getRandom() * canvasSize.height;
2910
+ particle.initialPosition.y = particle.position.y;
2911
+ }
2912
+ particle.justWarped = true;
2913
+ }
2914
+ if (direction === OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) {
2915
+ if (!warp) {
2916
+ particle.position.x = getRandom() * canvasSize.width;
2917
+ particle.initialPosition.x = particle.position.x;
2918
+ }
2919
+ particle.position.y = newPos.top;
2920
+ particle.initialPosition.y = particle.position.y;
2921
+ particle.justWarped = true;
2922
+ }
2923
+ else if (direction === OutModeDirection.top && nextBounds.bottom < -particle.offset.y) {
2924
+ if (!warp) {
2925
+ particle.position.x = getRandom() * canvasSize.width;
2926
+ particle.initialPosition.x = particle.position.x;
2927
+ }
2928
+ particle.position.y = newPos.bottom;
2929
+ particle.initialPosition.y = particle.position.y;
2930
+ particle.justWarped = true;
2931
+ }
2932
+ }
2933
+ #applyParticleModeOutside(particle) {
2934
+ particle.position.x =
2935
+ Math.floor(randomInRangeValue({
2936
+ min: -particle.moveCenter.radius,
2937
+ max: particle.moveCenter.radius,
2938
+ })) + particle.moveCenter.x;
2939
+ particle.position.y =
2940
+ Math.floor(randomInRangeValue({
2941
+ min: -particle.moveCenter.radius,
2942
+ max: particle.moveCenter.radius,
2943
+ })) + particle.moveCenter.y;
2944
+ const { dx, dy } = getDistances(particle.position, particle.moveCenter);
2945
+ if (particle.moveCenter.radius) {
2946
+ particle.direction = Math.atan2(dy, dx);
2947
+ particle.velocity.angle = particle.direction;
2948
+ }
2949
+ particle.justWarped = true;
2886
2950
  }
2887
2951
  }
2888
2952
 
@@ -2931,7 +2995,7 @@
2931
2995
  }
2932
2996
 
2933
2997
  async function loadOutModesUpdater(engine) {
2934
- engine.checkVersion("4.4.0");
2998
+ engine.checkVersion("4.5.0");
2935
2999
  await engine.pluginManager.register(e => {
2936
3000
  e.pluginManager.addParticleUpdater("outModes", container => {
2937
3001
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2948,39 +3012,9 @@
2948
3012
  this.#pluginManager = pluginManager;
2949
3013
  }
2950
3014
  init(particle) {
2951
- 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;
2952
- if (fill) {
2953
- const fillColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), fill.color);
2954
- particle.fillEnabled = fill.enable;
2955
- particle.fillOpacity = getRangeValue(fill.opacity);
2956
- particle.fillAnimation = fillColor.animation;
2957
- const fillHslColor = rangeColorToHsl(this.#pluginManager, fillColor);
2958
- if (fillHslColor) {
2959
- particle.fillColor = getHslAnimationFromHsl(fillHslColor, particle.fillAnimation, container.retina.reduceFactor);
2960
- }
2961
- }
2962
- else {
2963
- particle.fillEnabled = false;
2964
- particle.fillAnimation = undefined;
2965
- particle.fillColor = undefined;
2966
- particle.fillOpacity = defaultOpacity;
2967
- }
2968
- if (stroke) {
2969
- const strokeColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), stroke.color);
2970
- particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
2971
- particle.strokeOpacity = getRangeValue(stroke.opacity ?? defaultOpacity);
2972
- particle.strokeAnimation = strokeColor.animation;
2973
- const strokeHslColor = rangeColorToHsl(this.#pluginManager, strokeColor) ?? particle.getFillColor();
2974
- if (strokeHslColor) {
2975
- particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, particle.strokeAnimation, container.retina.reduceFactor);
2976
- }
2977
- }
2978
- else {
2979
- particle.strokeAnimation = undefined;
2980
- particle.strokeColor = undefined;
2981
- particle.strokeOpacity = defaultOpacity;
2982
- particle.strokeWidth = 0;
2983
- }
3015
+ const container = this.#container, options = particle.options, paint = itemFromSingleOrMultiple(options.paint, particle.id, options.reduceDuplicates);
3016
+ this.#initFill(paint, particle, container);
3017
+ this.#initStroke(paint, particle, container);
2984
3018
  }
2985
3019
  isEnabled(particle) {
2986
3020
  const { fillAnimation, fillColor, strokeAnimation, strokeColor } = particle, fillEnabled = !!fillAnimation &&
@@ -2999,10 +3033,48 @@
2999
3033
  updateColor(particle.fillColor, delta, this.#container.hdr);
3000
3034
  updateColor(particle.strokeColor, delta, this.#container.hdr);
3001
3035
  }
3036
+ #initFill(paint, particle, container) {
3037
+ const fill = paint?.fill, color = paint?.color, paintColor = color ?? undefined;
3038
+ if (!fill) {
3039
+ particle.fillEnabled = false;
3040
+ particle.fillAnimation = undefined;
3041
+ particle.fillColor = undefined;
3042
+ particle.fillOpacity = defaultOpacity;
3043
+ return;
3044
+ }
3045
+ const fillColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), fill.color);
3046
+ particle.fillEnabled = fill.enable;
3047
+ particle.fillOpacity = getRangeValue(fill.opacity);
3048
+ particle.fillAnimation = fillColor.animation;
3049
+ const fillHslColor = rangeColorToHsl(this.#pluginManager, fillColor);
3050
+ if (!fillHslColor) {
3051
+ return;
3052
+ }
3053
+ particle.fillColor = getHslAnimationFromHsl(fillHslColor, particle.fillAnimation, container.retina.reduceFactor);
3054
+ }
3055
+ #initStroke(paint, particle, container) {
3056
+ const stroke = paint?.stroke, color = paint?.color, paintColor = color ?? undefined;
3057
+ if (!stroke) {
3058
+ particle.strokeAnimation = undefined;
3059
+ particle.strokeColor = undefined;
3060
+ particle.strokeOpacity = defaultOpacity;
3061
+ particle.strokeWidth = 0;
3062
+ return;
3063
+ }
3064
+ const strokeColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), stroke.color);
3065
+ particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
3066
+ particle.strokeOpacity = getRangeValue(stroke.opacity ?? defaultOpacity);
3067
+ particle.strokeAnimation = strokeColor.animation;
3068
+ const strokeHslColor = rangeColorToHsl(this.#pluginManager, strokeColor) ?? particle.getFillColor();
3069
+ if (!strokeHslColor) {
3070
+ return;
3071
+ }
3072
+ particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, particle.strokeAnimation, container.retina.reduceFactor);
3073
+ }
3002
3074
  }
3003
3075
 
3004
3076
  async function loadPaintUpdater(engine) {
3005
- engine.checkVersion("4.4.0");
3077
+ engine.checkVersion("4.5.0");
3006
3078
  await engine.pluginManager.register(e => {
3007
3079
  e.pluginManager.addParticleUpdater("paint", container => {
3008
3080
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3044,7 +3116,7 @@
3044
3116
  if (!this.accepts(input)) {
3045
3117
  return;
3046
3118
  }
3047
- const result = rgbRegex.exec(input), radix = 10, minLength = 4, defaultAlpha = 1;
3119
+ const result = rgbRegex.exec(input), radix = 10, minLength = 4;
3048
3120
  return result
3049
3121
  ? {
3050
3122
  a: result.length > minLength ? parseAlpha(result[RgbIndexes.a]) : defaultAlpha,
@@ -3057,7 +3129,7 @@
3057
3129
  }
3058
3130
 
3059
3131
  async function loadRgbColorPlugin(engine) {
3060
- engine.checkVersion("4.4.0");
3132
+ engine.checkVersion("4.5.0");
3061
3133
  await engine.pluginManager.register(e => {
3062
3134
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3063
3135
  });
@@ -3142,7 +3214,7 @@
3142
3214
  }
3143
3215
 
3144
3216
  async function loadSizeUpdater(engine) {
3145
- engine.checkVersion("4.4.0");
3217
+ engine.checkVersion("4.5.0");
3146
3218
  await engine.pluginManager.register(e => {
3147
3219
  e.pluginManager.addParticleUpdater("size", container => {
3148
3220
  return Promise.resolve(new SizeUpdater(container));
@@ -3151,7 +3223,7 @@
3151
3223
  }
3152
3224
 
3153
3225
  async function loadBasic(engine) {
3154
- engine.checkVersion("4.4.0");
3226
+ engine.checkVersion("4.5.0");
3155
3227
  await engine.pluginManager.register(async (e) => {
3156
3228
  await Promise.all([
3157
3229
  loadBlendPlugin(e),
@@ -3260,6 +3332,8 @@
3260
3332
  autoPlay = true;
3261
3333
  direction;
3262
3334
  domId;
3335
+ draggable = false;
3336
+ draw = true;
3263
3337
  fill = true;
3264
3338
  life = new EmitterLife();
3265
3339
  name;
@@ -3283,6 +3357,8 @@
3283
3357
  }
3284
3358
  loadProperty(this, "direction", data.direction);
3285
3359
  loadProperty(this, "domId", data.domId);
3360
+ loadProperty(this, "draggable", data.draggable);
3361
+ loadProperty(this, "draw", data.draw);
3286
3362
  loadProperty(this, "fill", data.fill);
3287
3363
  this.life.load(data.life);
3288
3364
  loadProperty(this, "name", data.name);
@@ -3344,6 +3420,14 @@
3344
3420
  }
3345
3421
  }
3346
3422
 
3423
+ const ErrorCodes = {
3424
+ emittersPluginNotLoaded: "TSP-3101",
3425
+ };
3426
+
3427
+ const ErrorMessages = {
3428
+ [ErrorCodes.emittersPluginNotLoaded]: "tsParticles Emitters Plugin is not loaded",
3429
+ };
3430
+
3347
3431
  async function addEmittersShapesManager(e) {
3348
3432
  const { ShapeManager } = await Promise.resolve().then(function () { return ShapeManager$1; }), pluginManager = e.pluginManager;
3349
3433
  pluginManager.emitterShapeManager ??= new ShapeManager();
@@ -3379,6 +3463,8 @@
3379
3463
  this.fill = fill;
3380
3464
  this.options = options;
3381
3465
  }
3466
+ draw(_context) {
3467
+ }
3382
3468
  resize(position, size) {
3383
3469
  this.position = position;
3384
3470
  this.size = size;
@@ -3391,7 +3477,10 @@
3391
3477
  })(EmitterClickMode || (EmitterClickMode = {}));
3392
3478
 
3393
3479
  async function loadEmittersPluginSimple(engine) {
3394
- engine.checkVersion("4.4.0");
3480
+ engine.checkVersion("4.5.0");
3481
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
3482
+ addErrorMessages(ErrorMessages);
3483
+ }
3395
3484
  await engine.pluginManager.register(async (e) => {
3396
3485
  const instancesManager = await getEmittersInstancesManager(e);
3397
3486
  await addEmittersShapesManager(e);
@@ -3399,9 +3488,63 @@
3399
3488
  });
3400
3489
  }
3401
3490
 
3491
+ class EmittersPluginInstance {
3492
+ #container;
3493
+ #instancesManager;
3494
+ constructor(instancesManager, container) {
3495
+ this.#instancesManager = instancesManager;
3496
+ this.#container = container;
3497
+ this.#instancesManager.initContainer(container);
3498
+ }
3499
+ draw(context, _delta) {
3500
+ for (const emitter of this.#instancesManager.getArray(this.#container)) {
3501
+ emitter.draw(context);
3502
+ }
3503
+ }
3504
+ async init() {
3505
+ const emittersOptions = this.#container.actualOptions.emitters;
3506
+ if (isArray(emittersOptions)) {
3507
+ for (const emitterOptions of emittersOptions) {
3508
+ await this.#instancesManager.addEmitter(this.#container, emitterOptions);
3509
+ }
3510
+ }
3511
+ else {
3512
+ await this.#instancesManager.addEmitter(this.#container, emittersOptions);
3513
+ }
3514
+ }
3515
+ pause() {
3516
+ for (const emitter of this.#instancesManager.getArray(this.#container)) {
3517
+ emitter.pause();
3518
+ }
3519
+ }
3520
+ play() {
3521
+ for (const emitter of this.#instancesManager.getArray(this.#container)) {
3522
+ emitter.play();
3523
+ }
3524
+ }
3525
+ resize() {
3526
+ for (const emitter of this.#instancesManager.getArray(this.#container)) {
3527
+ emitter.resize();
3528
+ }
3529
+ }
3530
+ stop() {
3531
+ this.#instancesManager.clear(this.#container);
3532
+ }
3533
+ update(delta) {
3534
+ this.#instancesManager.getArray(this.#container).forEach(emitter => {
3535
+ emitter.update(delta);
3536
+ });
3537
+ }
3538
+ }
3539
+
3540
+ var EmittersPluginInstance$1 = /*#__PURE__*/Object.freeze({
3541
+ __proto__: null,
3542
+ EmittersPluginInstance: EmittersPluginInstance
3543
+ });
3544
+
3402
3545
  function ensureEmittersPluginLoaded(e) {
3403
3546
  if (!e.pluginManager.addEmitterShapeGenerator) {
3404
- throw new Error("tsParticles Emitters Plugin is not loaded");
3547
+ throw new Error(getErrorMessage(ErrorCodes.emittersPluginNotLoaded));
3405
3548
  }
3406
3549
  }
3407
3550
 
@@ -3417,12 +3560,16 @@
3417
3560
  return position + offset * (getRandom() - half);
3418
3561
  }
3419
3562
  function getRandomSize(sides) {
3420
- return Math.floor(getRandom() * sides);
3563
+ return toEnumValue(Sides, Math.floor(getRandom() * sides), Sides.BottomLeft);
3421
3564
  }
3422
3565
  class EmittersSquareShape extends EmitterShapeBase {
3423
3566
  constructor(position, size, fill, options) {
3424
3567
  super(position, size, fill, options);
3425
3568
  }
3569
+ draw(context) {
3570
+ const position = this.position, size = this.size, halfW = size.width * half, halfH = size.height * half;
3571
+ context.rect(position.x - halfW, position.y - halfH, size.width, size.height);
3572
+ }
3426
3573
  async init() {
3427
3574
  }
3428
3575
  randomPosition() {
@@ -3479,7 +3626,7 @@
3479
3626
  }
3480
3627
 
3481
3628
  async function loadEmittersShapeSquare(engine) {
3482
- engine.checkVersion("4.4.0");
3629
+ engine.checkVersion("4.5.0");
3483
3630
  await engine.pluginManager.register((e) => {
3484
3631
  ensureEmittersPluginLoaded(e);
3485
3632
  e.pluginManager.addEmitterShapeGenerator?.("square", new EmittersSquareShapeGenerator());
@@ -3623,7 +3770,7 @@
3623
3770
  }
3624
3771
 
3625
3772
  async function loadLifeUpdater(engine) {
3626
- engine.checkVersion("4.4.0");
3773
+ engine.checkVersion("4.5.0");
3627
3774
  await engine.pluginManager.register(e => {
3628
3775
  e.pluginManager.addParticleUpdater("life", container => {
3629
3776
  return Promise.resolve(new LifeUpdater(container));
@@ -3687,7 +3834,7 @@
3687
3834
  }
3688
3835
 
3689
3836
  async function loadTrailPlugin(engine) {
3690
- engine.checkVersion("4.4.0");
3837
+ engine.checkVersion("4.5.0");
3691
3838
  await engine.pluginManager.register(e => {
3692
3839
  e.pluginManager.addPlugin(new TrailPlugin(e.pluginManager));
3693
3840
  });
@@ -3839,21 +3986,28 @@
3839
3986
  });
3840
3987
  }
3841
3988
  clear() {
3989
+ const visited = new Set();
3842
3990
  for (const plugin of this.#canvasClearPlugins) {
3991
+ visited.add(plugin);
3843
3992
  if (plugin.canvasClear?.() ?? false) {
3844
- return;
3993
+ return plugin;
3845
3994
  }
3846
3995
  }
3847
3996
  for (const layer of Object.values(DrawLayer)) {
3848
3997
  if (typeof layer === "number") {
3849
3998
  for (const plugin of this.#getLayerPlugins(layer)) {
3999
+ if (visited.has(plugin)) {
4000
+ continue;
4001
+ }
4002
+ visited.add(plugin);
3850
4003
  if (plugin.canvasClear?.() ?? false) {
3851
- return;
4004
+ return plugin;
3852
4005
  }
3853
4006
  }
3854
4007
  }
3855
4008
  }
3856
4009
  this.canvasClear();
4010
+ return undefined;
3857
4011
  }
3858
4012
  destroy() {
3859
4013
  this.stop();
@@ -3931,8 +4085,7 @@
3931
4085
  });
3932
4086
  }
3933
4087
  drawParticles(delta) {
3934
- const { particles, actualOptions } = this.#container;
3935
- this.clear();
4088
+ const { particles, actualOptions } = this.#container, clearedPlugin = this.clear();
3936
4089
  particles.update(delta);
3937
4090
  this.draw(ctx => {
3938
4091
  const width = this.#canvasManager.size.width, height = this.#canvasManager.size.height;
@@ -3954,7 +4107,9 @@
3954
4107
  }
3955
4108
  }
3956
4109
  for (const plugin of this.#getLayerPlugins(DrawLayer.BackgroundMask)) {
3957
- plugin.canvasPaint?.();
4110
+ if (plugin !== clearedPlugin) {
4111
+ plugin.canvasPaint?.();
4112
+ }
3958
4113
  }
3959
4114
  for (const plugin of this.#getLayerPlugins(DrawLayer.CanvasSetup)) {
3960
4115
  plugin.drawSettingsSetup?.(ctx, delta);
@@ -3986,35 +4141,7 @@
3986
4141
  this.#layers[layer] = [];
3987
4142
  }
3988
4143
  }
3989
- for (const plugin of this.#container.plugins) {
3990
- if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
3991
- this.#colorPlugins.push(plugin);
3992
- }
3993
- if (plugin.drawParticle) {
3994
- this.#drawParticlePlugins.push(plugin);
3995
- }
3996
- if (plugin.drawParticleSetup) {
3997
- this.#drawParticlesSetupPlugins.push(plugin);
3998
- }
3999
- if (plugin.drawParticleCleanup) {
4000
- this.#drawParticlesCleanupPlugins.push(plugin);
4001
- }
4002
- if (plugin.canvasClear) {
4003
- this.#canvasClearPlugins.push(plugin);
4004
- }
4005
- if (plugin.canvasPaint) {
4006
- this.#getLayerPlugins(DrawLayer.BackgroundMask).push(plugin);
4007
- }
4008
- if (plugin.drawSettingsSetup) {
4009
- this.#getLayerPlugins(DrawLayer.CanvasSetup).push(plugin);
4010
- }
4011
- if (plugin.draw) {
4012
- this.#getLayerPlugins(DrawLayer.PluginContent).push(plugin);
4013
- }
4014
- if (plugin.clearDraw ?? plugin.drawSettingsCleanup) {
4015
- this.#getLayerPlugins(DrawLayer.CanvasCleanup).push(plugin);
4016
- }
4017
- }
4144
+ this.#initPluginsArray();
4018
4145
  }
4019
4146
  initUpdaters() {
4020
4147
  this.#preDrawUpdaters = [];
@@ -4212,16 +4339,55 @@
4212
4339
  if (!fColor && plugin.particleFillColor) {
4213
4340
  fColor = rangeColorToHsl(this.#pluginManager, plugin.particleFillColor(particle));
4214
4341
  }
4215
- if (!sColor && plugin.particleStrokeColor) {
4216
- sColor = rangeColorToHsl(this.#pluginManager, plugin.particleStrokeColor(particle));
4342
+ if (!sColor && plugin.particleStrokeColor) {
4343
+ sColor = rangeColorToHsl(this.#pluginManager, plugin.particleStrokeColor(particle));
4344
+ }
4345
+ if (fColor && sColor) {
4346
+ break;
4347
+ }
4348
+ }
4349
+ this.#reusablePluginColors[fColorIndex] = fColor;
4350
+ this.#reusablePluginColors[sColorIndex] = sColor;
4351
+ return this.#reusablePluginColors;
4352
+ }
4353
+ #initLayerPlugin(plugin) {
4354
+ const layerMap = [
4355
+ [DrawLayer.BackgroundMask, !!plugin.canvasPaint],
4356
+ [DrawLayer.CanvasSetup, !!plugin.drawSettingsSetup],
4357
+ [DrawLayer.PluginContent, !!plugin.draw],
4358
+ [DrawLayer.CanvasCleanup, !!(plugin.clearDraw ?? plugin.drawSettingsCleanup)],
4359
+ ];
4360
+ for (const [layer, active] of layerMap) {
4361
+ if (active) {
4362
+ this.#layers[layer].push(plugin);
4363
+ }
4364
+ }
4365
+ }
4366
+ #initPluginsArray() {
4367
+ for (const plugin of this.#container.plugins) {
4368
+ if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
4369
+ this.#colorPlugins.push(plugin);
4370
+ }
4371
+ if (plugin.drawParticle) {
4372
+ this.#drawParticlePlugins.push(plugin);
4373
+ }
4374
+ if (plugin.drawParticleSetup) {
4375
+ this.#drawParticlesSetupPlugins.push(plugin);
4376
+ }
4377
+ if (plugin.drawParticleCleanup) {
4378
+ this.#drawParticlesCleanupPlugins.push(plugin);
4217
4379
  }
4218
- if (fColor && sColor) {
4219
- break;
4380
+ if (plugin.canvasClear) {
4381
+ this.#canvasClearPlugins.push(plugin);
4220
4382
  }
4383
+ this.#initLayerPlugin(plugin);
4221
4384
  }
4222
- this.#reusablePluginColors[fColorIndex] = fColor;
4223
- this.#reusablePluginColors[sColorIndex] = sColor;
4224
- return this.#reusablePluginColors;
4385
+ }
4386
+ #isSupportedElement(element) {
4387
+ return ((typeof HTMLCanvasElement !== "undefined" && element instanceof HTMLCanvasElement) ||
4388
+ (typeof OffscreenCanvas !== "undefined" && element instanceof OffscreenCanvas) ||
4389
+ (typeof HTMLVideoElement !== "undefined" && element instanceof HTMLVideoElement) ||
4390
+ (typeof HTMLImageElement !== "undefined" && element instanceof HTMLImageElement));
4225
4391
  }
4226
4392
  #resolveBackgroundElement() {
4227
4393
  const background = this.#container.actualOptions.background;
@@ -4232,9 +4398,7 @@
4232
4398
  if (typeof background.element === "string") {
4233
4399
  if (typeof document !== "undefined") {
4234
4400
  const node = document.querySelector(background.element);
4235
- if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
4236
- (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
4237
- (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
4401
+ if (node && this.#isSupportedElement(node)) {
4238
4402
  this.#backgroundElement = node;
4239
4403
  }
4240
4404
  else if (node) {
@@ -4245,10 +4409,7 @@
4245
4409
  }
4246
4410
  }
4247
4411
  }
4248
- else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
4249
- (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
4250
- (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
4251
- (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
4412
+ else if (this.#isSupportedElement(background.element)) {
4252
4413
  this.#backgroundElement = background.element;
4253
4414
  }
4254
4415
  }
@@ -4266,7 +4427,7 @@
4266
4427
  return transferredCanvas;
4267
4428
  }
4268
4429
  if (typeof canvas.transferControlToOffscreen !== "function") {
4269
- throw new TypeError("OffscreenCanvas is required but not supported by this browser");
4430
+ throw new TypeError(getErrorMessage(ErrorCodes$2.offscreenCanvasUnsupported));
4270
4431
  }
4271
4432
  try {
4272
4433
  const offscreenCanvas = canvas.transferControlToOffscreen();
@@ -4274,10 +4435,16 @@
4274
4435
  return offscreenCanvas;
4275
4436
  }
4276
4437
  catch {
4277
- throw new TypeError("OffscreenCanvas transfer failed");
4438
+ throw new TypeError(getErrorMessage(ErrorCodes$2.offscreenCanvasTransferFailed));
4278
4439
  }
4279
4440
  }, isHtmlCanvasElement = (canvas) => {
4280
4441
  return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
4442
+ }, getEffectiveColorSpace = (context) => {
4443
+ if (!context) {
4444
+ return undefined;
4445
+ }
4446
+ const colorInfo = context;
4447
+ return colorInfo.getContextAttributes?.().colorSpace ?? undefined;
4281
4448
  };
4282
4449
  function setStyle(canvas, style, important = false) {
4283
4450
  if (!style) {
@@ -4402,7 +4569,7 @@
4402
4569
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4403
4570
  if (color) {
4404
4571
  const hdrOptions = container.actualOptions.hdr;
4405
- elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
4572
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, toEnumValue(HdrMode, hdrOptions.mode, HdrMode.standard));
4406
4573
  }
4407
4574
  else {
4408
4575
  elementStyle.backgroundColor = "";
@@ -4522,11 +4689,11 @@
4522
4689
  const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
4523
4690
  safeMatchMedia("(color-gamut: p3)")?.matches &&
4524
4691
  safeMatchMedia("(dynamic-range: high)")?.matches;
4525
- container.hdr = canSupportHdr ?? false;
4526
- container.hdrMode = container.actualOptions.hdr.mode;
4692
+ container.hdrMode = toEnumValue(HdrMode, container.actualOptions.hdr.mode, HdrMode.standard);
4527
4693
  container.peakNits = container.actualOptions.hdr.peakNits;
4528
4694
  const renderCanvas = this.renderCanvas;
4529
4695
  if (!renderCanvas) {
4696
+ container.hdr = canSupportHdr ?? false;
4530
4697
  return;
4531
4698
  }
4532
4699
  this.render.setContextSettings({
@@ -4545,7 +4712,6 @@
4545
4712
  context = null;
4546
4713
  }
4547
4714
  if (canSupportHdr && !context) {
4548
- container.hdr = false;
4549
4715
  const sdrSettings = {
4550
4716
  alpha: true,
4551
4717
  desynchronized: true,
@@ -4561,11 +4727,16 @@
4561
4727
  }
4562
4728
  }
4563
4729
  this.render.setContext(context);
4730
+ if (context) {
4731
+ const effectiveColorSpace = getEffectiveColorSpace(context);
4732
+ if (effectiveColorSpace !== undefined) {
4733
+ container.hdr = effectiveColorSpace === "display-p3";
4734
+ }
4735
+ }
4564
4736
  }
4565
4737
  #initHdrListeners() {
4566
4738
  this.#removeHdrListeners();
4567
4739
  const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
4568
- this.#recreateRenderCanvas();
4569
4740
  this.#initContext();
4570
4741
  this.initBackground();
4571
4742
  }, listeners = [];
@@ -4601,16 +4772,6 @@
4601
4772
  element.style.setProperty(key, value, "important");
4602
4773
  }
4603
4774
  }
4604
- #recreateRenderCanvas() {
4605
- const renderCanvas = this.renderCanvas;
4606
- if (!renderCanvas) {
4607
- return;
4608
- }
4609
- if (this.domElement) {
4610
- return;
4611
- }
4612
- this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
4613
- }
4614
4775
  #removeHdrListeners() {
4615
4776
  if (!this.#hdrMediaListeners) {
4616
4777
  return;
@@ -4709,8 +4870,7 @@
4709
4870
  this.#resizeTimeout = undefined;
4710
4871
  }
4711
4872
  const handleResize = async () => {
4712
- const canvas = this.#container.canvas;
4713
- await canvas.windowResize();
4873
+ await this.#container.canvas.windowResize();
4714
4874
  };
4715
4875
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
4716
4876
  }
@@ -4738,8 +4898,8 @@
4738
4898
  }
4739
4899
  else if (!this.#resizeObserver && add && canvasEl) {
4740
4900
  this.#resizeObserver = new ResizeObserver((entries) => {
4741
- const entry = entries.find(e => e.target === canvasEl);
4742
- if (!entry) {
4901
+ const res = entries.some(e => e.target === canvasEl);
4902
+ if (!res) {
4743
4903
  return;
4744
4904
  }
4745
4905
  this.#handleWindowResize();
@@ -5003,10 +5163,10 @@
5003
5163
  return this.#modifiers.find(m => m.id === id);
5004
5164
  }
5005
5165
  getOpacity() {
5006
- 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;
5007
- this.#cachedOpacityData.fillOpacity = fillOpacity;
5166
+ 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;
5167
+ this.#cachedOpacityData.fillOpacity = this.fillOpacity ?? defaultOpacity$1;
5008
5168
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
5009
- this.#cachedOpacityData.strokeOpacity = strokeOpacity;
5169
+ this.#cachedOpacityData.strokeOpacity = this.strokeOpacity ?? defaultOpacity$1;
5010
5170
  return this.#cachedOpacityData;
5011
5171
  }
5012
5172
  getPosition() {
@@ -5253,7 +5413,7 @@
5253
5413
  #initPosition(position) {
5254
5414
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
5255
5415
  if (!initialPosition) {
5256
- throw new Error("a valid position cannot be found for particle");
5416
+ throw new Error(getErrorMessage(ErrorCodes$2.particlePositionNotFound));
5257
5417
  }
5258
5418
  this.position = initialPosition;
5259
5419
  this.initialPosition = this.position.copy();
@@ -5302,6 +5462,12 @@
5302
5462
  this.#circlePoolIdx = 0;
5303
5463
  this.#rectanglePoolIdx = 0;
5304
5464
  }
5465
+ get cellSize() {
5466
+ return this.#cellSize;
5467
+ }
5468
+ set cellSize(value) {
5469
+ this.#pendingCellSize = value;
5470
+ }
5305
5471
  clear() {
5306
5472
  this.#cells.clear();
5307
5473
  const pendingCellSize = this.#pendingCellSize;
@@ -5325,18 +5491,7 @@
5325
5491
  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);
5326
5492
  for (let cx = minCellX; cx <= maxCellX; cx++) {
5327
5493
  for (let cy = minCellY; cy <= maxCellY; cy++) {
5328
- const key = `${cx}_${cy}`, cellParticles = this.#cells.get(key);
5329
- if (!cellParticles) {
5330
- continue;
5331
- }
5332
- for (const p of cellParticles) {
5333
- if (check && !check(p)) {
5334
- continue;
5335
- }
5336
- if (range.contains(p.getPosition())) {
5337
- out.push(p);
5338
- }
5339
- }
5494
+ this.#queryCell(cx, cy, range, check, out);
5340
5495
  }
5341
5496
  }
5342
5497
  return out;
@@ -5351,14 +5506,23 @@
5351
5506
  this.#releaseShapes();
5352
5507
  return result;
5353
5508
  }
5354
- setCellSize(cellSize) {
5355
- this.#pendingCellSize = cellSize;
5356
- }
5357
5509
  #acquireCircle(x, y, r) {
5358
- return (this.#circlePool[this.#circlePoolIdx++] ??= new Circle(x, y, r)).reset(x, y, r);
5510
+ const idx = this.#circlePoolIdx++;
5511
+ let circle = this.#circlePool[idx];
5512
+ if (!circle) {
5513
+ circle = new Circle(x, y, r);
5514
+ this.#circlePool[idx] = circle;
5515
+ }
5516
+ return circle.reset(x, y, r);
5359
5517
  }
5360
5518
  #acquireRectangle(x, y, w, h) {
5361
- return (this.#rectanglePool[this.#rectanglePoolIdx++] ??= new Rectangle(x, y, w, h)).reset(x, y, w, h);
5519
+ const idx = this.#rectanglePoolIdx++;
5520
+ let rectangle = this.#rectanglePool[idx];
5521
+ if (!rectangle) {
5522
+ rectangle = new Rectangle(x, y, w, h);
5523
+ this.#rectanglePool[idx] = rectangle;
5524
+ }
5525
+ return rectangle.reset(x, y, w, h);
5362
5526
  }
5363
5527
  #cellKeyFromCoords(x, y) {
5364
5528
  const cellX = Math.floor(x / this.#cellSize), cellY = Math.floor(y / this.#cellSize);
@@ -5385,6 +5549,20 @@
5385
5549
  }
5386
5550
  return null;
5387
5551
  }
5552
+ #queryCell(cx, cy, range, check, out) {
5553
+ const cellParticles = this.#cells.get(`${cx}_${cy}`);
5554
+ if (!cellParticles) {
5555
+ return;
5556
+ }
5557
+ for (const p of cellParticles) {
5558
+ if (check && !check(p)) {
5559
+ continue;
5560
+ }
5561
+ if (range.contains(p.getPosition())) {
5562
+ out.push(p);
5563
+ }
5564
+ }
5565
+ }
5388
5566
  #releaseShapes() {
5389
5567
  this.#circlePoolIdx = 0;
5390
5568
  this.#rectanglePoolIdx = 0;
@@ -5393,9 +5571,9 @@
5393
5571
 
5394
5572
  class ParticlesManager {
5395
5573
  checkParticlePositionPlugins;
5396
- grid;
5397
5574
  #array;
5398
5575
  #container;
5576
+ #grid;
5399
5577
  #groupLimits;
5400
5578
  #limit;
5401
5579
  #nextId;
@@ -5419,7 +5597,7 @@
5419
5597
  this.#groupLimits = new Map();
5420
5598
  this.#particleBuckets = new Map();
5421
5599
  this.#zBuckets = this.#createBuckets(this.#container.zLayers);
5422
- this.grid = new SpatialHashGrid(spatialHashGridCellSize);
5600
+ this.#grid = new SpatialHashGrid(spatialHashGridCellSize);
5423
5601
  this.checkParticlePositionPlugins = [];
5424
5602
  this.#particleResetPlugins = [];
5425
5603
  this.#particleUpdatePlugins = [];
@@ -5430,23 +5608,12 @@
5430
5608
  get count() {
5431
5609
  return this.#array.length;
5432
5610
  }
5611
+ get grid() {
5612
+ return this.#grid;
5613
+ }
5433
5614
  addParticle(position, overrideOptions, group, initializer) {
5434
- const limitMode = this.#container.actualOptions.particles.number.limit.mode, limit = group === undefined ? this.#limit : (this.#groupLimits.get(group) ?? this.#limit), currentCount = this.count;
5435
- if (limit > minLimit) {
5436
- switch (limitMode) {
5437
- case LimitMode.delete: {
5438
- const countToRemove = currentCount + countOffset - limit;
5439
- if (countToRemove > minCount) {
5440
- this.removeQuantity(countToRemove);
5441
- }
5442
- break;
5443
- }
5444
- case LimitMode.wait:
5445
- if (currentCount >= limit) {
5446
- return;
5447
- }
5448
- break;
5449
- }
5615
+ if (this.#checkAndApplyLimits(group, this.count)) {
5616
+ return;
5450
5617
  }
5451
5618
  try {
5452
5619
  const particle = this.#pool.pop() ?? new Particle(this.#pluginManager, this.#container);
@@ -5510,7 +5677,7 @@
5510
5677
  return this.#array[index];
5511
5678
  }
5512
5679
  async init() {
5513
- const container = this.#container, options = container.actualOptions;
5680
+ const container = this.#container;
5514
5681
  this.checkParticlePositionPlugins = [];
5515
5682
  this.#updatePlugins = [];
5516
5683
  this.#particleUpdatePlugins = [];
@@ -5519,59 +5686,16 @@
5519
5686
  this.#postParticleUpdatePlugins = [];
5520
5687
  this.#particleBuckets.clear();
5521
5688
  this.#resetBuckets(container.zLayers);
5522
- this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
5523
- for (const plugin of container.plugins) {
5524
- if (plugin.redrawInit) {
5525
- await plugin.redrawInit();
5526
- }
5527
- if (plugin.checkParticlePosition) {
5528
- this.checkParticlePositionPlugins.push(plugin);
5529
- }
5530
- if (plugin.update) {
5531
- this.#updatePlugins.push(plugin);
5532
- }
5533
- if (plugin.particleUpdate) {
5534
- this.#particleUpdatePlugins.push(plugin);
5535
- }
5536
- if (plugin.postUpdate) {
5537
- this.#postUpdatePlugins.push(plugin);
5538
- }
5539
- if (plugin.particleReset) {
5540
- this.#particleResetPlugins.push(plugin);
5541
- }
5542
- if (plugin.postParticleUpdate) {
5543
- this.#postParticleUpdatePlugins.push(plugin);
5544
- }
5545
- }
5546
- await this.#container.initDrawersAndUpdaters();
5547
- for (const drawer of this.#container.effectDrawers.values()) {
5548
- await drawer.init?.(container);
5549
- }
5550
- for (const drawer of this.#container.shapeDrawers.values()) {
5551
- await drawer.init?.(container);
5552
- }
5553
- let handled = false;
5554
- for (const plugin of container.plugins) {
5555
- handled = plugin.particlesInitialization?.() ?? handled;
5556
- if (handled) {
5557
- break;
5558
- }
5559
- }
5560
- if (!handled) {
5561
- const particlesOptions = options.particles, groups = particlesOptions.groups;
5562
- for (const group in groups) {
5563
- const groupOptions = groups[group];
5564
- if (!groupOptions) {
5565
- continue;
5566
- }
5567
- for (let i = this.count, j = 0; j < groupOptions.number.value && i < particlesOptions.number.value; i++, j++) {
5568
- this.addParticle(undefined, groupOptions, group);
5569
- }
5570
- }
5571
- for (let i = this.count; i < particlesOptions.number.value; i++) {
5572
- this.addParticle();
5689
+ this.#grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
5690
+ this.#applyLimits(container.actualOptions.particles);
5691
+ const particlesOptions = container.actualOptions.particles, groups = particlesOptions.groups;
5692
+ for (const group in groups) {
5693
+ const groupData = groups[group];
5694
+ if (groupData) {
5695
+ this.#applyLimits(loadParticlesOptions(this.#pluginManager, this.#container, groupData), group, groupData);
5573
5696
  }
5574
5697
  }
5698
+ await this.#initPlugins();
5575
5699
  }
5576
5700
  push(nb, position, overrideOptions, group) {
5577
5701
  for (let i = 0; i < nb; i++) {
@@ -5586,13 +5710,13 @@
5586
5710
  remove(particle, group, override) {
5587
5711
  this.removeAt(this.#array.indexOf(particle), undefined, group, override);
5588
5712
  }
5589
- removeAt(index, quantity = defaultRemoveQuantity, group, override) {
5713
+ removeAt(index, quantity = defaultRemoveQuantity, group, override, matchGroup = true) {
5590
5714
  if (index < minIndex || index > this.count) {
5591
5715
  return;
5592
5716
  }
5593
5717
  let deleted = 0;
5594
5718
  for (let i = index; deleted < quantity && i < this.count; i++) {
5595
- if (this.#removeParticle(i, group, override)) {
5719
+ if (this.#removeParticle(i, group, override, matchGroup)) {
5596
5720
  i--;
5597
5721
  deleted++;
5598
5722
  }
@@ -5623,7 +5747,7 @@
5623
5747
  this.#resizeFactor = factor;
5624
5748
  }
5625
5749
  update(delta) {
5626
- this.grid.clear();
5750
+ this.#grid.clear();
5627
5751
  for (const plugin of this.#updatePlugins) {
5628
5752
  plugin.update?.(delta);
5629
5753
  }
@@ -5634,7 +5758,7 @@
5634
5758
  this.#updateParticlesPhase2(delta, particlesToDelete);
5635
5759
  if (particlesToDelete.size) {
5636
5760
  for (const particle of particlesToDelete) {
5637
- this.remove(particle);
5761
+ this.remove(particle, particle.group);
5638
5762
  }
5639
5763
  }
5640
5764
  this.#resizeFactor = undefined;
@@ -5645,12 +5769,7 @@
5645
5769
  #applyDensity(options, pluginsCount, group, groupOptions) {
5646
5770
  const numberOptions = options.number;
5647
5771
  if (!numberOptions.density.enable) {
5648
- if (group === undefined) {
5649
- this.#limit = numberOptions.limit.value;
5650
- }
5651
- else if (groupOptions?.number.limit.value ?? numberOptions.limit.value) {
5652
- this.#groupLimits.set(group, groupOptions?.number.limit.value ?? numberOptions.limit.value);
5653
- }
5772
+ this.#applyLimits(options, group, groupOptions);
5654
5773
  return;
5655
5774
  }
5656
5775
  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);
@@ -5658,7 +5777,10 @@
5658
5777
  this.#limit = numberOptions.limit.value * densityFactor;
5659
5778
  }
5660
5779
  else {
5661
- this.#groupLimits.set(group, numberOptions.limit.value * densityFactor);
5780
+ this.#groupLimits.set(group, {
5781
+ limit: numberOptions.limit.value * densityFactor,
5782
+ mode: toEnumValue(LimitMode, numberOptions.limit.mode, LimitMode.delete),
5783
+ });
5662
5784
  }
5663
5785
  if (particlesCount < particlesNumber) {
5664
5786
  this.push(Math.abs(particlesNumber - particlesCount), undefined, options, group);
@@ -5667,6 +5789,55 @@
5667
5789
  this.removeQuantity(particlesCount - particlesNumber, group);
5668
5790
  }
5669
5791
  }
5792
+ #applyLimits(options, group, groupOptions) {
5793
+ if (group === undefined) {
5794
+ this.#limit = options.number.limit.value;
5795
+ const groups = this.#container.actualOptions.particles.groups;
5796
+ for (const existingGroup of this.#groupLimits.keys()) {
5797
+ if (!(existingGroup in groups)) {
5798
+ this.#groupLimits.delete(existingGroup);
5799
+ }
5800
+ }
5801
+ }
5802
+ else {
5803
+ const limitValue = groupOptions?.number?.limit?.value ?? options.number.limit.value;
5804
+ if (limitValue > minLimit) {
5805
+ this.#groupLimits.set(group, {
5806
+ limit: limitValue,
5807
+ mode: toEnumValue(LimitMode, groupOptions?.number?.limit?.mode ?? options.number.limit.mode, LimitMode.delete),
5808
+ });
5809
+ }
5810
+ else {
5811
+ this.#groupLimits.delete(group);
5812
+ }
5813
+ }
5814
+ }
5815
+ #checkAndApplyLimits(group, currentCount) {
5816
+ const globalLimit = this.#limit, globalMode = this.#container.actualOptions.particles.number.limit.mode;
5817
+ if (globalLimit > minLimit && globalMode === LimitMode.wait && currentCount >= globalLimit) {
5818
+ return true;
5819
+ }
5820
+ const groupLimitEntry = group === undefined ? undefined : this.#groupLimits.get(group);
5821
+ if (groupLimitEntry && groupLimitEntry.limit > minLimit && groupLimitEntry.mode === LimitMode.wait) {
5822
+ const groupCount = this.filter(t => t.group === group).length;
5823
+ if (groupCount >= groupLimitEntry.limit) {
5824
+ return true;
5825
+ }
5826
+ }
5827
+ if (groupLimitEntry && groupLimitEntry.limit > minLimit && groupLimitEntry.mode === LimitMode.delete) {
5828
+ const groupCountToRemove = this.filter(t => t.group === group).length + countOffset - groupLimitEntry.limit;
5829
+ if (groupCountToRemove > minCount) {
5830
+ this.removeQuantity(groupCountToRemove, group);
5831
+ }
5832
+ }
5833
+ if (globalLimit > minLimit && globalMode === LimitMode.delete) {
5834
+ const globalCountToRemove = this.count + countOffset - globalLimit;
5835
+ if (globalCountToRemove > minCount) {
5836
+ this.#removeAny(globalCountToRemove);
5837
+ }
5838
+ }
5839
+ return false;
5840
+ }
5670
5841
  #createBuckets(zLayers) {
5671
5842
  const bucketCount = Math.max(Math.floor(zLayers), one);
5672
5843
  return Array.from({ length: bucketCount }, () => []);
@@ -5689,6 +5860,70 @@
5689
5860
  }
5690
5861
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
5691
5862
  }
5863
+ async #initDrawersAndUpdaters() {
5864
+ const container = this.#container;
5865
+ await container.initDrawersAndUpdaters();
5866
+ for (const drawer of container.effectDrawers.values()) {
5867
+ await drawer.init?.(container);
5868
+ }
5869
+ for (const drawer of container.shapeDrawers.values()) {
5870
+ await drawer.init?.(container);
5871
+ }
5872
+ }
5873
+ async #initPlugins() {
5874
+ await this.#initPluginsArrays();
5875
+ await this.#initDrawersAndUpdaters();
5876
+ let handled = false;
5877
+ const container = this.#container;
5878
+ for (const plugin of container.plugins) {
5879
+ handled = plugin.particlesInitialization?.() ?? handled;
5880
+ if (handled) {
5881
+ break;
5882
+ }
5883
+ }
5884
+ if (handled) {
5885
+ return;
5886
+ }
5887
+ const particlesOptions = container.actualOptions.particles, groups = particlesOptions.groups;
5888
+ for (const group in groups) {
5889
+ const groupOptions = groups[group];
5890
+ if (!groupOptions) {
5891
+ continue;
5892
+ }
5893
+ for (let i = this.count, j = 0; j < groupOptions.number.value && i < particlesOptions.number.value; i++, j++) {
5894
+ this.addParticle(undefined, groupOptions, group);
5895
+ }
5896
+ }
5897
+ for (let i = this.count; i < particlesOptions.number.value; i++) {
5898
+ this.addParticle();
5899
+ }
5900
+ }
5901
+ async #initPluginsArrays() {
5902
+ const container = this.#container;
5903
+ for (const plugin of container.plugins) {
5904
+ if (plugin.redrawInit) {
5905
+ await plugin.redrawInit();
5906
+ }
5907
+ if (plugin.checkParticlePosition) {
5908
+ this.checkParticlePositionPlugins.push(plugin);
5909
+ }
5910
+ if (plugin.update) {
5911
+ this.#updatePlugins.push(plugin);
5912
+ }
5913
+ if (plugin.particleUpdate) {
5914
+ this.#particleUpdatePlugins.push(plugin);
5915
+ }
5916
+ if (plugin.postUpdate) {
5917
+ this.#postUpdatePlugins.push(plugin);
5918
+ }
5919
+ if (plugin.particleReset) {
5920
+ this.#particleResetPlugins.push(plugin);
5921
+ }
5922
+ if (plugin.postParticleUpdate) {
5923
+ this.#postParticleUpdatePlugins.push(plugin);
5924
+ }
5925
+ }
5926
+ }
5692
5927
  #insertParticleIntoBucket(particle) {
5693
5928
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
5694
5929
  if (!bucket) {
@@ -5697,12 +5932,15 @@
5697
5932
  bucket.push(particle);
5698
5933
  this.#particleBuckets.set(particle.id, bucketIndex);
5699
5934
  }
5700
- #removeParticle(index, group, override) {
5935
+ #removeAny(quantity) {
5936
+ this.removeAt(minIndex, quantity, undefined, undefined, false);
5937
+ }
5938
+ #removeParticle(index, group, override, matchGroup = true) {
5701
5939
  const particle = this.#array[index];
5702
5940
  if (!particle) {
5703
5941
  return false;
5704
5942
  }
5705
- if (particle.group !== group) {
5943
+ if (matchGroup && particle.group !== group) {
5706
5944
  return false;
5707
5945
  }
5708
5946
  this.#array.splice(index, deleteCount);
@@ -5789,7 +6027,7 @@
5789
6027
  particlesToDelete.add(particle);
5790
6028
  continue;
5791
6029
  }
5792
- this.grid.insert(particle);
6030
+ this.#grid.insert(particle);
5793
6031
  }
5794
6032
  return particlesToDelete;
5795
6033
  }
@@ -5965,7 +6203,6 @@
5965
6203
  this.shapeDrawers = new Map();
5966
6204
  this.particleUpdaters = [];
5967
6205
  this.plugins.length = 0;
5968
- this.#pluginManager.clearPlugins(this);
5969
6206
  this.destroyed = true;
5970
6207
  this.#onDestroy(remove);
5971
6208
  this.dispatchEvent(EventType.containerDestroyed);
@@ -6018,31 +6255,14 @@
6018
6255
  await this.initDrawersAndUpdaters();
6019
6256
  this.#options = loadContainerOptions(this.#pluginManager, this, this.#initialSourceOptions, this.sourceOptions);
6020
6257
  this.actualOptions = loadContainerOptions(this.#pluginManager, this, this.#options);
6021
- this.plugins.length = 0;
6022
- this.particleDestroyedPlugins.length = 0;
6023
- this.particleCreatedPlugins.length = 0;
6024
- this.particlePositionPlugins.length = 0;
6025
- for (const [plugin, containerPlugin] of allContainerPlugins) {
6026
- if (plugin.needsPlugin(this.actualOptions)) {
6027
- this.plugins.push(containerPlugin);
6028
- if (containerPlugin.particleCreated) {
6029
- this.particleCreatedPlugins.push(containerPlugin);
6030
- }
6031
- if (containerPlugin.particleDestroyed) {
6032
- this.particleDestroyedPlugins.push(containerPlugin);
6033
- }
6034
- if (containerPlugin.particlePosition) {
6035
- this.particlePositionPlugins.push(containerPlugin);
6036
- }
6037
- }
6038
- }
6258
+ this.#initPlugins(allContainerPlugins);
6039
6259
  this.retina.init();
6040
6260
  this.canvas.init();
6041
6261
  this.updateActualOptions();
6042
6262
  this.canvas.initBackground();
6043
6263
  this.canvas.resize();
6044
6264
  const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
6045
- this.hdrMode = hdrOptions.mode;
6265
+ this.hdrMode = toEnumValue(HdrMode, hdrOptions.mode, HdrMode.standard);
6046
6266
  this.peakNits = hdrOptions.peakNits;
6047
6267
  this.zLayers = zLayers;
6048
6268
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
@@ -6063,9 +6283,9 @@
6063
6283
  }
6064
6284
  async initDrawersAndUpdaters() {
6065
6285
  const pluginManager = this.#pluginManager;
6066
- this.effectDrawers = await pluginManager.getEffectDrawers(this, true);
6067
- this.shapeDrawers = await pluginManager.getShapeDrawers(this, true);
6068
- this.particleUpdaters = await pluginManager.getUpdaters(this, true);
6286
+ this.effectDrawers = await getItemMapFromInitializer(this, pluginManager.initializers.effects);
6287
+ this.shapeDrawers = await getItemMapFromInitializer(this, pluginManager.initializers.shapes);
6288
+ this.particleUpdaters = await getItemsFromInitializer(this, pluginManager.initializers.updaters);
6069
6289
  }
6070
6290
  pause() {
6071
6291
  if (!guardCheck(this)) {
@@ -6176,6 +6396,27 @@
6176
6396
  }
6177
6397
  return refresh;
6178
6398
  }
6399
+ #initPlugins(allContainerPlugins) {
6400
+ this.plugins.length = 0;
6401
+ this.particleDestroyedPlugins.length = 0;
6402
+ this.particleCreatedPlugins.length = 0;
6403
+ this.particlePositionPlugins.length = 0;
6404
+ for (const [plugin, containerPlugin] of allContainerPlugins) {
6405
+ if (!plugin.needsPlugin(this.actualOptions)) {
6406
+ continue;
6407
+ }
6408
+ this.plugins.push(containerPlugin);
6409
+ if (containerPlugin.particleCreated) {
6410
+ this.particleCreatedPlugins.push(containerPlugin);
6411
+ }
6412
+ if (containerPlugin.particleDestroyed) {
6413
+ this.particleDestroyedPlugins.push(containerPlugin);
6414
+ }
6415
+ if (containerPlugin.particlePosition) {
6416
+ this.particlePositionPlugins.push(containerPlugin);
6417
+ }
6418
+ }
6419
+ }
6179
6420
  #nextFrame(timestamp) {
6180
6421
  try {
6181
6422
  if (!this.#smooth &&
@@ -6452,11 +6693,11 @@
6452
6693
  }
6453
6694
  }
6454
6695
  async #init() {
6455
- const availablePathGenerators = await this.#pluginManager.getPathGenerators?.(this.#container, true);
6456
- if (!availablePathGenerators) {
6696
+ const pluginManager = this.#pluginManager;
6697
+ if (!pluginManager.initializers.pathGenerators) {
6457
6698
  return;
6458
6699
  }
6459
- this.availablePathGenerators = availablePathGenerators;
6700
+ this.availablePathGenerators = await getItemMapFromInitializer(this.#container, pluginManager.initializers.pathGenerators);
6460
6701
  this.pathGenerators = new Map();
6461
6702
  for (const pathGenerator of this.pathGenerators.values()) {
6462
6703
  pathGenerator.init();
@@ -6469,55 +6710,6 @@
6469
6710
  MovePluginInstance: MovePluginInstance
6470
6711
  });
6471
6712
 
6472
- class EmittersPluginInstance {
6473
- #container;
6474
- #instancesManager;
6475
- constructor(instancesManager, container) {
6476
- this.#instancesManager = instancesManager;
6477
- this.#container = container;
6478
- this.#instancesManager.initContainer(container);
6479
- }
6480
- async init() {
6481
- const emittersOptions = this.#container.actualOptions.emitters;
6482
- if (isArray(emittersOptions)) {
6483
- for (const emitterOptions of emittersOptions) {
6484
- await this.#instancesManager.addEmitter(this.#container, emitterOptions);
6485
- }
6486
- }
6487
- else {
6488
- await this.#instancesManager.addEmitter(this.#container, emittersOptions);
6489
- }
6490
- }
6491
- pause() {
6492
- for (const emitter of this.#instancesManager.getArray(this.#container)) {
6493
- emitter.pause();
6494
- }
6495
- }
6496
- play() {
6497
- for (const emitter of this.#instancesManager.getArray(this.#container)) {
6498
- emitter.play();
6499
- }
6500
- }
6501
- resize() {
6502
- for (const emitter of this.#instancesManager.getArray(this.#container)) {
6503
- emitter.resize();
6504
- }
6505
- }
6506
- stop() {
6507
- this.#instancesManager.clear(this.#container);
6508
- }
6509
- update(delta) {
6510
- this.#instancesManager.getArray(this.#container).forEach(emitter => {
6511
- emitter.update(delta);
6512
- });
6513
- }
6514
- }
6515
-
6516
- var EmittersPluginInstance$1 = /*#__PURE__*/Object.freeze({
6517
- __proto__: null,
6518
- EmittersPluginInstance: EmittersPluginInstance
6519
- });
6520
-
6521
6713
  const shapeGenerators = new Map();
6522
6714
  class ShapeManager {
6523
6715
  addShapeGenerator(name, generator) {
@@ -6547,14 +6739,21 @@
6547
6739
  this.#pluginManager = pluginManager;
6548
6740
  }
6549
6741
  async addEmitter(container, options, position) {
6550
- const emitterOptions = new Emitter();
6551
- emitterOptions.load(options);
6552
- const { EmitterInstance } = await Promise.resolve().then(function () { return EmitterInstance$1; }), emitter = new EmitterInstance(this.#pluginManager, container, (emitter) => {
6553
- this.removeEmitter(container, emitter);
6554
- }, emitterOptions, position);
6555
- await emitter.init();
6556
- this.getArray(container).push(emitter);
6557
- return emitter;
6742
+ return this.addEmitters(container, [{ options, position }]).then(t => t[defaultIndex]);
6743
+ }
6744
+ async addEmitters(container, emitters) {
6745
+ const { EmitterInstance } = await Promise.resolve().then(function () { return EmitterInstance$1; }), res = [];
6746
+ for (const { options, position } of emitters) {
6747
+ const emitterOptions = new Emitter();
6748
+ emitterOptions.load(options);
6749
+ const emitter = new EmitterInstance(this.#pluginManager, container, (emitter) => {
6750
+ this.removeEmitter(container, emitter);
6751
+ }, emitterOptions, position);
6752
+ await emitter.init();
6753
+ this.getArray(container).push(emitter);
6754
+ res.push(emitter);
6755
+ }
6756
+ return res;
6558
6757
  }
6559
6758
  clear(container) {
6560
6759
  this.initContainer(container);
@@ -6581,6 +6780,7 @@
6581
6780
  : array.find(t => t.name === idxOrName);
6582
6781
  };
6583
6782
  container.addEmitter = async (options, position) => this.addEmitter(container, options, position);
6783
+ container.addEmitters = async (emitters) => this.addEmitters(container, emitters);
6584
6784
  container.removeEmitter = (idxOrName) => {
6585
6785
  const emitter = container.getEmitter?.(idxOrName);
6586
6786
  if (emitter) {
@@ -6601,7 +6801,7 @@
6601
6801
  };
6602
6802
  }
6603
6803
  removeEmitter(container, emitter) {
6604
- const index = this.getArray(container).indexOf(emitter), minIndex = 0, deleteCount = 1;
6804
+ const index = this.getArray(container).indexOf(emitter), deleteCount = 1;
6605
6805
  if (index >= minIndex) {
6606
6806
  this.getArray(container).splice(index, deleteCount);
6607
6807
  }
@@ -6737,6 +6937,7 @@
6737
6937
  #particlesOptions;
6738
6938
  #paused;
6739
6939
  #pluginManager;
6940
+ #positionOverride = false;
6740
6941
  #removeCallback;
6741
6942
  #resizeObserver;
6742
6943
  #shape;
@@ -6813,6 +7014,31 @@
6813
7014
  });
6814
7015
  this.play();
6815
7016
  }
7017
+ draw(context) {
7018
+ if (!this.options.draw || !this.#shape) {
7019
+ return;
7020
+ }
7021
+ const container = this.#container, fillEnabled = this.options.spawn.fill?.enable ?? true;
7022
+ context.save();
7023
+ context.beginPath();
7024
+ if (fillEnabled) {
7025
+ context.fillStyle = this.spawnFillColor
7026
+ ? getStyleFromHsl(this.spawnFillColor, container.hdr, this.spawnFillOpacity ?? defaultOpacity$1, container.peakNits, container.hdrMode)
7027
+ : getStyleFromRgb({ r: 0, g: 0, b: 0 }, container.hdr, defaultOpacity$1, container.peakNits, container.hdrMode);
7028
+ }
7029
+ if (this.spawnStrokeColor) {
7030
+ context.strokeStyle = getStyleFromHsl(this.spawnStrokeColor, container.hdr, this.spawnStrokeOpacity ?? defaultOpacity$1, container.peakNits, container.hdrMode);
7031
+ context.lineWidth = this.spawnStrokeWidth ?? defaultStrokeWidth;
7032
+ }
7033
+ this.#shape.draw?.(context);
7034
+ if (fillEnabled) {
7035
+ context.fill();
7036
+ }
7037
+ if (this.spawnStrokeColor) {
7038
+ context.stroke();
7039
+ }
7040
+ context.restore();
7041
+ }
6816
7042
  externalPause() {
6817
7043
  this.#paused = true;
6818
7044
  this.pause();
@@ -6850,11 +7076,14 @@
6850
7076
  }
6851
7077
  }
6852
7078
  resize() {
6853
- const initialPosition = this.#initialPosition, container = this.#container;
6854
- this.position =
6855
- initialPosition && isPointInside(initialPosition, container.canvas.size, Vector.origin)
6856
- ? initialPosition
6857
- : this.#calcPosition();
7079
+ const container = this.#container;
7080
+ if (!this.#positionOverride) {
7081
+ const initialPosition = this.#initialPosition;
7082
+ this.position =
7083
+ initialPosition && isPointInside(initialPosition, container.canvas.size, Vector.origin)
7084
+ ? initialPosition
7085
+ : this.#calcPosition();
7086
+ }
6858
7087
  this.#size = this.#calcSize();
6859
7088
  this.size =
6860
7089
  this.#size.mode === PixelMode.percent
@@ -6865,6 +7094,11 @@
6865
7094
  : { width: this.#size.width, height: this.#size.height };
6866
7095
  this.#shape?.resize(this.position, this.size);
6867
7096
  }
7097
+ setPosition(position) {
7098
+ this.#positionOverride = true;
7099
+ this.position = { ...position };
7100
+ this.#shape?.resize(this.position, this.size);
7101
+ }
6868
7102
  update(delta) {
6869
7103
  if (this.#paused) {
6870
7104
  return;
@@ -7060,6 +7294,7 @@
7060
7294
  exports.loadHyperspacePreset = loadHyperspacePreset;
7061
7295
  exports.tsParticles = tsParticles;
7062
7296
 
7063
- }));
7297
+ })(g.__tsParticlesInternals.presets.hyperspace = g.__tsParticlesInternals.presets.hyperspace || {});
7298
+ })(typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : self);
7299
+
7064
7300
  Object.assign(globalThis.window || globalThis, { loadHyperspacePreset: (globalThis.__tsParticlesInternals.presets.hyperspace || {}).loadHyperspacePreset });
7065
- delete (globalThis.window || globalThis).tsparticlesInternalExports;