@tsparticles/preset-big-circles 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) :
@@ -292,6 +292,9 @@
292
292
  })(PixelMode || (PixelMode = {}));
293
293
 
294
294
  const minRadius = 0;
295
+ function isForbiddenKey(key) {
296
+ return key === "__proto__" || key === "constructor" || key === "prototype";
297
+ }
295
298
  function hasMatchMedia() {
296
299
  return typeof matchMedia !== "undefined";
297
300
  }
@@ -367,7 +370,7 @@
367
370
  if (!hasNested) {
368
371
  const sourceDict = source, destDict = destination;
369
372
  for (const key of sourceKeys) {
370
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
373
+ if (isForbiddenKey(key)) {
371
374
  continue;
372
375
  }
373
376
  const v = sourceDict[key];
@@ -378,7 +381,7 @@
378
381
  continue;
379
382
  }
380
383
  for (const key of sourceKeys) {
381
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
384
+ if (isForbiddenKey(key)) {
382
385
  continue;
383
386
  }
384
387
  const sourceDict = source, destDict = destination, value = sourceDict[key];
@@ -794,7 +797,7 @@
794
797
  return this.#domArray;
795
798
  }
796
799
  get version() {
797
- return "4.3.1";
800
+ return "4.4.0";
798
801
  }
799
802
  addEventListener(type, listener) {
800
803
  this.#eventDispatcher.addEventListener(type, listener);
@@ -875,6 +878,10 @@
875
878
  }
876
879
 
877
880
  function initEngine() {
881
+ const existing = globalThis.tsParticles;
882
+ if (existing?.pluginManager) {
883
+ return existing;
884
+ }
878
885
  return new Engine();
879
886
  }
880
887
 
@@ -972,6 +979,15 @@
972
979
  AnimationMode["random"] = "random";
973
980
  })(AnimationMode || (AnimationMode = {}));
974
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
+
975
991
  var LimitMode;
976
992
  (function (LimitMode) {
977
993
  LimitMode["delete"] = "delete";
@@ -1227,6 +1243,29 @@
1227
1243
  }
1228
1244
  }
1229
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
+
1230
1269
  class ResizeEvent extends OptionLoader {
1231
1270
  delay = 0.5;
1232
1271
  enable = true;
@@ -1670,7 +1709,7 @@
1670
1709
  duration = 0;
1671
1710
  fpsLimit = 120;
1672
1711
  fullScreen;
1673
- hdr = true;
1712
+ hdr;
1674
1713
  key;
1675
1714
  name;
1676
1715
  palette;
@@ -1690,6 +1729,7 @@
1690
1729
  this.#container = container;
1691
1730
  this.background = new Background();
1692
1731
  this.fullScreen = new FullScreen();
1732
+ this.hdr = new HDROptions();
1693
1733
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1694
1734
  this.resize = new ResizeEvent();
1695
1735
  }
@@ -1712,7 +1752,15 @@
1712
1752
  loadProperty(this, "detectRetina", data.detectRetina);
1713
1753
  loadRangeProperty(this, "duration", data.duration);
1714
1754
  loadProperty(this, "fpsLimit", data.fpsLimit);
1715
- 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
+ }
1716
1764
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1717
1765
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1718
1766
  loadProperty(this, "zLayers", data.zLayers);
@@ -1755,7 +1803,7 @@
1755
1803
  }
1756
1804
  }
1757
1805
 
1758
- 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;
1759
1807
  function getCachedStyle(key, generator) {
1760
1808
  let cached = styleCache.get(key);
1761
1809
  if (!cached) {
@@ -1767,6 +1815,42 @@
1767
1815
  }
1768
1816
  return cached;
1769
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
+ }
1770
1854
  function stringToRgba(pluginManager, input) {
1771
1855
  if (!input) {
1772
1856
  return;
@@ -1924,21 +2008,40 @@
1924
2008
  r: getRgbInRangeValue(),
1925
2009
  };
1926
2010
  }
1927
- function getStyleFromRgb(color, hdr, opacity) {
1928
- 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()}`;
1929
- 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));
1930
2016
  }
1931
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1932
- const headroom = peakNits / sdrReferenceWhiteNits;
1933
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
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()})`;
2020
+ }
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);
1934
2035
  }
1935
2036
  function getSdrStyleFromRgb(color, opacity) {
1936
2037
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
1937
2038
  }
