@tsparticles/preset-bubbles 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) :
@@ -810,7 +810,7 @@
810
810
  return this.#domArray;
811
811
  }
812
812
  get version() {
813
- return "4.3.2";
813
+ return "4.4.0";
814
814
  }
815
815
  addEventListener(type, listener) {
816
816
  this.#eventDispatcher.addEventListener(type, listener);
@@ -891,6 +891,10 @@
891
891
  }
892
892
 
893
893
  function initEngine() {
894
+ const existing = globalThis.tsParticles;
895
+ if (existing?.pluginManager) {
896
+ return existing;
897
+ }
894
898
  return new Engine();
895
899
  }
896
900
 
@@ -988,6 +992,15 @@
988
992
  AnimationMode["random"] = "random";
989
993
  })(AnimationMode || (AnimationMode = {}));
990
994
 
995
+ var HdrMode;
996
+ (function (HdrMode) {
997
+ HdrMode["standard"] = "standard";
998
+ HdrMode["natural"] = "natural";
999
+ HdrMode["vivid"] = "vivid";
1000
+ HdrMode["cinematic"] = "cinematic";
1001
+ HdrMode["dynamic"] = "dynamic";
1002
+ })(HdrMode || (HdrMode = {}));
1003
+
991
1004
  var LimitMode;
992
1005
  (function (LimitMode) {
993
1006
  LimitMode["delete"] = "delete";
@@ -1243,6 +1256,29 @@
1243
1256
  }
1244
1257
  }
1245
1258
 
1259
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
1260
+ class HDROptions extends OptionLoader {
1261
+ enable = true;
1262
+ mode = HdrMode.standard;
1263
+ peakNits = defaultPeakNits;
1264
+ doLoad(data) {
1265
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
1266
+ throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1267
+ }
1268
+ if (data.mode !== undefined &&
1269
+ (typeof data.mode !== "string" || !Object.values(HdrMode).includes(data.mode))) {
1270
+ throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1271
+ }
1272
+ if (data.peakNits !== undefined &&
1273
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1274
+ throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1275
+ }
1276
+ loadProperty(this, "enable", data.enable);
1277
+ loadProperty(this, "mode", data.mode);
1278
+ loadProperty(this, "peakNits", data.peakNits);
1279
+ }
1280
+ }
1281
+
1246
1282
  class ResizeEvent extends OptionLoader {
1247
1283
  delay = 0.5;
1248
1284
  enable = true;
@@ -1686,7 +1722,7 @@
1686
1722
  duration = 0;
1687
1723
  fpsLimit = 120;
1688
1724
  fullScreen;
1689
- hdr = true;
1725
+ hdr;
1690
1726
  key;
1691
1727
  name;
1692
1728
  palette;
@@ -1706,6 +1742,7 @@
1706
1742
  this.#container = container;
1707
1743
  this.background = new Background();
1708
1744
  this.fullScreen = new FullScreen();
1745
+ this.hdr = new HDROptions();
1709
1746
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1710
1747
  this.resize = new ResizeEvent();
1711
1748
  }
@@ -1728,7 +1765,15 @@
1728
1765
  loadProperty(this, "detectRetina", data.detectRetina);
1729
1766
  loadRangeProperty(this, "duration", data.duration);
1730
1767
  loadProperty(this, "fpsLimit", data.fpsLimit);
1731
- loadProperty(this, "hdr", data.hdr);
1768
+ const hdrData = data.hdr;
1769
+ if (isBoolean(hdrData)) {
1770
+ this.hdr.enable = hdrData;
1771
+ this.hdr.mode = HdrMode.standard;
1772
+ this.hdr.peakNits = 400;
1773
+ }
1774
+ else {
1775
+ this.hdr.load(hdrData);
1776
+ }
1732
1777
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1733
1778
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1734
1779
  loadProperty(this, "zLayers", data.zLayers);
@@ -1771,7 +1816,7 @@
1771
1816
  }
1772
1817
  }
1773
1818
 
1774
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1819
+ 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;
1775
1820
  function getCachedStyle(key, generator) {
1776
1821
  let cached = styleCache.get(key);
1777
1822
  if (!cached) {
@@ -1783,6 +1828,42 @@
1783
1828
  }
1784
1829
  return cached;
1785
1830
  }
