@tsparticles/preset-confetti-cannon 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();
@@ -2476,7 +2579,7 @@
2476
2579
  }
2477
2580
 
2478
2581
  async function loadOpacityUpdater(engine) {
2479
- engine.checkVersion("4.3.1");
2582
+ engine.checkVersion("4.4.0");
2480
2583
  await engine.pluginManager.register(e => {
2481
2584
  e.pluginManager.addParticleUpdater("opacity", container => {
2482
2585
  return Promise.resolve(new OpacityUpdater(container));
@@ -2821,7 +2924,7 @@
2821
2924
  }
2822
2925
 
2823
2926
  async function loadOutModesUpdater(engine) {
2824
- engine.checkVersion("4.3.1");
2927
+ engine.checkVersion("4.4.0");
2825
2928
  await engine.pluginManager.register(e => {
2826
2929
  e.pluginManager.addParticleUpdater("outModes", container => {
2827
2930
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2892,7 +2995,7 @@
2892
2995
  }
2893
2996
 
2894
2997
  async function loadPaintUpdater(engine) {
2895
- engine.checkVersion("4.3.1");
2998
+ engine.checkVersion("4.4.0");
2896
2999
  await engine.pluginManager.register(e => {
2897
3000
  e.pluginManager.addParticleUpdater("paint", container => {
2898
3001
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2947,7 +3050,7 @@
2947
3050
  }
2948
3051
 
2949
3052
  async function loadRgbColorPlugin(engine) {
2950
- engine.checkVersion("4.3.1");
3053
+ engine.checkVersion("4.4.0");
2951
3054
  await engine.pluginManager.register(e => {
2952
3055
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
2953
3056
  });
@@ -3032,7 +3135,7 @@
3032
3135
  }
3033
3136
 
3034
3137
  async function loadSizeUpdater(engine) {
3035
- engine.checkVersion("4.3.1");
3138
+ engine.checkVersion("4.4.0");
3036
3139
  await engine.pluginManager.register(e => {
3037
3140
  e.pluginManager.addParticleUpdater("size", container => {
3038
3141
  return Promise.resolve(new SizeUpdater(container));
@@ -3041,7 +3144,7 @@
3041
3144
  }
3042
3145
 
3043
3146
  async function loadBasic(engine) {
3044
- engine.checkVersion("4.3.1");
3147
+ engine.checkVersion("4.4.0");
3045
3148
  await engine.pluginManager.register(async (e) => {
3046
3149
  await Promise.all([
3047
3150
  loadBlendPlugin(e),
@@ -3272,7 +3375,7 @@
3272
3375
  const clickEvent = "click", mouseDownEvent = "pointerdown", mouseUpEvent = "pointerup", mouseLeaveEvent = "pointerleave", mouseMoveEvent = "pointermove", touchStartEvent = "touchstart", touchEndEvent = "touchend", touchMoveEvent = "touchmove", touchCancelEvent = "touchcancel";
3273
3376
 
3274
3377
  async function loadInteractivityPlugin(engine) {
3275
- engine.checkVersion("4.3.1");
3378
+ engine.checkVersion("4.4.0");
3276
3379
  await engine.pluginManager.register(e => {
3277
3380
  const interactivityEngine = e, interactivityPluginManager = interactivityEngine.pluginManager;
3278
3381
  interactivityPluginManager.addPlugin(new InteractivityPlugin(interactivityPluginManager));
@@ -3451,7 +3554,7 @@
3451
3554
  }
3452
3555
 
3453
3556
  async function loadExternalCannonInteraction(engine) {
3454
- engine.checkVersion("4.3.1");
3557
+ engine.checkVersion("4.4.0");
3455
3558
  await engine.pluginManager.register((e) => {
3456
3559
  ensureInteractivityPluginLoaded(e);
3457
3560
  e.pluginManager.addInteractor?.("externalCannon", container => {
@@ -3597,7 +3700,7 @@
3597
3700
  }
3598
3701
 
3599
3702
  async function loadLifeUpdater(engine) {
3600
- engine.checkVersion("4.3.1");
3703
+ engine.checkVersion("4.4.0");
3601
3704
  await engine.pluginManager.register(e => {
3602
3705
  e.pluginManager.addParticleUpdater("life", container => {
3603
3706
  return Promise.resolve(new LifeUpdater(container));
@@ -3651,7 +3754,7 @@
3651
3754
  }
3652
3755
 
3653
3756
  async function loadMotionPlugin(engine) {
3654
- engine.checkVersion("4.3.1");
3757
+ engine.checkVersion("4.4.0");
3655
3758
  await engine.pluginManager.register(e => {
3656
3759
  e.pluginManager.addPlugin(new MotionPlugin());
3657
3760
  });
@@ -3784,7 +3887,7 @@
3784
3887
  }
3785
3888
 
3786
3889
  async function loadRollUpdater(engine) {
3787
- engine.checkVersion("4.3.1");
3890
+ engine.checkVersion("4.4.0");
3788
3891
  await engine.pluginManager.register(e => {
3789
3892
  e.pluginManager.addParticleUpdater("roll", () => {
3790
3893
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -3890,7 +3993,7 @@
3890
3993
  }
3891
3994
 
3892
3995
  async function loadRotateUpdater(engine) {
3893
- engine.checkVersion("4.3.1");
3996
+ engine.checkVersion("4.4.0");
3894
3997
  await engine.pluginManager.register(e => {
3895
3998
  e.pluginManager.addParticleUpdater("rotate", container => {
3896
3999
  return Promise.resolve(new RotateUpdater(container));
@@ -3914,7 +4017,7 @@
3914
4017
  }
3915
4018
 
3916
4019
  async function loadSquareShape(engine) {
3917
- engine.checkVersion("4.3.1");
4020
+ engine.checkVersion("4.4.0");
3918
4021
  await engine.pluginManager.register(e => {
3919
4022
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
3920
4023
  });
@@ -4023,7 +4126,7 @@
4023
4126
  }
4024
4127
 
4025
4128
  async function loadTiltUpdater(engine) {
4026
- engine.checkVersion("4.3.1");
4129
+ engine.checkVersion("4.4.0");
4027
4130
  await engine.pluginManager.register(e => {
4028
4131
  e.pluginManager.addParticleUpdater("tilt", container => {
4029
4132
  return Promise.resolve(new TiltUpdater(container));
@@ -4125,7 +4228,7 @@
4125
4228
  }
4126
4229
 
4127
4230
  async function loadWobbleUpdater(engine) {
4128
- engine.checkVersion("4.3.1");
4231
+ engine.checkVersion("4.4.0");
4129
4232
  await engine.pluginManager.register(e => {
4130
4233
  e.pluginManager.addParticleUpdater("wobble", container => {
4131
4234
  return Promise.resolve(new WobbleUpdater(container));
@@ -4390,7 +4493,11 @@
4390
4493
  if (!fColor && !sColor) {
4391
4494
  return;
4392
4495
  }
4393
- 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;
4496
+ 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
4497
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
4498
+ : undefined, stroke = sColor
4499
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
4500
+ : fill;
4394
4501
  transform.a = transform.b = transform.c = transform.d = undefined;
4395
4502
  colorStyles.fill = fill;
4396
4503
  colorStyles.stroke = stroke;
@@ -4724,7 +4831,9 @@
4724
4831
  if (typeof background.element === "string") {
4725
4832
  if (typeof document !== "undefined") {
4726
4833
  const node = document.querySelector(background.element);
4727
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
4834
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
4835
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
4836
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
4728
4837
  this.#backgroundElement = node;
4729
4838
  }
4730
4839
  else if (node) {
@@ -4735,10 +4844,10 @@
4735
4844
  }
4736
4845
  }
4737
4846
  }
4738
- else if (background.element instanceof HTMLCanvasElement ||
4739
- background.element instanceof OffscreenCanvas ||
4740
- background.element instanceof HTMLVideoElement ||
4741
- background.element instanceof HTMLImageElement) {
4847
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
4848
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
4849
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
4850
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
4742
4851
  this.#backgroundElement = background.element;
4743
4852
  }
4744
4853
  }
@@ -4806,6 +4915,7 @@
4806
4915
  zoom = defaultZoom;
4807
4916
  #container;
4808
4917
  #generated;
4918
+ #hdrMediaListeners;
4809
4919
  #mutationObserver;
4810
4920
  #originalStyle;
4811
4921
  #pluginManager;
@@ -4870,7 +4980,6 @@
4870
4980
  });
4871
4981
  this.resize();
4872
4982
  this.#initStyle();
4873
- this.initBackground();
4874
4983
  this.#safeMutationObserver(obs => {
4875
4984
  const element = this.domElement;
4876
4985
  if (!element || !(element instanceof Node)) {
@@ -4880,6 +4989,8 @@
4880
4989
  });
4881
4990
  this.initPlugins();
4882
4991
  this.#initContext();
4992
+ this.initBackground();
4993
+ this.#initHdrListeners();
4883
4994
  this.render.init();
4884
4995
  }
4885
4996
  initBackground() {
@@ -4889,7 +5000,8 @@
4889
5000
  }
4890
5001
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4891
5002
  if (color) {
4892
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
5003
+ const hdrOptions = container.actualOptions.hdr;
5004
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
4893
5005
  }
4894
5006
  else {
4895
5007
  elementStyle.backgroundColor = "";
@@ -4986,6 +5098,7 @@
4986
5098
  obs.disconnect();
4987
5099
  });
4988
5100
  this.#mutationObserver = undefined;
5101
+ this.#removeHdrListeners();
4989
5102
  this.render.stop();
4990
5103
  }
4991
5104
  async windowResize() {
@@ -5005,9 +5118,16 @@
5005
5118
  }
5006
5119
  }
5007
5120
  #initContext() {
5008
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
5121
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
5009
5122
  safeMatchMedia("(color-gamut: p3)")?.matches &&
5010
5123
  safeMatchMedia("(dynamic-range: high)")?.matches;
5124
+ container.hdr = canSupportHdr ?? false;
5125
+ container.hdrMode = container.actualOptions.hdr.mode;
5126
+ container.peakNits = container.actualOptions.hdr.peakNits;
5127
+ const renderCanvas = this.renderCanvas;
5128
+ if (!renderCanvas) {
5129
+ return;
5130
+ }
5011
5131
  this.render.setContextSettings({
5012
5132
  alpha: true,
5013
5133
  desynchronized: true,
@@ -5016,11 +5136,47 @@
5016
5136
  ? { colorSpace: "display-p3", colorType: "float16" }
5017
5137
  : { colorSpace: "srgb" }),
5018
5138
  });
5019
- const renderCanvas = this.renderCanvas;
5020
- if (!renderCanvas) {
5021
- return;
5139
+ let context;
5140
+ try {
5141
+ context = renderCanvas.getContext("2d", this.render.settings);
5142
+ }
5143
+ catch {
5144
+ context = null;
5145
+ }
5146
+ if (canSupportHdr && !context) {
5147
+ container.hdr = false;
5148
+ const sdrSettings = {
5149
+ alpha: true,
5150
+ desynchronized: true,
5151
+ willReadFrequently: false,
5152
+ colorSpace: "srgb",
5153
+ };
5154
+ this.render.setContextSettings(sdrSettings);
5155
+ try {
5156
+ context = renderCanvas.getContext("2d", sdrSettings);
5157
+ }
5158
+ catch {
5159
+ context = null;
5160
+ }
5161
+ }
5162
+ this.render.setContext(context);
5163
+ }
5164
+ #initHdrListeners() {
5165
+ this.#removeHdrListeners();
5166
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
5167
+ this.#recreateRenderCanvas();
5168
+ this.#initContext();
5169
+ this.initBackground();
5170
+ }, listeners = [];
5171
+ if (p3Query) {
5172
+ p3Query.addEventListener("change", handleChange);
5173
+ listeners.push({ handler: handleChange, mql: p3Query });
5174
+ }
5175
+ if (hdrQuery) {
5176
+ hdrQuery.addEventListener("change", handleChange);
5177
+ listeners.push({ handler: handleChange, mql: hdrQuery });
5022
5178
  }
5023
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
5179
+ this.#hdrMediaListeners = listeners;
5024
5180
  }
5025
5181
  #initStyle() {
5026
5182
  const element = this.domElement, options = this.#container.actualOptions;
@@ -5044,6 +5200,25 @@
5044
5200
  element.style.setProperty(key, value, "important");
5045
5201
  }
5046
5202
  }
5203
+ #recreateRenderCanvas() {
5204
+ const renderCanvas = this.renderCanvas;
5205
+ if (!renderCanvas) {
5206
+ return;
5207
+ }
5208
+ if (this.domElement) {
5209
+ return;
5210
+ }
5211
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
5212
+ }
5213
+ #removeHdrListeners() {
5214
+ if (!this.#hdrMediaListeners) {
5215
+ return;
5216
+ }
5217
+ for (const { handler, mql } of this.#hdrMediaListeners) {
5218
+ mql.removeEventListener("change", handler);
5219
+ }
5220
+ this.#hdrMediaListeners = undefined;
5221
+ }
5047
5222
  #repairStyle() {
5048
5223
  const element = this.domElement;
5049
5224
  if (!element) {
@@ -5428,9 +5603,9 @@
5428
5603
  }
5429
5604
  getOpacity() {
5430
5605
  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;
5431
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
5606
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
5432
5607
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
5433
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
5608
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
5434
5609
  return this.#cachedOpacityData;
5435
5610
  }
5436
5611
  getPosition() {
@@ -6285,6 +6460,7 @@
6285
6460
  effectDrawers;
6286
6461
  fpsLimit;
6287
6462
  hdr;
6463
+ hdrMode;
6288
6464
  id;
6289
6465
  pageHidden;
6290
6466
  particleCreatedPlugins;
@@ -6292,6 +6468,7 @@
6292
6468
  particlePositionPlugins;
6293
6469
  particleUpdaters;
6294
6470
  particles;
6471
+ peakNits;
6295
6472
  plugins;
6296
6473
  retina;
6297
6474
  shapeDrawers;
@@ -6322,6 +6499,8 @@
6322
6499
  this.id = Symbol(id);
6323
6500
  this.fpsLimit = 120;
6324
6501
  this.hdr = false;
6502
+ this.hdrMode = HdrMode.standard;
6503
+ this.peakNits = 400;
6325
6504
  this.#smooth = false;
6326
6505
  this.#delay = 0;
6327
6506
  this.#duration = 0;
@@ -6461,8 +6640,9 @@
6461
6640
  this.updateActualOptions();
6462
6641
  this.canvas.initBackground();
6463
6642
  this.canvas.resize();
6464
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
6465
- this.hdr = hdr;
6643
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
6644
+ this.hdrMode = hdrOptions.mode;
6645
+ this.peakNits = hdrOptions.peakNits;
6466
6646
  this.zLayers = zLayers;
6467
6647
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
6468
6648
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;