@tsparticles/preset-confetti 4.3.1 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  (function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
- /* Preset v4.3.1 */
2
+ /* Preset v4.4.0 */
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
5
5
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -305,6 +305,9 @@
305
305
  })(PixelMode || (PixelMode = {}));
306
306
 
307
307
  const minRadius = 0;
308
+ function isForbiddenKey(key) {
309
+ return key === "__proto__" || key === "constructor" || key === "prototype";
310
+ }
308
311
  function hasMatchMedia() {
309
312
  return typeof matchMedia !== "undefined";
310
313
  }
@@ -380,7 +383,7 @@
380
383
  if (!hasNested) {
381
384
  const sourceDict = source, destDict = destination;
382
385
  for (const key of sourceKeys) {
383
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
386
+ if (isForbiddenKey(key)) {
384
387
  continue;
385
388
  }
386
389
  const v = sourceDict[key];
@@ -391,7 +394,7 @@
391
394
  continue;
392
395
  }
393
396
  for (const key of sourceKeys) {
394
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
397
+ if (isForbiddenKey(key)) {
395
398
  continue;
396
399
  }
397
400
  const sourceDict = source, destDict = destination, value = sourceDict[key];
@@ -807,7 +810,7 @@
807
810
  return this.#domArray;
808
811
  }
809
812
  get version() {
810
- return "4.3.1";
813
+ return "4.4.0";
811
814
  }
812
815
  addEventListener(type, listener) {
813
816
  this.#eventDispatcher.addEventListener(type, listener);
@@ -888,6 +891,10 @@
888
891
  }
889
892
 
890
893
  function initEngine() {
894
+ const existing = globalThis.tsParticles;
895
+ if (existing?.pluginManager) {
896
+ return existing;
897
+ }
891
898
  return new Engine();
892
899
  }
893
900
 
@@ -985,6 +992,15 @@
985
992
  AnimationMode["random"] = "random";
986
993
  })(AnimationMode || (AnimationMode = {}));
987
994
 
995
+ var HdrMode;
996
+ (function (HdrMode) {
997
+ HdrMode["standard"] = "standard";
998
+ HdrMode["natural"] = "natural";
999
+ HdrMode["vivid"] = "vivid";
1000
+ HdrMode["cinematic"] = "cinematic";
1001
+ HdrMode["dynamic"] = "dynamic";
1002
+ })(HdrMode || (HdrMode = {}));
1003
+
988
1004
  var LimitMode;
989
1005
  (function (LimitMode) {
990
1006
  LimitMode["delete"] = "delete";
@@ -1240,6 +1256,29 @@
1240
1256
  }
1241
1257
  }
1242
1258
 
1259
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
1260
+ class HDROptions extends OptionLoader {
1261
+ enable = true;
1262
+ mode = HdrMode.standard;
1263
+ peakNits = defaultPeakNits;
1264
+ doLoad(data) {
1265
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
1266
+ throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1267
+ }
1268
+ if (data.mode !== undefined &&
1269
+ (typeof data.mode !== "string" || !Object.values(HdrMode).includes(data.mode))) {
1270
+ throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1271
+ }
1272
+ if (data.peakNits !== undefined &&
1273
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1274
+ throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1275
+ }
1276
+ loadProperty(this, "enable", data.enable);
1277
+ loadProperty(this, "mode", data.mode);
1278
+ loadProperty(this, "peakNits", data.peakNits);
1279
+ }
1280
+ }
1281
+
1243
1282
  class ResizeEvent extends OptionLoader {
1244
1283
  delay = 0.5;
1245
1284
  enable = true;
@@ -1683,7 +1722,7 @@
1683
1722
  duration = 0;
1684
1723
  fpsLimit = 120;
1685
1724
  fullScreen;
1686
- hdr = true;
1725
+ hdr;
1687
1726
  key;
1688
1727
  name;
1689
1728
  palette;
@@ -1703,6 +1742,7 @@
1703
1742
  this.#container = container;
1704
1743
  this.background = new Background();
1705
1744
  this.fullScreen = new FullScreen();
1745
+ this.hdr = new HDROptions();
1706
1746
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1707
1747
  this.resize = new ResizeEvent();
1708
1748
  }
