@tsparticles/preset-stars 4.3.2 → 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.3.2 */
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.stars = global.__tsParticlesInternals.presets.stars || {})));
7
- })(this, (function (exports) { 'use strict';
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
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, 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;
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, 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
  }
@@ -270,11 +301,61 @@
270
301
  };
271
302
  }
272
303
  function parseAlpha(input) {
273
- const defaultAlpha = 1;
274
304
  if (!input) {
275
305
  return defaultAlpha;
276
306
  }
277
- return input.endsWith("%") ? parseFloat(input) / percentDenominator : parseFloat(input);
307
+ return input.endsWith("%") ? Number.parseFloat(input) / percentDenominator : Number.parseFloat(input);
308
+ }
309
+
310
+ const ErrorCodes$1 = {
311
+ engineVersionMismatch: "TSP-1001",
312
+ particlePositionNotFound: "TSP-1002",
313
+ pluginRegisterAfterLoad: "TSP-1003",
314
+ offscreenCanvasUnsupported: "TSP-1101",
315
+ offscreenCanvasTransferFailed: "TSP-1102",
316
+ hdrEnableInvalid: "TSP-1201",
317
+ hdrModeInvalid: "TSP-1202",
318
+ hdrPeakNitsInvalid: "TSP-1203",
319
+ };
320
+
321
+ const messages = {
322
+ [ErrorCodes$1.engineVersionMismatch]: "The tsParticles version is different from the loaded plugins version. Engine version: {0}. Plugin version: {1}",
323
+ [ErrorCodes$1.particlePositionNotFound]: "a valid position cannot be found for particle",
324
+ [ErrorCodes$1.pluginRegisterAfterLoad]: "Register plugins can only be done before calling tsParticles.load()",
325
+ [ErrorCodes$1.offscreenCanvasUnsupported]: "OffscreenCanvas is required but not supported by this browser",
326
+ [ErrorCodes$1.offscreenCanvasTransferFailed]: "OffscreenCanvas transfer failed",
327
+ [ErrorCodes$1.hdrEnableInvalid]: 'Invalid HDR "enable" value: expected a boolean, got "{0}"',
328
+ [ErrorCodes$1.hdrModeInvalid]: 'Invalid HDR "mode" value: expected one of {0}, got "{1}"',
329
+ [ErrorCodes$1.hdrPeakNitsInvalid]: 'Invalid HDR "peakNits" value: expected a positive number, got "{0}"',
330
+ };
331
+
332
+ let registeredMessages;
333
+ const ensureRegisteredMessages = () => {
334
+ registeredMessages ??= new Map(Object.entries(messages));
335
+ return registeredMessages;
336
+ }, toStringValue$1 = (value) => String(value), format = (template, args) => {
337
+ return template.replace(/\{(\d+)\}/g, (match, index) => {
338
+ const arg = args[Number(index)];
339
+ return arg === undefined ? match : toStringValue$1(arg);
340
+ });
341
+ };
342
+ function addErrorMessages(extraMessages) {
343
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "production") {
344
+ return;
345
+ }
346
+ const catalog = ensureRegisteredMessages();
347
+ for (const [code, message] of Object.entries(extraMessages)) {
348
+ if (message !== undefined) {
349
+ catalog.set(code, message);
350
+ }
351
+ }
352
+ }
353
+ function getErrorMessage(code, ...args) {
354
+ if (typeof process !== "undefined" && process.env.NODE_ENV === "production") {
355
+ return `[tsParticles Error ${code}] https://particles.js.org/errors/#${code}`;
356
+ }
357
+ const template = ensureRegisteredMessages().get(code) ?? `Unknown error code ${code}`;
358
+ return format(template, args);
278
359
  }
279
360
 
280
361
  var OutModeDirection;
@@ -291,7 +372,6 @@
291
372
  PixelMode["percent"] = "percent";
292
373
  })(PixelMode || (PixelMode = {}));
293
374
 
294
- const minRadius = 0;
295
375
  function isForbiddenKey(key) {
296
376
  return key === "__proto__" || key === "constructor" || key === "prototype";
297
377
  }
@@ -487,22 +567,84 @@
487
567
  element.removeEventListener(event, handler, removeOptions);
488
568
  }
489
569
  }
