@tsparticles/preset-confetti-cannon 4.3.2 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  (function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this);
2
- /* Preset v4.3.2 */
2
+ /* Preset v4.4.0 */
3
3
  (function (global, factory) {
4
4
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
5
5
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -797,7 +797,7 @@
797
797
  return this.#domArray;
798
798
  }
799
799
  get version() {
800
- return "4.3.2";
800
+ return "4.4.0";
801
801
  }
802
802
  addEventListener(type, listener) {
803
803
  this.#eventDispatcher.addEventListener(type, listener);
@@ -878,6 +878,10 @@
878
878
  }
879
879
 
880
880
  function initEngine() {
881
+ const existing = globalThis.tsParticles;
882
+ if (existing?.pluginManager) {
883
+ return existing;
884
+ }
881
885
  return new Engine();
882
886
  }
883
887
 
@@ -975,6 +979,15 @@
975
979
  AnimationMode["random"] = "random";
976
980
  })(AnimationMode || (AnimationMode = {}));
977
981
 
982
+ var HdrMode;
983
+ (function (HdrMode) {
984
+ HdrMode["standard"] = "standard";
985
+ HdrMode["natural"] = "natural";
986
+ HdrMode["vivid"] = "vivid";
987
+ HdrMode["cinematic"] = "cinematic";
988
+ HdrMode["dynamic"] = "dynamic";
989
+ })(HdrMode || (HdrMode = {}));
990
+
978
991
  var LimitMode;
979
992
  (function (LimitMode) {
980
993
  LimitMode["delete"] = "delete";
@@ -1230,6 +1243,29 @@
1230
1243
  }
1231
1244
  }
1232
1245
 
1246
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
1247
+ class HDROptions extends OptionLoader {
1248
+ enable = true;
1249
+ mode = HdrMode.standard;
1250
+ peakNits = defaultPeakNits;
1251
+ doLoad(data) {
1252
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
1253
+ throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1254
+ }
1255
+ if (data.mode !== undefined &&
1256
+ (typeof data.mode !== "string" || !Object.values(HdrMode).includes(data.mode))) {
1257
+ throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1258
+ }
1259
+ if (data.peakNits !== undefined &&
1260
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1261
+ throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1262
+ }
1263
+ loadProperty(this, "enable", data.enable);
1264
+ loadProperty(this, "mode", data.mode);
1265
+ loadProperty(this, "peakNits", data.peakNits);
1266
+ }
1267
+ }
1268
+
1233
1269
  class ResizeEvent extends OptionLoader {
1234
1270
  delay = 0.5;
1235
1271
  enable = true;
@@ -1673,7 +1709,7 @@
1673
1709
  duration = 0;
1674
1710
  fpsLimit = 120;
1675
1711
  fullScreen;
1676
- hdr = true;
1712
+ hdr;
1677
1713
  key;
1678
1714
  name;
1679
1715
  palette;
@@ -1693,6 +1729,7 @@
1693
1729
  this.#container = container;
1694
1730
  this.background = new Background();
1695
1731
  this.fullScreen = new FullScreen();
1732
+ this.hdr = new HDROptions();
1696
1733
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1697
1734
  this.resize = new ResizeEvent();
1698
1735
  }
@@ -1715,7 +1752,15 @@
1715
1752
  loadProperty(this, "detectRetina", data.detectRetina);
1716
1753
  loadRangeProperty(this, "duration", data.duration);
1717
1754
  loadProperty(this, "fpsLimit", data.fpsLimit);
1718
- loadProperty(this, "hdr", data.hdr);
1755
+ const hdrData = data.hdr;
1756
+ if (isBoolean(hdrData)) {
1757
+ this.hdr.enable = hdrData;
1758
+ this.hdr.mode = HdrMode.standard;
1759
+ this.hdr.peakNits = 400;
1760
+ }
1761
+ else {
1762
+ this.hdr.load(hdrData);
1763
+ }
1719
1764
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1720
1765
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1721
1766
  loadProperty(this, "zLayers", data.zLayers);