1831
+ function acesFilmic(x) {
1832
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
1833
+ }
1834
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
1835
+ switch (mode) {
1836
+ case HdrMode.vivid: {
1837
+ const avg = (r + g + b) / channelCount;
1838
+ return {
1839
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1840
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1841
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1842
+ };
1843
+ }
1844
+ case HdrMode.cinematic: {
1845
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
1846
+ return {
1847
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
1848
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
1849
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
1850
+ };
1851
+ }
1852
+ case HdrMode.dynamic: {
1853
+ 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;
1854
+ return {
1855
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
1856
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
1857
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
1858
+ };
1859
+ }
1860
+ case HdrMode.standard:
1861
+ return { b, g, r };
1862
+ case HdrMode.natural:
1863
+ default:
1864
+ return { b, g, r };
1865
+ }
1866
+ }
1786
1867
  function stringToRgba(pluginManager, input) {
1787
1868
  if (!input) {
1788
1869
  return;
@@ -1940,21 +2021,40 @@
1940
2021
  r: getRgbInRangeValue(),
1941
2022
  };
1942
2023
  }
1943
- function getStyleFromRgb(color, hdr, opacity) {
1944
- 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()}`;
1945
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2024
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
2025
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2026
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2027
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
2028
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
2029
+ }
2030
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = HdrMode.standard) {
2031
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
2032
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
1946
2033
  }
1947
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
1948
- const headroom = peakNits / sdrReferenceWhiteNits;
1949
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2034
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
2035
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
2036
+ if (mode !== HdrMode.natural && mode !== HdrMode.vivid && mode !== HdrMode.cinematic && mode !== HdrMode.dynamic) {
2037
+ return { b: bNorm, g: gNorm, r: rNorm };
2038
+ }
2039
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
2040
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
2041
+ }
2042
+ function hdrToneMap(normalized, headroom, middleGray) {
2043
+ if (normalized <= middleGray) {
2044
+ return acesFilmic(normalized);
2045
+ }
2046
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
2047
+ return acesFilmic(expanded);
1950
2048
  }
1951
2049
  function getSdrStyleFromRgb(color, opacity) {
1952
2050
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
1953
2051
  }
1954
- function getStyleFromHsl(color, hdr, opacity) {
1955
- 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()}`;
2052
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
2053
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2054
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? HdrMode.standard}`
2055
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
1956
2056
  return getCachedStyle(key, () => hdr
1957
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2057
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
1958
2058
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1959
2059
  }
1960
2060
  function getHslFromAnimation(animation) {
@@ -2017,7 +2117,7 @@
2017
2117
  colorValue.velocity = defaultVelocity;
2018
2118
  }
2019
2119
  }
2020
- function updateColorValue(data, decrease, delta, hdr) {
2120
+ function updateColorValue(data, decrease, delta, _hdr) {
2021
2121
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2022
2122
  if (!data.enable ||
2023
2123
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2030,7 +2130,7 @@
2030
2130
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2031
2131
  return;
2032
2132
  }
2033
- 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;
2133
+ 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;
2034
2134
  if (!decrease || data.status === AnimationStatus.increasing) {
2035
2135
  data.value += velocity;
2036
2136
  if (data.value > max) {
@@ -2062,9 +2162,9 @@
2062
2162
  return;
2063
2163
  }
2064
2164
  const { h, s, l } = color;
2065
- updateColorValue(h, false, delta, hdr);
2066
- updateColorValue(s, true, delta, hdr);
2067
- updateColorValue(l, true, delta, hdr);
2165
+ updateColorValue(h, false, delta);
2166
+ updateColorValue(s, true, delta);
2167
+ updateColorValue(l, true, delta);
2068
2168
  }
2069
2169
  function alterHsl(color, type, value) {
2070
2170
  return {
@@ -2114,7 +2214,7 @@
2114
2214
  }
2115
2215
 
2116
2216
  async function loadBlendPlugin(engine) {
2117
- engine.checkVersion("4.3.2");
2217
+ engine.checkVersion("4.4.0");
2118
2218
  await engine.pluginManager.register(e => {
2119
2219
  e.pluginManager.addPlugin(new BlendPlugin());
2120
2220
  });
@@ -2151,7 +2251,7 @@
2151
2251
  }
2152
2252
 
2153
2253
  async function loadCircleShape(engine) {
2154
- engine.checkVersion("4.3.2");
2254
+ engine.checkVersion("4.4.0");
2155
2255
  await engine.pluginManager.register(e => {
2156
2256
  e.pluginManager.addShape(["circle"], () => {
2157
2257
  return Promise.resolve(new CircleDrawer());
@@ -2199,7 +2299,7 @@
2199
2299
  }
2200
2300
 
2201
2301
  async function loadHexColorPlugin(engine) {
2202
- engine.checkVersion("4.3.2");
2302
+ engine.checkVersion("4.4.0");
2203
2303
  await engine.pluginManager.register(e => {
2204
2304
  e.pluginManager.addColorManager("hex", new HexColorManager());
2205
2305
  });
@@ -2252,7 +2352,7 @@
2252
2352
  }
2253
2353
 
2254
2354
  async function loadHslColorPlugin(engine) {
2255
- engine.checkVersion("4.3.2");
2355
+ engine.checkVersion("4.4.0");
2256
2356
  await engine.pluginManager.register(e => {
2257
2357
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2258
2358
  });
@@ -2276,7 +2376,7 @@
2276
2376
  }
2277
2377
 
2278
2378
  async function loadMovePlugin(engine) {
2279
- engine.checkVersion("4.3.2");
2379
+ engine.checkVersion("4.4.0");
2280
2380
  await engine.pluginManager.register(e => {
2281
2381
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2282
2382
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2486,7 +2586,7 @@
2486
2586
  }
2487
2587
 
2488
2588
  async function loadOpacityUpdater(engine) {
2489
- engine.checkVersion("4.3.2");
2589
+ engine.checkVersion("4.4.0");
2490
2590
  await engine.pluginManager.register(e => {
2491
2591
  e.pluginManager.addParticleUpdater("opacity", container => {
2492
2592
  return Promise.resolve(new OpacityUpdater(container));
@@ -2831,7 +2931,7 @@
2831
2931
  }
2832
2932
 
2833
2933
  async function loadOutModesUpdater(engine) {
2834
- engine.checkVersion("4.3.2");
2934
+ engine.checkVersion("4.4.0");
2835
2935
  await engine.pluginManager.register(e => {
2836
2936
  e.pluginManager.addParticleUpdater("outModes", container => {
2837
2937
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2902,7 +3002,7 @@
2902
3002
  }
2903
3003
 
2904
3004
  async function loadPaintUpdater(engine) {
2905
- engine.checkVersion("4.3.2");
3005
+ engine.checkVersion("4.4.0");
2906
3006
  await engine.pluginManager.register(e => {
2907
3007
  e.pluginManager.addParticleUpdater("paint", container => {
2908
3008
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2957,7 +3057,7 @@
2957
3057
  }
2958
3058
 
2959
3059
  async function loadRgbColorPlugin(engine) {
2960
- engine.checkVersion("4.3.2");
3060
+ engine.checkVersion("4.4.0");
2961
3061
  await engine.pluginManager.register(e => {
2962
3062
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
2963
3063
  });
@@ -3042,7 +3142,7 @@
3042
3142
  }
3043
3143
 
3044
3144
  async function loadSizeUpdater(engine) {
3045
- engine.checkVersion("4.3.2");
3145
+ engine.checkVersion("4.4.0");
3046
3146
  await engine.pluginManager.register(e => {
3047
3147
  e.pluginManager.addParticleUpdater("size", container => {
3048
3148
  return Promise.resolve(new SizeUpdater(container));
@@ -3051,7 +3151,7 @@
3051
3151
  }
3052
3152
 
3053
3153
  async function loadBasic(engine) {
3054
- engine.checkVersion("4.3.2");
3154
+ engine.checkVersion("4.4.0");
3055
3155
  await engine.pluginManager.register(async (e) => {
3056
3156
  await Promise.all([
3057
3157
  loadBlendPlugin(e),
@@ -3274,7 +3374,7 @@
3274
3374
  })(EmitterClickMode || (EmitterClickMode = {}));
3275
3375
 
3276
3376
  async function loadEmittersPluginSimple(engine) {
3277
- engine.checkVersion("4.3.2");
3377
+ engine.checkVersion("4.4.0");
3278
3378
  await engine.pluginManager.register(async (e) => {
3279
3379
  const instancesManager = await getEmittersInstancesManager(e);
3280
3380
  await addEmittersShapesManager(e);
@@ -3469,7 +3569,11 @@
3469
3569
  if (!fColor && !sColor) {
3470
3570
  return;
3471
3571
  }
3472
- 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;
3572
+ 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
3573
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
3574
+ : undefined, stroke = sColor
3575
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
3576
+ : fill;
3473
3577
  transform.a = transform.b = transform.c = transform.d = undefined;
3474
3578
  colorStyles.fill = fill;
3475
3579
  colorStyles.stroke = stroke;
@@ -3803,7 +3907,9 @@
3803
3907
  if (typeof background.element === "string") {
3804
3908
  if (typeof document !== "undefined") {
3805
3909
  const node = document.querySelector(background.element);
3806
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
3910
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
3911
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
3912
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
3807
3913
  this.#backgroundElement = node;
3808
3914
  }
3809
3915
  else if (node) {
@@ -3814,10 +3920,10 @@
3814
3920
  }
3815
3921
  }
3816
3922
  }
3817
- else if (background.element instanceof HTMLCanvasElement ||
3818
- background.element instanceof OffscreenCanvas ||
3819
- background.element instanceof HTMLVideoElement ||
3820
- background.element instanceof HTMLImageElement) {
3923
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
3924
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
3925
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
3926
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
3821
3927
  this.#backgroundElement = background.element;
3822
3928
  }
3823
3929
  }
@@ -3885,6 +3991,7 @@
3885
3991
  zoom = defaultZoom;
3886
3992
  #container;
3887
3993
  #generated;
3994
+ #hdrMediaListeners;
3888
3995
  #mutationObserver;
3889
3996
  #originalStyle;
3890
3997
  #pluginManager;
@@ -3949,7 +4056,6 @@
3949
4056
  });
3950
4057
  this.resize();
3951
4058
  this.#initStyle();
3952
- this.initBackground();
3953
4059
  this.#safeMutationObserver(obs => {
3954
4060
  const element = this.domElement;
3955
4061
  if (!element || !(element instanceof Node)) {
@@ -3959,6 +4065,8 @@
3959
4065
  });
3960
4066
  this.initPlugins();
3961
4067
  this.#initContext();
4068
+ this.initBackground();
4069
+ this.#initHdrListeners();
3962
4070
  this.render.init();
3963
4071
  }
3964
4072
  initBackground() {
@@ -3968,7 +4076,8 @@
3968
4076
  }
3969
4077
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
3970
4078
  if (color) {
3971
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
4079
+ const hdrOptions = container.actualOptions.hdr;
4080
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
3972
4081
  }
3973
4082
  else {
3974
4083
  elementStyle.backgroundColor = "";
@@ -4065,6 +4174,7 @@
4065
4174
  obs.disconnect();
4066
4175
  });
4067
4176
  this.#mutationObserver = undefined;
4177
+ this.#removeHdrListeners();
4068
4178
  this.render.stop();
4069
4179
  }
4070
4180
  async windowResize() {
@@ -4084,9 +4194,16 @@
4084
4194
  }
4085
4195
  }
4086
4196
  #initContext() {
4087
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
4197
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
4088
4198
  safeMatchMedia("(color-gamut: p3)")?.matches &&
4089
4199
  safeMatchMedia("(dynamic-range: high)")?.matches;
4200
+ container.hdr = canSupportHdr ?? false;
4201
+ container.hdrMode = container.actualOptions.hdr.mode;
4202
+ container.peakNits = container.actualOptions.hdr.peakNits;
4203
+ const renderCanvas = this.renderCanvas;
4204
+ if (!renderCanvas) {
4205
+ return;
4206
+ }
4090
4207
  this.render.setContextSettings({
4091
4208
  alpha: true,
4092
4209
  desynchronized: true,
@@ -4095,11 +4212,47 @@
4095
4212
  ? { colorSpace: "display-p3", colorType: "float16" }
4096
4213
  : { colorSpace: "srgb" }),
4097
4214
  });
4098
- const renderCanvas = this.renderCanvas;
4099
- if (!renderCanvas) {
4100
- return;
4215
+ let context;
4216
+ try {
4217
+ context = renderCanvas.getContext("2d", this.render.settings);
4218
+ }
4219
+ catch {
4220
+ context = null;
4221
+ }
4222
+ if (canSupportHdr && !context) {
4223
+ container.hdr = false;
4224
+ const sdrSettings = {
4225
+ alpha: true,
4226
+ desynchronized: true,
4227
+ willReadFrequently: false,
4228
+ colorSpace: "srgb",
4229
+ };
4230
+ this.render.setContextSettings(sdrSettings);
4231
+ try {
4232
+ context = renderCanvas.getContext("2d", sdrSettings);
4233
+ }
4234
+ catch {
4235
+ context = null;
4236
+ }
4237
+ }
4238
+ this.render.setContext(context);
4239
+ }
4240
+ #initHdrListeners() {
4241
+ this.#removeHdrListeners();
4242
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
4243
+ this.#recreateRenderCanvas();
4244
+ this.#initContext();
4245
+ this.initBackground();
4246
+ }, listeners = [];
4247
+ if (p3Query) {
4248
+ p3Query.addEventListener("change", handleChange);
4249
+ listeners.push({ handler: handleChange, mql: p3Query });
4250
+ }
4251
+ if (hdrQuery) {
4252
+ hdrQuery.addEventListener("change", handleChange);
4253
+ listeners.push({ handler: handleChange, mql: hdrQuery });
4101
4254
  }
4102
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
4255
+ this.#hdrMediaListeners = listeners;
4103
4256
  }
4104
4257
  #initStyle() {
4105
4258
  const element = this.domElement, options = this.#container.actualOptions;
@@ -4123,6 +4276,25 @@
4123
4276
  element.style.setProperty(key, value, "important");
4124
4277
  }
4125
4278
  }
4279
+ #recreateRenderCanvas() {
4280
+ const renderCanvas = this.renderCanvas;
4281
+ if (!renderCanvas) {
4282
+ return;
4283
+ }
4284
+ if (this.domElement) {
4285
+ return;
4286
+ }
4287
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
4288
+ }
4289
+ #removeHdrListeners() {
4290
+ if (!this.#hdrMediaListeners) {
4291
+ return;
4292
+ }
4293
+ for (const { handler, mql } of this.#hdrMediaListeners) {
4294
+ mql.removeEventListener("change", handler);
4295
+ }
4296
+ this.#hdrMediaListeners = undefined;
4297
+ }
4126
4298
  #repairStyle() {
4127
4299
  const element = this.domElement;
4128
4300
  if (!element) {
@@ -4507,9 +4679,9 @@
4507
4679
  }
4508
4680
  getOpacity() {
4509
4681
  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;
4510
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
4682
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
4511
4683
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
4512
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
4684
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
4513
4685
  return this.#cachedOpacityData;
4514
4686
  }
4515
4687
  getPosition() {
@@ -5364,6 +5536,7 @@
5364
5536
  effectDrawers;
5365
5537
  fpsLimit;
5366
5538
  hdr;
5539
+ hdrMode;
5367
5540
  id;
5368
5541
  pageHidden;
5369
5542
  particleCreatedPlugins;
@@ -5371,6 +5544,7 @@
5371
5544
  particlePositionPlugins;
5372
5545
  particleUpdaters;
5373
5546
  particles;
5547
+ peakNits;
5374
5548
  plugins;
5375
5549
  retina;
5376
5550
  shapeDrawers;
@@ -5401,6 +5575,8 @@
5401
5575
  this.id = Symbol(id);
5402
5576
  this.fpsLimit = 120;
5403
5577
  this.hdr = false;
5578
+ this.hdrMode = HdrMode.standard;
5579
+ this.peakNits = 400;
5404
5580
  this.#smooth = false;
5405
5581
  this.#delay = 0;
5406
5582
  this.#duration = 0;
@@ -5540,8 +5716,9 @@
5540
5716
  this.updateActualOptions();
5541
5717
  this.canvas.initBackground();
5542
5718
  this.canvas.resize();
5543
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
5544
- this.hdr = hdr;
5719
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
5720
+ this.hdrMode = hdrOptions.mode;
5721
+ this.peakNits = hdrOptions.peakNits;
5545
5722
  this.zLayers = zLayers;
5546
5723
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
5547
5724
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;