1938
- function getStyleFromHsl(color, hdr, opacity) {
1939
- 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()}`;
1940
2043
  return getCachedStyle(key, () => hdr
1941
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2044
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
1942
2045
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1943
2046
  }
1944
2047
  function getHslFromAnimation(animation) {
@@ -2001,7 +2104,7 @@
2001
2104
  colorValue.velocity = defaultVelocity;
2002
2105
  }
2003
2106
  }
2004
- function updateColorValue(data, decrease, delta, hdr) {
2107
+ function updateColorValue(data, decrease, delta, _hdr) {
2005
2108
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2006
2109
  if (!data.enable ||
2007
2110
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2014,7 +2117,7 @@
2014
2117
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2015
2118
  return;
2016
2119
  }
2017
- 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;
2018
2121
  if (!decrease || data.status === AnimationStatus.increasing) {
2019
2122
  data.value += velocity;
2020
2123
  if (data.value > max) {
@@ -2046,9 +2149,9 @@
2046
2149
  return;
2047
2150
  }
2048
2151
  const { h, s, l } = color;
2049
- updateColorValue(h, false, delta, hdr);
2050
- updateColorValue(s, true, delta, hdr);
2051
- updateColorValue(l, true, delta, hdr);
2152
+ updateColorValue(h, false, delta);
2153
+ updateColorValue(s, true, delta);
2154
+ updateColorValue(l, true, delta);
2052
2155
  }
2053
2156
  function alterHsl(color, type, value) {
2054
2157
  return {
@@ -2098,7 +2201,7 @@
2098
2201
  }
2099
2202
 
2100
2203
  async function loadBlendPlugin(engine) {
2101
- engine.checkVersion("4.3.1");
2204
+ engine.checkVersion("4.4.0");
2102
2205
  await engine.pluginManager.register(e => {
2103
2206
  e.pluginManager.addPlugin(new BlendPlugin());
2104
2207
  });
@@ -2135,7 +2238,7 @@
2135
2238
  }
2136
2239
 
2137
2240
  async function loadCircleShape(engine) {
2138
- engine.checkVersion("4.3.1");
2241
+ engine.checkVersion("4.4.0");
2139
2242
  await engine.pluginManager.register(e => {
2140
2243
  e.pluginManager.addShape(["circle"], () => {
2141
2244
  return Promise.resolve(new CircleDrawer());
@@ -2183,7 +2286,7 @@
2183
2286
  }
2184
2287
 
2185
2288
  async function loadHexColorPlugin(engine) {
2186
- engine.checkVersion("4.3.1");
2289
+ engine.checkVersion("4.4.0");
2187
2290
  await engine.pluginManager.register(e => {
2188
2291
  e.pluginManager.addColorManager("hex", new HexColorManager());
2189
2292
  });
@@ -2236,7 +2339,7 @@
2236
2339
  }
2237
2340
 
2238
2341
  async function loadHslColorPlugin(engine) {
2239
- engine.checkVersion("4.3.1");
2342
+ engine.checkVersion("4.4.0");
2240
2343
  await engine.pluginManager.register(e => {
2241
2344
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2242
2345
  });
@@ -2260,7 +2363,7 @@
2260
2363
  }
2261
2364
 
2262
2365
  async function loadMovePlugin(engine) {
2263
- engine.checkVersion("4.3.1");
2366
+ engine.checkVersion("4.4.0");
2264
2367
  await engine.pluginManager.register(e => {
2265
2368
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2266
2369
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2470,7 +2573,7 @@
2470
2573
  }
2471
2574
 
2472
2575
  async function loadOpacityUpdater(engine) {
2473
- engine.checkVersion("4.3.1");
2576
+ engine.checkVersion("4.4.0");
2474
2577
  await engine.pluginManager.register(e => {
2475
2578
  e.pluginManager.addParticleUpdater("opacity", container => {
2476
2579
  return Promise.resolve(new OpacityUpdater(container));
@@ -2815,7 +2918,7 @@
2815
2918
  }
2816
2919
 
2817
2920
  async function loadOutModesUpdater(engine) {
2818
- engine.checkVersion("4.3.1");
2921
+ engine.checkVersion("4.4.0");
2819
2922
  await engine.pluginManager.register(e => {
2820
2923
  e.pluginManager.addParticleUpdater("outModes", container => {
2821
2924
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2886,7 +2989,7 @@
2886
2989
  }
2887
2990
 
2888
2991
  async function loadPaintUpdater(engine) {
2889
- engine.checkVersion("4.3.1");
2992
+ engine.checkVersion("4.4.0");
2890
2993
  await engine.pluginManager.register(e => {
2891
2994
  e.pluginManager.addParticleUpdater("paint", container => {
2892
2995
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2941,7 +3044,7 @@
2941
3044
  }
2942
3045
 
2943
3046
  async function loadRgbColorPlugin(engine) {
2944
- engine.checkVersion("4.3.1");
3047
+ engine.checkVersion("4.4.0");
2945
3048
  await engine.pluginManager.register(e => {
2946
3049
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
2947
3050
  });
@@ -3026,7 +3129,7 @@
3026
3129
  }
3027
3130
 
3028
3131
  async function loadSizeUpdater(engine) {
3029
- engine.checkVersion("4.3.1");
3132
+ engine.checkVersion("4.4.0");
3030
3133
  await engine.pluginManager.register(e => {
3031
3134
  e.pluginManager.addParticleUpdater("size", container => {
3032
3135
  return Promise.resolve(new SizeUpdater(container));
@@ -3035,7 +3138,7 @@
3035
3138
  }
3036
3139
 
3037
3140
  async function loadBasic(engine) {
3038
- engine.checkVersion("4.3.1");
3141
+ engine.checkVersion("4.4.0");
3039
3142
  await engine.pluginManager.register(async (e) => {
3040
3143
  await Promise.all([
3041
3144
  loadBlendPlugin(e),
@@ -3267,7 +3370,11 @@
3267
3370
  if (!fColor && !sColor) {
3268
3371
  return;
3269
3372
  }
3270
- 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;
3373
+ 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
3374
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
3375
+ : undefined, stroke = sColor
3376
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
3377
+ : fill;
3271
3378
  transform.a = transform.b = transform.c = transform.d = undefined;
3272
3379
  colorStyles.fill = fill;
3273
3380
  colorStyles.stroke = stroke;
@@ -3601,7 +3708,9 @@
3601
3708
  if (typeof background.element === "string") {
3602
3709
  if (typeof document !== "undefined") {
3603
3710
  const node = document.querySelector(background.element);
3604
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
3711
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
3712
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
3713
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
3605
3714
  this.#backgroundElement = node;
3606
3715
  }
3607
3716
  else if (node) {
@@ -3612,10 +3721,10 @@
3612
3721
  }
3613
3722
  }
3614
3723
  }
3615
- else if (background.element instanceof HTMLCanvasElement ||
3616
- background.element instanceof OffscreenCanvas ||
3617
- background.element instanceof HTMLVideoElement ||
3618
- background.element instanceof HTMLImageElement) {
3724
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
3725
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
3726
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
3727
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
3619
3728
  this.#backgroundElement = background.element;
3620
3729
  }
3621
3730
  }
@@ -3683,6 +3792,7 @@
3683
3792
  zoom = defaultZoom;
3684
3793
  #container;
3685
3794
  #generated;
3795
+ #hdrMediaListeners;
3686
3796
  #mutationObserver;
3687
3797
  #originalStyle;
3688
3798
  #pluginManager;
@@ -3747,7 +3857,6 @@
3747
3857
  });
3748
3858
  this.resize();
3749
3859
  this.#initStyle();
3750
- this.initBackground();
3751
3860
  this.#safeMutationObserver(obs => {
3752
3861
  const element = this.domElement;
3753
3862
  if (!element || !(element instanceof Node)) {
@@ -3757,6 +3866,8 @@
3757
3866
  });
3758
3867
  this.initPlugins();
3759
3868
  this.#initContext();
3869
+ this.initBackground();
3870
+ this.#initHdrListeners();
3760
3871
  this.render.init();
3761
3872
  }
3762
3873
  initBackground() {
@@ -3766,7 +3877,8 @@
3766
3877
  }
3767
3878
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
3768
3879
  if (color) {
3769
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
3880
+ const hdrOptions = container.actualOptions.hdr;
3881
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
3770
3882
  }
3771
3883
  else {
3772
3884
  elementStyle.backgroundColor = "";
@@ -3863,6 +3975,7 @@
3863
3975
  obs.disconnect();
3864
3976
  });
3865
3977
  this.#mutationObserver = undefined;
3978
+ this.#removeHdrListeners();
3866
3979
  this.render.stop();
3867
3980
  }
3868
3981
  async windowResize() {
@@ -3882,9 +3995,16 @@
3882
3995
  }
3883
3996
  }
3884
3997
  #initContext() {
3885
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
3998
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
3886
3999
  safeMatchMedia("(color-gamut: p3)")?.matches &&
3887
4000
  safeMatchMedia("(dynamic-range: high)")?.matches;
4001
+ container.hdr = canSupportHdr ?? false;
4002
+ container.hdrMode = container.actualOptions.hdr.mode;
4003
+ container.peakNits = container.actualOptions.hdr.peakNits;
4004
+ const renderCanvas = this.renderCanvas;
4005
+ if (!renderCanvas) {
4006
+ return;
4007
+ }
3888
4008
  this.render.setContextSettings({
3889
4009
  alpha: true,
3890
4010
  desynchronized: true,
@@ -3893,11 +4013,47 @@
3893
4013
  ? { colorSpace: "display-p3", colorType: "float16" }
3894
4014
  : { colorSpace: "srgb" }),
3895
4015
  });
3896
- const renderCanvas = this.renderCanvas;
3897
- if (!renderCanvas) {
3898
- return;
4016
+ let context;
4017
+ try {
4018
+ context = renderCanvas.getContext("2d", this.render.settings);
4019
+ }
4020
+ catch {
4021
+ context = null;
4022
+ }
4023
+ if (canSupportHdr && !context) {
4024
+ container.hdr = false;
4025
+ const sdrSettings = {
4026
+ alpha: true,
4027
+ desynchronized: true,
4028
+ willReadFrequently: false,
4029
+ colorSpace: "srgb",
4030
+ };
4031
+ this.render.setContextSettings(sdrSettings);
4032
+ try {
4033
+ context = renderCanvas.getContext("2d", sdrSettings);
4034
+ }
4035
+ catch {
4036
+ context = null;
4037
+ }
4038
+ }
4039
+ this.render.setContext(context);
4040
+ }
4041
+ #initHdrListeners() {
4042
+ this.#removeHdrListeners();
4043
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
4044
+ this.#recreateRenderCanvas();
4045
+ this.#initContext();
4046
+ this.initBackground();
4047
+ }, listeners = [];
4048
+ if (p3Query) {
4049
+ p3Query.addEventListener("change", handleChange);
4050
+ listeners.push({ handler: handleChange, mql: p3Query });
4051
+ }
4052
+ if (hdrQuery) {
4053
+ hdrQuery.addEventListener("change", handleChange);
4054
+ listeners.push({ handler: handleChange, mql: hdrQuery });
3899
4055
  }
3900
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4056
+ this.#hdrMediaListeners = listeners;
3901
4057
  }
3902
4058
  #initStyle() {
3903
4059
  const element = this.domElement, options = this.#container.actualOptions;
@@ -3921,6 +4077,25 @@
3921
4077
  element.style.setProperty(key, value, "important");
3922
4078
  }
3923
4079
  }
4080
+ #recreateRenderCanvas() {
4081
+ const renderCanvas = this.renderCanvas;
4082
+ if (!renderCanvas) {
4083
+ return;
4084
+ }
4085
+ if (this.domElement) {
4086
+ return;
4087
+ }
4088
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
4089
+ }
4090
+ #removeHdrListeners() {
4091
+ if (!this.#hdrMediaListeners) {
4092
+ return;
4093
+ }
4094
+ for (const { handler, mql } of this.#hdrMediaListeners) {
4095
+ mql.removeEventListener("change", handler);
4096
+ }
4097
+ this.#hdrMediaListeners = undefined;
4098
+ }
3924
4099
  #repairStyle() {
3925
4100
  const element = this.domElement;
3926
4101
  if (!element) {
@@ -4305,9 +4480,9 @@
4305
4480
  }
4306
4481
  getOpacity() {
4307
4482
  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;
4308
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
4483
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
4309
4484
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
4310
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
4485
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
4311
4486
  return this.#cachedOpacityData;
4312
4487
  }
4313
4488
  getPosition() {
@@ -5162,6 +5337,7 @@
5162
5337
  effectDrawers;
5163
5338
  fpsLimit;
5164
5339
  hdr;
5340
+ hdrMode;
5165
5341
  id;
5166
5342
  pageHidden;
5167
5343
  particleCreatedPlugins;
@@ -5169,6 +5345,7 @@
5169
5345
  particlePositionPlugins;
5170
5346
  particleUpdaters;
5171
5347
  particles;
5348
+ peakNits;
5172
5349
  plugins;
5173
5350
  retina;
5174
5351
  shapeDrawers;
@@ -5199,6 +5376,8 @@
5199
5376
  this.id = Symbol(id);
5200
5377
  this.fpsLimit = 120;
5201
5378
  this.hdr = false;
5379
+ this.hdrMode = HdrMode.standard;
5380
+ this.peakNits = 400;
5202
5381
  this.#smooth = false;
5203
5382
  this.#delay = 0;
5204
5383
  this.#duration = 0;
@@ -5338,8 +5517,9 @@
5338
5517
  this.updateActualOptions();
5339
5518
  this.canvas.initBackground();
5340
5519
  this.canvas.resize();
5341
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
5342
- this.hdr = hdr;
5520
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
5521
+ this.hdrMode = hdrOptions.mode;
5522
+ this.peakNits = hdrOptions.peakNits;
5343
5523
  this.zLayers = zLayers;
5344
5524
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
5345
5525
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;