@tsparticles/preset-squares 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) :
@@ -796,7 +796,7 @@
796
796
  return this.#domArray;
797
797
  }
798
798
  get version() {
799
- return "4.3.2";
799
+ return "4.4.0";
800
800
  }
801
801
  addEventListener(type, listener) {
802
802
  this.#eventDispatcher.addEventListener(type, listener);
@@ -877,6 +877,10 @@
877
877
  }
878
878
 
879
879
  function initEngine() {
880
+ const existing = globalThis.tsParticles;
881
+ if (existing?.pluginManager) {
882
+ return existing;
883
+ }
880
884
  return new Engine();
881
885
  }
882
886
 
@@ -974,6 +978,15 @@
974
978
  AnimationMode["random"] = "random";
975
979
  })(AnimationMode || (AnimationMode = {}));
976
980
 
981
+ var HdrMode;
982
+ (function (HdrMode) {
983
+ HdrMode["standard"] = "standard";
984
+ HdrMode["natural"] = "natural";
985
+ HdrMode["vivid"] = "vivid";
986
+ HdrMode["cinematic"] = "cinematic";
987
+ HdrMode["dynamic"] = "dynamic";
988
+ })(HdrMode || (HdrMode = {}));
989
+
977
990
  var LimitMode;
978
991
  (function (LimitMode) {
979
992
  LimitMode["delete"] = "delete";
@@ -1229,6 +1242,29 @@
1229
1242
  }
1230
1243
  }
1231
1244
 
1245
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
1246
+ class HDROptions extends OptionLoader {
1247
+ enable = true;
1248
+ mode = HdrMode.standard;
1249
+ peakNits = defaultPeakNits;
1250
+ doLoad(data) {
1251
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
1252
+ throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1253
+ }
1254
+ if (data.mode !== undefined &&
1255
+ (typeof data.mode !== "string" || !Object.values(HdrMode).includes(data.mode))) {
1256
+ throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1257
+ }
1258
+ if (data.peakNits !== undefined &&
1259
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1260
+ throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1261
+ }
1262
+ loadProperty(this, "enable", data.enable);
1263
+ loadProperty(this, "mode", data.mode);
1264
+ loadProperty(this, "peakNits", data.peakNits);
1265
+ }
1266
+ }
1267
+
1232
1268
  class ResizeEvent extends OptionLoader {
1233
1269
  delay = 0.5;
1234
1270
  enable = true;
@@ -1672,7 +1708,7 @@
1672
1708
  duration = 0;
1673
1709
  fpsLimit = 120;
1674
1710
  fullScreen;
1675
- hdr = true;
1711
+ hdr;
1676
1712
  key;
1677
1713
  name;
1678
1714
  palette;
@@ -1692,6 +1728,7 @@
1692
1728
  this.#container = container;
1693
1729
  this.background = new Background();
1694
1730
  this.fullScreen = new FullScreen();
1731
+ this.hdr = new HDROptions();
1695
1732
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1696
1733
  this.resize = new ResizeEvent();
1697
1734
  }
@@ -1714,7 +1751,15 @@
1714
1751
  loadProperty(this, "detectRetina", data.detectRetina);
1715
1752
  loadRangeProperty(this, "duration", data.duration);
1716
1753
  loadProperty(this, "fpsLimit", data.fpsLimit);
1717
- loadProperty(this, "hdr", data.hdr);
1754
+ const hdrData = data.hdr;
1755
+ if (isBoolean(hdrData)) {
1756
+ this.hdr.enable = hdrData;
1757
+ this.hdr.mode = HdrMode.standard;
1758
+ this.hdr.peakNits = 400;
1759
+ }
1760
+ else {
1761
+ this.hdr.load(hdrData);
1762
+ }
1718
1763
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1719
1764
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1720
1765
  loadProperty(this, "zLayers", data.zLayers);
@@ -1757,7 +1802,7 @@
1757
1802
  }
1758
1803
  }
1759
1804
 
1760
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1805
+ 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;
1761
1806
  function getCachedStyle(key, generator) {
1762
1807
  let cached = styleCache.get(key);
1763
1808
  if (!cached) {
@@ -1769,6 +1814,42 @@
1769
1814
  }
1770
1815
  return cached;
1771
1816
  }