@@ -1758,7 +1803,7 @@
1758
1803
  }
1759
1804
  }
1760
1805
 
1761
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1806
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, acesA = 2.51, acesB = 0.03, acesC = 2.43, acesD = 0.59, acesE = 0.14, saturationBoost = 1.15, lightnessBoost = 1.05, temperatureR = 1.05, temperatureB = 0.95, contrastFactor = 1.1, luminanceR = 0.2126, luminanceG = 0.7152, luminanceB = 0.0722, dynamicLuminanceFactor = 2, channelCount = 3;
1762
1807
  function getCachedStyle(key, generator) {
1763
1808
  let cached = styleCache.get(key);
1764
1809
  if (!cached) {
@@ -1770,6 +1815,42 @@
1770
1815
  }
1771
1816
  return cached;
1772
1817
  }
1818
+ function acesFilmic(x) {
1819
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
1820
+ }
1821
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
1822
+ switch (mode) {
1823
+ case HdrMode.vivid: {
1824
+ const avg = (r + g + b) / channelCount;
1825
+ return {
1826
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1827
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1828
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1829
+ };
1830
+ }
1831
+ case HdrMode.cinematic: {
1832
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
1833
+ return {
1834
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
1835
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
1836
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
1837
+ };
1838
+ }
1839
+ case HdrMode.dynamic: {
1840
+ const luminance = luminanceR * r + luminanceG * g + luminanceB * b, vividWeight = Math.min(one, luminance * dynamicLuminanceFactor), naturalWeight = one - vividWeight, avg = (r + g + b) / channelCount, vividR = clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, vividG = clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, vividB = clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost;
1841
+ return {
1842
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
1843
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
1844
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
1845
+ };
1846
+ }
1847
+ case HdrMode.standard:
1848
+ return { b, g, r };
1849
+ case HdrMode.natural:
1850
+ default:
1851
+ return { b, g, r };
1852
+ }
1853
+ }
1773
1854
  function stringToRgba(pluginManager, input) {
1774
1855
  if (!input) {
1775
1856
  return;
@@ -1927,21 +2008,40 @@
1927
2008
  r: getRgbInRangeValue(),
1928
2009
  };
1929
2010
  }
1930
- function getStyleFromRgb(color, hdr, opacity) {
1931
- const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
1932
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2011
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
2012
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2013
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2014
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
2015
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
2016
+ }
2017
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = HdrMode.standard) {
2018
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
2019
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1933
2020
  }
1934
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1935
- const headroom = peakNits / sdrReferenceWhiteNits;
1936
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2021
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
2022
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
2023
+ if (mode !== HdrMode.natural && mode !== HdrMode.vivid && mode !== HdrMode.cinematic && mode !== HdrMode.dynamic) {
2024
+ return { b: bNorm, g: gNorm, r: rNorm };
2025
+ }
2026
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
2027
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
2028
+ }
2029
+ function hdrToneMap(normalized, headroom, middleGray) {
2030
+ if (normalized <= middleGray) {
2031
+ return acesFilmic(normalized);
2032
+ }
2033
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
2034
+ return acesFilmic(expanded);
1937
2035
  }
1938
2036
  function getSdrStyleFromRgb(color, opacity) {
1939
2037
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
1940
2038
  }
1941
- function getStyleFromHsl(color, hdr, opacity) {
1942
- const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2039
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
2040
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2041
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2042
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
1943
2043
  return getCachedStyle(key, () => hdr
1944
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2044
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
1945
2045
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1946
2046
  }
1947
2047
  function getHslFromAnimation(animation) {
@@ -2004,7 +2104,7 @@
2004
2104
  colorValue.velocity = defaultVelocity;
2005
2105
  }
2006
2106
  }