@@ -1725,7 +1765,15 @@
1725
1765
  loadProperty(this, "detectRetina", data.detectRetina);
1726
1766
  loadRangeProperty(this, "duration", data.duration);
1727
1767
  loadProperty(this, "fpsLimit", data.fpsLimit);
1728
- loadProperty(this, "hdr", data.hdr);
1768
+ const hdrData = data.hdr;
1769
+ if (isBoolean(hdrData)) {
1770
+ this.hdr.enable = hdrData;
1771
+ this.hdr.mode = HdrMode.standard;
1772
+ this.hdr.peakNits = 400;
1773
+ }
1774
+ else {
1775
+ this.hdr.load(hdrData);
1776
+ }
1729
1777
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1730
1778
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1731
1779
  loadProperty(this, "zLayers", data.zLayers);
@@ -1768,7 +1816,7 @@
1768
1816
  }
1769
1817
  }
1770
1818
 
1771
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1819
+ 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;
1772
1820
  function getCachedStyle(key, generator) {
1773
1821
  let cached = styleCache.get(key);
1774
1822
  if (!cached) {
@@ -1780,6 +1828,42 @@
1780
1828
  }
1781
1829
  return cached;
1782
1830
  }
1831
+ function acesFilmic(x) {
1832
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
1833
+ }
1834
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
1835
+ switch (mode) {
1836
+ case HdrMode.vivid: {
1837
+ const avg = (r + g + b) / channelCount;
1838
+ return {
1839
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1840
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1841
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1842
+ };
1843
+ }
1844
+ case HdrMode.cinematic: {
1845
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
1846
+ return {
1847
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
1848
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
1849
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
1850
+ };
1851
+ }
1852
+ case HdrMode.dynamic: {
1853
+ 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;
1854
+ return {
1855
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
1856
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
1857
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
1858
+ };
1859
+ }
1860
+ case HdrMode.standard:
1861
+ return { b, g, r };
1862
+ case HdrMode.natural:
1863
+ default:
1864
+ return { b, g, r };
1865
+ }
1866
+ }
1783
1867
  function stringToRgba(pluginManager, input) {
1784
1868
  if (!input) {
1785
1869
  return;
@@ -1937,21 +2021,40 @@
1937
2021
  r: getRgbInRangeValue(),
1938
2022
  };
1939
2023
  }
1940
- function getStyleFromRgb(color, hdr, opacity) {
1941
- 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()}`;
1942
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2024
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
2025
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2026
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2027
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
2028
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
1943
2029
  }
1944
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1945
- const headroom = peakNits / sdrReferenceWhiteNits;
1946
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2030
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = HdrMode.standard) {
2031
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
2032
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2033
+ }
2034
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
2035
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
2036
+ if (mode !== HdrMode.natural && mode !== HdrMode.vivid && mode !== HdrMode.cinematic && mode !== HdrMode.dynamic) {
2037
+ return { b: bNorm, g: gNorm, r: rNorm };
2038
+ }
2039
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
2040
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
2041
+ }
2042
+ function hdrToneMap(normalized, headroom, middleGray) {
2043
+ if (normalized <= middleGray) {
2044
+ return acesFilmic(normalized);
2045
+ }
2046
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
2047
+ return acesFilmic(expanded);
1947
2048
  }
1948
2049
  function getSdrStyleFromRgb(color, opacity) {
1949
2050
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
1950
2051
  }
1951
- function getStyleFromHsl(color, hdr, opacity) {
1952
- 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()}`;
2052
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
2053
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2054
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2055
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
1953
2056
  return getCachedStyle(key, () => hdr
1954
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2057
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
1955
2058
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1956
2059
  }
1957
2060
  function getHslFromAnimation(animation) {
@@ -2014,7 +2117,7 @@
2014
2117
  colorValue.velocity = defaultVelocity;
2015
2118
  }
2016
2119
  }