1817
+ function acesFilmic(x) {
1818
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
1819
+ }
1820
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
1821
+ switch (mode) {
1822
+ case HdrMode.vivid: {
1823
+ const avg = (r + g + b) / channelCount;
1824
+ return {
1825
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1826
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1827
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1828
+ };
1829
+ }
1830
+ case HdrMode.cinematic: {
1831
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
1832
+ return {
1833
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
1834
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
1835
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
1836
+ };
1837
+ }
1838
+ case HdrMode.dynamic: {
1839
+ 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;
1840
+ return {
1841
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
1842
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
1843
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
1844
+ };
1845
+ }
1846
+ case HdrMode.standard:
1847
+ return { b, g, r };
1848
+ case HdrMode.natural:
1849
+ default:
1850
+ return { b, g, r };
1851
+ }
1852
+ }
1772
1853
  function stringToRgba(pluginManager, input) {
1773
1854
  if (!input) {
1774
1855
  return;
@@ -1906,21 +1987,40 @@
1906
1987
  r: getRgbInRangeValue(),
1907
1988
  };
1908
1989
  }
1909
- function getStyleFromRgb(color, hdr, opacity) {
1910
- 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()}`;
1911
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
1990
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
1991
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
1992
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
1993
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
1994
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
1995
+ }
1996
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = HdrMode.standard) {
1997
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
1998
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1912
1999
  }
1913
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1914
- const headroom = peakNits / sdrReferenceWhiteNits;
1915
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2000
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
2001
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
2002
+ if (mode !== HdrMode.natural && mode !== HdrMode.vivid && mode !== HdrMode.cinematic && mode !== HdrMode.dynamic) {
2003
+ return { b: bNorm, g: gNorm, r: rNorm };
2004
+ }
2005
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
2006
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
2007
+ }
2008
+ function hdrToneMap(normalized, headroom, middleGray) {
2009
+ if (normalized <= middleGray) {
2010
+ return acesFilmic(normalized);
2011
+ }
2012
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
2013
+ return acesFilmic(expanded);
1916
2014
  }
1917
2015
  function getSdrStyleFromRgb(color, opacity) {
1918
2016
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
1919
2017
  }
1920
- function getStyleFromHsl(color, hdr, opacity) {
1921
- 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()}`;
2018
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
2019
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2020
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2021
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
1922
2022
  return getCachedStyle(key, () => hdr
1923
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2023
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
1924
2024
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1925
2025
  }
1926
2026
  function getHslFromAnimation(animation) {
@@ -1983,7 +2083,7 @@
1983
2083
  colorValue.velocity = defaultVelocity;
1984
2084
  }
1985
2085
  }
