@tsparticles/preset-matrix 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
- /* Preset v4.3.2 */
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) :
@@ -797,7 +797,7 @@
797
797
  return this.#domArray;
798
798
  }
799
799
  get version() {
800
- return "4.3.2";
800
+ return "4.4.0";
801
801
  }
802
802
  addEventListener(type, listener) {
803
803
  this.#eventDispatcher.addEventListener(type, listener);
@@ -878,6 +878,10 @@
878
878
  }
879
879
 
880
880
  function initEngine() {
881
+ const existing = globalThis.tsParticles;
882
+ if (existing?.pluginManager) {
883
+ return existing;
884
+ }
881
885
  return new Engine();
882
886
  }
883
887
 
@@ -975,6 +979,15 @@
975
979
  AnimationMode["random"] = "random";
976
980
  })(AnimationMode || (AnimationMode = {}));
977
981
 
982
+ var HdrMode;
983
+ (function (HdrMode) {
984
+ HdrMode["standard"] = "standard";
985
+ HdrMode["natural"] = "natural";
986
+ HdrMode["vivid"] = "vivid";
987
+ HdrMode["cinematic"] = "cinematic";
988
+ HdrMode["dynamic"] = "dynamic";
989
+ })(HdrMode || (HdrMode = {}));
990
+
978
991
  var LimitMode;
979
992
  (function (LimitMode) {
980
993
  LimitMode["delete"] = "delete";
@@ -1230,6 +1243,29 @@
1230
1243
  }
1231
1244
  }
1232
1245
 
1246
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
1247
+ class HDROptions extends OptionLoader {
1248
+ enable = true;
1249
+ mode = HdrMode.standard;
1250
+ peakNits = defaultPeakNits;
1251
+ doLoad(data) {
1252
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
1253
+ throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1254
+ }
1255
+ if (data.mode !== undefined &&
1256
+ (typeof data.mode !== "string" || !Object.values(HdrMode).includes(data.mode))) {
1257
+ throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1258
+ }
1259
+ if (data.peakNits !== undefined &&
1260
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1261
+ throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1262
+ }
1263
+ loadProperty(this, "enable", data.enable);
1264
+ loadProperty(this, "mode", data.mode);
1265
+ loadProperty(this, "peakNits", data.peakNits);
1266
+ }
1267
+ }
1268
+
1233
1269
  class ResizeEvent extends OptionLoader {
1234
1270
  delay = 0.5;
1235
1271
  enable = true;
@@ -1673,7 +1709,7 @@
1673
1709
  duration = 0;
1674
1710
  fpsLimit = 120;
1675
1711
  fullScreen;
1676
- hdr = true;
1712
+ hdr;
1677
1713
  key;
1678
1714
  name;
1679
1715
  palette;
@@ -1693,6 +1729,7 @@
1693
1729
  this.#container = container;
1694
1730
  this.background = new Background();
1695
1731
  this.fullScreen = new FullScreen();
1732
+ this.hdr = new HDROptions();
1696
1733
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1697
1734
  this.resize = new ResizeEvent();
1698
1735
  }
@@ -1715,7 +1752,15 @@
1715
1752
  loadProperty(this, "detectRetina", data.detectRetina);
1716
1753
  loadRangeProperty(this, "duration", data.duration);
1717
1754
  loadProperty(this, "fpsLimit", data.fpsLimit);
1718
- loadProperty(this, "hdr", data.hdr);
1755
+ const hdrData = data.hdr;
1756
+ if (isBoolean(hdrData)) {
1757
+ this.hdr.enable = hdrData;
1758
+ this.hdr.mode = HdrMode.standard;
1759
+ this.hdr.peakNits = 400;
1760
+ }
1761
+ else {
1762
+ this.hdr.load(hdrData);
1763
+ }
1719
1764
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1720
1765
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1721
1766
  loadProperty(this, "zLayers", data.zLayers);
@@ -1758,7 +1803,7 @@
1758
1803
  }
