@tsparticles/fireworks 4.3.2 → 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
- /* tsParticles v4.3.2 */
2
+ /* tsParticles 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) :
@@ -880,7 +880,7 @@
880
880
  return this.#domArray;
881
881
  }
882
882
  get version() {
883
- return "4.3.2";
883
+ return "4.4.0";
884
884
  }
885
885
  addEventListener(type, listener) {
886
886
  this.#eventDispatcher.addEventListener(type, listener);
@@ -961,6 +961,10 @@
961
961
  }
962
962
 
963
963
  function initEngine() {
964
+ const existing = globalThis.tsParticles;
965
+ if (existing?.pluginManager) {
966
+ return existing;
967
+ }
964
968
  return new Engine();
965
969
  }
966
970
 
@@ -1058,6 +1062,15 @@
1058
1062
  AnimationMode["random"] = "random";
1059
1063
  })(exports.AnimationMode || (exports.AnimationMode = {}));
1060
1064
 
1065
+ exports.HdrMode = void 0;
1066
+ (function (HdrMode) {
1067
+ HdrMode["standard"] = "standard";
1068
+ HdrMode["natural"] = "natural";
1069
+ HdrMode["vivid"] = "vivid";
1070
+ HdrMode["cinematic"] = "cinematic";
1071
+ HdrMode["dynamic"] = "dynamic";
1072
+ })(exports.HdrMode || (exports.HdrMode = {}));
1073
+
1061
1074
  exports.LimitMode = void 0;
1062
1075
  (function (LimitMode) {
1063
1076
  LimitMode["delete"] = "delete";
@@ -1323,6 +1336,29 @@
1323
1336
  }
1324
1337
  }
1325
1338
 
1339
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
1340
+ class HDROptions extends OptionLoader {
1341
+ enable = true;
1342
+ mode = exports.HdrMode.standard;
1343
+ peakNits = defaultPeakNits;
1344
+ doLoad(data) {
1345
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
1346
+ throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1347
+ }
1348
+ if (data.mode !== undefined &&
1349
+ (typeof data.mode !== "string" || !Object.values(exports.HdrMode).includes(data.mode))) {
1350
+ throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(exports.HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1351
+ }
1352
+ if (data.peakNits !== undefined &&
1353
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1354
+ throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1355
+ }
1356
+ loadProperty(this, "enable", data.enable);
1357
+ loadProperty(this, "mode", data.mode);
1358
+ loadProperty(this, "peakNits", data.peakNits);
1359
+ }
1360
+ }
1361
+
1326
1362
  class ResizeEvent extends OptionLoader {
1327
1363
  delay = 0.5;
1328
1364
  enable = true;
@@ -1766,7 +1802,7 @@
1766
1802
  duration = 0;
1767
1803
  fpsLimit = 120;
1768
1804
  fullScreen;
1769
- hdr = true;
1805
+ hdr;
1770
1806
  key;
1771
1807
  name;
1772
1808
  palette;
@@ -1786,6 +1822,7 @@
1786
1822
  this.#container = container;
1787
1823
  this.background = new Background();
1788
1824
  this.fullScreen = new FullScreen();
1825
+ this.hdr = new HDROptions();
1789
1826
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1790
1827
  this.resize = new ResizeEvent();
1791
1828
  }
@@ -1808,7 +1845,15 @@
1808
1845
  loadProperty(this, "detectRetina", data.detectRetina);
1809
1846
  loadRangeProperty(this, "duration", data.duration);
1810
1847
  loadProperty(this, "fpsLimit", data.fpsLimit);
1811
- loadProperty(this, "hdr", data.hdr);
1848
+ const hdrData = data.hdr;
1849
+ if (isBoolean(hdrData)) {
1850
+ this.hdr.enable = hdrData;
1851
+ this.hdr.mode = exports.HdrMode.standard;
1852
+ this.hdr.peakNits = 400;
1853
+ }
1854
+ else {
1855
+ this.hdr.load(hdrData);
1856
+ }
1812
1857
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1813
1858
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1814
1859
  loadProperty(this, "zLayers", data.zLayers);
@@ -1851,7 +1896,7 @@
1851
1896
  }
1852
1897
  }
1853
1898
 
1854
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1899
+ 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, srgbThreshold = 0.04045, srgbDivisor = 12.92, srgbOffset = 0.055, srgbScale = 1.055, srgbExponent = 2.4, linearThreshold = 0.0031308, linearScale = 12.92;
1855
1900
  function getCachedStyle(key, generator) {
1856
1901
  let cached = styleCache.get(key);
1857
1902
  if (!cached) {
@@ -1863,6 +1908,48 @@
1863
1908
  }
1864
1909
  return cached;
1865
1910
  }
1911
+ function acesFilmic(x) {
1912
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
1913
+ }
1914
+ function srgbToLinear(c) {
1915
+ return c <= srgbThreshold ? c / srgbDivisor : Math.pow((c + srgbOffset) / srgbScale, srgbExponent);
1916
+ }
1917
+ function linearToSrgb(c) {
1918
+ return c <= linearThreshold ? c * linearScale : srgbScale * Math.pow(c, one / srgbExponent) - srgbOffset;
1919
+ }
1920
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
1921
+ switch (mode) {
1922
+ case exports.HdrMode.vivid: {
1923
+ const avg = (r + g + b) / channelCount;
1924
+ return {
1925
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1926
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1927
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1928
+ };
1929
+ }
1930
+ case exports.HdrMode.cinematic: {
1931
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
1932
+ return {
1933
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
1934
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
1935
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
1936
+ };
1937
+ }
1938
+ case exports.HdrMode.dynamic: {
1939
+ 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;
1940
+ return {
1941
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
1942
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
1943
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
1944
+ };
1945
+ }
1946
+ case exports.HdrMode.standard:
1947
+ return { b, g, r };
1948
+ case exports.HdrMode.natural:
1949
+ default:
1950
+ return { b, g, r };
1951
+ }
1952
+ }
1866
1953
  function stringToRgba(pluginManager, input) {
1867
1954
  if (!input) {
1868
1955
  return;
@@ -2030,30 +2117,65 @@
2030
2117
  r: getRgbInRangeValue(),
2031
2118
  };
2032
2119
  }
2033
- function getStyleFromRgb(color, hdr, opacity) {
2034
- 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()}`;
2035
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2120
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
2121
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2122
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? exports.HdrMode.standard}`
2123
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
2124
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
2036
2125
  }
2037
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
2038
- const headroom = peakNits / sdrReferenceWhiteNits;
2039
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2126
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = exports.HdrMode.standard) {
2127
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
2128
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2129
+ }
2130
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
2131
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
2132
+ if (mode !== exports.HdrMode.natural && mode !== exports.HdrMode.vivid && mode !== exports.HdrMode.cinematic && mode !== exports.HdrMode.dynamic) {
2133
+ return { b: bNorm, g: gNorm, r: rNorm };
2134
+ }
2135
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
2136
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
2137
+ }
2138
+ function hdrToneMap(normalized, headroom, middleGray) {
2139
+ if (normalized <= middleGray) {
2140
+ return acesFilmic(normalized);
2141
+ }
2142
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
2143
+ return acesFilmic(expanded);
2040
2144
  }
2041
2145
  function getSdrStyleFromRgb(color, opacity) {
2042
2146
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
2043
2147
  }
2044
- function getStyleFromHsl(color, hdr, opacity) {
2045
- 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()}`;
2148
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
2149
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2150
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? exports.HdrMode.standard}`
2151
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
2046
2152
  return getCachedStyle(key, () => hdr
2047
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2153
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
2048
2154
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
2049
2155
  }
2050
- function colorMix(color1, color2, size1, size2) {
2156
+ function colorMix(color1, color2, size1, size2, hdr) {
2051
2157
  let rgb1 = color1, rgb2 = color2;
2052
2158
  if (!("r" in rgb1)) {
2053
- rgb1 = hslToRgb(color1);
2159
+ rgb1 = hdr ? hslToRgbFloat(color1) : hslToRgb(color1);
2054
2160
  }
2055
2161
  if (!("r" in rgb2)) {
2056
- rgb2 = hslToRgb(color2);
2162
+ rgb2 = hdr ? hslToRgbFloat(color2) : hslToRgb(color2);
2163
+ }
2164
+ if (hdr) {
2165
+ const lin1 = {
2166
+ b: srgbToLinear(rgb1.b / rgbMax),
2167
+ g: srgbToLinear(rgb1.g / rgbMax),
2168
+ r: srgbToLinear(rgb1.r / rgbMax),
2169
+ }, lin2 = {
2170
+ b: srgbToLinear(rgb2.b / rgbMax),
2171
+ g: srgbToLinear(rgb2.g / rgbMax),
2172
+ r: srgbToLinear(rgb2.r / rgbMax),
2173
+ }, totalWeight = size1 + size2;
2174
+ return {
2175
+ b: linearToSrgb((lin1.b * size1 + lin2.b * size2) / totalWeight) * rgbMax,
2176
+ g: linearToSrgb((lin1.g * size1 + lin2.g * size2) / totalWeight) * rgbMax,
2177
+ r: linearToSrgb((lin1.r * size1 + lin2.r * size2) / totalWeight) * rgbMax,
2178
+ };
2057
2179
  }
2058
2180
  return {
2059
2181
  b: mix(rgb1.b, rgb2.b, size1, size2),
@@ -2061,14 +2183,14 @@
2061
2183
  r: mix(rgb1.r, rgb2.r, size1, size2),
2062
2184
  };
2063
2185
  }
2064
- function getLinkColor(p1, p2, linkColor) {
2186
+ function getLinkColor(p1, p2, linkColor, hdr) {
2065
2187
  if (linkColor === randomColorValue) {
2066
2188
  return getRandomRgbColor();
2067
2189
  }
2068
2190
  else if (linkColor === midColorValue) {
2069
2191
  const sourceColor = p1.getFillColor() ?? p1.getStrokeColor(), destColor = p2?.getFillColor() ?? p2?.getStrokeColor();
2070
2192
  if (sourceColor && destColor && p2) {
2071
- return colorMix(sourceColor, destColor, p1.getRadius(), p2.getRadius());
2193
+ return colorMix(sourceColor, destColor, p1.getRadius(), p2.getRadius(), hdr);
2072
2194
  }
2073
2195
  else {
2074
2196
  const hslColor = sourceColor ?? destColor;
@@ -2164,7 +2286,7 @@
2164
2286
  colorValue.velocity = defaultVelocity;
2165
2287
  }
2166
2288
  }
2167
- function updateColorValue(data, decrease, delta, hdr) {
2289
+ function updateColorValue(data, decrease, delta, _hdr) {
2168
2290
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2169
2291
  if (!data.enable ||
2170
2292
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2177,7 +2299,7 @@
2177
2299
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2178
2300
  return;
2179
2301
  }
2180
- 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;
2302
+ 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;
2181
2303
  if (!decrease || data.status === exports.AnimationStatus.increasing) {
2182
2304
  data.value += velocity;
2183
2305
  if (data.value > max) {
@@ -2209,9 +2331,9 @@
2209
2331
  return;
2210
2332
  }
2211
2333
  const { h, s, l } = color;
2212
- updateColorValue(h, false, delta, hdr);
2213
- updateColorValue(s, true, delta, hdr);
2214
- updateColorValue(l, true, delta, hdr);
2334
+ updateColorValue(h, false, delta);
2335
+ updateColorValue(s, true, delta);
2336
+ updateColorValue(l, true, delta);
2215
2337
  }
2216
2338
  function alterHsl(color, type, value) {
2217
2339
  return {
@@ -2554,7 +2676,7 @@
2554
2676
  }
2555
2677
 
2556
2678
  async function loadBlendPlugin(engine) {
2557
- engine.checkVersion("4.3.2");
2679
+ engine.checkVersion("4.4.0");
2558
2680
  await engine.pluginManager.register(e => {
2559
2681
  e.pluginManager.addPlugin(new BlendPlugin());
2560
2682
  });
@@ -2591,7 +2713,7 @@
2591
2713
  }
2592
2714
 
2593
2715
  async function loadCircleShape(engine) {
2594
- engine.checkVersion("4.3.2");
2716
+ engine.checkVersion("4.4.0");
2595
2717
  await engine.pluginManager.register(e => {
2596
2718
  e.pluginManager.addShape(["circle"], () => {
2597
2719
  return Promise.resolve(new CircleDrawer());
@@ -2639,7 +2761,7 @@
2639
2761
  }
2640
2762
 
2641
2763
  async function loadHexColorPlugin(engine) {
2642
- engine.checkVersion("4.3.2");
2764
+ engine.checkVersion("4.4.0");
2643
2765
  await engine.pluginManager.register(e => {
2644
2766
  e.pluginManager.addColorManager("hex", new HexColorManager());
2645
2767
  });
@@ -2692,7 +2814,7 @@
2692
2814
  }
2693
2815
 
2694
2816
  async function loadHslColorPlugin(engine) {
2695
- engine.checkVersion("4.3.2");
2817
+ engine.checkVersion("4.4.0");
2696
2818
  await engine.pluginManager.register(e => {
2697
2819
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2698
2820
  });
@@ -2716,7 +2838,7 @@
2716
2838
  }
2717
2839
 
2718
2840
  async function loadMovePlugin(engine) {
2719
- engine.checkVersion("4.3.2");
2841
+ engine.checkVersion("4.4.0");
2720
2842
  await engine.pluginManager.register(e => {
2721
2843
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2722
2844
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2932,7 +3054,7 @@
2932
3054
  }
2933
3055
 
2934
3056
  async function loadOpacityUpdater(engine) {
2935
- engine.checkVersion("4.3.2");
3057
+ engine.checkVersion("4.4.0");
2936
3058
  await engine.pluginManager.register(e => {
2937
3059
  e.pluginManager.addParticleUpdater("opacity", container => {
2938
3060
  return Promise.resolve(new OpacityUpdater(container));
@@ -3277,7 +3399,7 @@
3277
3399
  }
3278
3400
 
3279
3401
  async function loadOutModesUpdater(engine) {
3280
- engine.checkVersion("4.3.2");
3402
+ engine.checkVersion("4.4.0");
3281
3403
  await engine.pluginManager.register(e => {
3282
3404
  e.pluginManager.addParticleUpdater("outModes", container => {
3283
3405
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3348,7 +3470,7 @@
3348
3470
  }
3349
3471
 
3350
3472
  async function loadPaintUpdater(engine) {
3351
- engine.checkVersion("4.3.2");
3473
+ engine.checkVersion("4.4.0");
3352
3474
  await engine.pluginManager.register(e => {
3353
3475
  e.pluginManager.addParticleUpdater("paint", container => {
3354
3476
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3403,7 +3525,7 @@
3403
3525
  }
3404
3526
 
3405
3527
  async function loadRgbColorPlugin(engine) {
3406
- engine.checkVersion("4.3.2");
3528
+ engine.checkVersion("4.4.0");
3407
3529
  await engine.pluginManager.register(e => {
3408
3530
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3409
3531
  });
@@ -3488,7 +3610,7 @@
3488
3610
  }
3489
3611
 
3490
3612
  async function loadSizeUpdater(engine) {
3491
- engine.checkVersion("4.3.2");
3613
+ engine.checkVersion("4.4.0");
3492
3614
  await engine.pluginManager.register(e => {
3493
3615
  e.pluginManager.addParticleUpdater("size", container => {
3494
3616
  return Promise.resolve(new SizeUpdater(container));
@@ -3497,7 +3619,7 @@
3497
3619
  }
3498
3620
 
3499
3621
  async function loadBasic(engine) {
3500
- engine.checkVersion("4.3.2");
3622
+ engine.checkVersion("4.4.0");
3501
3623
  await engine.pluginManager.register(async (e) => {
3502
3624
  await Promise.all([
3503
3625
  loadBlendPlugin(e),
@@ -3828,7 +3950,7 @@
3828
3950
  }
3829
3951
 
3830
3952
  async function loadDestroyUpdater(engine) {
3831
- engine.checkVersion("4.3.2");
3953
+ engine.checkVersion("4.4.0");
3832
3954
  await engine.pluginManager.register(e => {
3833
3955
  e.pluginManager.addParticleUpdater("destroy", container => {
3834
3956
  return Promise.resolve(new DestroyUpdater(e.pluginManager, container));
@@ -4059,7 +4181,7 @@
4059
4181
  })(EmitterClickMode || (EmitterClickMode = {}));
4060
4182
 
4061
4183
  async function loadEmittersPluginSimple(engine) {
4062
- engine.checkVersion("4.3.2");
4184
+ engine.checkVersion("4.4.0");
4063
4185
  await engine.pluginManager.register(async (e) => {
4064
4186
  const instancesManager = await getEmittersInstancesManager(e);
4065
4187
  await addEmittersShapesManager(e);
@@ -4147,7 +4269,7 @@
4147
4269
  }
4148
4270
 
4149
4271
  async function loadEmittersShapeSquare(engine) {
4150
- engine.checkVersion("4.3.2");
4272
+ engine.checkVersion("4.4.0");
4151
4273
  await engine.pluginManager.register((e) => {
4152
4274
  ensureEmittersPluginLoaded(e);
4153
4275
  e.pluginManager.addEmitterShapeGenerator?.("square", new EmittersSquareShapeGenerator());
@@ -4291,7 +4413,7 @@
4291
4413
  }
4292
4414
 
4293
4415
  async function loadLifeUpdater(engine) {
4294
- engine.checkVersion("4.3.2");
4416
+ engine.checkVersion("4.4.0");
4295
4417
  await engine.pluginManager.register(e => {
4296
4418
  e.pluginManager.addParticleUpdater("life", container => {
4297
4419
  return Promise.resolve(new LifeUpdater(container));
@@ -4317,7 +4439,7 @@
4317
4439
  }
4318
4440
 
4319
4441
  async function loadLineShape(engine) {
4320
- engine.checkVersion("4.3.2");
4442
+ engine.checkVersion("4.4.0");
4321
4443
  await engine.pluginManager.register(e => {
4322
4444
  e.pluginManager.addShape(["line"], () => Promise.resolve(new LineDrawer()));
4323
4445
  });
@@ -4421,7 +4543,7 @@
4421
4543
  }
4422
4544
 
4423
4545
  async function loadRotateUpdater(engine) {
4424
- engine.checkVersion("4.3.2");
4546
+ engine.checkVersion("4.4.0");
4425
4547
  await engine.pluginManager.register(e => {
4426
4548
  e.pluginManager.addParticleUpdater("rotate", container => {
4427
4549
  return Promise.resolve(new RotateUpdater(container));
@@ -4737,7 +4859,7 @@
4737
4859
  }
4738
4860
 
4739
4861
  async function loadSoundsPlugin(engine) {
4740
- engine.checkVersion("4.3.2");
4862
+ engine.checkVersion("4.4.0");
4741
4863
  await engine.pluginManager.register(e => {
4742
4864
  e.pluginManager.addPlugin(new SoundsPlugin(e));
4743
4865
  });
@@ -4745,7 +4867,7 @@
4745
4867
 
4746
4868
  let initPromise = null;
4747
4869
  async function doInitPlugins(engine) {
4748
- engine.checkVersion("4.3.2");
4870
+ engine.checkVersion("4.4.0");
4749
4871
  await engine.pluginManager.register(async (e) => {
4750
4872
  const loadEmittersForFireworks = async (e) => {
4751
4873
  await loadEmittersPluginSimple(e);
@@ -4792,7 +4914,7 @@
4792
4914
  fireworks.init = async () => {
4793
4915
  await initPlugins(tsParticles);
4794
4916
  };
4795
- fireworks.version = "4.3.2";
4917
+ fireworks.version = "4.4.0";
4796
4918
  globalThis.fireworks = fireworks;
4797
4919
 
4798
4920
  const globalObject = globalThis;
@@ -4917,7 +5039,11 @@
4917
5039
  if (!fColor && !sColor) {
4918
5040
  return;
4919
5041
  }
4920
- 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;
5042
+ 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
5043
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
5044
+ : undefined, stroke = sColor
5045
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
5046
+ : fill;
4921
5047
  transform.a = transform.b = transform.c = transform.d = undefined;
4922
5048
  colorStyles.fill = fill;
4923
5049
  colorStyles.stroke = stroke;
@@ -5251,7 +5377,9 @@
5251
5377
  if (typeof background.element === "string") {
5252
5378
  if (typeof document !== "undefined") {
5253
5379
  const node = document.querySelector(background.element);
5254
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
5380
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
5381
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
5382
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
5255
5383
  this.#backgroundElement = node;
5256
5384
  }
5257
5385
  else if (node) {
@@ -5262,10 +5390,10 @@
5262
5390
  }
5263
5391
  }
5264
5392
  }
5265
- else if (background.element instanceof HTMLCanvasElement ||
5266
- background.element instanceof OffscreenCanvas ||
5267
- background.element instanceof HTMLVideoElement ||
5268
- background.element instanceof HTMLImageElement) {
5393
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
5394
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
5395
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
5396
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
5269
5397
  this.#backgroundElement = background.element;
5270
5398
  }
5271
5399
  }
@@ -5333,6 +5461,7 @@
5333
5461
  zoom = defaultZoom;
5334
5462
  #container;
5335
5463
  #generated;
5464
+ #hdrMediaListeners;
5336
5465
  #mutationObserver;
5337
5466
  #originalStyle;
5338
5467
  #pluginManager;
@@ -5397,7 +5526,6 @@
5397
5526
  });
5398
5527
  this.resize();
5399
5528
  this.#initStyle();
5400
- this.initBackground();
5401
5529
  this.#safeMutationObserver(obs => {
5402
5530
  const element = this.domElement;
5403
5531
  if (!element || !(element instanceof Node)) {
@@ -5407,6 +5535,8 @@
5407
5535
  });
5408
5536
  this.initPlugins();
5409
5537
  this.#initContext();
5538
+ this.initBackground();
5539
+ this.#initHdrListeners();
5410
5540
  this.render.init();
5411
5541
  }
5412
5542
  initBackground() {
@@ -5416,7 +5546,8 @@
5416
5546
  }
5417
5547
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
5418
5548
  if (color) {
5419
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
5549
+ const hdrOptions = container.actualOptions.hdr;
5550
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
5420
5551
  }
5421
5552
  else {
5422
5553
  elementStyle.backgroundColor = "";
@@ -5513,6 +5644,7 @@
5513
5644
  obs.disconnect();
5514
5645
  });
5515
5646
  this.#mutationObserver = undefined;
5647
+ this.#removeHdrListeners();
5516
5648
  this.render.stop();
5517
5649
  }
5518
5650
  async windowResize() {
@@ -5532,9 +5664,16 @@
5532
5664
  }
5533
5665
  }
5534
5666
  #initContext() {
5535
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
5667
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
5536
5668
  safeMatchMedia("(color-gamut: p3)")?.matches &&
5537
5669
  safeMatchMedia("(dynamic-range: high)")?.matches;
5670
+ container.hdr = canSupportHdr ?? false;
5671
+ container.hdrMode = container.actualOptions.hdr.mode;
5672
+ container.peakNits = container.actualOptions.hdr.peakNits;
5673
+ const renderCanvas = this.renderCanvas;
5674
+ if (!renderCanvas) {
5675
+ return;
5676
+ }
5538
5677
  this.render.setContextSettings({
5539
5678
  alpha: true,
5540
5679
  desynchronized: true,
@@ -5543,11 +5682,47 @@
5543
5682
  ? { colorSpace: "display-p3", colorType: "float16" }
5544
5683
  : { colorSpace: "srgb" }),
5545
5684
  });
5546
- const renderCanvas = this.renderCanvas;
5547
- if (!renderCanvas) {
5548
- return;
5685
+ let context;
5686
+ try {
5687
+ context = renderCanvas.getContext("2d", this.render.settings);
5688
+ }
5689
+ catch {
5690
+ context = null;
5691
+ }
5692
+ if (canSupportHdr && !context) {
5693
+ container.hdr = false;
5694
+ const sdrSettings = {
5695
+ alpha: true,
5696
+ desynchronized: true,
5697
+ willReadFrequently: false,
5698
+ colorSpace: "srgb",
5699
+ };
5700
+ this.render.setContextSettings(sdrSettings);
5701
+ try {
5702
+ context = renderCanvas.getContext("2d", sdrSettings);
5703
+ }
5704
+ catch {
5705
+ context = null;
5706
+ }
5707
+ }
5708
+ this.render.setContext(context);
5709
+ }
5710
+ #initHdrListeners() {
5711
+ this.#removeHdrListeners();
5712
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
5713
+ this.#recreateRenderCanvas();
5714
+ this.#initContext();
5715
+ this.initBackground();
5716
+ }, listeners = [];
5717
+ if (p3Query) {
5718
+ p3Query.addEventListener("change", handleChange);
5719
+ listeners.push({ handler: handleChange, mql: p3Query });
5549
5720
  }
5550
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
5721
+ if (hdrQuery) {
5722
+ hdrQuery.addEventListener("change", handleChange);
5723
+ listeners.push({ handler: handleChange, mql: hdrQuery });
5724
+ }
5725
+ this.#hdrMediaListeners = listeners;
5551
5726
  }
5552
5727
  #initStyle() {
5553
5728
  const element = this.domElement, options = this.#container.actualOptions;
@@ -5571,6 +5746,25 @@
5571
5746
  element.style.setProperty(key, value, "important");
5572
5747
  }
5573
5748
  }
5749
+ #recreateRenderCanvas() {
5750
+ const renderCanvas = this.renderCanvas;
5751
+ if (!renderCanvas) {
5752
+ return;
5753
+ }
5754
+ if (this.domElement) {
5755
+ return;
5756
+ }
5757
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
5758
+ }
5759
+ #removeHdrListeners() {
5760
+ if (!this.#hdrMediaListeners) {
5761
+ return;
5762
+ }
5763
+ for (const { handler, mql } of this.#hdrMediaListeners) {
5764
+ mql.removeEventListener("change", handler);
5765
+ }
5766
+ this.#hdrMediaListeners = undefined;
5767
+ }
5574
5768
  #repairStyle() {
5575
5769
  const element = this.domElement;
5576
5770
  if (!element) {
@@ -5955,9 +6149,9 @@
5955
6149
  }
5956
6150
  getOpacity() {
5957
6151
  const zIndexOptions = this.options.zIndex, zIndexFactor = zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, baseOpacity = getRangeValue(this.opacity?.value ?? defaultOpacity$1), modifierOpacity = this.#applyModifiers(undefined, m => m.opacity), opacity = modifierOpacity ?? baseOpacity, fillOpacity = this.fillOpacity ?? defaultOpacity$1, strokeOpacity = this.strokeOpacity ?? defaultOpacity$1;
5958
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
6152
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
5959
6153
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
5960
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
6154
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
5961
6155
  return this.#cachedOpacityData;
5962
6156
  }
5963
6157
  getPosition() {
@@ -6812,6 +7006,7 @@
6812
7006
  effectDrawers;
6813
7007
  fpsLimit;
6814
7008
  hdr;
7009
+ hdrMode;
6815
7010
  id;
6816
7011
  pageHidden;
6817
7012
  particleCreatedPlugins;
@@ -6819,6 +7014,7 @@
6819
7014
  particlePositionPlugins;
6820
7015
  particleUpdaters;
6821
7016
  particles;
7017
+ peakNits;
6822
7018
  plugins;
6823
7019
  retina;
6824
7020
  shapeDrawers;
@@ -6849,6 +7045,8 @@
6849
7045
  this.id = Symbol(id);
6850
7046
  this.fpsLimit = 120;
6851
7047
  this.hdr = false;
7048
+ this.hdrMode = exports.HdrMode.standard;
7049
+ this.peakNits = 400;
6852
7050
  this.#smooth = false;
6853
7051
  this.#delay = 0;
6854
7052
  this.#duration = 0;
@@ -6988,8 +7186,9 @@
6988
7186
  this.updateActualOptions();
6989
7187
  this.canvas.initBackground();
6990
7188
  this.canvas.resize();
6991
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
6992
- this.hdr = hdr;
7189
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
7190
+ this.hdrMode = hdrOptions.mode;
7191
+ this.peakNits = hdrOptions.peakNits;
6993
7192
  this.zLayers = zLayers;
6994
7193
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
6995
7194
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;
@@ -8411,6 +8610,7 @@
8411
8610
  exports.ColorAnimation = ColorAnimation;
8412
8611
  exports.Fill = Fill;
8413
8612
  exports.FullScreen = FullScreen;
8613
+ exports.HDROptions = HDROptions;
8414
8614
  exports.HslAnimation = HslAnimation;
8415
8615
  exports.Move = Move;
8416
8616
  exports.MoveAngle = MoveAngle;