1986
- function updateColorValue(data, decrease, delta, hdr) {
2086
+ function updateColorValue(data, decrease, delta, _hdr) {
1987
2087
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
1988
2088
  if (!data.enable ||
1989
2089
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -1996,7 +2096,7 @@
1996
2096
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
1997
2097
  return;
1998
2098
  }
1999
- 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;
2099
+ 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;
2000
2100
  if (!decrease || data.status === AnimationStatus.increasing) {
2001
2101
  data.value += velocity;
2002
2102
  if (data.value > max) {
@@ -2028,9 +2128,9 @@
2028
2128
  return;
2029
2129
  }
2030
2130
  const { h, s, l } = color;
2031
- updateColorValue(h, false, delta, hdr);
2032
- updateColorValue(s, true, delta, hdr);
2033
- updateColorValue(l, true, delta, hdr);
2131
+ updateColorValue(h, false, delta);
2132
+ updateColorValue(s, true, delta);
2133
+ updateColorValue(l, true, delta);
2034
2134
  }
2035
2135
  function alterHsl(color, type, value) {
2036
2136
  return {
@@ -2248,7 +2348,7 @@
2248
2348
  })(EmitterClickMode || (EmitterClickMode = {}));
2249
2349
 
2250
2350
  async function loadEmittersPluginSimple(engine) {
2251
- engine.checkVersion("4.3.2");
2351
+ engine.checkVersion("4.4.0");
2252
2352
  await engine.pluginManager.register(async (e) => {
2253
2353
  const instancesManager = await getEmittersInstancesManager(e);
2254
2354
  await addEmittersShapesManager(e);
@@ -2296,7 +2396,7 @@
2296
2396
  }
2297
2397
 
2298
2398
  async function loadHexColorPlugin(engine) {
2299
- engine.checkVersion("4.3.2");
2399
+ engine.checkVersion("4.4.0");
2300
2400
  await engine.pluginManager.register(e => {
2301
2401
  e.pluginManager.addColorManager("hex", new HexColorManager());
2302
2402
  });
@@ -2365,7 +2465,7 @@
2365
2465
  }
2366
2466
 
2367
2467
  async function loadPaintUpdater(engine) {
2368
- engine.checkVersion("4.3.2");
2468
+ engine.checkVersion("4.4.0");
2369
2469
  await engine.pluginManager.register(e => {
2370
2470
  e.pluginManager.addParticleUpdater("paint", container => {
2371
2471
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2594,7 +2694,7 @@
2594
2694
  }
2595
2695
 
2596
2696
  async function loadRotateUpdater(engine) {
2597
- engine.checkVersion("4.3.2");
2697
+ engine.checkVersion("4.4.0");
2598
2698
  await engine.pluginManager.register(e => {
2599
2699
  e.pluginManager.addParticleUpdater("rotate", container => {
2600
2700
  return Promise.resolve(new RotateUpdater(container));
@@ -2681,7 +2781,7 @@
2681
2781
  }
2682
2782
 
2683
2783
  async function loadSizeUpdater(engine) {
2684
- engine.checkVersion("4.3.2");
2784
+ engine.checkVersion("4.4.0");
2685
2785
  await engine.pluginManager.register(e => {
2686
2786
  e.pluginManager.addParticleUpdater("size", container => {
2687
2787
  return Promise.resolve(new SizeUpdater(container));
@@ -2705,7 +2805,7 @@
2705
2805
  }
2706
2806
 
2707
2807
  async function loadSquareShape(engine) {
2708
- engine.checkVersion("4.3.2");
2808
+ engine.checkVersion("4.4.0");
2709
2809
  await engine.pluginManager.register(e => {
2710
2810
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
2711
2811
  });
@@ -2899,7 +2999,11 @@
2899
2999
  if (!fColor && !sColor) {
2900
3000
  return;
2901
3001
  }
2902
- 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;
3002
+ 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
3003
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
3004
+ : undefined, stroke = sColor
3005
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
3006
+ : fill;
2903
3007
  transform.a = transform.b = transform.c = transform.d = undefined;
2904
3008
  colorStyles.fill = fill;
2905
3009
  colorStyles.stroke = stroke;
@@ -3233,7 +3337,9 @@
3233
3337
  if (typeof background.element === "string") {
3234
3338
  if (typeof document !== "undefined") {
3235
3339
  const node = document.querySelector(background.element);
3236
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
3340
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
3341
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
3342
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
3237
3343
  this.#backgroundElement = node;
3238
3344
  }
3239
3345
  else if (node) {
@@ -3244,10 +3350,10 @@
3244
3350
  }
3245
3351
  }
3246
3352
  }
3247
- else if (background.element instanceof HTMLCanvasElement ||
3248
- background.element instanceof OffscreenCanvas ||
3249
- background.element instanceof HTMLVideoElement ||
3250
- background.element instanceof HTMLImageElement) {
3353
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
3354
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
3355
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
3356
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
3251
3357
  this.#backgroundElement = background.element;
3252
3358
  }
3253
3359
  }
@@ -3315,6 +3421,7 @@
3315
3421
  zoom = defaultZoom;
3316
3422
  #container;
3317
3423
  #generated;
3424
+ #hdrMediaListeners;
3318
3425
  #mutationObserver;
3319
3426
  #originalStyle;
3320
3427
  #pluginManager;
@@ -3379,7 +3486,6 @@
3379
3486
  });
3380
3487
  this.resize();
3381
3488
  this.#initStyle();
3382
- this.initBackground();
3383
3489
  this.#safeMutationObserver(obs => {
3384
3490
  const element = this.domElement;
3385
3491
  if (!element || !(element instanceof Node)) {
@@ -3389,6 +3495,8 @@
3389
3495
  });
3390
3496
  this.initPlugins();
3391
3497
  this.#initContext();
3498
+ this.initBackground();
3499
+ this.#initHdrListeners();
3392
3500
  this.render.init();
3393
3501
  }
3394
3502
  initBackground() {
@@ -3398,7 +3506,8 @@
3398
3506
  }
3399
3507
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
3400
3508
  if (color) {
3401
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
3509
+ const hdrOptions = container.actualOptions.hdr;
3510
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
3402
3511
  }
3403
3512
  else {
3404
3513
  elementStyle.backgroundColor = "";
@@ -3495,6 +3604,7 @@
3495
3604
  obs.disconnect();
3496
3605
  });
3497
3606
  this.#mutationObserver = undefined;
3607
+ this.#removeHdrListeners();
3498
3608
  this.render.stop();
3499
3609
  }
3500
3610
  async windowResize() {
@@ -3514,9 +3624,16 @@
3514
3624
  }
3515
3625
  }
3516
3626
  #initContext() {
3517
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
3627
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
3518
3628
  safeMatchMedia("(color-gamut: p3)")?.matches &&
3519
3629
  safeMatchMedia("(dynamic-range: high)")?.matches;
3630
+ container.hdr = canSupportHdr ?? false;
3631
+ container.hdrMode = container.actualOptions.hdr.mode;
3632
+ container.peakNits = container.actualOptions.hdr.peakNits;
3633
+ const renderCanvas = this.renderCanvas;
3634
+ if (!renderCanvas) {
3635
+ return;
3636
+ }
3520
3637
  this.render.setContextSettings({
3521
3638
  alpha: true,
3522
3639
  desynchronized: true,
@@ -3525,11 +3642,47 @@
3525
3642
  ? { colorSpace: "display-p3", colorType: "float16" }
3526
3643
  : { colorSpace: "srgb" }),
3527
3644
  });
3528
- const renderCanvas = this.renderCanvas;
3529
- if (!renderCanvas) {
3530
- return;
3645
+ let context;
3646
+ try {
3647
+ context = renderCanvas.getContext("2d", this.render.settings);
3648
+ }
3649
+ catch {
3650
+ context = null;
3651
+ }
3652
+ if (canSupportHdr && !context) {
3653
+ container.hdr = false;
3654
+ const sdrSettings = {
3655
+ alpha: true,
3656
+ desynchronized: true,
3657
+ willReadFrequently: false,
3658
+ colorSpace: "srgb",
3659
+ };
3660
+ this.render.setContextSettings(sdrSettings);
3661
+ try {
3662
+ context = renderCanvas.getContext("2d", sdrSettings);
3663
+ }
3664
+ catch {
3665
+ context = null;
3666
+ }
3667
+ }
3668
+ this.render.setContext(context);
3669
+ }
3670
+ #initHdrListeners() {
3671
+ this.#removeHdrListeners();
3672
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
3673
+ this.#recreateRenderCanvas();
3674
+ this.#initContext();
3675
+ this.initBackground();
3676
+ }, listeners = [];
3677
+ if (p3Query) {
3678
+ p3Query.addEventListener("change", handleChange);
3679
+ listeners.push({ handler: handleChange, mql: p3Query });
3680
+ }
3681
+ if (hdrQuery) {
3682
+ hdrQuery.addEventListener("change", handleChange);
3683
+ listeners.push({ handler: handleChange, mql: hdrQuery });
3531
3684
  }
3532
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
3685
+ this.#hdrMediaListeners = listeners;
3533
3686
  }
3534
3687
  #initStyle() {
3535
3688
  const element = this.domElement, options = this.#container.actualOptions;
@@ -3553,6 +3706,25 @@
3553
3706
  element.style.setProperty(key, value, "important");
3554
3707
  }
3555
3708
  }
3709
+ #recreateRenderCanvas() {
3710
+ const renderCanvas = this.renderCanvas;
3711
+ if (!renderCanvas) {
3712
+ return;
3713
+ }
3714
+ if (this.domElement) {
3715
+ return;
3716
+ }
3717
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
3718
+ }
3719
+ #removeHdrListeners() {
3720
+ if (!this.#hdrMediaListeners) {
3721
+ return;
3722
+ }
3723
+ for (const { handler, mql } of this.#hdrMediaListeners) {
3724
+ mql.removeEventListener("change", handler);
3725
+ }
3726
+ this.#hdrMediaListeners = undefined;
3727
+ }
3556
3728
  #repairStyle() {
3557
3729
  const element = this.domElement;
3558
3730
  if (!element) {
@@ -3937,9 +4109,9 @@
3937
4109
  }
3938
4110
  getOpacity() {
3939
4111
  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;
3940
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
4112
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
3941
4113
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
3942
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
4114
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
3943
4115
  return this.#cachedOpacityData;
3944
4116
  }
3945
4117
  getPosition() {
@@ -4794,6 +4966,7 @@
4794
4966
  effectDrawers;
4795
4967
  fpsLimit;
4796
4968
  hdr;
4969
+ hdrMode;
4797
4970
  id;
4798
4971
  pageHidden;
4799
4972
  particleCreatedPlugins;
@@ -4801,6 +4974,7 @@
4801
4974
  particlePositionPlugins;
4802
4975
  particleUpdaters;
4803
4976
  particles;
4977
+ peakNits;
4804
4978
  plugins;
4805
4979
  retina;
4806
4980
  shapeDrawers;
@@ -4831,6 +5005,8 @@
4831
5005
  this.id = Symbol(id);
4832
5006
  this.fpsLimit = 120;
4833
5007
  this.hdr = false;
5008
+ this.hdrMode = HdrMode.standard;
5009
+ this.peakNits = 400;
4834
5010
  this.#smooth = false;
4835
5011
  this.#delay = 0;
4836
5012
  this.#duration = 0;
@@ -4970,8 +5146,9 @@
4970
5146
  this.updateActualOptions();
4971
5147
  this.canvas.initBackground();
4972
5148
  this.canvas.resize();
4973
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
4974
- this.hdr = hdr;
5149
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
5150
+ this.hdrMode = hdrOptions.mode;
5151
+ this.peakNits = hdrOptions.peakNits;
4975
5152
  this.zLayers = zLayers;
4976
5153
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
4977
5154
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;