2007
- function updateColorValue(data, decrease, delta, hdr) {
2107
+ function updateColorValue(data, decrease, delta, _hdr) {
2008
2108
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2009
2109
  if (!data.enable ||
2010
2110
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2017,7 +2117,7 @@
2017
2117
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2018
2118
  return;
2019
2119
  }
2020
- const offset = data.offset ? randomInRangeValue(data.offset) : minOffset, velocity = ((data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor) * (hdr ? hdrAnimationScale : identity), decay = data.decay ?? identity, max = data.max, min = data.min;
2120
+ const offset = data.offset ? randomInRangeValue(data.offset) : minOffset, velocity = (data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor, decay = data.decay ?? identity, max = data.max, min = data.min;
2021
2121
  if (!decrease || data.status === AnimationStatus.increasing) {
2022
2122
  data.value += velocity;
2023
2123
  if (data.value > max) {
@@ -2049,9 +2149,9 @@
2049
2149
  return;
2050
2150
  }
2051
2151
  const { h, s, l } = color;
2052
- updateColorValue(h, false, delta, hdr);
2053
- updateColorValue(s, true, delta, hdr);
2054
- updateColorValue(l, true, delta, hdr);
2152
+ updateColorValue(h, false, delta);
2153
+ updateColorValue(s, true, delta);
2154
+ updateColorValue(l, true, delta);
2055
2155
  }
2056
2156
  function alterHsl(color, type, value) {
2057
2157
  return {
@@ -2101,7 +2201,7 @@
2101
2201
  }
2102
2202
 
2103
2203
  async function loadBlendPlugin(engine) {
2104
- engine.checkVersion("4.3.2");
2204
+ engine.checkVersion("4.4.0");
2105
2205
  await engine.pluginManager.register(e => {
2106
2206
  e.pluginManager.addPlugin(new BlendPlugin());
2107
2207
  });
@@ -2138,7 +2238,7 @@
2138
2238
  }
2139
2239
 
2140
2240
  async function loadCircleShape(engine) {
2141
- engine.checkVersion("4.3.2");
2241
+ engine.checkVersion("4.4.0");
2142
2242
  await engine.pluginManager.register(e => {
2143
2243
  e.pluginManager.addShape(["circle"], () => {
2144
2244
  return Promise.resolve(new CircleDrawer());
@@ -2186,7 +2286,7 @@
2186
2286
  }
2187
2287
 
2188
2288
  async function loadHexColorPlugin(engine) {
2189
- engine.checkVersion("4.3.2");
2289
+ engine.checkVersion("4.4.0");
2190
2290
  await engine.pluginManager.register(e => {
2191
2291
  e.pluginManager.addColorManager("hex", new HexColorManager());
2192
2292
  });
@@ -2239,7 +2339,7 @@
2239
2339
  }
2240
2340
 
2241
2341
  async function loadHslColorPlugin(engine) {
2242
- engine.checkVersion("4.3.2");
2342
+ engine.checkVersion("4.4.0");
2243
2343
  await engine.pluginManager.register(e => {
2244
2344
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2245
2345
  });
@@ -2263,7 +2363,7 @@
2263
2363
  }
2264
2364
 
2265
2365
  async function loadMovePlugin(engine) {
2266
- engine.checkVersion("4.3.2");
2366
+ engine.checkVersion("4.4.0");
2267
2367
  await engine.pluginManager.register(e => {
2268
2368
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2269
2369
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2479,7 +2579,7 @@
2479
2579
  }
2480
2580
 
2481
2581
  async function loadOpacityUpdater(engine) {
2482
- engine.checkVersion("4.3.2");
2582
+ engine.checkVersion("4.4.0");
2483
2583
  await engine.pluginManager.register(e => {
2484
2584
  e.pluginManager.addParticleUpdater("opacity", container => {
2485
2585
  return Promise.resolve(new OpacityUpdater(container));
@@ -2824,7 +2924,7 @@
2824
2924
  }
2825
2925
 
2826
2926
  async function loadOutModesUpdater(engine) {
2827
- engine.checkVersion("4.3.2");
2927
+ engine.checkVersion("4.4.0");
2828
2928
  await engine.pluginManager.register(e => {
2829
2929
  e.pluginManager.addParticleUpdater("outModes", container => {
2830
2930
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2895,7 +2995,7 @@
2895
2995
  }
2896
2996
 
2897
2997
  async function loadPaintUpdater(engine) {
2898
- engine.checkVersion("4.3.2");
2998
+ engine.checkVersion("4.4.0");
2899
2999
  await engine.pluginManager.register(e => {
2900
3000
  e.pluginManager.addParticleUpdater("paint", container => {
2901
3001
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2950,7 +3050,7 @@
2950
3050
  }
2951
3051
 
2952
3052
  async function loadRgbColorPlugin(engine) {
2953
- engine.checkVersion("4.3.2");
3053
+ engine.checkVersion("4.4.0");
2954
3054
  await engine.pluginManager.register(e => {
2955
3055
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
2956
3056
  });
@@ -3035,7 +3135,7 @@
3035
3135
  }
3036
3136
 
3037
3137
  async function loadSizeUpdater(engine) {
3038
- engine.checkVersion("4.3.2");
3138
+ engine.checkVersion("4.4.0");
3039
3139
  await engine.pluginManager.register(e => {
3040
3140
  e.pluginManager.addParticleUpdater("size", container => {
3041
3141
  return Promise.resolve(new SizeUpdater(container));
@@ -3044,7 +3144,7 @@
3044
3144
  }
3045
3145
 
3046
3146
  async function loadBasic(engine) {
3047
- engine.checkVersion("4.3.2");
3147
+ engine.checkVersion("4.4.0");
3048
3148
  await engine.pluginManager.register(async (e) => {
3049
3149
  await Promise.all([
3050
3150
  loadBlendPlugin(e),
@@ -3275,7 +3375,7 @@
3275
3375
  const clickEvent = "click", mouseDownEvent = "pointerdown", mouseUpEvent = "pointerup", mouseLeaveEvent = "pointerleave", mouseMoveEvent = "pointermove", touchStartEvent = "touchstart", touchEndEvent = "touchend", touchMoveEvent = "touchmove", touchCancelEvent = "touchcancel";
3276
3376
 
3277
3377
  async function loadInteractivityPlugin(engine) {
3278
- engine.checkVersion("4.3.2");
3378
+ engine.checkVersion("4.4.0");
3279
3379
  await engine.pluginManager.register(e => {
3280
3380
  const interactivityEngine = e, interactivityPluginManager = interactivityEngine.pluginManager;
3281
3381
  interactivityPluginManager.addPlugin(new InteractivityPlugin(interactivityPluginManager));
@@ -3454,7 +3554,7 @@
3454
3554
  }
3455
3555
 
3456
3556
  async function loadExternalCannonInteraction(engine) {
3457
- engine.checkVersion("4.3.2");
3557
+ engine.checkVersion("4.4.0");
3458
3558
  await engine.pluginManager.register((e) => {
3459
3559
  ensureInteractivityPluginLoaded(e);
3460
3560
  e.pluginManager.addInteractor?.("externalCannon", container => {
@@ -3600,7 +3700,7 @@
3600
3700
  }
3601
3701
 
3602
3702
  async function loadLifeUpdater(engine) {
3603
- engine.checkVersion("4.3.2");
3703
+ engine.checkVersion("4.4.0");
3604
3704
  await engine.pluginManager.register(e => {
3605
3705
  e.pluginManager.addParticleUpdater("life", container => {
3606
3706
  return Promise.resolve(new LifeUpdater(container));
@@ -3654,7 +3754,7 @@
3654
3754
  }
3655
3755
 
3656
3756
  async function loadMotionPlugin(engine) {
3657
- engine.checkVersion("4.3.2");
3757
+ engine.checkVersion("4.4.0");
3658
3758
  await engine.pluginManager.register(e => {
3659
3759
  e.pluginManager.addPlugin(new MotionPlugin());
3660
3760
  });
@@ -3787,7 +3887,7 @@
3787
3887
  }
3788
3888
 
3789
3889
  async function loadRollUpdater(engine) {
3790
- engine.checkVersion("4.3.2");
3890
+ engine.checkVersion("4.4.0");
3791
3891
  await engine.pluginManager.register(e => {
3792
3892
  e.pluginManager.addParticleUpdater("roll", () => {
3793
3893
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -3893,7 +3993,7 @@
3893
3993
  }
3894
3994
 
3895
3995
  async function loadRotateUpdater(engine) {
3896
- engine.checkVersion("4.3.2");
3996
+ engine.checkVersion("4.4.0");
3897
3997
  await engine.pluginManager.register(e => {
3898
3998
  e.pluginManager.addParticleUpdater("rotate", container => {
3899
3999
  return Promise.resolve(new RotateUpdater(container));
@@ -3917,7 +4017,7 @@
3917
4017
  }
3918
4018
 
3919
4019
  async function loadSquareShape(engine) {
3920
- engine.checkVersion("4.3.2");
4020
+ engine.checkVersion("4.4.0");
3921
4021
  await engine.pluginManager.register(e => {
3922
4022
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
3923
4023
  });
@@ -4026,7 +4126,7 @@
4026
4126
  }
4027
4127
 
4028
4128
  async function loadTiltUpdater(engine) {
4029
- engine.checkVersion("4.3.2");
4129
+ engine.checkVersion("4.4.0");
4030
4130
  await engine.pluginManager.register(e => {
4031
4131
  e.pluginManager.addParticleUpdater("tilt", container => {
4032
4132
  return Promise.resolve(new TiltUpdater(container));
@@ -4128,7 +4228,7 @@
4128
4228
  }
4129
4229
 
4130
4230
  async function loadWobbleUpdater(engine) {
4131
- engine.checkVersion("4.3.2");
4231
+ engine.checkVersion("4.4.0");
4132
4232
  await engine.pluginManager.register(e => {
4133
4233
  e.pluginManager.addParticleUpdater("wobble", container => {
4134
4234
  return Promise.resolve(new WobbleUpdater(container));
@@ -4393,7 +4493,11 @@
4393
4493
  if (!fColor && !sColor) {
4394
4494
  return;
4395
4495
  }
4396
- 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;
4397
4501
  transform.a = transform.b = transform.c = transform.d = undefined;
4398
4502
  colorStyles.fill = fill;
4399
4503
  colorStyles.stroke = stroke;
@@ -4727,7 +4831,9 @@
4727
4831
  if (typeof background.element === "string") {
4728
4832
  if (typeof document !== "undefined") {
4729
4833
  const node = document.querySelector(background.element);
4730
- 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)) {
4731
4837
  this.#backgroundElement = node;
4732
4838
  }
4733
4839
  else if (node) {
@@ -4738,10 +4844,10 @@
4738
4844
  }
4739
4845
  }
4740
4846
  }
4741
- else if (background.element instanceof HTMLCanvasElement ||
4742
- background.element instanceof OffscreenCanvas ||
4743
- background.element instanceof HTMLVideoElement ||
4744
- 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)) {
4745
4851
  this.#backgroundElement = background.element;
4746
4852
  }
4747
4853
  }
@@ -4809,6 +4915,7 @@
4809
4915
  zoom = defaultZoom;
4810
4916
  #container;
4811
4917
  #generated;
4918
+ #hdrMediaListeners;
4812
4919
  #mutationObserver;
4813
4920
  #originalStyle;
4814
4921
  #pluginManager;
@@ -4873,7 +4980,6 @@
4873
4980
  });
4874
4981
  this.resize();
4875
4982
  this.#initStyle();
4876
- this.initBackground();
4877
4983
  this.#safeMutationObserver(obs => {
4878
4984
  const element = this.domElement;
4879
4985
  if (!element || !(element instanceof Node)) {
@@ -4883,6 +4989,8 @@
4883
4989
  });
4884
4990
  this.initPlugins();
4885
4991
  this.#initContext();
4992
+ this.initBackground();
4993
+ this.#initHdrListeners();
4886
4994
  this.render.init();
4887
4995
  }
4888
4996
  initBackground() {
@@ -4892,7 +5000,8 @@
4892
5000
  }
4893
5001
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
4894
5002
  if (color) {
4895
- 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);
4896
5005
  }
4897
5006
  else {
4898
5007
  elementStyle.backgroundColor = "";
@@ -4989,6 +5098,7 @@
4989
5098
  obs.disconnect();
4990
5099
  });
4991
5100
  this.#mutationObserver = undefined;
5101
+ this.#removeHdrListeners();
4992
5102
  this.render.stop();
4993
5103
  }
4994
5104
  async windowResize() {
@@ -5008,9 +5118,16 @@
5008
5118
  }
5009
5119
  }
5010
5120
  #initContext() {
5011
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
5121
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
5012
5122
  safeMatchMedia("(color-gamut: p3)")?.matches &&
5013
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
+ }
5014
5131
  this.render.setContextSettings({
5015
5132
  alpha: true,
5016
5133
  desynchronized: true,
@@ -5019,11 +5136,47 @@
5019
5136
  ? { colorSpace: "display-p3", colorType: "float16" }
5020
5137
  : { colorSpace: "srgb" }),
5021
5138
  });
5022
- const renderCanvas = this.renderCanvas;
5023
- if (!renderCanvas) {
5024
- 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 });
5025
5178
  }
5026
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
5179
+ this.#hdrMediaListeners = listeners;
5027
5180
  }
5028
5181
  #initStyle() {
5029
5182
  const element = this.domElement, options = this.#container.actualOptions;
@@ -5047,6 +5200,25 @@
5047
5200
  element.style.setProperty(key, value, "important");
5048
5201
  }
5049
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
+ }
5050
5222
  #repairStyle() {
5051
5223
  const element = this.domElement;
5052
5224
  if (!element) {
@@ -5431,9 +5603,9 @@
5431
5603
  }
5432
5604
  getOpacity() {
5433
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;
5434
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
5606
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
5435
5607
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
5436
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
5608
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
5437
5609
  return this.#cachedOpacityData;
5438
5610
  }
5439
5611
  getPosition() {
@@ -6288,6 +6460,7 @@
6288
6460
  effectDrawers;
6289
6461
  fpsLimit;
6290
6462
  hdr;
6463
+ hdrMode;
6291
6464
  id;
6292
6465
  pageHidden;
6293
6466
  particleCreatedPlugins;
@@ -6295,6 +6468,7 @@
6295
6468
  particlePositionPlugins;
6296
6469
  particleUpdaters;
6297
6470
  particles;
6471
+ peakNits;
6298
6472
  plugins;
6299
6473
  retina;
6300
6474
  shapeDrawers;
@@ -6325,6 +6499,8 @@
6325
6499
  this.id = Symbol(id);
6326
6500
  this.fpsLimit = 120;
6327
6501
  this.hdr = false;
6502
+ this.hdrMode = HdrMode.standard;
6503
+ this.peakNits = 400;
6328
6504
  this.#smooth = false;
6329
6505
  this.#delay = 0;
6330
6506
  this.#duration = 0;
@@ -6464,8 +6640,9 @@
6464
6640
  this.updateActualOptions();
6465
6641
  this.canvas.initBackground();
6466
6642
  this.canvas.resize();
6467
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
6468
- 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;
6469
6646
  this.zLayers = zLayers;
6470
6647
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
6471
6648
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;