2017
- function updateColorValue(data, decrease, delta, hdr) {
2120
+ function updateColorValue(data, decrease, delta, _hdr) {
2018
2121
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2019
2122
  if (!data.enable ||
2020
2123
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2027,7 +2130,7 @@
2027
2130
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2028
2131
  return;
2029
2132
  }
2030
- 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;
2133
+ 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;
2031
2134
  if (!decrease || data.status === AnimationStatus.increasing) {
2032
2135
  data.value += velocity;
2033
2136
  if (data.value > max) {
@@ -2059,9 +2162,9 @@
2059
2162
  return;
2060
2163
  }
2061
2164
  const { h, s, l } = color;
2062
- updateColorValue(h, false, delta, hdr);
2063
- updateColorValue(s, true, delta, hdr);
2064
- updateColorValue(l, true, delta, hdr);
2165
+ updateColorValue(h, false, delta);
2166
+ updateColorValue(s, true, delta);
2167
+ updateColorValue(l, true, delta);
2065
2168
  }
2066
2169
  function alterHsl(color, type, value) {
2067
2170
  return {
@@ -2111,7 +2214,7 @@
2111
2214
  }
2112
2215
 
2113
2216
  async function loadBlendPlugin(engine) {
2114
- engine.checkVersion("4.3.1");
2217
+ engine.checkVersion("4.4.0");
2115
2218
  await engine.pluginManager.register(e => {
2116
2219
  e.pluginManager.addPlugin(new BlendPlugin());
2117
2220
  });
@@ -2148,7 +2251,7 @@
2148
2251
  }
2149
2252
 
2150
2253
  async function loadCircleShape(engine) {
2151
- engine.checkVersion("4.3.1");
2254
+ engine.checkVersion("4.4.0");
2152
2255
  await engine.pluginManager.register(e => {
2153
2256
  e.pluginManager.addShape(["circle"], () => {
2154
2257
  return Promise.resolve(new CircleDrawer());
@@ -2196,7 +2299,7 @@
2196
2299
  }
2197
2300
 
2198
2301
  async function loadHexColorPlugin(engine) {
2199
- engine.checkVersion("4.3.1");
2302
+ engine.checkVersion("4.4.0");
2200
2303
  await engine.pluginManager.register(e => {
2201
2304
  e.pluginManager.addColorManager("hex", new HexColorManager());
2202
2305
  });
@@ -2249,7 +2352,7 @@
2249
2352
  }
2250
2353
 
2251
2354
  async function loadHslColorPlugin(engine) {
2252
- engine.checkVersion("4.3.1");
2355
+ engine.checkVersion("4.4.0");
2253
2356
  await engine.pluginManager.register(e => {
2254
2357
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2255
2358
  });
@@ -2273,7 +2376,7 @@
2273
2376
  }
2274
2377
 
2275
2378
  async function loadMovePlugin(engine) {
2276
- engine.checkVersion("4.3.1");
2379
+ engine.checkVersion("4.4.0");
2277
2380
  await engine.pluginManager.register(e => {
2278
2381
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2279
2382
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2489,7 +2592,7 @@
2489
2592
  }
2490
2593
 
2491
2594
  async function loadOpacityUpdater(engine) {
2492
- engine.checkVersion("4.3.1");
2595
+ engine.checkVersion("4.4.0");
2493
2596
  await engine.pluginManager.register(e => {
2494
2597
  e.pluginManager.addParticleUpdater("opacity", container => {
2495
2598
  return Promise.resolve(new OpacityUpdater(container));
@@ -2834,7 +2937,7 @@
2834
2937
  }
2835
2938
 
2836
2939
  async function loadOutModesUpdater(engine) {
2837
- engine.checkVersion("4.3.1");
2940
+ engine.checkVersion("4.4.0");
2838
2941
  await engine.pluginManager.register(e => {
2839
2942
  e.pluginManager.addParticleUpdater("outModes", container => {
2840
2943
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2905,7 +3008,7 @@
2905
3008
  }
2906
3009
 
2907
3010
  async function loadPaintUpdater(engine) {
2908
- engine.checkVersion("4.3.1");
3011
+ engine.checkVersion("4.4.0");
2909
3012
  await engine.pluginManager.register(e => {
2910
3013
  e.pluginManager.addParticleUpdater("paint", container => {
2911
3014
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2960,7 +3063,7 @@
2960
3063
  }
2961
3064
 
2962
3065
  async function loadRgbColorPlugin(engine) {
2963
- engine.checkVersion("4.3.1");
3066
+ engine.checkVersion("4.4.0");
2964
3067
  await engine.pluginManager.register(e => {
2965
3068
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
2966
3069
  });
@@ -3045,7 +3148,7 @@
3045
3148
  }
3046
3149
 
3047
3150
  async function loadSizeUpdater(engine) {
3048
- engine.checkVersion("4.3.1");
3151
+ engine.checkVersion("4.4.0");
3049
3152
  await engine.pluginManager.register(e => {
3050
3153
  e.pluginManager.addParticleUpdater("size", container => {
3051
3154
  return Promise.resolve(new SizeUpdater(container));
@@ -3054,7 +3157,7 @@
3054
3157
  }
3055
3158
 
3056
3159
  async function loadBasic(engine) {
3057
- engine.checkVersion("4.3.1");
3160
+ engine.checkVersion("4.4.0");
3058
3161
  await engine.pluginManager.register(async (e) => {
3059
3162
  await Promise.all([
3060
3163
  loadBlendPlugin(e),
@@ -3307,7 +3410,7 @@
3307
3410
  })(EmitterClickMode || (EmitterClickMode = {}));
3308
3411
 
3309
3412
  async function loadEmittersPluginSimple(engine) {
3310
- engine.checkVersion("4.3.1");
3413
+ engine.checkVersion("4.4.0");
3311
3414
  await engine.pluginManager.register(async (e) => {
3312
3415
  const instancesManager = await getEmittersInstancesManager(e);
3313
3416
  await addEmittersShapesManager(e);
@@ -3452,7 +3555,7 @@
3452
3555
  }
3453
3556
 
3454
3557
  async function loadLifeUpdater(engine) {
3455
- engine.checkVersion("4.3.1");
3558
+ engine.checkVersion("4.4.0");
3456
3559
  await engine.pluginManager.register(e => {
3457
3560
  e.pluginManager.addParticleUpdater("life", container => {
3458
3561
  return Promise.resolve(new LifeUpdater(container));
@@ -3506,7 +3609,7 @@
3506
3609
  }
3507
3610
 
3508
3611
  async function loadMotionPlugin(engine) {
3509
- engine.checkVersion("4.3.1");
3612
+ engine.checkVersion("4.4.0");
3510
3613
  await engine.pluginManager.register(e => {
3511
3614
  e.pluginManager.addPlugin(new MotionPlugin());
3512
3615
  });
@@ -3639,7 +3742,7 @@
3639
3742
  }
3640
3743
 
3641
3744
  async function loadRollUpdater(engine) {
3642
- engine.checkVersion("4.3.1");
3745
+ engine.checkVersion("4.4.0");
3643
3746
  await engine.pluginManager.register(e => {
3644
3747
  e.pluginManager.addParticleUpdater("roll", () => {
3645
3748
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -3745,7 +3848,7 @@
3745
3848
  }
3746
3849
 
3747
3850
  async function loadRotateUpdater(engine) {
3748
- engine.checkVersion("4.3.1");
3851
+ engine.checkVersion("4.4.0");
3749
3852
  await engine.pluginManager.register(e => {
3750
3853
  e.pluginManager.addParticleUpdater("rotate", container => {
3751
3854
  return Promise.resolve(new RotateUpdater(container));
@@ -3769,7 +3872,7 @@
3769
3872
  }
3770
3873
 
3771
3874
  async function loadSquareShape(engine) {
3772
- engine.checkVersion("4.3.1");
3875
+ engine.checkVersion("4.4.0");
3773
3876
  await engine.pluginManager.register(e => {
3774
3877
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
3775
3878
  });
@@ -3878,7 +3981,7 @@
3878
3981
  }
3879
3982
 
3880
3983
  async function loadTiltUpdater(engine) {
3881
- engine.checkVersion("4.3.1");
3984
+ engine.checkVersion("4.4.0");
3882
3985
  await engine.pluginManager.register(e => {
3883
3986
  e.pluginManager.addParticleUpdater("tilt", container => {
3884
3987
  return Promise.resolve(new TiltUpdater(container));
@@ -3980,7 +4083,7 @@
3980
4083
  }
3981
4084
 
3982
4085
  async function loadWobbleUpdater(engine) {
3983
- engine.checkVersion("4.3.1");
4086
+ engine.checkVersion("4.4.0");
3984
4087
  await engine.pluginManager.register(e => {
3985
4088
  e.pluginManager.addParticleUpdater("wobble", container => {
3986
4089
  return Promise.resolve(new WobbleUpdater(container));
@@ -4259,7 +4362,11 @@
4259
4362
  if (!fColor && !sColor) {
4260
4363
  return;
4261
4364
  }
4262
- 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;
4365
+ 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
4366
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
4367
+ : undefined, stroke = sColor
4368
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
4369
+ : fill;
4263
4370
  transform.a = transform.b = transform.c = transform.d = undefined;
4264
4371
  colorStyles.fill = fill;
4265
4372
  colorStyles.stroke = stroke;
@@ -4593,7 +4700,9 @@
4593
4700
  if (typeof background.element === "string") {
4594
4701
  if (typeof document !== "undefined") {
4595
4702
  const node = document.querySelector(background.element);
4596
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
4703
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
4704
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
4705
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
4597
4706
  this.#backgroundElement = node;
4598
4707
  }
4599
4708
  else if (node) {
@@ -4604,10 +4713,10 @@
4604
4713
  }
4605
4714
  }
4606
4715
  }
4607
- else if (background.element instanceof HTMLCanvasElement ||
4608
- background.element instanceof OffscreenCanvas ||
4609
- background.element instanceof HTMLVideoElement ||
4610
- background.element instanceof HTMLImageElement) {
4716
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
4717
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
4718
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
4719
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
4611
4720
  this.#backgroundElement = background.element;
4612
4721
  }
4613
4722
  }
@@ -4675,6 +4784,7 @@
4675
4784
  zoom = defaultZoom;
4676
4785
  #container;
4677
4786
  #generated;
4787
+ #hdrMediaListeners;
4678
4788
  #mutationObserver;
4679
4789
  #originalStyle;
4680
4790
  #pluginManager;
@@ -4739,7 +4849,6 @@
4739
4849
  });
4740
4850
  this.resize();
4741
4851
  this.#initStyle();
4742
- this.initBackground();
4743
4852
  this.#safeMutationObserver(obs => {
4744
4853
  const element = this.domElement;
4745
4854
  if (!element || !(element instanceof Node)) {
@@ -4749,6 +4858,8 @@
4749
4858
  });
4750
4859
  this.initPlugins();
4751
4860
  this.#initContext();
4861
+ this.initBackground();
4862
+ this.#initHdrListeners();
4752
4863
  this.render.init();
4753
4864
  }
4754
4865
  initBackground() {
@@ -4758,7 +4869,8 @@
4758
4869
  }
4759
4870
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4760
4871
  if (color) {
4761
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
4872
+ const hdrOptions = container.actualOptions.hdr;
4873
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
4762
4874
  }
4763
4875
  else {
4764
4876
  elementStyle.backgroundColor = "";
@@ -4855,6 +4967,7 @@
4855
4967
  obs.disconnect();
4856
4968
  });
4857
4969
  this.#mutationObserver = undefined;
4970
+ this.#removeHdrListeners();
4858
4971
  this.render.stop();
4859
4972
  }
4860
4973
  async windowResize() {
@@ -4874,9 +4987,16 @@
4874
4987
  }
4875
4988
  }
4876
4989
  #initContext() {
4877
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4990
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
4878
4991
  safeMatchMedia("(color-gamut: p3)")?.matches &&
4879
4992
  safeMatchMedia("(dynamic-range: high)")?.matches;
4993
+ container.hdr = canSupportHdr ?? false;
4994
+ container.hdrMode = container.actualOptions.hdr.mode;
4995
+ container.peakNits = container.actualOptions.hdr.peakNits;
4996
+ const renderCanvas = this.renderCanvas;
4997
+ if (!renderCanvas) {
4998
+ return;
4999
+ }
4880
5000
  this.render.setContextSettings({
4881
5001
  alpha: true,
4882
5002
  desynchronized: true,
@@ -4885,11 +5005,47 @@
4885
5005
  ? { colorSpace: "display-p3", colorType: "float16" }
4886
5006
  : { colorSpace: "srgb" }),
4887
5007
  });
4888
- const renderCanvas = this.renderCanvas;
4889
- if (!renderCanvas) {
4890
- return;
5008
+ let context;
5009
+ try {
5010
+ context = renderCanvas.getContext("2d", this.render.settings);
5011
+ }
5012
+ catch {
5013
+ context = null;
5014
+ }
5015
+ if (canSupportHdr && !context) {
5016
+ container.hdr = false;
5017
+ const sdrSettings = {
5018
+ alpha: true,
5019
+ desynchronized: true,
5020
+ willReadFrequently: false,
5021
+ colorSpace: "srgb",
5022
+ };
5023
+ this.render.setContextSettings(sdrSettings);
5024
+ try {
5025
+ context = renderCanvas.getContext("2d", sdrSettings);
5026
+ }
5027
+ catch {
5028
+ context = null;
5029
+ }
5030
+ }
5031
+ this.render.setContext(context);
5032
+ }
5033
+ #initHdrListeners() {
5034
+ this.#removeHdrListeners();
5035
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
5036
+ this.#recreateRenderCanvas();
5037
+ this.#initContext();
5038
+ this.initBackground();
5039
+ }, listeners = [];
5040
+ if (p3Query) {
5041
+ p3Query.addEventListener("change", handleChange);
5042
+ listeners.push({ handler: handleChange, mql: p3Query });
5043
+ }
5044
+ if (hdrQuery) {
5045
+ hdrQuery.addEventListener("change", handleChange);
5046
+ listeners.push({ handler: handleChange, mql: hdrQuery });
4891
5047
  }
4892
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
5048
+ this.#hdrMediaListeners = listeners;
4893
5049
  }
4894
5050
  #initStyle() {
4895
5051
  const element = this.domElement, options = this.#container.actualOptions;
@@ -4913,6 +5069,25 @@
4913
5069
  element.style.setProperty(key, value, "important");
4914
5070
  }
4915
5071
  }
5072
+ #recreateRenderCanvas() {
5073
+ const renderCanvas = this.renderCanvas;
5074
+ if (!renderCanvas) {
5075
+ return;
5076
+ }
5077
+ if (this.domElement) {
5078
+ return;
5079
+ }
5080
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
5081
+ }
5082
+ #removeHdrListeners() {
5083
+ if (!this.#hdrMediaListeners) {
5084
+ return;
5085
+ }
5086
+ for (const { handler, mql } of this.#hdrMediaListeners) {
5087
+ mql.removeEventListener("change", handler);
5088
+ }
5089
+ this.#hdrMediaListeners = undefined;
5090
+ }
4916
5091
  #repairStyle() {
4917
5092
  const element = this.domElement;
4918
5093
  if (!element) {
@@ -5297,9 +5472,9 @@
5297
5472
  }
5298
5473
  getOpacity() {
5299
5474
  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;
5300
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
5475
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
5301
5476
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
5302
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
5477
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
5303
5478
  return this.#cachedOpacityData;
5304
5479
  }
5305
5480
  getPosition() {
@@ -6154,6 +6329,7 @@
6154
6329
  effectDrawers;
6155
6330
  fpsLimit;
6156
6331
  hdr;
6332
+ hdrMode;
6157
6333
  id;
6158
6334
  pageHidden;
6159
6335
  particleCreatedPlugins;
@@ -6161,6 +6337,7 @@
6161
6337
  particlePositionPlugins;
6162
6338
  particleUpdaters;
6163
6339
  particles;
6340
+ peakNits;
6164
6341
  plugins;
6165
6342
  retina;
6166
6343
  shapeDrawers;
@@ -6191,6 +6368,8 @@
6191
6368
  this.id = Symbol(id);
6192
6369
  this.fpsLimit = 120;
6193
6370
  this.hdr = false;
6371
+ this.hdrMode = HdrMode.standard;
6372
+ this.peakNits = 400;
6194
6373
  this.#smooth = false;
6195
6374
  this.#delay = 0;
6196
6375
  this.#duration = 0;
@@ -6330,8 +6509,9 @@
6330
6509
  this.updateActualOptions();
6331
6510
  this.canvas.initBackground();
6332
6511
  this.canvas.resize();
6333
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
6334
- this.hdr = hdr;
6512
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
6513
+ this.hdrMode = hdrOptions.mode;
6514
+ this.peakNits = hdrOptions.peakNits;
6335
6515
  this.zLayers = zLayers;
6336
6516
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
6337
6517
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;