490
- async function getItemsFromInitializer(container, map, initializers, force = false) {
491
- let res = map.get(container);
492
- if (!res || force) {
493
- res = await Promise.all([...initializers.values()].map(t => t(container)));
494
- map.set(container, res);
570
+ async function getItemsFromInitializer(container, initializers) {
571
+ return await Promise.all([...initializers.values()].map(t => t(container)));
572
+ }
573
+ async function getItemMapFromInitializer(container, initializers) {
574
+ const entries = await Promise.all([...initializers.entries()].map(([key, initializer]) => initializer(container).then(item => [key, item])));
575
+ return new Map(entries);
576
+ }
577
+ async function getDataFromUrl(data) {
578
+ const url = itemFromSingleOrMultiple(data.url, data.index);
579
+ if (!url) {
580
+ return data.fallback;
495
581
  }
496
- return res;
582
+ try {
583
+ const response = await fetch(url);
584
+ if (response.ok) {
585
+ const current = (await response.json());
586
+ if (isSourceOptionsValue(current)) {
587
+ return current;
588
+ }
589
+ getLogger().error("invalid configuration data while retrieving config file");
590
+ }
591
+ else {
592
+ getLogger().error(`${response.status.toString()} while retrieving config file`);
593
+ }
594
+ }
595
+ catch (error) {
596
+ getLogger().error(`error while retrieving config file: ${error}`);
597
+ }
598
+ return data.fallback;
497
599
  }
498
- async function getItemMapFromInitializer(container, map, initializers, force = false) {
499
- let res = map.get(container);
500
- if (!res || force) {
501
- const entries = await Promise.all([...initializers.entries()].map(([key, initializer]) => initializer(container).then(item => [key, item])));
502
- res = new Map(entries);
503
- map.set(container, res);
600
+ function isSourceOptionsValue(value) {
601
+ if (isArray(value)) {
602
+ return value.every((entry) => isObject(entry) && !isArray(entry));
504
603
  }
505
- return res;
604
+ return isObject(value) && !isArray(value);
605
+ }
606
+ function getCanvasFromContainer(domContainer) {
607
+ let canvasEl;
608
+ const documentSafe = safeDocument(), isCanvas = domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag;
609
+ if (isCanvas) {
610
+ canvasEl = domContainer;
611
+ canvasEl.dataset[generatedAttribute] ??= generatedFalse;
612
+ if (canvasEl.dataset[generatedAttribute] === generatedTrue) {
613
+ canvasEl.style.width ||= fullPercent;
614
+ canvasEl.style.height ||= fullPercent;
615
+ canvasEl.style.pointerEvents = "none";
616
+ canvasEl.style.setProperty("pointer-events", "none");
617
+ }
618
+ }
619
+ else {
620
+ const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
621
+ if (foundCanvas) {
622
+ canvasEl = foundCanvas;
623
+ canvasEl.dataset[generatedAttribute] = generatedFalse;
624
+ }
625
+ else {
626
+ canvasEl = documentSafe.createElement(canvasTag);
627
+ canvasEl.dataset[generatedAttribute] = generatedTrue;
628
+ domContainer.appendChild(canvasEl);
629
+ }
630
+ canvasEl.style.width ||= fullPercent;
631
+ canvasEl.style.height ||= fullPercent;
632
+ canvasEl.style.pointerEvents = "none";
633
+ canvasEl.style.setProperty("pointer-events", "none");
634
+ }
635
+ return canvasEl;
636
+ }
637
+ function getDomContainer(id, source) {
638
+ const documentSafe = safeDocument();
639
+ let domContainer = source ?? documentSafe.getElementById(id);
640
+ if (domContainer) {
641
+ return domContainer;
642
+ }
643
+ domContainer = documentSafe.createElement("canvas");
644
+ domContainer.id = id;
645
+ domContainer.dataset[generatedAttribute] = generatedTrue;
646
+ documentSafe.body.append(domContainer);
647
+ return domContainer;
506
648
  }
507
649
 
508
650
  class EventDispatcher {
@@ -573,7 +715,6 @@
573
715
  class PluginManager {
574
716
  colorManagers = new Map();
575
717
  easingFunctions = new Map();
576
- effectDrawers = new Map();
577
718
  initializers = {
578
719
  effects: new Map(),
579
720
  shapes: new Map(),
@@ -582,8 +723,6 @@
582
723
  palettes = new Map();
583
724
  plugins = [];
584
725
  presets = new Map();
585
- shapeDrawers = new Map();
586
- updaters = new Map();
587
726
  #allLoadersSet = new Set();
588
727
  #configs = new Map();
589
728
  #engine;
@@ -601,57 +740,79 @@
601
740
  }
602
741
  return res;
603
742
  }
743
+ get initialized() {
744
+ return this.#initialized;
745
+ }
604
746
  addColorManager(name, manager) {
747
+ if (this.#initialized) {
748
+ return;
749
+ }
605
750
  this.colorManagers.set(name, manager);
606
751
  }
607
752
  addConfig(config) {
753
+ if (this.#initialized) {
754
+ return;
755
+ }
608
756
  const key = config.key ?? config.name ?? "default";
609
757
  this.#configs.set(key, config);
610
758
  this.#engine.dispatchEvent(EventType.configAdded, { data: { name: key, config } });
611
759
  }
612
760
  addEasing(name, easing) {
761
+ if (this.#initialized) {
762
+ return;
763
+ }
613
764
  if (this.easingFunctions.get(name)) {
614
765
  return;
615
766
  }
616
767
  this.easingFunctions.set(name, easing);
617
768
  }
618
769
  addEffect(effect, drawer) {
770
+ if (this.#initialized) {
771
+ return;
772
+ }
619
773
  this.initializers.effects.set(effect, drawer);
620
774
  }
621
775
  addPalette(name, palette) {
776
+ if (this.#initialized) {
777
+ return;
778
+ }
622
779
  this.palettes.set(name, palette);
623
780
  }
624
781
  addParticleUpdater(name, updaterInitializer) {
782
+ if (this.#initialized) {
783
+ return;
784
+ }
625
785
  this.initializers.updaters.set(name, updaterInitializer);
626
786
  }
627
787
  addPlugin(plugin) {
788
+ if (this.#initialized) {
789
+ return;
790
+ }
628
791
  if (this.getPlugin(plugin.id)) {
629
792
  return;
630
793
  }
631
794
  this.plugins.push(plugin);
632
795
  }
633
796
  addPreset(preset, options, override = false) {
797
+ if (this.#initialized) {
798
+ return;
799
+ }
634
800
  if (!(override || !this.getPreset(preset))) {
635
801
  return;
636
802
  }
637
803
  this.presets.set(preset, options);
638
804
  }
639
805
  addShape(shapes, drawer) {
806
+ if (this.#initialized) {
807
+ return;
808
+ }
640
809
  for (const shape of shapes) {
641
810
  this.initializers.shapes.set(shape, drawer);
642
811
  }
643
812
  }
644
- clearPlugins(container) {
645
- this.effectDrawers.delete(container);
646
- this.shapeDrawers.delete(container);
647
- this.updaters.delete(container);
648
- }
649
813
  getEasing(name) {
650
814
  return this.easingFunctions.get(name) ?? ((value) => value);
651
815
  }
652
- getEffectDrawers(container, force = false) {
653
- return getItemMapFromInitializer(container, this.effectDrawers, this.initializers.effects, force);
654
- }
655
816
  getPalette(name) {
656
817
  return this.palettes.get(name);
657
818
  }
@@ -661,12 +822,6 @@
661
822
  getPreset(preset) {
662
823
  return this.presets.get(preset);
663
824
  }
664
- async getShapeDrawers(container, force = false) {
665
- return getItemMapFromInitializer(container, this.shapeDrawers, this.initializers.shapes, force);
666
- }
667
- async getUpdaters(container, force = false) {
668
- return getItemsFromInitializer(container, this.updaters, this.initializers.updaters, force);
669
- }
670
825
  async init() {
671
826
  if (this.#initialized || this.#isRunningLoaders) {
672
827
  return;
@@ -685,16 +840,9 @@
685
840
  this.#initialized = true;
686
841
  }
687
842
  }
688
- loadParticlesOptions(container, options, ...sourceOptions) {
689
- const updaters = this.updaters.get(container);
690
- if (!updaters) {
691
- return;
692
- }
693
- updaters.forEach(updater => updater.loadOptions?.(options, ...sourceOptions));
694
- }
695
843
  async register(...loaders) {
696
844
  if (this.#initialized) {
697
- throw new Error("Register plugins can only be done before calling tsParticles.load()");
845
+ throw new Error(getErrorMessage(ErrorCodes$1.pluginRegisterAfterLoad));
698
846
  }
699
847
  for (const loader of loaders) {
700
848
  if (this.#isRunningLoaders) {
@@ -706,88 +854,15 @@
706
854
  }
707
855
  }
708
856
  async #runLoader(loader, executed, allLoaders) {
709
- if (executed.has(loader))
857
+ if (executed.has(loader)) {
710
858
  return;
859
+ }
711
860
  executed.add(loader);
712
861
  allLoaders.add(loader);
713
862
  await loader(this.#engine);
714
863
  }
715
864
  }
716
865
 
717
- const errorPrefix = "tsParticles - Error";
718
- const wrap = (fn) => (...args) => {
719
- fn(...args);
720
- }, _logger = {
721
- debug: wrap(console.debug),
722
- error: (message, ...optionalParams) => {
723
- console.error(`${errorPrefix} - ${message}`, ...optionalParams);
724
- },
725
- info: wrap(console.info),
726
- log: wrap(console.log),
727
- trace: wrap(console.trace),
728
- verbose: wrap(console.log),
729
- warning: wrap(console.warn),
730
- };
731
- function getLogger() {
732
- return _logger;
733
- }
734
-
735
- const fullPercent = "100%";
736
- async function getDataFromUrl(data) {
737
- const url = itemFromSingleOrMultiple(data.url, data.index);
738
- if (!url) {
739
- return data.fallback;
740
- }
741
- const response = await fetch(url);
742
- if (response.ok) {
743
- return (await response.json());
744
- }
745
- getLogger().error(`${response.status.toString()} while retrieving config file`);
746
- return data.fallback;
747
- }
748
- const getCanvasFromContainer = (domContainer) => {
749
- const documentSafe = safeDocument();
750
- let canvasEl;
751
- const isCanvas = domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag;
752
- if (isCanvas) {
753
- canvasEl = domContainer;
754
- canvasEl.dataset[generatedAttribute] ??= generatedFalse;
755
- if (canvasEl.dataset[generatedAttribute] === generatedTrue) {
756
- canvasEl.style.width ||= fullPercent;
757
- canvasEl.style.height ||= fullPercent;
758
- canvasEl.style.pointerEvents = "none";
759
- canvasEl.style.setProperty("pointer-events", "none");
760
- }
761
- }
762
- else {
763
- const existingCanvases = domContainer.getElementsByTagName(canvasTag), foundCanvas = existingCanvases.item(canvasFirstIndex);
764
- if (foundCanvas) {
765
- canvasEl = foundCanvas;
766
- canvasEl.dataset[generatedAttribute] = generatedFalse;
767
- }
768
- else {
769
- canvasEl = documentSafe.createElement(canvasTag);
770
- canvasEl.dataset[generatedAttribute] = generatedTrue;
771
- domContainer.appendChild(canvasEl);
772
- }
773
- canvasEl.style.width ||= fullPercent;
774
- canvasEl.style.height ||= fullPercent;
775
- canvasEl.style.pointerEvents = "none";
776
- canvasEl.style.setProperty("pointer-events", "none");
777
- }
778
- return canvasEl;
779
- }, getDomContainer = (id, source) => {
780
- const documentSafe = safeDocument();
781
- let domContainer = source ?? documentSafe.getElementById(id);
782
- if (domContainer) {
783
- return domContainer;
784
- }
785
- domContainer = documentSafe.createElement("canvas");
786
- domContainer.id = id;
787
- domContainer.dataset[generatedAttribute] = generatedTrue;
788
- documentSafe.body.append(domContainer);
789
- return domContainer;
790
- };
791
866
  class Engine {
792
867
  pluginManager = new PluginManager(this);
793
868
  #domArray = [];
@@ -797,7 +872,7 @@
797
872
  return this.#domArray;
798
873
  }
799
874
  get version() {
800
- return "4.3.2";
875
+ return "4.5.0";
801
876
  }
802
877
  addEventListener(type, listener) {
803
878
  this.#eventDispatcher.addEventListener(type, listener);
@@ -806,7 +881,7 @@
806
881
  if (this.version === pluginVersion) {
807
882
  return;
808
883
  }
809
- throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${this.version}. Plugin version: ${pluginVersion}`);
884
+ throw new Error(getErrorMessage(ErrorCodes$1.engineVersionMismatch, this.version, pluginVersion));
810
885
  }
811
886
  dispatchEvent(type, args) {
812
887
  this.#eventDispatcher.dispatchEvent(type, args);
@@ -878,6 +953,10 @@
878
953
  }
879
954
 
880
955
  function initEngine() {
956
+ const existing = globalThis.tsParticles;
957
+ if (existing?.pluginManager) {
958
+ return existing;
959
+ }
881
960
  return new Engine();
882
961
  }
883
962
 
@@ -975,6 +1054,15 @@
975
1054
  AnimationMode["random"] = "random";
976
1055
  })(AnimationMode || (AnimationMode = {}));
977
1056
 
1057
+ var HdrMode;
1058
+ (function (HdrMode) {
1059
+ HdrMode["standard"] = "standard";
1060
+ HdrMode["natural"] = "natural";
1061
+ HdrMode["vivid"] = "vivid";
1062
+ HdrMode["cinematic"] = "cinematic";
1063
+ HdrMode["dynamic"] = "dynamic";
1064
+ })(HdrMode || (HdrMode = {}));
1065
+
978
1066
  var LimitMode;
979
1067
  (function (LimitMode) {
980
1068
  LimitMode["delete"] = "delete";
@@ -1042,20 +1130,6 @@
1042
1130
  DrawLayer[DrawLayer["Foreground"] = 7] = "Foreground";
1043
1131
  })(DrawLayer || (DrawLayer = {}));
1044
1132
 
1045
- class OptionLoader {
1046
- load(data) {
1047
- if (isNull(data)) {
1048
- return;
1049
- }
1050
- this.doLoad(data);
1051
- }
1052
- }
1053
- function loadOptions(options, ...sourceOptionsArr) {
1054
- for (const sourceOptions of sourceOptionsArr) {
1055
- options.load(sourceOptions);
1056
- }
1057
- }
1058
-
1059
1133
  function loadProperty(obj, key, value) {
1060
1134
  if (value !== undefined) {
1061
1135
  obj[key] = value;
@@ -1087,6 +1161,20 @@
1087
1161
  }
1088
1162
  }
1089
1163
 
1164
+ class OptionLoader {
1165
+ load(data) {
1166
+ if (isNull(data)) {
1167
+ return;
1168
+ }
1169
+ this.doLoad(data);
1170
+ }
1171
+ }
1172
+ function loadOptions(options, ...sourceOptionsArr) {
1173
+ for (const sourceOptions of sourceOptionsArr) {
1174
+ options.load(sourceOptions);
1175
+ }
1176
+ }
1177
+
1090
1178
  class AnimationOptions extends OptionLoader {
1091
1179
  count = 0;
1092
1180
  decay = 0;
@@ -1230,6 +1318,28 @@
1230
1318
  }
1231
1319
  }
1232
1320
 
1321
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
1322
+ class HDROptions extends OptionLoader {
1323
+ enable = true;
1324
+ mode = HdrMode.standard;
1325
+ peakNits = defaultPeakNits;
1326
+ doLoad(data) {
1327
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
1328
+ throw new Error(getErrorMessage(ErrorCodes$1.hdrEnableInvalid, String(data.enable)));
1329
+ }
1330
+ if (data.mode !== undefined && !isEnumValue(HdrMode, data.mode)) {
1331
+ throw new Error(getErrorMessage(ErrorCodes$1.hdrModeInvalid, Object.values(HdrMode).join(", "), toStringValue(data.mode)));
1332
+ }
1333
+ if (data.peakNits !== undefined &&
1334
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1335
+ throw new Error(getErrorMessage(ErrorCodes$1.hdrPeakNitsInvalid, String(data.peakNits)));
1336
+ }
1337
+ loadProperty(this, "enable", data.enable);
1338
+ loadProperty(this, "mode", data.mode);
1339
+ loadProperty(this, "peakNits", data.peakNits);
1340
+ }
1341
+ }
1342
+
1233
1343
  class ResizeEvent extends OptionLoader {
1234
1344
  delay = 0.5;
1235
1345
  enable = true;
@@ -1600,12 +1710,10 @@
1600
1710
  plugin.loadParticlesOptions(this.#container, this, data);
1601
1711
  }
1602
1712
  }
1603
- const updaters = this.#pluginManager.updaters.get(this.#container);
1604
- if (updaters) {
1605
- for (const updater of updaters) {
1606
- if (updater.loadOptions) {
1607
- updater.loadOptions(this, data);
1608
- }
1713
+ const updaters = this.#container.particleUpdaters;
1714
+ for (const updater of updaters) {
1715
+ if (updater.loadOptions) {
1716
+ updater.loadOptions(this, data);
1609
1717
  }
1610
1718
  }
1611
1719
  }
@@ -1673,7 +1781,7 @@
1673
1781
  duration = 0;
1674
1782
  fpsLimit = 120;
1675
1783
  fullScreen;
1676
- hdr = true;
1784
+ hdr;
1677
1785
  key;
1678
1786
  name;
1679
1787
  palette;
@@ -1693,6 +1801,7 @@
1693
1801
  this.#container = container;
1694
1802
  this.background = new Background();
1695
1803
  this.fullScreen = new FullScreen();
1804
+ this.hdr = new HDROptions();
1696
1805
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1697
1806
  this.resize = new ResizeEvent();
1698
1807
  }
@@ -1715,7 +1824,15 @@
1715
1824
  loadProperty(this, "detectRetina", data.detectRetina);
1716
1825
  loadRangeProperty(this, "duration", data.duration);
1717
1826
  loadProperty(this, "fpsLimit", data.fpsLimit);
1718
- loadProperty(this, "hdr", data.hdr);
1827
+ const hdrData = data.hdr;
1828
+ if (isBoolean(hdrData)) {
1829
+ this.hdr.enable = hdrData;
1830
+ this.hdr.mode = HdrMode.standard;
1831
+ this.hdr.peakNits = 400;
1832
+ }
1833
+ else {
1834
+ this.hdr.load(hdrData);
1835
+ }
1719
1836
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1720
1837
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1721
1838
  loadProperty(this, "zLayers", data.zLayers);
@@ -1758,7 +1875,7 @@
1758
1875
  }
1759
1876
  }
1760
1877
 
1761
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1878
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, acesA = 2.51, acesB = 0.03, acesC = 2.43, acesD = 0.59, acesE = 0.14, saturationBoost = 1.15, lightnessBoost = 1.05, temperatureR = 1.05, temperatureB = 0.95, contrastFactor = 1.1, luminanceR = 0.2126, luminanceG = 0.7152, luminanceB = 0.0722, dynamicLuminanceFactor = 2, channelCount = 3;
1762
1879
  function getCachedStyle(key, generator) {
1763
1880
  let cached = styleCache.get(key);
1764
1881
  if (!cached) {
@@ -1770,6 +1887,42 @@
1770
1887
  }
1771
1888
  return cached;
1772
1889
  }
1890
+ function acesFilmic(x) {
1891
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
1892
+ }
1893
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
1894
+ switch (mode) {
1895
+ case HdrMode.vivid: {
1896
+ const avg = (r + g + b) / channelCount;
1897
+ return {
1898
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1899
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1900
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1901
+ };
1902
+ }
1903
+ case HdrMode.cinematic: {
1904
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
1905
+ return {
1906
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
1907
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
1908
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
1909
+ };
1910
+ }
1911
+ case HdrMode.dynamic: {
1912
+ const luminance = luminanceR * r + luminanceG * g + luminanceB * b, vividWeight = Math.min(one, luminance * dynamicLuminanceFactor), naturalWeight = one - vividWeight, avg = (r + g + b) / channelCount, vividR = clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, vividG = clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, vividB = clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost;
1913
+ return {
1914
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
1915
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
1916
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
1917
+ };
1918
+ }
1919
+ case HdrMode.standard:
1920
+ return { b, g, r };
1921
+ case HdrMode.natural:
1922
+ default:
1923
+ return { b, g, r };
1924
+ }
1925
+ }
1773
1926
  function stringToRgba(pluginManager, input) {
1774
1927
  if (!input) {
1775
1928
  return;
@@ -1893,9 +2046,9 @@
1893
2046
  const grayscaleValue = Math.round(lNormalized * rgbMax);
1894
2047
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
1895
2048
  }
1896
- const temp1 = lNormalized < half
2049
+ const temp2 = lNormalized < half
1897
2050
  ? lNormalized * (sNormalizedOffset + sNormalized)
1898
- : 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));
2051
+ : 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));
1899
2052
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
1900
2053
  }
1901
2054
  function hslToRgbFloat(hsl) {
@@ -1904,9 +2057,9 @@
1904
2057
  const grayscaleValue = lNormalized * rgbMax;
1905
2058
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
1906
2059
  }
1907
- const temp1 = lNormalized < half
2060
+ const temp2 = lNormalized < half
1908
2061
  ? lNormalized * (sNormalizedOffset + sNormalized)
1909
- : 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));
2062
+ : 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));
1910
2063
  return { r: red, g: green, b: blue };
1911
2064
  }
1912
2065
  function hslaToRgba(hsla) {
@@ -1927,21 +2080,40 @@
1927
2080
  r: getRgbInRangeValue(),
1928
2081
  };
1929
2082
  }
1930
- function getStyleFromRgb(color, hdr, opacity) {
1931
- const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
1932
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2083
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
2084
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2085
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2086
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
2087
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
1933
2088
  }
1934
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1935
- const headroom = peakNits / sdrReferenceWhiteNits;
1936
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2089
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = HdrMode.standard) {
2090
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
2091
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2092
+ }
2093
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
2094
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
2095
+ if (mode !== HdrMode.natural && mode !== HdrMode.vivid && mode !== HdrMode.cinematic && mode !== HdrMode.dynamic) {
2096
+ return { b: bNorm, g: gNorm, r: rNorm };
2097
+ }
2098
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
2099
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
2100
+ }
2101
+ function hdrToneMap(normalized, headroom, middleGray) {
2102
+ if (normalized <= middleGray) {
2103
+ return acesFilmic(normalized);
2104
+ }
2105
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
2106
+ return acesFilmic(expanded);
1937
2107
  }
1938
2108
  function getSdrStyleFromRgb(color, opacity) {
1939
2109
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
1940
2110
  }
1941
- function getStyleFromHsl(color, hdr, opacity) {
1942
- const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2111
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
2112
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2113
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2114
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
1943
2115
  return getCachedStyle(key, () => hdr
1944
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2116
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
1945
2117
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1946
2118
  }
1947
2119
  function getHslFromAnimation(animation) {
@@ -2004,7 +2176,7 @@
2004
2176
  colorValue.velocity = defaultVelocity;
2005
2177
  }
2006
2178
  }
2007
- function updateColorValue(data, decrease, delta, hdr) {
2179
+ function updateColorValue(data, decrease, delta, _hdr) {
2008
2180
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2009
2181
  if (!data.enable ||
2010
2182
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2017,7 +2189,7 @@
2017
2189
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2018
2190
  return;
2019
2191
  }
2020
- const offset = data.offset ? randomInRangeValue(data.offset) : minOffset, velocity = ((data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor) * (hdr ? hdrAnimationScale : identity), decay = data.decay ?? identity, max = data.max, min = data.min;
2192
+ const offset = data.offset ? randomInRangeValue(data.offset) : minOffset, velocity = (data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor, decay = data.decay ?? identity, max = data.max, min = data.min;
2021
2193
  if (!decrease || data.status === AnimationStatus.increasing) {
2022
2194
  data.value += velocity;
2023
2195
  if (data.value > max) {
@@ -2049,9 +2221,9 @@
2049
2221
  return;
2050
2222
  }
2051
2223
  const { h, s, l } = color;
2052
- updateColorValue(h, false, delta, hdr);
2053
- updateColorValue(s, true, delta, hdr);
2054
- updateColorValue(l, true, delta, hdr);
2224
+ updateColorValue(h, false, delta);
2225
+ updateColorValue(s, true, delta);
2226
+ updateColorValue(l, true, delta);
2055
2227
  }
2056
2228
  function alterHsl(color, type, value) {
2057
2229
  return {
@@ -2101,7 +2273,7 @@
2101
2273
  }
2102
2274
 
2103
2275
  async function loadBlendPlugin(engine) {
2104
- engine.checkVersion("4.3.2");
2276
+ engine.checkVersion("4.5.0");
2105
2277
  await engine.pluginManager.register(e => {
2106
2278
  e.pluginManager.addPlugin(new BlendPlugin());
2107
2279
  });
@@ -2138,7 +2310,7 @@
2138
2310
  }
2139
2311
 
2140
2312
  async function loadCircleShape(engine) {
2141
- engine.checkVersion("4.3.2");
2313
+ engine.checkVersion("4.5.0");
2142
2314
  await engine.pluginManager.register(e => {
2143
2315
  e.pluginManager.addShape(["circle"], () => {
2144
2316
  return Promise.resolve(new CircleDrawer());
@@ -2153,7 +2325,7 @@
2153
2325
  RgbIndexes[RgbIndexes["b"] = 3] = "b";
2154
2326
  RgbIndexes[RgbIndexes["a"] = 4] = "a";
2155
2327
  })(RgbIndexes$1 || (RgbIndexes$1 = {}));
2156
- 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;
2328
+ 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;
2157
2329
  class HexColorManager {
2158
2330
  accepts(input) {
2159
2331
  return input.startsWith("#");
@@ -2186,7 +2358,7 @@
2186
2358
  }
2187
2359
 
2188
2360
  async function loadHexColorPlugin(engine) {
2189
- engine.checkVersion("4.3.2");
2361
+ engine.checkVersion("4.5.0");
2190
2362
  await engine.pluginManager.register(e => {
2191
2363
  e.pluginManager.addColorManager("hex", new HexColorManager());
2192
2364
  });
@@ -2226,7 +2398,7 @@
2226
2398
  if (!this.accepts(input)) {
2227
2399
  return;
2228
2400
  }
2229
- const result = hslRegex.exec(input), minLength = 4, defaultAlpha = 1, radix = 10;
2401
+ const result = hslRegex.exec(input), minLength = 4, radix = 10;
2230
2402
  return result
2231
2403
  ? hslaToRgba({
2232
2404
  a: result.length > minLength ? parseAlpha(result[HslIndexes.a]) : defaultAlpha,
@@ -2239,12 +2411,20 @@
2239
2411
  }
2240
2412
 
2241
2413
  async function loadHslColorPlugin(engine) {
2242
- engine.checkVersion("4.3.2");
2414
+ engine.checkVersion("4.5.0");
2243
2415
  await engine.pluginManager.register(e => {
2244
2416
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2245
2417
  });
2246
2418
  }
2247
2419
 
2420
+ const ErrorCodes = {
2421
+ baseMoverNotLoaded: "TSP-3203",
2422
+ };
2423
+
2424
+ const ErrorMessages = {
2425
+ [ErrorCodes.baseMoverNotLoaded]: "tsParticles Base Mover is not loaded",
2426
+ };
2427
+
2248
2428
  class MovePlugin {
2249
2429
  id = "move";
2250
2430
  #pluginManager;
@@ -2263,20 +2443,20 @@
2263
2443
  }
2264
2444
 
2265
2445
  async function loadMovePlugin(engine) {
2266
- engine.checkVersion("4.3.2");
2446
+ engine.checkVersion("4.5.0");
2447
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
2448
+ addErrorMessages(ErrorMessages);
2449
+ }
2267
2450
  await engine.pluginManager.register(e => {
2268
2451
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2269
2452
  movePluginManager.initializers.pathGenerators ??= new Map();
2270
- movePluginManager.pathGenerators ??= new Map();
2271
2453
  movePluginManager.addPathGenerator = (name, generator) => {
2454
+ if (movePluginManager.initialized) {
2455
+ return;
2456
+ }
2272
2457
  movePluginManager.initializers.pathGenerators ??= new Map();
2273
2458
  movePluginManager.initializers.pathGenerators.set(name, generator);
2274
2459
  };
2275
- movePluginManager.getPathGenerators = async (container, force = false) => {
2276
- movePluginManager.initializers.pathGenerators ??= new Map();
2277
- movePluginManager.pathGenerators ??= new Map();
2278
- return getItemMapFromInitializer(container, movePluginManager.pathGenerators, movePluginManager.initializers.pathGenerators, force);
2279
- };
2280
2460
  e.pluginManager.addPlugin(new MovePlugin(e.pluginManager));
2281
2461
  });
2282
2462
  }
@@ -2473,7 +2653,7 @@
2473
2653
  }
2474
2654
 
2475
2655
  async function loadOpacityUpdater(engine) {
2476
- engine.checkVersion("4.3.2");
2656
+ engine.checkVersion("4.5.0");
2477
2657
  await engine.pluginManager.register(e => {
2478
2658
  e.pluginManager.addParticleUpdater("opacity", container => {
2479
2659
  return Promise.resolve(new OpacityUpdater(container));
@@ -2482,70 +2662,60 @@
2482
2662
  }
2483
2663
 
2484
2664
  const boundsMin = 0;
2485
- function bounceHorizontal(data) {
2486
- if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
2487
- (data.direction !== OutModeDirection.left && data.direction !== OutModeDirection.right)) {
2488
- return;
2489
- }
2490
- if (data.bounds.right < boundsMin && data.direction === OutModeDirection.left) {
2491
- data.particle.position.x = data.size + data.offset.x;
2492
- }
2493
- else if (data.bounds.left > data.canvasSize.width && data.direction === OutModeDirection.right) {
2494
- data.particle.position.x = data.canvasSize.width - data.size - data.offset.x;
2495
- }
2496
- const velocity = data.particle.velocity.x;
2497
- let bounced = false;
2498
- if (data.outOfCanvas &&
2499
- ((data.direction === OutModeDirection.right && velocity > minVelocity) ||
2500
- (data.direction === OutModeDirection.left && velocity < minVelocity))) {
2501
- const newVelocity = getRangeValue(data.particle.options.bounce.horizontal.value);
2502
- data.particle.velocity.x *= -newVelocity;
2503
- bounced = true;
2504
- }
2505
- if (!bounced) {
2506
- return;
2507
- }
2508
- const minPos = data.offset.x + data.size;
2509
- if (data.outOfCanvas && data.direction === OutModeDirection.right) {
2510
- data.particle.position.x = data.canvasSize.width - minPos;
2511
- }
2512
- else if (data.outOfCanvas && data.direction === OutModeDirection.left) {
2513
- data.particle.position.x = minPos;
2514
- }
2515
- if (data.outMode === OutMode.split) {
2516
- data.particle.destroy();
2517
- }
2518
- }
2519
- function bounceVertical(data) {
2520
- if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) ||
2521
- (data.direction !== OutModeDirection.bottom && data.direction !== OutModeDirection.top)) {
2665
+ const bounceAxisConfigs = {
2666
+ [OutModeDirection.left]: {
2667
+ axis: "x",
2668
+ canvas: "width",
2669
+ bounce: "horizontal",
2670
+ negativeEdge: "right",
2671
+ positiveEdge: "left",
2672
+ negative: true,
2673
+ },
2674
+ [OutModeDirection.right]: {
2675
+ axis: "x",
2676
+ canvas: "width",
2677
+ bounce: "horizontal",
2678
+ negativeEdge: "right",
2679
+ positiveEdge: "left",
2680
+ negative: false,
2681
+ },
2682
+ [OutModeDirection.top]: {
2683
+ axis: "y",
2684
+ canvas: "height",
2685
+ bounce: "vertical",
2686
+ negativeEdge: "bottom",
2687
+ positiveEdge: "top",
2688
+ negative: true,
2689
+ },
2690
+ [OutModeDirection.bottom]: {
2691
+ axis: "y",
2692
+ canvas: "height",
2693
+ bounce: "vertical",
2694
+ negativeEdge: "bottom",
2695
+ positiveEdge: "top",
2696
+ negative: false,
2697
+ },
2698
+ };
2699
+ function bounce(data) {
2700
+ if ((data.outMode !== OutMode.bounce && data.outMode !== OutMode.split) || !(data.direction in bounceAxisConfigs)) {
2522
2701
  return;
2523
2702
  }
2524
- if (data.bounds.bottom < boundsMin && data.direction === OutModeDirection.top) {
2525
- data.particle.position.y = data.size + data.offset.y;
2703
+ const config = bounceAxisConfigs[data.direction], bounds = data.bounds, canvasDim = data.canvasSize[config.canvas], position = data.particle.position, velocity = data.particle.velocity[config.axis];
2704
+ if (config.negative && bounds[config.negativeEdge] < boundsMin) {
2705
+ position[config.axis] = data.size + data.offset[config.axis];
2526
2706
  }
2527
- else if (data.bounds.top > data.canvasSize.height && data.direction === OutModeDirection.bottom) {
2528
- data.particle.position.y = data.canvasSize.height - data.size - data.offset.y;
2707
+ else if (!config.negative && bounds[config.positiveEdge] > canvasDim) {
2708
+ position[config.axis] = canvasDim - data.size - data.offset[config.axis];
2529
2709
  }
2530
- const velocity = data.particle.velocity.y;
2531
- let bounced = false;
2532
2710
  if (data.outOfCanvas &&
2533
- ((data.direction === OutModeDirection.bottom && velocity > minVelocity) ||
2534
- (data.direction === OutModeDirection.top && velocity < minVelocity))) {
2535
- const newVelocity = getRangeValue(data.particle.options.bounce.vertical.value);
2536
- data.particle.velocity.y *= -newVelocity;
2537
- bounced = true;
2711
+ ((config.negative && velocity < minVelocity) || (!config.negative && velocity > minVelocity))) {
2712
+ data.particle.velocity[config.axis] *= -getRangeValue(data.particle.options.bounce[config.bounce].value);
2538
2713
  }
2539
- if (!bounced) {
2714
+ else {
2540
2715
  return;
2541
2716
  }
2542
- const minPos = data.offset.y + data.size;
2543
- if (data.outOfCanvas && data.direction === OutModeDirection.bottom) {
2544
- data.particle.position.y = data.canvasSize.height - minPos;
2545
- }
2546
- else if (data.outOfCanvas && data.direction === OutModeDirection.top) {
2547
- data.particle.position.y = minPos;
2548
- }
2717
+ const minPos = data.offset[config.axis] + data.size;
2718
+ position[config.axis] = config.negative ? minPos : canvasDim - minPos;
2549
2719
  if (data.outMode === OutMode.split) {
2550
2720
  data.particle.destroy();
2551
2721
  }
@@ -2561,26 +2731,19 @@
2561
2731
  OutMode.bounce,
2562
2732
  OutMode.split,
2563
2733
  ];
2564
- this.#particleBouncePlugins = container.plugins.filter(p => p.particleBounce !== undefined);
2734
+ this.#particleBouncePlugins = container.plugins.filter(p => !!p.particleBounce);
2565
2735
  }
2566
2736
  update(particle, direction, delta, outMode) {
2567
2737
  if (!this.modes.includes(outMode)) {
2568
2738
  return;
2569
2739
  }
2570
- const container = this.#container;
2571
- let handled = false;
2572
2740
  for (const plugin of this.#particleBouncePlugins) {
2573
- handled = plugin.particleBounce?.(particle, delta, direction) ?? false;
2574
- if (handled) {
2575
- break;
2741
+ if (plugin.particleBounce?.(particle, delta, direction)) {
2742
+ return;
2576
2743
  }
2577
2744
  }
2578
- if (handled) {
2579
- return;
2580
- }
2581
- const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = container.canvas.size, outOfCanvas = !particle.isInsideCanvasForOutMode(outMode, direction);
2582
- bounceHorizontal({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
2583
- bounceVertical({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
2745
+ const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = this.#container.canvas.size, outOfCanvas = !particle.isInsideCanvasForOutMode(outMode, direction);
2746
+ bounce({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size });
2584
2747
  }
2585
2748
  }
2586
2749
 
@@ -2669,108 +2832,109 @@
2669
2832
  return;
2670
2833
  }
2671
2834
  const container = this.#container;
2672
- switch (particle.outType) {
2673
- case ParticleOutType.inside: {
2674
- const { x: vx, y: vy } = particle.velocity;
2675
- updateVector.setTo(originPoint);
2676
- updateVector.length = particle.moveCenter.radius;
2677
- updateVector.angle = particle.velocity.angle + Math.PI;
2678
- updateVector.addTo(particle.moveCenter);
2679
- const { dx, dy } = getDistances(particle.position, updateVector);
2680
- if ((vx <= minVelocity && dx >= minDistance) ||
2681
- (vy <= minVelocity && dy >= minDistance) ||
2682
- (vx >= minVelocity && dx <= minDistance) ||
2683
- (vy >= minVelocity && dy <= minDistance)) {
2684
- return;
2685
- }
2686
- particle.position.x = Math.floor(randomInRangeValue({
2687
- min: 0,
2688
- max: container.canvas.size.width,
2689
- }));
2690
- particle.position.y = Math.floor(randomInRangeValue({
2691
- min: 0,
2692
- max: container.canvas.size.height,
2693
- }));
2694
- const { dx: newDx, dy: newDy } = getDistances(particle.position, particle.moveCenter);
2695
- particle.direction = Math.atan2(-newDy, -newDx);
2696
- particle.velocity.angle = particle.direction;
2697
- particle.justWarped = true;
2698
- break;
2835
+ if (particle.outType === ParticleOutType.inside) {
2836
+ this.#applyOutModeInside(particle, container);
2837
+ }
2838
+ else {
2839
+ if (particle.isInsideCanvasForOutMode(outMode, direction)) {
2840
+ return;
2699
2841
  }
2700
- default: {
2701
- if (particle.isInsideCanvasForOutMode(outMode, direction)) {
2702
- return;
2703
- }
2704
- switch (particle.outType) {
2705
- case ParticleOutType.outside: {
2706
- particle.position.x =
2707
- Math.floor(randomInRangeValue({
2708
- min: -particle.moveCenter.radius,
2709
- max: particle.moveCenter.radius,
2710
- })) + particle.moveCenter.x;
2711
- particle.position.y =
2712
- Math.floor(randomInRangeValue({
2713
- min: -particle.moveCenter.radius,
2714
- max: particle.moveCenter.radius,
2715
- })) + particle.moveCenter.y;
2716
- const { dx, dy } = getDistances(particle.position, particle.moveCenter);
2717
- if (particle.moveCenter.radius) {
2718
- particle.direction = Math.atan2(dy, dx);
2719
- particle.velocity.angle = particle.direction;
2720
- }
2721
- particle.justWarped = true;
2722
- break;
2723
- }
2724
- case ParticleOutType.normal: {
2725
- const warp = particle.options.move.warp, canvasSize = container.canvas.size, newPos = {
2726
- bottom: canvasSize.height + particle.getRadius() + particle.offset.y,
2727
- left: -particle.getRadius() - particle.offset.x,
2728
- right: canvasSize.width + particle.getRadius() + particle.offset.x,
2729
- top: -particle.getRadius() - particle.offset.y,
2730
- }, sizeValue = particle.getRadius(), nextBounds = calculateBounds(particle.position, sizeValue);
2731
- if (direction === OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) {
2732
- particle.position.x = newPos.left;
2733
- particle.initialPosition.x = particle.position.x;
2734
- if (!warp) {
2735
- particle.position.y = getRandom() * canvasSize.height;
2736
- particle.initialPosition.y = particle.position.y;
2737
- }
2738
- particle.justWarped = true;
2739
- }
2740
- else if (direction === OutModeDirection.left && nextBounds.right < -particle.offset.x) {
2741
- particle.position.x = newPos.right;
2742
- particle.initialPosition.x = particle.position.x;
2743
- if (!warp) {
2744
- particle.position.y = getRandom() * canvasSize.height;
2745
- particle.initialPosition.y = particle.position.y;
2746
- }
2747
- particle.justWarped = true;
2748
- }
2749
- if (direction === OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) {
2750
- if (!warp) {
2751
- particle.position.x = getRandom() * canvasSize.width;
2752
- particle.initialPosition.x = particle.position.x;
2753
- }
2754
- particle.position.y = newPos.top;
2755
- particle.initialPosition.y = particle.position.y;
2756
- particle.justWarped = true;
2757
- }
2758
- else if (direction === OutModeDirection.top && nextBounds.bottom < -particle.offset.y) {
2759
- if (!warp) {
2760
- particle.position.x = getRandom() * canvasSize.width;
2761
- particle.initialPosition.x = particle.position.x;
2762
- }
2763
- particle.position.y = newPos.bottom;
2764
- particle.initialPosition.y = particle.position.y;
2765
- particle.justWarped = true;
2766
- }
2767
- break;
2768
- }
2769
- }
2770
- break;
2842
+ if (particle.outType === ParticleOutType.outside) {
2843
+ this.#applyParticleModeOutside(particle);
2844
+ }
2845
+ else {
2846
+ this.#applyOutModeNormal(particle, container, direction);
2771
2847
  }
2772
2848
  }
2773
2849
  }
2850
+ #applyOutModeInside(particle, container) {
2851
+ const { x: vx, y: vy } = particle.velocity;
2852
+ updateVector.setTo(originPoint);
2853
+ updateVector.length = particle.moveCenter.radius;
2854
+ updateVector.angle = particle.velocity.angle + Math.PI;
2855
+ updateVector.addTo(particle.moveCenter);
2856
+ const { dx, dy } = getDistances(particle.position, updateVector);
2857
+ if ((vx <= minVelocity && dx >= minDistance) ||
2858
+ (vy <= minVelocity && dy >= minDistance) ||
2859
+ (vx >= minVelocity && dx <= minDistance) ||
2860
+ (vy >= minVelocity && dy <= minDistance)) {
2861
+ return;
2862
+ }
2863
+ particle.position.x = Math.floor(randomInRangeValue({
2864
+ min: 0,
2865
+ max: container.canvas.size.width,
2866
+ }));
2867
+ particle.position.y = Math.floor(randomInRangeValue({
2868
+ min: 0,
2869
+ max: container.canvas.size.height,
2870
+ }));
2871
+ const { dx: newDx, dy: newDy } = getDistances(particle.position, particle.moveCenter);
2872
+ particle.direction = Math.atan2(-newDy, -newDx);
2873
+ particle.velocity.angle = particle.direction;
2874
+ particle.justWarped = true;
2875
+ }
2876
+ #applyOutModeNormal(particle, container, direction) {
2877
+ const warp = particle.options.move.warp, canvasSize = container.canvas.size, sizeValue = particle.getRadius(), newPos = {
2878
+ bottom: canvasSize.height + sizeValue + particle.offset.y,
2879
+ left: -sizeValue - particle.offset.x,
2880
+ right: canvasSize.width + sizeValue + particle.offset.x,
2881
+ top: -sizeValue - particle.offset.y,
2882
+ }, nextBounds = calculateBounds(particle.position, sizeValue);
2883
+ if (direction === OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) {
2884
+ particle.position.x = newPos.left;
2885
+ particle.initialPosition.x = particle.position.x;
2886
+ if (!warp) {
2887
+ particle.position.y = getRandom() * canvasSize.height;
2888
+ particle.initialPosition.y = particle.position.y;
2889
+ }
2890
+ particle.justWarped = true;
2891
+ }
2892
+ else if (direction === OutModeDirection.left && nextBounds.right < -particle.offset.x) {
2893
+ particle.position.x = newPos.right;
2894
+ particle.initialPosition.x = particle.position.x;
2895
+ if (!warp) {
2896
+ particle.position.y = getRandom() * canvasSize.height;
2897
+ particle.initialPosition.y = particle.position.y;
2898
+ }
2899
+ particle.justWarped = true;
2900
+ }
2901
+ if (direction === OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) {
2902
+ if (!warp) {
2903
+ particle.position.x = getRandom() * canvasSize.width;
2904
+ particle.initialPosition.x = particle.position.x;
2905
+ }
2906
+ particle.position.y = newPos.top;
2907
+ particle.initialPosition.y = particle.position.y;
2908
+ particle.justWarped = true;
2909
+ }
2910
+ else if (direction === OutModeDirection.top && nextBounds.bottom < -particle.offset.y) {
2911
+ if (!warp) {
2912
+ particle.position.x = getRandom() * canvasSize.width;
2913
+ particle.initialPosition.x = particle.position.x;
2914
+ }
2915
+ particle.position.y = newPos.bottom;
2916
+ particle.initialPosition.y = particle.position.y;
2917
+ particle.justWarped = true;
2918
+ }
2919
+ }
2920
+ #applyParticleModeOutside(particle) {
2921
+ particle.position.x =
2922
+ Math.floor(randomInRangeValue({
2923
+ min: -particle.moveCenter.radius,
2924
+ max: particle.moveCenter.radius,
2925
+ })) + particle.moveCenter.x;
2926
+ particle.position.y =
2927
+ Math.floor(randomInRangeValue({
2928
+ min: -particle.moveCenter.radius,
2929
+ max: particle.moveCenter.radius,
2930
+ })) + particle.moveCenter.y;
2931
+ const { dx, dy } = getDistances(particle.position, particle.moveCenter);
2932
+ if (particle.moveCenter.radius) {
2933
+ particle.direction = Math.atan2(dy, dx);
2934
+ particle.velocity.angle = particle.direction;
2935
+ }
2936
+ particle.justWarped = true;
2937
+ }
2774
2938
  }
2775
2939
 
2776
2940
  const checkOutMode = (outModes, outMode) => {
@@ -2818,7 +2982,7 @@
2818
2982
  }
2819
2983
 
2820
2984
  async function loadOutModesUpdater(engine) {
2821
- engine.checkVersion("4.3.2");
2985
+ engine.checkVersion("4.5.0");
2822
2986
  await engine.pluginManager.register(e => {
2823
2987
  e.pluginManager.addParticleUpdater("outModes", container => {
2824
2988
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2835,39 +2999,9 @@
2835
2999
  this.#pluginManager = pluginManager;
2836
3000
  }
2837
3001
  init(particle) {
2838
- 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;
2839
- if (fill) {
2840
- const fillColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), fill.color);
2841
- particle.fillEnabled = fill.enable;
2842
- particle.fillOpacity = getRangeValue(fill.opacity);
2843
- particle.fillAnimation = fillColor.animation;
2844
- const fillHslColor = rangeColorToHsl(this.#pluginManager, fillColor);
2845
- if (fillHslColor) {
2846
- particle.fillColor = getHslAnimationFromHsl(fillHslColor, particle.fillAnimation, container.retina.reduceFactor);
2847
- }
2848
- }
2849
- else {
2850
- particle.fillEnabled = false;
2851
- particle.fillAnimation = undefined;
2852
- particle.fillColor = undefined;
2853
- particle.fillOpacity = defaultOpacity;
2854
- }
2855
- if (stroke) {
2856
- const strokeColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), stroke.color);
2857
- particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
2858
- particle.strokeOpacity = getRangeValue(stroke.opacity ?? defaultOpacity);
2859
- particle.strokeAnimation = strokeColor.animation;
2860
- const strokeHslColor = rangeColorToHsl(this.#pluginManager, strokeColor) ?? particle.getFillColor();
2861
- if (strokeHslColor) {
2862
- particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, particle.strokeAnimation, container.retina.reduceFactor);
2863
- }
2864
- }
2865
- else {
2866
- particle.strokeAnimation = undefined;
2867
- particle.strokeColor = undefined;
2868
- particle.strokeOpacity = defaultOpacity;
2869
- particle.strokeWidth = 0;
2870
- }
3002
+ const container = this.#container, options = particle.options, paint = itemFromSingleOrMultiple(options.paint, particle.id, options.reduceDuplicates);
3003
+ this.#initFill(paint, particle, container);
3004
+ this.#initStroke(paint, particle, container);
2871
3005
  }
2872
3006
  isEnabled(particle) {
2873
3007
  const { fillAnimation, fillColor, strokeAnimation, strokeColor } = particle, fillEnabled = !!fillAnimation &&
@@ -2879,17 +3013,55 @@
2879
3013
  (strokeColor?.l.value !== undefined && strokeColor.l.enable));
2880
3014
  return !particle.destroyed && !particle.spawning && (fillEnabled || strokeEnabled);
2881
3015
  }
2882
- update(particle, delta) {
2883
- if (!this.isEnabled(particle)) {
3016
+ update(particle, delta) {
3017
+ if (!this.isEnabled(particle)) {
3018
+ return;
3019
+ }
3020
+ updateColor(particle.fillColor, delta, this.#container.hdr);
3021
+ updateColor(particle.strokeColor, delta, this.#container.hdr);
3022
+ }
3023
+ #initFill(paint, particle, container) {
3024
+ const fill = paint?.fill, color = paint?.color, paintColor = color ?? undefined;
3025
+ if (!fill) {
3026
+ particle.fillEnabled = false;
3027
+ particle.fillAnimation = undefined;
3028
+ particle.fillColor = undefined;
3029
+ particle.fillOpacity = defaultOpacity;
3030
+ return;
3031
+ }
3032
+ const fillColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), fill.color);
3033
+ particle.fillEnabled = fill.enable;
3034
+ particle.fillOpacity = getRangeValue(fill.opacity);
3035
+ particle.fillAnimation = fillColor.animation;
3036
+ const fillHslColor = rangeColorToHsl(this.#pluginManager, fillColor);
3037
+ if (!fillHslColor) {
3038
+ return;
3039
+ }
3040
+ particle.fillColor = getHslAnimationFromHsl(fillHslColor, particle.fillAnimation, container.retina.reduceFactor);
3041
+ }
3042
+ #initStroke(paint, particle, container) {
3043
+ const stroke = paint?.stroke, color = paint?.color, paintColor = color ?? undefined;
3044
+ if (!stroke) {
3045
+ particle.strokeAnimation = undefined;
3046
+ particle.strokeColor = undefined;
3047
+ particle.strokeOpacity = defaultOpacity;
3048
+ particle.strokeWidth = 0;
2884
3049
  return;
2885
3050
  }
2886
- updateColor(particle.fillColor, delta, this.#container.hdr);
2887
- updateColor(particle.strokeColor, delta, this.#container.hdr);
3051
+ const strokeColor = AnimatableColor.create(paintColor === undefined ? undefined : AnimatableColor.create(undefined, paintColor), stroke.color);
3052
+ particle.strokeWidth = getRangeValue(stroke.width) * container.retina.pixelRatio;
3053
+ particle.strokeOpacity = getRangeValue(stroke.opacity ?? defaultOpacity);
3054
+ particle.strokeAnimation = strokeColor.animation;
3055
+ const strokeHslColor = rangeColorToHsl(this.#pluginManager, strokeColor) ?? particle.getFillColor();
3056
+ if (!strokeHslColor) {
3057
+ return;
3058
+ }
3059
+ particle.strokeColor = getHslAnimationFromHsl(strokeHslColor, particle.strokeAnimation, container.retina.reduceFactor);
2888
3060
  }
2889
3061
  }
2890
3062
 
2891
3063
  async function loadPaintUpdater(engine) {
2892
- engine.checkVersion("4.3.2");
3064
+ engine.checkVersion("4.5.0");
2893
3065
  await engine.pluginManager.register(e => {
2894
3066
  e.pluginManager.addParticleUpdater("paint", container => {
2895
3067
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2931,7 +3103,7 @@
2931
3103
  if (!this.accepts(input)) {
2932
3104
  return;
2933
3105
  }
2934
- const result = rgbRegex.exec(input), radix = 10, minLength = 4, defaultAlpha = 1;
3106
+ const result = rgbRegex.exec(input), radix = 10, minLength = 4;
2935
3107
  return result
2936
3108
  ? {
2937
3109
  a: result.length > minLength ? parseAlpha(result[RgbIndexes.a]) : defaultAlpha,
@@ -2944,7 +3116,7 @@
2944
3116
  }
2945
3117
 
2946
3118
  async function loadRgbColorPlugin(engine) {
2947
- engine.checkVersion("4.3.2");
3119
+ engine.checkVersion("4.5.0");
2948
3120
  await engine.pluginManager.register(e => {
2949
3121
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
2950
3122
  });
@@ -3029,7 +3201,7 @@
3029
3201
  }
3030
3202
 
3031
3203
  async function loadSizeUpdater(engine) {
3032
- engine.checkVersion("4.3.2");
3204
+ engine.checkVersion("4.5.0");
3033
3205
  await engine.pluginManager.register(e => {
3034
3206
  e.pluginManager.addParticleUpdater("size", container => {
3035
3207
  return Promise.resolve(new SizeUpdater(container));
@@ -3038,7 +3210,7 @@
3038
3210
  }
3039
3211
 
3040
3212
  async function loadBasic(engine) {
3041
- engine.checkVersion("4.3.2");
3213
+ engine.checkVersion("4.5.0");
3042
3214
  await engine.pluginManager.register(async (e) => {
3043
3215
  await Promise.all([
3044
3216
  loadBlendPlugin(e),
@@ -3169,21 +3341,28 @@
3169
3341
  });
3170
3342
  }
3171
3343
  clear() {
3344
+ const visited = new Set();
3172
3345
  for (const plugin of this.#canvasClearPlugins) {
3346
+ visited.add(plugin);
3173
3347
  if (plugin.canvasClear?.() ?? false) {
3174
- return;
3348
+ return plugin;
3175
3349
  }
3176
3350
  }
3177
3351
  for (const layer of Object.values(DrawLayer)) {
3178
3352
  if (typeof layer === "number") {
3179
3353
  for (const plugin of this.#getLayerPlugins(layer)) {
3354
+ if (visited.has(plugin)) {
3355
+ continue;
3356
+ }
3357
+ visited.add(plugin);
3180
3358
  if (plugin.canvasClear?.() ?? false) {
3181
- return;
3359
+ return plugin;
3182
3360
  }
3183
3361
  }
3184
3362
  }
3185
3363
  }
3186
3364
  this.canvasClear();
3365
+ return undefined;
3187
3366
  }
3188
3367
  destroy() {
3189
3368
  this.stop();
@@ -3224,7 +3403,11 @@
3224
3403
  if (!fColor && !sColor) {
3225
3404
  return;
3226
3405
  }
3227
- const container = this.#container, zIndexOptions = particle.options.zIndex, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, { fillOpacity, opacity, strokeOpacity } = particle.getOpacity(), transform = this.#reusableTransform, colorStyles = this.#reusableColorStyles, fill = fColor ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity) : undefined, stroke = sColor ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity) : fill;
3406
+ const container = this.#container, zIndexOptions = particle.options.zIndex, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, { fillOpacity, opacity, strokeOpacity } = particle.getOpacity(), transform = this.#reusableTransform, colorStyles = this.#reusableColorStyles, fill = fColor
3407
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
3408
+ : undefined, stroke = sColor
3409
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
3410
+ : fill;
3228
3411
  transform.a = transform.b = transform.c = transform.d = undefined;
3229
3412
  colorStyles.fill = fill;
3230
3413
  colorStyles.stroke = stroke;
@@ -3257,8 +3440,7 @@
3257
3440
  });
3258
3441
  }
3259
3442
  drawParticles(delta) {
3260
- const { particles, actualOptions } = this.#container;
3261
- this.clear();
3443
+ const { particles, actualOptions } = this.#container, clearedPlugin = this.clear();
3262
3444
  particles.update(delta);
3263
3445
  this.draw(ctx => {
3264
3446
  const width = this.#canvasManager.size.width, height = this.#canvasManager.size.height;
@@ -3280,7 +3462,9 @@
3280
3462
  }
3281
3463
  }
3282
3464
  for (const plugin of this.#getLayerPlugins(DrawLayer.BackgroundMask)) {
3283
- plugin.canvasPaint?.();
3465
+ if (plugin !== clearedPlugin) {
3466
+ plugin.canvasPaint?.();
3467
+ }
3284
3468
  }
3285
3469
  for (const plugin of this.#getLayerPlugins(DrawLayer.CanvasSetup)) {
3286
3470
  plugin.drawSettingsSetup?.(ctx, delta);
@@ -3312,35 +3496,7 @@
3312
3496
  this.#layers[layer] = [];
3313
3497
  }
3314
3498
  }
3315
- for (const plugin of this.#container.plugins) {
3316
- if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
3317
- this.#colorPlugins.push(plugin);
3318
- }
3319
- if (plugin.drawParticle) {
3320
- this.#drawParticlePlugins.push(plugin);
3321
- }
3322
- if (plugin.drawParticleSetup) {
3323
- this.#drawParticlesSetupPlugins.push(plugin);
3324
- }
3325
- if (plugin.drawParticleCleanup) {
3326
- this.#drawParticlesCleanupPlugins.push(plugin);
3327
- }
3328
- if (plugin.canvasClear) {
3329
- this.#canvasClearPlugins.push(plugin);
3330
- }
3331
- if (plugin.canvasPaint) {
3332
- this.#getLayerPlugins(DrawLayer.BackgroundMask).push(plugin);
3333
- }
3334
- if (plugin.drawSettingsSetup) {
3335
- this.#getLayerPlugins(DrawLayer.CanvasSetup).push(plugin);
3336
- }
3337
- if (plugin.draw) {
3338
- this.#getLayerPlugins(DrawLayer.PluginContent).push(plugin);
3339
- }
3340
- if (plugin.clearDraw ?? plugin.drawSettingsCleanup) {
3341
- this.#getLayerPlugins(DrawLayer.CanvasCleanup).push(plugin);
3342
- }
3343
- }
3499
+ this.#initPluginsArray();
3344
3500
  }
3345
3501
  initUpdaters() {
3346
3502
  this.#preDrawUpdaters = [];
@@ -3549,6 +3705,45 @@
3549
3705
  this.#reusablePluginColors[sColorIndex] = sColor;
3550
3706
  return this.#reusablePluginColors;
3551
3707
  }
3708
+ #initLayerPlugin(plugin) {
3709
+ const layerMap = [
3710
+ [DrawLayer.BackgroundMask, !!plugin.canvasPaint],
3711
+ [DrawLayer.CanvasSetup, !!plugin.drawSettingsSetup],
3712
+ [DrawLayer.PluginContent, !!plugin.draw],
3713
+ [DrawLayer.CanvasCleanup, !!(plugin.clearDraw ?? plugin.drawSettingsCleanup)],
3714
+ ];
3715
+ for (const [layer, active] of layerMap) {
3716
+ if (active) {
3717
+ this.#layers[layer].push(plugin);
3718
+ }
3719
+ }
3720
+ }
3721
+ #initPluginsArray() {
3722
+ for (const plugin of this.#container.plugins) {
3723
+ if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
3724
+ this.#colorPlugins.push(plugin);
3725
+ }
3726
+ if (plugin.drawParticle) {
3727
+ this.#drawParticlePlugins.push(plugin);
3728
+ }
3729
+ if (plugin.drawParticleSetup) {
3730
+ this.#drawParticlesSetupPlugins.push(plugin);
3731
+ }
3732
+ if (plugin.drawParticleCleanup) {
3733
+ this.#drawParticlesCleanupPlugins.push(plugin);
3734
+ }
3735
+ if (plugin.canvasClear) {
3736
+ this.#canvasClearPlugins.push(plugin);
3737
+ }
3738
+ this.#initLayerPlugin(plugin);
3739
+ }
3740
+ }
3741
+ #isSupportedElement(element) {
3742
+ return ((typeof HTMLCanvasElement !== "undefined" && element instanceof HTMLCanvasElement) ||
3743
+ (typeof OffscreenCanvas !== "undefined" && element instanceof OffscreenCanvas) ||
3744
+ (typeof HTMLVideoElement !== "undefined" && element instanceof HTMLVideoElement) ||
3745
+ (typeof HTMLImageElement !== "undefined" && element instanceof HTMLImageElement));
3746
+ }
3552
3747
  #resolveBackgroundElement() {
3553
3748
  const background = this.#container.actualOptions.background;
3554
3749
  this.#backgroundElement = null;
@@ -3558,7 +3753,7 @@
3558
3753
  if (typeof background.element === "string") {
3559
3754
  if (typeof document !== "undefined") {
3560
3755
  const node = document.querySelector(background.element);
3561
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
3756
+ if (node && this.#isSupportedElement(node)) {
3562
3757
  this.#backgroundElement = node;
3563
3758
  }
3564
3759
  else if (node) {
@@ -3569,10 +3764,7 @@
3569
3764
  }
3570
3765
  }
3571
3766
  }
3572
- else if (background.element instanceof HTMLCanvasElement ||
3573
- background.element instanceof OffscreenCanvas ||
3574
- background.element instanceof HTMLVideoElement ||
3575
- background.element instanceof HTMLImageElement) {
3767
+ else if (this.#isSupportedElement(background.element)) {
3576
3768
  this.#backgroundElement = background.element;
3577
3769
  }
3578
3770
  }
@@ -3590,7 +3782,7 @@
3590
3782
  return transferredCanvas;
3591
3783
  }
3592
3784
  if (typeof canvas.transferControlToOffscreen !== "function") {
3593
- throw new TypeError("OffscreenCanvas is required but not supported by this browser");
3785
+ throw new TypeError(getErrorMessage(ErrorCodes$1.offscreenCanvasUnsupported));
3594
3786
  }
3595
3787
  try {
3596
3788
  const offscreenCanvas = canvas.transferControlToOffscreen();
@@ -3598,10 +3790,16 @@
3598
3790
  return offscreenCanvas;
3599
3791
  }
3600
3792
  catch {
3601
- throw new TypeError("OffscreenCanvas transfer failed");
3793
+ throw new TypeError(getErrorMessage(ErrorCodes$1.offscreenCanvasTransferFailed));
3602
3794
  }
3603
3795
  }, isHtmlCanvasElement = (canvas) => {
3604
3796
  return typeof HTMLCanvasElement !== "undefined" && canvas instanceof HTMLCanvasElement;
3797
+ }, getEffectiveColorSpace = (context) => {
3798
+ if (!context) {
3799
+ return undefined;
3800
+ }
3801
+ const colorInfo = context;
3802
+ return colorInfo.getContextAttributes?.().colorSpace ?? undefined;
3605
3803
  };
3606
3804
  function setStyle(canvas, style, important = false) {
3607
3805
  if (!style) {
@@ -3640,6 +3838,7 @@
3640
3838
  zoom = defaultZoom;
3641
3839
  #container;
3642
3840
  #generated;
3841
+ #hdrMediaListeners;
3643
3842
  #mutationObserver;
3644
3843
  #originalStyle;
3645
3844
  #pluginManager;
@@ -3704,7 +3903,6 @@
3704
3903
  });
3705
3904
  this.resize();
3706
3905
  this.#initStyle();
3707
- this.initBackground();
3708
3906
  this.#safeMutationObserver(obs => {
3709
3907
  const element = this.domElement;
3710
3908
  if (!element || !(element instanceof Node)) {
@@ -3714,6 +3912,8 @@
3714
3912
  });
3715
3913
  this.initPlugins();
3716
3914
  this.#initContext();
3915
+ this.initBackground();
3916
+ this.#initHdrListeners();
3717
3917
  this.render.init();
3718
3918
  }
3719
3919
  initBackground() {
@@ -3723,7 +3923,8 @@
3723
3923
  }
3724
3924
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
3725
3925
  if (color) {
3726
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
3926
+ const hdrOptions = container.actualOptions.hdr;
3927
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, toEnumValue(HdrMode, hdrOptions.mode, HdrMode.standard));
3727
3928
  }
3728
3929
  else {
3729
3930
  elementStyle.backgroundColor = "";
@@ -3820,6 +4021,7 @@
3820
4021
  obs.disconnect();
3821
4022
  });
3822
4023
  this.#mutationObserver = undefined;
4024
+ this.#removeHdrListeners();
3823
4025
  this.render.stop();
3824
4026
  }
3825
4027
  async windowResize() {
@@ -3839,9 +4041,16 @@
3839
4041
  }
3840
4042
  }
3841
4043
  #initContext() {
3842
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4044
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
3843
4045
  safeMatchMedia("(color-gamut: p3)")?.matches &&
3844
4046
  safeMatchMedia("(dynamic-range: high)")?.matches;
4047
+ container.hdrMode = toEnumValue(HdrMode, container.actualOptions.hdr.mode, HdrMode.standard);
4048
+ container.peakNits = container.actualOptions.hdr.peakNits;
4049
+ const renderCanvas = this.renderCanvas;
4050
+ if (!renderCanvas) {
4051
+ container.hdr = canSupportHdr ?? false;
4052
+ return;
4053
+ }
3845
4054
  this.render.setContextSettings({
3846
4055
  alpha: true,
3847
4056
  desynchronized: true,
@@ -3850,11 +4059,51 @@
3850
4059
  ? { colorSpace: "display-p3", colorType: "float16" }
3851
4060
  : { colorSpace: "srgb" }),
3852
4061
  });
3853
- const renderCanvas = this.renderCanvas;
3854
- if (!renderCanvas) {
3855
- return;
4062
+ let context;
4063
+ try {
4064
+ context = renderCanvas.getContext("2d", this.render.settings);
4065
+ }
4066
+ catch {
4067
+ context = null;
4068
+ }
4069
+ if (canSupportHdr && !context) {
4070
+ const sdrSettings = {
4071
+ alpha: true,
4072
+ desynchronized: true,
4073
+ willReadFrequently: false,
4074
+ colorSpace: "srgb",
4075
+ };
4076
+ this.render.setContextSettings(sdrSettings);
4077
+ try {
4078
+ context = renderCanvas.getContext("2d", sdrSettings);
4079
+ }
4080
+ catch {
4081
+ context = null;
4082
+ }
4083
+ }
4084
+ this.render.setContext(context);
4085
+ if (context) {
4086
+ const effectiveColorSpace = getEffectiveColorSpace(context);
4087
+ if (effectiveColorSpace !== undefined) {
4088
+ container.hdr = effectiveColorSpace === "display-p3";
4089
+ }
3856
4090
  }
3857
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4091
+ }
4092
+ #initHdrListeners() {
4093
+ this.#removeHdrListeners();
4094
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
4095
+ this.#initContext();
4096
+ this.initBackground();
4097
+ }, listeners = [];
4098
+ if (p3Query) {
4099
+ p3Query.addEventListener("change", handleChange);
4100
+ listeners.push({ handler: handleChange, mql: p3Query });
4101
+ }
4102
+ if (hdrQuery) {
4103
+ hdrQuery.addEventListener("change", handleChange);
4104
+ listeners.push({ handler: handleChange, mql: hdrQuery });
4105
+ }
4106
+ this.#hdrMediaListeners = listeners;
3858
4107
  }
3859
4108
  #initStyle() {
3860
4109
  const element = this.domElement, options = this.#container.actualOptions;
@@ -3878,6 +4127,15 @@
3878
4127
  element.style.setProperty(key, value, "important");
3879
4128
  }
3880
4129
  }
4130
+ #removeHdrListeners() {
4131
+ if (!this.#hdrMediaListeners) {
4132
+ return;
4133
+ }
4134
+ for (const { handler, mql } of this.#hdrMediaListeners) {
4135
+ mql.removeEventListener("change", handler);
4136
+ }
4137
+ this.#hdrMediaListeners = undefined;
4138
+ }
3881
4139
  #repairStyle() {
3882
4140
  const element = this.domElement;
3883
4141
  if (!element) {
@@ -3967,8 +4225,7 @@
3967
4225
  this.#resizeTimeout = undefined;
3968
4226
  }
3969
4227
  const handleResize = async () => {
3970
- const canvas = this.#container.canvas;
3971
- await canvas.windowResize();
4228
+ await this.#container.canvas.windowResize();
3972
4229
  };
3973
4230
  this.#resizeTimeout = setTimeout(() => void handleResize(), this.#container.actualOptions.resize.delay * millisecondsToSeconds);
3974
4231
  }
@@ -3996,8 +4253,8 @@
3996
4253
  }
3997
4254
  else if (!this.#resizeObserver && add && canvasEl) {
3998
4255
  this.#resizeObserver = new ResizeObserver((entries) => {
3999
- const entry = entries.find(e => e.target === canvasEl);
4000
- if (!entry) {
4256
+ const res = entries.some(e => e.target === canvasEl);
4257
+ if (!res) {
4001
4258
  return;
4002
4259
  }
4003
4260
  this.#handleWindowResize();
@@ -4261,10 +4518,10 @@
4261
4518
  return this.#modifiers.find(m => m.id === id);
4262
4519
  }
4263
4520
  getOpacity() {
4264
- 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;
4265
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
4521
+ 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;
4522
+ this.#cachedOpacityData.fillOpacity = this.fillOpacity ?? defaultOpacity$1;
4266
4523
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
4267
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
4524
+ this.#cachedOpacityData.strokeOpacity = this.strokeOpacity ?? defaultOpacity$1;
4268
4525
  return this.#cachedOpacityData;
4269
4526
  }
4270
4527
  getPosition() {
@@ -4511,7 +4768,7 @@
4511
4768
  #initPosition(position) {
4512
4769
  const container = this.#container, zIndexValue = Math.floor(getRangeValue(this.options.zIndex.value)), initialPosition = this.#calcPosition(position, clamp(zIndexValue, minZ, container.zLayers));
4513
4770
  if (!initialPosition) {
4514
- throw new Error("a valid position cannot be found for particle");
4771
+ throw new Error(getErrorMessage(ErrorCodes$1.particlePositionNotFound));
4515
4772
  }
4516
4773
  this.position = initialPosition;
4517
4774
  this.initialPosition = this.position.copy();
@@ -4560,6 +4817,12 @@
4560
4817
  this.#circlePoolIdx = 0;
4561
4818
  this.#rectanglePoolIdx = 0;
4562
4819
  }
4820
+ get cellSize() {
4821
+ return this.#cellSize;
4822
+ }
4823
+ set cellSize(value) {
4824
+ this.#pendingCellSize = value;
4825
+ }
4563
4826
  clear() {
4564
4827
  this.#cells.clear();
4565
4828
  const pendingCellSize = this.#pendingCellSize;
@@ -4583,18 +4846,7 @@
4583
4846
  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);
4584
4847
  for (let cx = minCellX; cx <= maxCellX; cx++) {
4585
4848
  for (let cy = minCellY; cy <= maxCellY; cy++) {
4586
- const key = `${cx}_${cy}`, cellParticles = this.#cells.get(key);
4587
- if (!cellParticles) {
4588
- continue;
4589
- }
4590
- for (const p of cellParticles) {
4591
- if (check && !check(p)) {
4592
- continue;
4593
- }
4594
- if (range.contains(p.getPosition())) {
4595
- out.push(p);
4596
- }
4597
- }
4849
+ this.#queryCell(cx, cy, range, check, out);
4598
4850
  }
4599
4851
  }
4600
4852
  return out;
@@ -4609,14 +4861,23 @@
4609
4861
  this.#releaseShapes();
4610
4862
  return result;
4611
4863
  }
4612
- setCellSize(cellSize) {
4613
- this.#pendingCellSize = cellSize;
4614
- }
4615
4864
  #acquireCircle(x, y, r) {
4616
- return (this.#circlePool[this.#circlePoolIdx++] ??= new Circle(x, y, r)).reset(x, y, r);
4865
+ const idx = this.#circlePoolIdx++;
4866
+ let circle = this.#circlePool[idx];
4867
+ if (!circle) {
4868
+ circle = new Circle(x, y, r);
4869
+ this.#circlePool[idx] = circle;
4870
+ }
4871
+ return circle.reset(x, y, r);
4617
4872
  }
4618
4873
  #acquireRectangle(x, y, w, h) {
4619
- return (this.#rectanglePool[this.#rectanglePoolIdx++] ??= new Rectangle(x, y, w, h)).reset(x, y, w, h);
4874
+ const idx = this.#rectanglePoolIdx++;
4875
+ let rectangle = this.#rectanglePool[idx];
4876
+ if (!rectangle) {
4877
+ rectangle = new Rectangle(x, y, w, h);
4878
+ this.#rectanglePool[idx] = rectangle;
4879
+ }
4880
+ return rectangle.reset(x, y, w, h);
4620
4881
  }
4621
4882
  #cellKeyFromCoords(x, y) {
4622
4883
  const cellX = Math.floor(x / this.#cellSize), cellY = Math.floor(y / this.#cellSize);
@@ -4643,6 +4904,20 @@
4643
4904
  }
4644
4905
  return null;
4645
4906
  }
4907
+ #queryCell(cx, cy, range, check, out) {
4908
+ const cellParticles = this.#cells.get(`${cx}_${cy}`);
4909
+ if (!cellParticles) {
4910
+ return;
4911
+ }
4912
+ for (const p of cellParticles) {
4913
+ if (check && !check(p)) {
4914
+ continue;
4915
+ }
4916
+ if (range.contains(p.getPosition())) {
4917
+ out.push(p);
4918
+ }
4919
+ }
4920
+ }
4646
4921
  #releaseShapes() {
4647
4922
  this.#circlePoolIdx = 0;
4648
4923
  this.#rectanglePoolIdx = 0;
@@ -4651,9 +4926,9 @@
4651
4926
 
4652
4927
  class ParticlesManager {
4653
4928
  checkParticlePositionPlugins;
4654
- grid;
4655
4929
  #array;
4656
4930
  #container;
4931
+ #grid;
4657
4932
  #groupLimits;
4658
4933
  #limit;
4659
4934
  #nextId;
@@ -4677,7 +4952,7 @@
4677
4952
  this.#groupLimits = new Map();
4678
4953
  this.#particleBuckets = new Map();
4679
4954
  this.#zBuckets = this.#createBuckets(this.#container.zLayers);
4680
- this.grid = new SpatialHashGrid(spatialHashGridCellSize);
4955
+ this.#grid = new SpatialHashGrid(spatialHashGridCellSize);
4681
4956
  this.checkParticlePositionPlugins = [];
4682
4957
  this.#particleResetPlugins = [];
4683
4958
  this.#particleUpdatePlugins = [];
@@ -4688,23 +4963,12 @@
4688
4963
  get count() {
4689
4964
  return this.#array.length;
4690
4965
  }
4966
+ get grid() {
4967
+ return this.#grid;
4968
+ }
4691
4969
  addParticle(position, overrideOptions, group, initializer) {
4692
- const limitMode = this.#container.actualOptions.particles.number.limit.mode, limit = group === undefined ? this.#limit : (this.#groupLimits.get(group) ?? this.#limit), currentCount = this.count;
4693
- if (limit > minLimit) {
4694
- switch (limitMode) {
4695
- case LimitMode.delete: {
4696
- const countToRemove = currentCount + countOffset - limit;
4697
- if (countToRemove > minCount) {
4698
- this.removeQuantity(countToRemove);
4699
- }
4700
- break;
4701
- }
4702
- case LimitMode.wait:
4703
- if (currentCount >= limit) {
4704
- return;
4705
- }
4706
- break;
4707
- }
4970
+ if (this.#checkAndApplyLimits(group, this.count)) {
4971
+ return;
4708
4972
  }
4709
4973
  try {
4710
4974
  const particle = this.#pool.pop() ?? new Particle(this.#pluginManager, this.#container);
@@ -4768,7 +5032,7 @@
4768
5032
  return this.#array[index];
4769
5033
  }
4770
5034
  async init() {
4771
- const container = this.#container, options = container.actualOptions;
5035
+ const container = this.#container;
4772
5036
  this.checkParticlePositionPlugins = [];
4773
5037
  this.#updatePlugins = [];
4774
5038
  this.#particleUpdatePlugins = [];
@@ -4777,59 +5041,16 @@
4777
5041
  this.#postParticleUpdatePlugins = [];
4778
5042
  this.#particleBuckets.clear();
4779
5043
  this.#resetBuckets(container.zLayers);
4780
- this.grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
4781
- for (const plugin of container.plugins) {
4782
- if (plugin.redrawInit) {
4783
- await plugin.redrawInit();
4784
- }
4785
- if (plugin.checkParticlePosition) {
4786
- this.checkParticlePositionPlugins.push(plugin);
4787
- }
4788
- if (plugin.update) {
4789
- this.#updatePlugins.push(plugin);
4790
- }
4791
- if (plugin.particleUpdate) {
4792
- this.#particleUpdatePlugins.push(plugin);
4793
- }
4794
- if (plugin.postUpdate) {
4795
- this.#postUpdatePlugins.push(plugin);
4796
- }
4797
- if (plugin.particleReset) {
4798
- this.#particleResetPlugins.push(plugin);
4799
- }
4800
- if (plugin.postParticleUpdate) {
4801
- this.#postParticleUpdatePlugins.push(plugin);
4802
- }
4803
- }
4804
- await this.#container.initDrawersAndUpdaters();
4805
- for (const drawer of this.#container.effectDrawers.values()) {
4806
- await drawer.init?.(container);
4807
- }
4808
- for (const drawer of this.#container.shapeDrawers.values()) {
4809
- await drawer.init?.(container);
4810
- }
4811
- let handled = false;
4812
- for (const plugin of container.plugins) {
4813
- handled = plugin.particlesInitialization?.() ?? handled;
4814
- if (handled) {
4815
- break;
4816
- }
4817
- }
4818
- if (!handled) {
4819
- const particlesOptions = options.particles, groups = particlesOptions.groups;
4820
- for (const group in groups) {
4821
- const groupOptions = groups[group];
4822
- if (!groupOptions) {
4823
- continue;
4824
- }
4825
- for (let i = this.count, j = 0; j < groupOptions.number.value && i < particlesOptions.number.value; i++, j++) {
4826
- this.addParticle(undefined, groupOptions, group);
4827
- }
4828
- }
4829
- for (let i = this.count; i < particlesOptions.number.value; i++) {
4830
- this.addParticle();
5044
+ this.#grid = new SpatialHashGrid(spatialHashGridCellSize * container.retina.pixelRatio);
5045
+ this.#applyLimits(container.actualOptions.particles);
5046
+ const particlesOptions = container.actualOptions.particles, groups = particlesOptions.groups;
5047
+ for (const group in groups) {
5048
+ const groupData = groups[group];
5049
+ if (groupData) {
5050
+ this.#applyLimits(loadParticlesOptions(this.#pluginManager, this.#container, groupData), group, groupData);
4831
5051
  }
4832
5052
  }
5053
+ await this.#initPlugins();
4833
5054
  }
4834
5055
  push(nb, position, overrideOptions, group) {
4835
5056
  for (let i = 0; i < nb; i++) {
@@ -4844,13 +5065,13 @@
4844
5065
  remove(particle, group, override) {
4845
5066
  this.removeAt(this.#array.indexOf(particle), undefined, group, override);
4846
5067
  }
4847
- removeAt(index, quantity = defaultRemoveQuantity, group, override) {
5068
+ removeAt(index, quantity = defaultRemoveQuantity, group, override, matchGroup = true) {
4848
5069
  if (index < minIndex || index > this.count) {
4849
5070
  return;
4850
5071
  }
4851
5072
  let deleted = 0;
4852
5073
  for (let i = index; deleted < quantity && i < this.count; i++) {
4853
- if (this.#removeParticle(i, group, override)) {
5074
+ if (this.#removeParticle(i, group, override, matchGroup)) {
4854
5075
  i--;
4855
5076
  deleted++;
4856
5077
  }
@@ -4881,7 +5102,7 @@
4881
5102
  this.#resizeFactor = factor;
4882
5103
  }
4883
5104
  update(delta) {
4884
- this.grid.clear();
5105
+ this.#grid.clear();
4885
5106
  for (const plugin of this.#updatePlugins) {
4886
5107
  plugin.update?.(delta);
4887
5108
  }
@@ -4892,7 +5113,7 @@
4892
5113
  this.#updateParticlesPhase2(delta, particlesToDelete);
4893
5114
  if (particlesToDelete.size) {
4894
5115
  for (const particle of particlesToDelete) {
4895
- this.remove(particle);
5116
+ this.remove(particle, particle.group);
4896
5117
  }
4897
5118
  }
4898
5119
  this.#resizeFactor = undefined;
@@ -4903,12 +5124,7 @@
4903
5124
  #applyDensity(options, pluginsCount, group, groupOptions) {
4904
5125
  const numberOptions = options.number;
4905
5126
  if (!numberOptions.density.enable) {
4906
- if (group === undefined) {
4907
- this.#limit = numberOptions.limit.value;
4908
- }
4909
- else if (groupOptions?.number.limit.value ?? numberOptions.limit.value) {
4910
- this.#groupLimits.set(group, groupOptions?.number.limit.value ?? numberOptions.limit.value);
4911
- }
5127
+ this.#applyLimits(options, group, groupOptions);
4912
5128
  return;
4913
5129
  }
4914
5130
  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);
@@ -4916,7 +5132,10 @@
4916
5132
  this.#limit = numberOptions.limit.value * densityFactor;
4917
5133
  }
4918
5134
  else {
4919
- this.#groupLimits.set(group, numberOptions.limit.value * densityFactor);
5135
+ this.#groupLimits.set(group, {
5136
+ limit: numberOptions.limit.value * densityFactor,
5137
+ mode: toEnumValue(LimitMode, numberOptions.limit.mode, LimitMode.delete),
5138
+ });
4920
5139
  }
4921
5140
  if (particlesCount < particlesNumber) {
4922
5141
  this.push(Math.abs(particlesNumber - particlesCount), undefined, options, group);
@@ -4925,6 +5144,55 @@
4925
5144
  this.removeQuantity(particlesCount - particlesNumber, group);
4926
5145
  }
4927
5146
  }
5147
+ #applyLimits(options, group, groupOptions) {
5148
+ if (group === undefined) {
5149
+ this.#limit = options.number.limit.value;
5150
+ const groups = this.#container.actualOptions.particles.groups;
5151
+ for (const existingGroup of this.#groupLimits.keys()) {
5152
+ if (!(existingGroup in groups)) {
5153
+ this.#groupLimits.delete(existingGroup);
5154
+ }
5155
+ }
5156
+ }
5157
+ else {
5158
+ const limitValue = groupOptions?.number?.limit?.value ?? options.number.limit.value;
5159
+ if (limitValue > minLimit) {
5160
+ this.#groupLimits.set(group, {
5161
+ limit: limitValue,
5162
+ mode: toEnumValue(LimitMode, groupOptions?.number?.limit?.mode ?? options.number.limit.mode, LimitMode.delete),
5163
+ });
5164
+ }
5165
+ else {
5166
+ this.#groupLimits.delete(group);
5167
+ }
5168
+ }
5169
+ }
5170
+ #checkAndApplyLimits(group, currentCount) {
5171
+ const globalLimit = this.#limit, globalMode = this.#container.actualOptions.particles.number.limit.mode;
5172
+ if (globalLimit > minLimit && globalMode === LimitMode.wait && currentCount >= globalLimit) {
5173
+ return true;
5174
+ }
5175
+ const groupLimitEntry = group === undefined ? undefined : this.#groupLimits.get(group);
5176
+ if (groupLimitEntry && groupLimitEntry.limit > minLimit && groupLimitEntry.mode === LimitMode.wait) {
5177
+ const groupCount = this.filter(t => t.group === group).length;
5178
+ if (groupCount >= groupLimitEntry.limit) {
5179
+ return true;
5180
+ }
5181
+ }
5182
+ if (groupLimitEntry && groupLimitEntry.limit > minLimit && groupLimitEntry.mode === LimitMode.delete) {
5183
+ const groupCountToRemove = this.filter(t => t.group === group).length + countOffset - groupLimitEntry.limit;
5184
+ if (groupCountToRemove > minCount) {
5185
+ this.removeQuantity(groupCountToRemove, group);
5186
+ }
5187
+ }
5188
+ if (globalLimit > minLimit && globalMode === LimitMode.delete) {
5189
+ const globalCountToRemove = this.count + countOffset - globalLimit;
5190
+ if (globalCountToRemove > minCount) {
5191
+ this.#removeAny(globalCountToRemove);
5192
+ }
5193
+ }
5194
+ return false;
5195
+ }
4928
5196
  #createBuckets(zLayers) {
4929
5197
  const bucketCount = Math.max(Math.floor(zLayers), one);
4930
5198
  return Array.from({ length: bucketCount }, () => []);
@@ -4947,6 +5215,70 @@
4947
5215
  }
4948
5216
  return ((canvasSize.width * canvasSize.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp));
4949
5217
  }
5218
+ async #initDrawersAndUpdaters() {
5219
+ const container = this.#container;
5220
+ await container.initDrawersAndUpdaters();
5221
+ for (const drawer of container.effectDrawers.values()) {
5222
+ await drawer.init?.(container);
5223
+ }
5224
+ for (const drawer of container.shapeDrawers.values()) {
5225
+ await drawer.init?.(container);
5226
+ }
5227
+ }
5228
+ async #initPlugins() {
5229
+ await this.#initPluginsArrays();
5230
+ await this.#initDrawersAndUpdaters();
5231
+ let handled = false;
5232
+ const container = this.#container;
5233
+ for (const plugin of container.plugins) {
5234
+ handled = plugin.particlesInitialization?.() ?? handled;
5235
+ if (handled) {
5236
+ break;
5237
+ }
5238
+ }
5239
+ if (handled) {
5240
+ return;
5241
+ }
5242
+ const particlesOptions = container.actualOptions.particles, groups = particlesOptions.groups;
5243
+ for (const group in groups) {
5244
+ const groupOptions = groups[group];
5245
+ if (!groupOptions) {
5246
+ continue;
5247
+ }
5248
+ for (let i = this.count, j = 0; j < groupOptions.number.value && i < particlesOptions.number.value; i++, j++) {
5249
+ this.addParticle(undefined, groupOptions, group);
5250
+ }
5251
+ }
5252
+ for (let i = this.count; i < particlesOptions.number.value; i++) {
5253
+ this.addParticle();
5254
+ }
5255
+ }
5256
+ async #initPluginsArrays() {
5257
+ const container = this.#container;
5258
+ for (const plugin of container.plugins) {
5259
+ if (plugin.redrawInit) {
5260
+ await plugin.redrawInit();
5261
+ }
5262
+ if (plugin.checkParticlePosition) {
5263
+ this.checkParticlePositionPlugins.push(plugin);
5264
+ }
5265
+ if (plugin.update) {
5266
+ this.#updatePlugins.push(plugin);
5267
+ }
5268
+ if (plugin.particleUpdate) {
5269
+ this.#particleUpdatePlugins.push(plugin);
5270
+ }
5271
+ if (plugin.postUpdate) {
5272
+ this.#postUpdatePlugins.push(plugin);
5273
+ }
5274
+ if (plugin.particleReset) {
5275
+ this.#particleResetPlugins.push(plugin);
5276
+ }
5277
+ if (plugin.postParticleUpdate) {
5278
+ this.#postParticleUpdatePlugins.push(plugin);
5279
+ }
5280
+ }
5281
+ }
4950
5282
  #insertParticleIntoBucket(particle) {
4951
5283
  const bucketIndex = this.#getBucketIndex(particle.position.z), bucket = this.#zBuckets[bucketIndex];
4952
5284
  if (!bucket) {
@@ -4955,12 +5287,15 @@
4955
5287
  bucket.push(particle);
4956
5288
  this.#particleBuckets.set(particle.id, bucketIndex);
4957
5289
  }
4958
- #removeParticle(index, group, override) {
5290
+ #removeAny(quantity) {
5291
+ this.removeAt(minIndex, quantity, undefined, undefined, false);
5292
+ }
5293
+ #removeParticle(index, group, override, matchGroup = true) {
4959
5294
  const particle = this.#array[index];
4960
5295
  if (!particle) {
4961
5296
  return false;
4962
5297
  }
4963
- if (particle.group !== group) {
5298
+ if (matchGroup && particle.group !== group) {
4964
5299
  return false;
4965
5300
  }
4966
5301
  this.#array.splice(index, deleteCount);
@@ -5047,7 +5382,7 @@
5047
5382
  particlesToDelete.add(particle);
5048
5383
  continue;
5049
5384
  }
5050
- this.grid.insert(particle);
5385
+ this.#grid.insert(particle);
5051
5386
  }
5052
5387
  return particlesToDelete;
5053
5388
  }
@@ -5119,6 +5454,7 @@
5119
5454
  effectDrawers;
5120
5455
  fpsLimit;
5121
5456
  hdr;
5457
+ hdrMode;
5122
5458
  id;
5123
5459
  pageHidden;
5124
5460
  particleCreatedPlugins;
@@ -5126,6 +5462,7 @@
5126
5462
  particlePositionPlugins;
5127
5463
  particleUpdaters;
5128
5464
  particles;
5465
+ peakNits;
5129
5466
  plugins;
5130
5467
  retina;
5131
5468
  shapeDrawers;
@@ -5156,6 +5493,8 @@
5156
5493
  this.id = Symbol(id);
5157
5494
  this.fpsLimit = 120;
5158
5495
  this.hdr = false;
5496
+ this.hdrMode = HdrMode.standard;
5497
+ this.peakNits = 400;
5159
5498
  this.#smooth = false;
5160
5499
  this.#delay = 0;
5161
5500
  this.#duration = 0;
@@ -5219,7 +5558,6 @@
5219
5558
  this.shapeDrawers = new Map();
5220
5559
  this.particleUpdaters = [];
5221
5560
  this.plugins.length = 0;
5222
- this.#pluginManager.clearPlugins(this);
5223
5561
  this.destroyed = true;
5224
5562
  this.#onDestroy(remove);
5225
5563
  this.dispatchEvent(EventType.containerDestroyed);
@@ -5272,31 +5610,15 @@
5272
5610
  await this.initDrawersAndUpdaters();
5273
5611
  this.#options = loadContainerOptions(this.#pluginManager, this, this.#initialSourceOptions, this.sourceOptions);
5274
5612
  this.actualOptions = loadContainerOptions(this.#pluginManager, this, this.#options);
5275
- this.plugins.length = 0;
5276
- this.particleDestroyedPlugins.length = 0;
5277
- this.particleCreatedPlugins.length = 0;
5278
- this.particlePositionPlugins.length = 0;
5279
- for (const [plugin, containerPlugin] of allContainerPlugins) {
5280
- if (plugin.needsPlugin(this.actualOptions)) {
5281
- this.plugins.push(containerPlugin);
5282
- if (containerPlugin.particleCreated) {
5283
- this.particleCreatedPlugins.push(containerPlugin);
5284
- }
5285
- if (containerPlugin.particleDestroyed) {
5286
- this.particleDestroyedPlugins.push(containerPlugin);
5287
- }
5288
- if (containerPlugin.particlePosition) {
5289
- this.particlePositionPlugins.push(containerPlugin);
5290
- }
5291
- }
5292
- }
5613
+ this.#initPlugins(allContainerPlugins);
5293
5614
  this.retina.init();
5294
5615
  this.canvas.init();
5295
5616
  this.updateActualOptions();
5296
5617
  this.canvas.initBackground();
5297
5618
  this.canvas.resize();
5298
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
5299
- this.hdr = hdr;
5619
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
5620
+ this.hdrMode = toEnumValue(HdrMode, hdrOptions.mode, HdrMode.standard);
5621
+ this.peakNits = hdrOptions.peakNits;
5300
5622
  this.zLayers = zLayers;
5301
5623
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
5302
5624
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;
@@ -5316,9 +5638,9 @@
5316
5638
  }
5317
5639
  async initDrawersAndUpdaters() {
5318
5640
  const pluginManager = this.#pluginManager;
5319
- this.effectDrawers = await pluginManager.getEffectDrawers(this, true);
5320
- this.shapeDrawers = await pluginManager.getShapeDrawers(this, true);
5321
- this.particleUpdaters = await pluginManager.getUpdaters(this, true);
5641
+ this.effectDrawers = await getItemMapFromInitializer(this, pluginManager.initializers.effects);
5642
+ this.shapeDrawers = await getItemMapFromInitializer(this, pluginManager.initializers.shapes);
5643
+ this.particleUpdaters = await getItemsFromInitializer(this, pluginManager.initializers.updaters);
5322
5644
  }
5323
5645
  pause() {
5324
5646
  if (!guardCheck(this)) {
@@ -5429,6 +5751,27 @@
5429
5751
  }
5430
5752
  return refresh;
5431
5753
  }
5754
+ #initPlugins(allContainerPlugins) {
5755
+ this.plugins.length = 0;
5756
+ this.particleDestroyedPlugins.length = 0;
5757
+ this.particleCreatedPlugins.length = 0;
5758
+ this.particlePositionPlugins.length = 0;
5759
+ for (const [plugin, containerPlugin] of allContainerPlugins) {
5760
+ if (!plugin.needsPlugin(this.actualOptions)) {
5761
+ continue;
5762
+ }
5763
+ this.plugins.push(containerPlugin);
5764
+ if (containerPlugin.particleCreated) {
5765
+ this.particleCreatedPlugins.push(containerPlugin);
5766
+ }
5767
+ if (containerPlugin.particleDestroyed) {
5768
+ this.particleDestroyedPlugins.push(containerPlugin);
5769
+ }
5770
+ if (containerPlugin.particlePosition) {
5771
+ this.particlePositionPlugins.push(containerPlugin);
5772
+ }
5773
+ }
5774
+ }
5432
5775
  #nextFrame(timestamp) {
5433
5776
  try {
5434
5777
  if (!this.#smooth &&
@@ -5705,11 +6048,11 @@
5705
6048
  }
5706
6049
  }
5707
6050
  async #init() {
5708
- const availablePathGenerators = await this.#pluginManager.getPathGenerators?.(this.#container, true);
5709
- if (!availablePathGenerators) {
6051
+ const pluginManager = this.#pluginManager;
6052
+ if (!pluginManager.initializers.pathGenerators) {
5710
6053
  return;
5711
6054
  }
5712
- this.availablePathGenerators = availablePathGenerators;
6055
+ this.availablePathGenerators = await getItemMapFromInitializer(this.#container, pluginManager.initializers.pathGenerators);
5713
6056
  this.pathGenerators = new Map();
5714
6057
  for (const pathGenerator of this.pathGenerators.values()) {
5715
6058
  pathGenerator.init();
@@ -5725,6 +6068,7 @@
5725
6068
  exports.loadStarsPreset = loadStarsPreset;
5726
6069
  exports.tsParticles = tsParticles;
5727
6070
 
5728
- }));
6071
+ })(g.__tsParticlesInternals.presets.stars = g.__tsParticlesInternals.presets.stars || {});
6072
+ })(typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : self);
6073
+
5729
6074
  Object.assign(globalThis.window || globalThis, { loadStarsPreset: (globalThis.__tsParticlesInternals.presets.stars || {}).loadStarsPreset });
5730
- delete (globalThis.window || globalThis).tsparticlesInternalExports;