1759
1804
  }
1760
1805
 
1761
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1806
+ 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
1807
  function getCachedStyle(key, generator) {
1763
1808
  let cached = styleCache.get(key);
1764
1809
  if (!cached) {
@@ -1770,6 +1815,42 @@
1770
1815
  }
1771
1816
  return cached;
1772
1817
  }
1818
+ function acesFilmic(x) {
1819
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
1820
+ }
1821
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
1822
+ switch (mode) {
1823
+ case HdrMode.vivid: {
1824
+ const avg = (r + g + b) / channelCount;
1825
+ return {
1826
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1827
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1828
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1829
+ };
1830
+ }
1831
+ case HdrMode.cinematic: {
1832
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
1833
+ return {
1834
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
1835
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
1836
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
1837
+ };
1838
+ }
1839
+ case HdrMode.dynamic: {
1840
+ 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;
1841
+ return {
1842
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
1843
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
1844
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
1845
+ };
1846
+ }
1847
+ case HdrMode.standard:
1848
+ return { b, g, r };
1849
+ case HdrMode.natural:
1850
+ default:
1851
+ return { b, g, r };
1852
+ }
1853
+ }
1773
1854
  function stringToRgba(pluginManager, input) {
1774
1855
  if (!input) {
1775
1856
  return;
@@ -1927,21 +2008,40 @@
1927
2008
  r: getRgbInRangeValue(),
1928
2009
  };
1929
2010
  }
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)));
2011
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
2012
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2013
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2014
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
2015
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
2016
+ }
2017
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = HdrMode.standard) {
2018
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
2019
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1933
2020
  }
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()})`;
2021
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
2022
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
2023
+ if (mode !== HdrMode.natural && mode !== HdrMode.vivid && mode !== HdrMode.cinematic && mode !== HdrMode.dynamic) {
2024
+ return { b: bNorm, g: gNorm, r: rNorm };
2025
+ }
2026
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
2027
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
2028
+ }
2029
+ function hdrToneMap(normalized, headroom, middleGray) {
2030
+ if (normalized <= middleGray) {
2031
+ return acesFilmic(normalized);
2032
+ }
2033
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
2034
+ return acesFilmic(expanded);
1937
2035
  }
1938
2036
  function getSdrStyleFromRgb(color, opacity) {
1939
2037
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
1940
2038
  }
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()}`;
2039
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
2040
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2041
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2042
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
1943
2043
  return getCachedStyle(key, () => hdr
1944
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2044
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
1945
2045
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1946
2046
  }
1947
2047
  function getHslFromAnimation(animation) {
@@ -2004,7 +2104,7 @@
2004
2104
  colorValue.velocity = defaultVelocity;
2005
2105
  }
2006
2106
  }
2007
- function updateColorValue(data, decrease, delta, hdr) {
2107
+ function updateColorValue(data, decrease, delta, _hdr) {
2008
2108
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2009
2109
  if (!data.enable ||
2010
2110
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2017,7 +2117,7 @@
2017
2117
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2018
2118
  return;
2019
2119
  }
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;
2120
+ 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
2121
  if (!decrease || data.status === AnimationStatus.increasing) {
2022
2122
  data.value += velocity;
2023
2123
  if (data.value > max) {
@@ -2049,9 +2149,9 @@
2049
2149
  return;
2050
2150
  }
2051
2151
  const { h, s, l } = color;
2052
- updateColorValue(h, false, delta, hdr);
2053
- updateColorValue(s, true, delta, hdr);
2054
- updateColorValue(l, true, delta, hdr);
2152
+ updateColorValue(h, false, delta);
2153
+ updateColorValue(s, true, delta);
2154
+ updateColorValue(l, true, delta);
2055
2155
  }
2056
2156
  function alterHsl(color, type, value) {
2057
2157
  return {
@@ -2101,7 +2201,7 @@
2101
2201
  }
2102
2202
 
2103
2203
  async function loadBlendPlugin(engine) {
2104
- engine.checkVersion("4.3.2");
2204
+ engine.checkVersion("4.4.0");
2105
2205
  await engine.pluginManager.register(e => {
2106
2206
  e.pluginManager.addPlugin(new BlendPlugin());
2107
2207
  });
@@ -2138,7 +2238,7 @@
2138
2238
  }
2139
2239
 
2140
2240
  async function loadCircleShape(engine) {
2141
- engine.checkVersion("4.3.2");
2241
+ engine.checkVersion("4.4.0");
2142
2242
  await engine.pluginManager.register(e => {
2143
2243
  e.pluginManager.addShape(["circle"], () => {
2144
2244
  return Promise.resolve(new CircleDrawer());
@@ -2186,7 +2286,7 @@
2186
2286
  }
2187
2287
 
2188
2288
  async function loadHexColorPlugin(engine) {
2189
- engine.checkVersion("4.3.2");
2289
+ engine.checkVersion("4.4.0");
2190
2290
  await engine.pluginManager.register(e => {
2191
2291
  e.pluginManager.addColorManager("hex", new HexColorManager());
2192
2292
  });
@@ -2239,7 +2339,7 @@
2239
2339
  }
2240
2340
 
2241
2341
  async function loadHslColorPlugin(engine) {
2242
- engine.checkVersion("4.3.2");
2342
+ engine.checkVersion("4.4.0");
2243
2343
  await engine.pluginManager.register(e => {
2244
2344
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2245
2345
  });
@@ -2263,7 +2363,7 @@
2263
2363
  }
2264
2364
 
2265
2365
  async function loadMovePlugin(engine) {
2266
- engine.checkVersion("4.3.2");
2366
+ engine.checkVersion("4.4.0");
2267
2367
  await engine.pluginManager.register(e => {
2268
2368
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2269
2369
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2473,7 +2573,7 @@
2473
2573
  }
2474
2574
 
2475
2575
  async function loadOpacityUpdater(engine) {
2476
- engine.checkVersion("4.3.2");
2576
+ engine.checkVersion("4.4.0");
2477
2577
  await engine.pluginManager.register(e => {
2478
2578
  e.pluginManager.addParticleUpdater("opacity", container => {
2479
2579
  return Promise.resolve(new OpacityUpdater(container));
@@ -2818,7 +2918,7 @@
2818
2918
  }
2819
2919
 
2820
2920
  async function loadOutModesUpdater(engine) {
2821
- engine.checkVersion("4.3.2");
2921
+ engine.checkVersion("4.4.0");
2822
2922
  await engine.pluginManager.register(e => {
2823
2923
  e.pluginManager.addParticleUpdater("outModes", container => {
2824
2924
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2889,7 +2989,7 @@
2889
2989
  }
2890
2990
 
2891
2991
  async function loadPaintUpdater(engine) {
2892
- engine.checkVersion("4.3.2");
2992
+ engine.checkVersion("4.4.0");
2893
2993
  await engine.pluginManager.register(e => {
2894
2994
  e.pluginManager.addParticleUpdater("paint", container => {
2895
2995
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2944,7 +3044,7 @@
2944
3044
  }
2945
3045
 
2946
3046
  async function loadRgbColorPlugin(engine) {
2947
- engine.checkVersion("4.3.2");
3047
+ engine.checkVersion("4.4.0");
2948
3048
  await engine.pluginManager.register(e => {
2949
3049
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
2950
3050
  });
@@ -3029,7 +3129,7 @@
3029
3129
  }
3030
3130
 
3031
3131
  async function loadSizeUpdater(engine) {
3032
- engine.checkVersion("4.3.2");
3132
+ engine.checkVersion("4.4.0");
3033
3133
  await engine.pluginManager.register(e => {
3034
3134
  e.pluginManager.addParticleUpdater("size", container => {
3035
3135
  return Promise.resolve(new SizeUpdater(container));
@@ -3038,7 +3138,7 @@
3038
3138
  }
3039
3139
 
3040
3140
  async function loadBasic(engine) {
3041
- engine.checkVersion("4.3.2");
3141
+ engine.checkVersion("4.4.0");
3042
3142
  await engine.pluginManager.register(async (e) => {
3043
3143
  await Promise.all([
3044
3144
  loadBlendPlugin(e),
@@ -3270,7 +3370,7 @@
3270
3370
  }
3271
3371
 
3272
3372
  async function loadMatrixShape(engine) {
3273
- engine.checkVersion("4.3.2");
3373
+ engine.checkVersion("4.4.0");
3274
3374
  await engine.pluginManager.register(e => {
3275
3375
  e.pluginManager.addShape(["matrix"], () => Promise.resolve(new MatrixDrawer()));
3276
3376
  });
@@ -3315,7 +3415,7 @@
3315
3415
  }
3316
3416
 
3317
3417
  async function loadPoissonDiscPlugin(engine) {
3318
- engine.checkVersion("4.3.2");
3418
+ engine.checkVersion("4.4.0");
3319
3419
  await engine.pluginManager.register(e => {
3320
3420
  e.pluginManager.addPlugin(new PoissonDiscPlugin());
3321
3421
  });
@@ -3340,7 +3440,7 @@
3340
3440
  }
3341
3441
  context.save();
3342
3442
  context.shadowBlur = shadowParticle.shadowBlur ?? defaultShadowBlur;
3343
- context.shadowColor = getStyleFromRgb(shadowColor, container.hdr);
3443
+ context.shadowColor = getStyleFromRgb(shadowColor, container.hdr, undefined, container.peakNits, container.hdrMode);
3344
3444
  context.shadowOffsetX = shadowOffset?.x ?? defaultShadowOffsetValue;
3345
3445
  context.shadowOffsetY = shadowOffset?.y ?? defaultShadowOffsetValue;
3346
3446
  }
@@ -3353,7 +3453,7 @@
3353
3453
  }
3354
3454
 
3355
3455
  async function loadShadowEffect(engine) {
3356
- engine.checkVersion("4.3.2");
3456
+ engine.checkVersion("4.4.0");
3357
3457
  await engine.pluginManager.register(e => {
3358
3458
  e.pluginManager.addEffect("shadow", container => {
3359
3459
  return Promise.resolve(new ShadowDrawer(e.pluginManager, container));
@@ -3417,7 +3517,7 @@
3417
3517
  }
3418
3518
 
3419
3519
  async function loadTrailPlugin(engine) {
3420
- engine.checkVersion("4.3.2");
3520
+ engine.checkVersion("4.4.0");
3421
3521
  await engine.pluginManager.register(e => {
3422
3522
  e.pluginManager.addPlugin(new TrailPlugin(e.pluginManager));
3423
3523
  });
@@ -3637,7 +3737,11 @@
3637
3737
  if (!fColor && !sColor) {
3638
3738
  return;
3639
3739
  }
3640
- 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;
3740
+ 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
3741
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
3742
+ : undefined, stroke = sColor
3743
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
3744
+ : fill;
3641
3745
  transform.a = transform.b = transform.c = transform.d = undefined;
3642
3746
  colorStyles.fill = fill;
3643
3747
  colorStyles.stroke = stroke;
@@ -3971,7 +4075,9 @@
3971
4075
  if (typeof background.element === "string") {
3972
4076
  if (typeof document !== "undefined") {
3973
4077
  const node = document.querySelector(background.element);
3974
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
4078
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
4079
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
4080
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
3975
4081
  this.#backgroundElement = node;
3976
4082
  }
3977
4083
  else if (node) {
@@ -3982,10 +4088,10 @@
3982
4088
  }
3983
4089
  }
3984
4090
  }
3985
- else if (background.element instanceof HTMLCanvasElement ||
3986
- background.element instanceof OffscreenCanvas ||
3987
- background.element instanceof HTMLVideoElement ||
3988
- background.element instanceof HTMLImageElement) {
4091
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
4092
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
4093
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
4094
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
3989
4095
  this.#backgroundElement = background.element;
3990
4096
  }
3991
4097
  }
@@ -4053,6 +4159,7 @@
4053
4159
  zoom = defaultZoom;
4054
4160
  #container;
4055
4161
  #generated;
4162
+ #hdrMediaListeners;
4056
4163
  #mutationObserver;
4057
4164
  #originalStyle;
4058
4165
  #pluginManager;
@@ -4117,7 +4224,6 @@
4117
4224
  });
4118
4225
  this.resize();
4119
4226
  this.#initStyle();
4120
- this.initBackground();
4121
4227
  this.#safeMutationObserver(obs => {
4122
4228
  const element = this.domElement;
4123
4229
  if (!element || !(element instanceof Node)) {
@@ -4127,6 +4233,8 @@
4127
4233
  });
4128
4234
  this.initPlugins();
4129
4235
  this.#initContext();
4236
+ this.initBackground();
4237
+ this.#initHdrListeners();
4130
4238
  this.render.init();
4131
4239
  }
4132
4240
  initBackground() {
@@ -4136,7 +4244,8 @@
4136
4244
  }
4137
4245
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4138
4246
  if (color) {
4139
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
4247
+ const hdrOptions = container.actualOptions.hdr;
4248
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
4140
4249
  }
4141
4250
  else {
4142
4251
  elementStyle.backgroundColor = "";
@@ -4233,6 +4342,7 @@
4233
4342
  obs.disconnect();
4234
4343
  });
4235
4344
  this.#mutationObserver = undefined;
4345
+ this.#removeHdrListeners();
4236
4346
  this.render.stop();
4237
4347
  }
4238
4348
  async windowResize() {
@@ -4252,9 +4362,16 @@
4252
4362
  }
4253
4363
  }
4254
4364
  #initContext() {
4255
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4365
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
4256
4366
  safeMatchMedia("(color-gamut: p3)")?.matches &&
4257
4367
  safeMatchMedia("(dynamic-range: high)")?.matches;
4368
+ container.hdr = canSupportHdr ?? false;
4369
+ container.hdrMode = container.actualOptions.hdr.mode;
4370
+ container.peakNits = container.actualOptions.hdr.peakNits;
4371
+ const renderCanvas = this.renderCanvas;
4372
+ if (!renderCanvas) {
4373
+ return;
4374
+ }
4258
4375
  this.render.setContextSettings({
4259
4376
  alpha: true,
4260
4377
  desynchronized: true,
@@ -4263,11 +4380,47 @@
4263
4380
  ? { colorSpace: "display-p3", colorType: "float16" }
4264
4381
  : { colorSpace: "srgb" }),
4265
4382
  });
4266
- const renderCanvas = this.renderCanvas;
4267
- if (!renderCanvas) {
4268
- return;
4383
+ let context;
4384
+ try {
4385
+ context = renderCanvas.getContext("2d", this.render.settings);
4386
+ }
4387
+ catch {
4388
+ context = null;
4389
+ }
4390
+ if (canSupportHdr && !context) {
4391
+ container.hdr = false;
4392
+ const sdrSettings = {
4393
+ alpha: true,
4394
+ desynchronized: true,
4395
+ willReadFrequently: false,
4396
+ colorSpace: "srgb",
4397
+ };
4398
+ this.render.setContextSettings(sdrSettings);
4399
+ try {
4400
+ context = renderCanvas.getContext("2d", sdrSettings);
4401
+ }
4402
+ catch {
4403
+ context = null;
4404
+ }
4405
+ }
4406
+ this.render.setContext(context);
4407
+ }
4408
+ #initHdrListeners() {
4409
+ this.#removeHdrListeners();
4410
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
4411
+ this.#recreateRenderCanvas();
4412
+ this.#initContext();
4413
+ this.initBackground();
4414
+ }, listeners = [];
4415
+ if (p3Query) {
4416
+ p3Query.addEventListener("change", handleChange);
4417
+ listeners.push({ handler: handleChange, mql: p3Query });
4418
+ }
4419
+ if (hdrQuery) {
4420
+ hdrQuery.addEventListener("change", handleChange);
4421
+ listeners.push({ handler: handleChange, mql: hdrQuery });
4269
4422
  }
4270
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4423
+ this.#hdrMediaListeners = listeners;
4271
4424
  }
4272
4425
  #initStyle() {
4273
4426
  const element = this.domElement, options = this.#container.actualOptions;
@@ -4291,6 +4444,25 @@
4291
4444
  element.style.setProperty(key, value, "important");
4292
4445
  }
4293
4446
  }
4447
+ #recreateRenderCanvas() {
4448
+ const renderCanvas = this.renderCanvas;
4449
+ if (!renderCanvas) {
4450
+ return;
4451
+ }
4452
+ if (this.domElement) {
4453
+ return;
4454
+ }
4455
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
4456
+ }
4457
+ #removeHdrListeners() {
4458
+ if (!this.#hdrMediaListeners) {
4459
+ return;
4460
+ }
4461
+ for (const { handler, mql } of this.#hdrMediaListeners) {
4462
+ mql.removeEventListener("change", handler);
4463
+ }
4464
+ this.#hdrMediaListeners = undefined;
4465
+ }
4294
4466
  #repairStyle() {
4295
4467
  const element = this.domElement;
4296
4468
  if (!element) {
@@ -4675,9 +4847,9 @@
4675
4847
  }
4676
4848
  getOpacity() {
4677
4849
  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;
4678
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
4850
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
4679
4851
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
4680
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
4852
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
4681
4853
  return this.#cachedOpacityData;
4682
4854
  }
4683
4855
  getPosition() {
@@ -5532,6 +5704,7 @@
5532
5704
  effectDrawers;
5533
5705
  fpsLimit;
5534
5706
  hdr;
5707
+ hdrMode;
5535
5708
  id;
5536
5709
  pageHidden;
5537
5710
  particleCreatedPlugins;
@@ -5539,6 +5712,7 @@
5539
5712
  particlePositionPlugins;
5540
5713
  particleUpdaters;
5541
5714
  particles;
5715
+ peakNits;
5542
5716
  plugins;
5543
5717
  retina;
5544
5718
  shapeDrawers;
@@ -5569,6 +5743,8 @@
5569
5743
  this.id = Symbol(id);
5570
5744
  this.fpsLimit = 120;
5571
5745
  this.hdr = false;
5746
+ this.hdrMode = HdrMode.standard;
5747
+ this.peakNits = 400;
5572
5748
  this.#smooth = false;
5573
5749
  this.#delay = 0;
5574
5750
  this.#duration = 0;
@@ -5708,8 +5884,9 @@
5708
5884
  this.updateActualOptions();
5709
5885
  this.canvas.initBackground();
5710
5886
  this.canvas.resize();
5711
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
5712
- this.hdr = hdr;
5887
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
5888
+ this.hdrMode = hdrOptions.mode;
5889
+ this.peakNits = hdrOptions.peakNits;
5713
5890
  this.zLayers = zLayers;
5714
5891
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
5715
5892
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;
@@ -6220,7 +6397,7 @@
6220
6397
  let handled = false;
6221
6398
  const canvas = container.canvas;
6222
6399
  if (trailFill.color) {
6223
- canvas.render.paintBase(getStyleFromRgb(trailFill.color, container.hdr, trailFill.opacity));
6400
+ canvas.render.paintBase(getStyleFromRgb(trailFill.color, container.hdr, trailFill.opacity, container.peakNits, container.hdrMode));
6224
6401
  handled = true;
6225
6402
  }
6226
6403
  else if (trailFill.image) {