@tsparticles/fireworks 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
- /* tsParticles v4.3.1 */
2
+ /* tsParticles 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) :
@@ -332,6 +332,9 @@
332
332
  })(exports.PixelMode || (exports.PixelMode = {}));
333
333
 
334
334
  const minRadius = 0;
335
+ function isForbiddenKey(key) {
336
+ return key === "__proto__" || key === "constructor" || key === "prototype";
337
+ }
335
338
  function hasMatchMedia() {
336
339
  return typeof matchMedia !== "undefined";
337
340
  }
@@ -407,7 +410,7 @@
407
410
  if (!hasNested) {
408
411
  const sourceDict = source, destDict = destination;
409
412
  for (const key of sourceKeys) {
410
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
413
+ if (isForbiddenKey(key)) {
411
414
  continue;
412
415
  }
413
416
  const v = sourceDict[key];
@@ -418,7 +421,7 @@
418
421
  continue;
419
422
  }
420
423
  for (const key of sourceKeys) {
421
- if (key === "__proto__" || key === "constructor" || key === "prototype") {
424
+ if (isForbiddenKey(key)) {
422
425
  continue;
423
426
  }
424
427
  const sourceDict = source, destDict = destination, value = sourceDict[key];
@@ -877,7 +880,7 @@
877
880
  return this.#domArray;
878
881
  }
879
882
  get version() {
880
- return "4.3.1";
883
+ return "4.4.0";
881
884
  }
882
885
  addEventListener(type, listener) {
883
886
  this.#eventDispatcher.addEventListener(type, listener);
@@ -958,6 +961,10 @@
958
961
  }
959
962
 
960
963
  function initEngine() {
964
+ const existing = globalThis.tsParticles;
965
+ if (existing?.pluginManager) {
966
+ return existing;
967
+ }
961
968
  return new Engine();
962
969
  }
963
970
 
@@ -1055,6 +1062,15 @@
1055
1062
  AnimationMode["random"] = "random";
1056
1063
  })(exports.AnimationMode || (exports.AnimationMode = {}));
1057
1064
 
1065
+ exports.HdrMode = void 0;
1066
+ (function (HdrMode) {
1067
+ HdrMode["standard"] = "standard";
1068
+ HdrMode["natural"] = "natural";
1069
+ HdrMode["vivid"] = "vivid";
1070
+ HdrMode["cinematic"] = "cinematic";
1071
+ HdrMode["dynamic"] = "dynamic";
1072
+ })(exports.HdrMode || (exports.HdrMode = {}));
1073
+
1058
1074
  exports.LimitMode = void 0;
1059
1075
  (function (LimitMode) {
1060
1076
  LimitMode["delete"] = "delete";
@@ -1160,7 +1176,12 @@
1160
1176
  }
1161
1177
  function loadExtendProperty(obj, key, value) {
1162
1178
  if (value !== undefined) {
1163
- obj[key] = deepExtend(obj[key] ?? {}, value);
1179
+ const keyStr = key;
1180
+ if (keyStr === "__proto__" || keyStr === "constructor" || keyStr === "prototype") {
1181
+ return;
1182
+ }
1183
+ const objRecord = obj, currentValue = Object.prototype.hasOwnProperty.call(objRecord, keyStr) ? objRecord[keyStr] : {};
1184
+ objRecord[keyStr] = deepExtend(currentValue, value);
1164
1185
  }
1165
1186
  }
1166
1187
  function loadOptionProperty(obj, key, optionClass, ...sources) {
@@ -1315,6 +1336,29 @@
1315
1336
  }
1316
1337
  }
1317
1338
 
1339
+ const defaultPeakNits = 400, minPeakNits = 0, toStringValue = (value) => String(value);
1340
+ class HDROptions extends OptionLoader {
1341
+ enable = true;
1342
+ mode = exports.HdrMode.standard;
1343
+ peakNits = defaultPeakNits;
1344
+ doLoad(data) {
1345
+ if (data.enable !== undefined && !isBoolean(data.enable)) {
1346
+ throw new Error(`Invalid HDR "enable" value: expected a boolean, got "${String(data.enable)}"`);
1347
+ }
1348
+ if (data.mode !== undefined &&
1349
+ (typeof data.mode !== "string" || !Object.values(exports.HdrMode).includes(data.mode))) {
1350
+ throw new Error(`Invalid HDR "mode" value: expected one of ${Object.values(exports.HdrMode).join(", ")}, got "${toStringValue(data.mode)}"`);
1351
+ }
1352
+ if (data.peakNits !== undefined &&
1353
+ (!isNumber(data.peakNits) || !Number.isFinite(data.peakNits) || data.peakNits <= minPeakNits)) {
1354
+ throw new Error(`Invalid HDR "peakNits" value: expected a positive number, got "${String(data.peakNits)}"`);
1355
+ }
1356
+ loadProperty(this, "enable", data.enable);
1357
+ loadProperty(this, "mode", data.mode);
1358
+ loadProperty(this, "peakNits", data.peakNits);
1359
+ }
1360
+ }
1361
+
1318
1362
  class ResizeEvent extends OptionLoader {
1319
1363
  delay = 0.5;
1320
1364
  enable = true;
@@ -1758,7 +1802,7 @@
1758
1802
  duration = 0;
1759
1803
  fpsLimit = 120;
1760
1804
  fullScreen;
1761
- hdr = true;
1805
+ hdr;
1762
1806
  key;
1763
1807
  name;
1764
1808
  palette;
@@ -1778,6 +1822,7 @@
1778
1822
  this.#container = container;
1779
1823
  this.background = new Background();
1780
1824
  this.fullScreen = new FullScreen();
1825
+ this.hdr = new HDROptions();
1781
1826
  this.particles = loadParticlesOptions(this.#pluginManager, this.#container);
1782
1827
  this.resize = new ResizeEvent();
1783
1828
  }
@@ -1800,7 +1845,15 @@
1800
1845
  loadProperty(this, "detectRetina", data.detectRetina);
1801
1846
  loadRangeProperty(this, "duration", data.duration);
1802
1847
  loadProperty(this, "fpsLimit", data.fpsLimit);
1803
- loadProperty(this, "hdr", data.hdr);
1848
+ const hdrData = data.hdr;
1849
+ if (isBoolean(hdrData)) {
1850
+ this.hdr.enable = hdrData;
1851
+ this.hdr.mode = exports.HdrMode.standard;
1852
+ this.hdr.peakNits = 400;
1853
+ }
1854
+ else {
1855
+ this.hdr.load(hdrData);
1856
+ }
1804
1857
  loadProperty(this, "pauseOnBlur", data.pauseOnBlur);
1805
1858
  loadProperty(this, "pauseOnOutsideViewport", data.pauseOnOutsideViewport);
1806
1859
  loadProperty(this, "zLayers", data.zLayers);
@@ -1843,7 +1896,7 @@
1843
1896
  }
1844
1897
  }
1845
1898
 
1846
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1899
+ 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, srgbThreshold = 0.04045, srgbDivisor = 12.92, srgbOffset = 0.055, srgbScale = 1.055, srgbExponent = 2.4, linearThreshold = 0.0031308, linearScale = 12.92;
1847
1900
  function getCachedStyle(key, generator) {
1848
1901
  let cached = styleCache.get(key);
1849
1902
  if (!cached) {
@@ -1855,6 +1908,48 @@
1855
1908
  }
1856
1909
  return cached;
1857
1910
  }
1911
+ function acesFilmic(x) {
1912
+ return clamp((x * (acesA * x + acesB)) / (x * (acesC * x + acesD) + acesE), none, one);
1913
+ }
1914
+ function srgbToLinear(c) {
1915
+ return c <= srgbThreshold ? c / srgbDivisor : Math.pow((c + srgbOffset) / srgbScale, srgbExponent);
1916
+ }
1917
+ function linearToSrgb(c) {
1918
+ return c <= linearThreshold ? c * linearScale : srgbScale * Math.pow(c, one / srgbExponent) - srgbOffset;
1919
+ }
1920
+ function applyHdrModeAdjustments(r, g, b, mode, maxChannel) {
1921
+ switch (mode) {
1922
+ case exports.HdrMode.vivid: {
1923
+ const avg = (r + g + b) / channelCount;
1924
+ return {
1925
+ b: clamp(clamp(avg + (b - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1926
+ g: clamp(clamp(avg + (g - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1927
+ r: clamp(clamp(avg + (r - avg) * saturationBoost, none, maxChannel) * lightnessBoost, none, maxChannel),
1928
+ };
1929
+ }
1930
+ case exports.HdrMode.cinematic: {
1931
+ const tempR = r * temperatureR, tempB = b * temperatureB, avg = (tempR + g + tempB) / channelCount;
1932
+ return {
1933
+ b: clamp(avg + (tempB - avg) * contrastFactor, none, maxChannel),
1934
+ g: clamp(avg + (g - avg) * contrastFactor, none, maxChannel),
1935
+ r: clamp(avg + (tempR - avg) * contrastFactor, none, maxChannel),
1936
+ };
1937
+ }
1938
+ case exports.HdrMode.dynamic: {
1939
+ 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;
1940
+ return {
1941
+ b: clamp(b * naturalWeight + vividB * vividWeight, none, maxChannel),
1942
+ g: clamp(g * naturalWeight + vividG * vividWeight, none, maxChannel),
1943
+ r: clamp(r * naturalWeight + vividR * vividWeight, none, maxChannel),
1944
+ };
1945
+ }
1946
+ case exports.HdrMode.standard:
1947
+ return { b, g, r };
1948
+ case exports.HdrMode.natural:
1949
+ default:
1950
+ return { b, g, r };
1951
+ }
1952
+ }
1858
1953
  function stringToRgba(pluginManager, input) {
1859
1954
  if (!input) {
1860
1955
  return;
@@ -2022,30 +2117,65 @@
2022
2117
  r: getRgbInRangeValue(),
2023
2118
  };
2024
2119
  }
2025
- function getStyleFromRgb(color, hdr, opacity) {
2026
- 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()}`;
2027
- return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
2120
+ function getStyleFromRgb(color, hdr, opacity, peakNits, mode) {
2121
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2122
+ ? `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? exports.HdrMode.standard}`
2123
+ : `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-sdr-${op.toString()}`;
2124
+ return getCachedStyle(key, () => hdr ? getHdrStyleFromRgb(color, opacity, peakNits, mode) : getSdrStyleFromRgb(color, opacity));
2028
2125
  }
2029
- function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
2030
- const headroom = peakNits / sdrReferenceWhiteNits;
2031
- return `color(display-p3 ${((color.r / rgbMax) * headroom).toString()} ${((color.g / rgbMax) * headroom).toString()} ${((color.b / rgbMax) * headroom).toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2126
+ function getHdrStyleFromRgb(color, opacity, peakNits = maxNits, mode = exports.HdrMode.standard) {
2127
+ const headroom = peakNits / sdrReferenceWhiteNits, middleGray = 0.18, mapped = hdrToneMapColor(color, headroom, middleGray, mode);
2128
+ return `color(display-p3 ${mapped.r.toString()} ${mapped.g.toString()} ${mapped.b.toString()} / ${(opacity ?? defaultOpacity$1).toString()})`;
2129
+ }
2130
+ function hdrToneMapColor(color, headroom, middleGray, mode) {
2131
+ const rNorm = color.r / rgbMax, gNorm = color.g / rgbMax, bNorm = color.b / rgbMax;
2132
+ if (mode !== exports.HdrMode.natural && mode !== exports.HdrMode.vivid && mode !== exports.HdrMode.cinematic && mode !== exports.HdrMode.dynamic) {
2133
+ return { b: bNorm, g: gNorm, r: rNorm };
2134
+ }
2135
+ const maxChannel = Math.max(one, headroom), luminance = luminanceR * rNorm + luminanceG * gNorm + luminanceB * bNorm, mappedLuminance = hdrToneMap(luminance, headroom, middleGray), scale = luminance > none ? mappedLuminance / luminance : one;
2136
+ return applyHdrModeAdjustments(clamp(rNorm * scale, none, maxChannel), clamp(gNorm * scale, none, maxChannel), clamp(bNorm * scale, none, maxChannel), mode, maxChannel);
2137
+ }
2138
+ function hdrToneMap(normalized, headroom, middleGray) {
2139
+ if (normalized <= middleGray) {
2140
+ return acesFilmic(normalized);
2141
+ }
2142
+ const expanded = normalized + (normalized - middleGray) * (headroom - one);
2143
+ return acesFilmic(expanded);
2032
2144
  }
2033
2145
  function getSdrStyleFromRgb(color, opacity) {
2034
2146
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
2035
2147
  }
2036
- function getStyleFromHsl(color, hdr, opacity) {
2037
- 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()}`;
2148
+ function getStyleFromHsl(color, hdr, opacity, peakNits, mode) {
2149
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$1, key = hdr
2150
+ ? `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-hdr-${op.toString()}-${(peakNits ?? maxNits).toString()}-${mode ?? exports.HdrMode.standard}`
2151
+ : `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-sdr-${op.toString()}`;
2038
2152
  return getCachedStyle(key, () => hdr
2039
- ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2153
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity, peakNits, mode)
2040
2154
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
2041
2155
  }
2042
- function colorMix(color1, color2, size1, size2) {
2156
+ function colorMix(color1, color2, size1, size2, hdr) {
2043
2157
  let rgb1 = color1, rgb2 = color2;
2044
2158
  if (!("r" in rgb1)) {
2045
- rgb1 = hslToRgb(color1);
2159
+ rgb1 = hdr ? hslToRgbFloat(color1) : hslToRgb(color1);
2046
2160
  }
2047
2161
  if (!("r" in rgb2)) {
2048
- rgb2 = hslToRgb(color2);
2162
+ rgb2 = hdr ? hslToRgbFloat(color2) : hslToRgb(color2);
2163
+ }
2164
+ if (hdr) {
2165
+ const lin1 = {
2166
+ b: srgbToLinear(rgb1.b / rgbMax),
2167
+ g: srgbToLinear(rgb1.g / rgbMax),
2168
+ r: srgbToLinear(rgb1.r / rgbMax),
2169
+ }, lin2 = {
2170
+ b: srgbToLinear(rgb2.b / rgbMax),
2171
+ g: srgbToLinear(rgb2.g / rgbMax),
2172
+ r: srgbToLinear(rgb2.r / rgbMax),
2173
+ }, totalWeight = size1 + size2;
2174
+ return {
2175
+ b: linearToSrgb((lin1.b * size1 + lin2.b * size2) / totalWeight) * rgbMax,
2176
+ g: linearToSrgb((lin1.g * size1 + lin2.g * size2) / totalWeight) * rgbMax,
2177
+ r: linearToSrgb((lin1.r * size1 + lin2.r * size2) / totalWeight) * rgbMax,
2178
+ };
2049
2179
  }
2050
2180
  return {
2051
2181
  b: mix(rgb1.b, rgb2.b, size1, size2),
@@ -2053,14 +2183,14 @@
2053
2183
  r: mix(rgb1.r, rgb2.r, size1, size2),
2054
2184
  };
2055
2185
  }
2056
- function getLinkColor(p1, p2, linkColor) {
2186
+ function getLinkColor(p1, p2, linkColor, hdr) {
2057
2187
  if (linkColor === randomColorValue) {
2058
2188
  return getRandomRgbColor();
2059
2189
  }
2060
2190
  else if (linkColor === midColorValue) {
2061
2191
  const sourceColor = p1.getFillColor() ?? p1.getStrokeColor(), destColor = p2?.getFillColor() ?? p2?.getStrokeColor();
2062
2192
  if (sourceColor && destColor && p2) {
2063
- return colorMix(sourceColor, destColor, p1.getRadius(), p2.getRadius());
2193
+ return colorMix(sourceColor, destColor, p1.getRadius(), p2.getRadius(), hdr);
2064
2194
  }
2065
2195
  else {
2066
2196
  const hslColor = sourceColor ?? destColor;
@@ -2156,7 +2286,7 @@
2156
2286
  colorValue.velocity = defaultVelocity;
2157
2287
  }
2158
2288
  }
2159
- function updateColorValue(data, decrease, delta, hdr) {
2289
+ function updateColorValue(data, decrease, delta, _hdr) {
2160
2290
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2161
2291
  if (!data.enable ||
2162
2292
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2169,7 +2299,7 @@
2169
2299
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2170
2300
  return;
2171
2301
  }
2172
- 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;
2302
+ 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;
2173
2303
  if (!decrease || data.status === exports.AnimationStatus.increasing) {
2174
2304
  data.value += velocity;
2175
2305
  if (data.value > max) {
@@ -2201,9 +2331,9 @@
2201
2331
  return;
2202
2332
  }
2203
2333
  const { h, s, l } = color;
2204
- updateColorValue(h, false, delta, hdr);
2205
- updateColorValue(s, true, delta, hdr);
2206
- updateColorValue(l, true, delta, hdr);
2334
+ updateColorValue(h, false, delta);
2335
+ updateColorValue(s, true, delta);
2336
+ updateColorValue(l, true, delta);
2207
2337
  }
2208
2338
  function alterHsl(color, type, value) {
2209
2339
  return {
@@ -2546,7 +2676,7 @@
2546
2676
  }
2547
2677
 
2548
2678
  async function loadBlendPlugin(engine) {
2549
- engine.checkVersion("4.3.1");
2679
+ engine.checkVersion("4.4.0");
2550
2680
  await engine.pluginManager.register(e => {
2551
2681
  e.pluginManager.addPlugin(new BlendPlugin());
2552
2682
  });
@@ -2583,7 +2713,7 @@
2583
2713
  }
2584
2714
 
2585
2715
  async function loadCircleShape(engine) {
2586
- engine.checkVersion("4.3.1");
2716
+ engine.checkVersion("4.4.0");
2587
2717
  await engine.pluginManager.register(e => {
2588
2718
  e.pluginManager.addShape(["circle"], () => {
2589
2719
  return Promise.resolve(new CircleDrawer());
@@ -2631,7 +2761,7 @@
2631
2761
  }
2632
2762
 
2633
2763
  async function loadHexColorPlugin(engine) {
2634
- engine.checkVersion("4.3.1");
2764
+ engine.checkVersion("4.4.0");
2635
2765
  await engine.pluginManager.register(e => {
2636
2766
  e.pluginManager.addColorManager("hex", new HexColorManager());
2637
2767
  });
@@ -2684,7 +2814,7 @@
2684
2814
  }
2685
2815
 
2686
2816
  async function loadHslColorPlugin(engine) {
2687
- engine.checkVersion("4.3.1");
2817
+ engine.checkVersion("4.4.0");
2688
2818
  await engine.pluginManager.register(e => {
2689
2819
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2690
2820
  });
@@ -2708,7 +2838,7 @@
2708
2838
  }
2709
2839
 
2710
2840
  async function loadMovePlugin(engine) {
2711
- engine.checkVersion("4.3.1");
2841
+ engine.checkVersion("4.4.0");
2712
2842
  await engine.pluginManager.register(e => {
2713
2843
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2714
2844
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2924,7 +3054,7 @@
2924
3054
  }
2925
3055
 
2926
3056
  async function loadOpacityUpdater(engine) {
2927
- engine.checkVersion("4.3.1");
3057
+ engine.checkVersion("4.4.0");
2928
3058
  await engine.pluginManager.register(e => {
2929
3059
  e.pluginManager.addParticleUpdater("opacity", container => {
2930
3060
  return Promise.resolve(new OpacityUpdater(container));
@@ -3269,7 +3399,7 @@
3269
3399
  }
3270
3400
 
3271
3401
  async function loadOutModesUpdater(engine) {
3272
- engine.checkVersion("4.3.1");
3402
+ engine.checkVersion("4.4.0");
3273
3403
  await engine.pluginManager.register(e => {
3274
3404
  e.pluginManager.addParticleUpdater("outModes", container => {
3275
3405
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -3340,7 +3470,7 @@
3340
3470
  }
3341
3471
 
3342
3472
  async function loadPaintUpdater(engine) {
3343
- engine.checkVersion("4.3.1");
3473
+ engine.checkVersion("4.4.0");
3344
3474
  await engine.pluginManager.register(e => {
3345
3475
  e.pluginManager.addParticleUpdater("paint", container => {
3346
3476
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -3395,7 +3525,7 @@
3395
3525
  }
3396
3526
 
3397
3527
  async function loadRgbColorPlugin(engine) {
3398
- engine.checkVersion("4.3.1");
3528
+ engine.checkVersion("4.4.0");
3399
3529
  await engine.pluginManager.register(e => {
3400
3530
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
3401
3531
  });
@@ -3480,7 +3610,7 @@
3480
3610
  }
3481
3611
 
3482
3612
  async function loadSizeUpdater(engine) {
3483
- engine.checkVersion("4.3.1");
3613
+ engine.checkVersion("4.4.0");
3484
3614
  await engine.pluginManager.register(e => {
3485
3615
  e.pluginManager.addParticleUpdater("size", container => {
3486
3616
  return Promise.resolve(new SizeUpdater(container));
@@ -3489,7 +3619,7 @@
3489
3619
  }
3490
3620
 
3491
3621
  async function loadBasic(engine) {
3492
- engine.checkVersion("4.3.1");
3622
+ engine.checkVersion("4.4.0");
3493
3623
  await engine.pluginManager.register(async (e) => {
3494
3624
  await Promise.all([
3495
3625
  loadBlendPlugin(e),
@@ -3820,7 +3950,7 @@
3820
3950
  }
3821
3951
 
3822
3952
  async function loadDestroyUpdater(engine) {
3823
- engine.checkVersion("4.3.1");
3953
+ engine.checkVersion("4.4.0");
3824
3954
  await engine.pluginManager.register(e => {
3825
3955
  e.pluginManager.addParticleUpdater("destroy", container => {
3826
3956
  return Promise.resolve(new DestroyUpdater(e.pluginManager, container));
@@ -4051,7 +4181,7 @@
4051
4181
  })(EmitterClickMode || (EmitterClickMode = {}));
4052
4182
 
4053
4183
  async function loadEmittersPluginSimple(engine) {
4054
- engine.checkVersion("4.3.1");
4184
+ engine.checkVersion("4.4.0");
4055
4185
  await engine.pluginManager.register(async (e) => {
4056
4186
  const instancesManager = await getEmittersInstancesManager(e);
4057
4187
  await addEmittersShapesManager(e);
@@ -4139,7 +4269,7 @@
4139
4269
  }
4140
4270
 
4141
4271
  async function loadEmittersShapeSquare(engine) {
4142
- engine.checkVersion("4.3.1");
4272
+ engine.checkVersion("4.4.0");
4143
4273
  await engine.pluginManager.register((e) => {
4144
4274
  ensureEmittersPluginLoaded(e);
4145
4275
  e.pluginManager.addEmitterShapeGenerator?.("square", new EmittersSquareShapeGenerator());
@@ -4283,7 +4413,7 @@
4283
4413
  }
4284
4414
 
4285
4415
  async function loadLifeUpdater(engine) {
4286
- engine.checkVersion("4.3.1");
4416
+ engine.checkVersion("4.4.0");
4287
4417
  await engine.pluginManager.register(e => {
4288
4418
  e.pluginManager.addParticleUpdater("life", container => {
4289
4419
  return Promise.resolve(new LifeUpdater(container));
@@ -4309,7 +4439,7 @@
4309
4439
  }
4310
4440
 
4311
4441
  async function loadLineShape(engine) {
4312
- engine.checkVersion("4.3.1");
4442
+ engine.checkVersion("4.4.0");
4313
4443
  await engine.pluginManager.register(e => {
4314
4444
  e.pluginManager.addShape(["line"], () => Promise.resolve(new LineDrawer()));
4315
4445
  });
@@ -4413,7 +4543,7 @@
4413
4543
  }
4414
4544
 
4415
4545
  async function loadRotateUpdater(engine) {
4416
- engine.checkVersion("4.3.1");
4546
+ engine.checkVersion("4.4.0");
4417
4547
  await engine.pluginManager.register(e => {
4418
4548
  e.pluginManager.addParticleUpdater("rotate", container => {
4419
4549
  return Promise.resolve(new RotateUpdater(container));
@@ -4729,7 +4859,7 @@
4729
4859
  }
4730
4860
 
4731
4861
  async function loadSoundsPlugin(engine) {
4732
- engine.checkVersion("4.3.1");
4862
+ engine.checkVersion("4.4.0");
4733
4863
  await engine.pluginManager.register(e => {
4734
4864
  e.pluginManager.addPlugin(new SoundsPlugin(e));
4735
4865
  });
@@ -4737,7 +4867,7 @@
4737
4867
 
4738
4868
  let initPromise = null;
4739
4869
  async function doInitPlugins(engine) {
4740
- engine.checkVersion("4.3.1");
4870
+ engine.checkVersion("4.4.0");
4741
4871
  await engine.pluginManager.register(async (e) => {
4742
4872
  const loadEmittersForFireworks = async (e) => {
4743
4873
  await loadEmittersPluginSimple(e);
@@ -4784,7 +4914,7 @@
4784
4914
  fireworks.init = async () => {
4785
4915
  await initPlugins(tsParticles);
4786
4916
  };
4787
- fireworks.version = "4.3.1";
4917
+ fireworks.version = "4.4.0";
4788
4918
  globalThis.fireworks = fireworks;
4789
4919
 
4790
4920
  const globalObject = globalThis;
@@ -4909,7 +5039,11 @@
4909
5039
  if (!fColor && !sColor) {
4910
5040
  return;
4911
5041
  }
4912
- 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;
5042
+ 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
5043
+ ? getStyleFromHsl(fColor, container.hdr, fillOpacity * opacity, container.peakNits, container.hdrMode)
5044
+ : undefined, stroke = sColor
5045
+ ? getStyleFromHsl(sColor, container.hdr, strokeOpacity * opacity, container.peakNits, container.hdrMode)
5046
+ : fill;
4913
5047
  transform.a = transform.b = transform.c = transform.d = undefined;
4914
5048
  colorStyles.fill = fill;
4915
5049
  colorStyles.stroke = stroke;
@@ -5243,7 +5377,9 @@
5243
5377
  if (typeof background.element === "string") {
5244
5378
  if (typeof document !== "undefined") {
5245
5379
  const node = document.querySelector(background.element);
5246
- if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
5380
+ if ((typeof HTMLCanvasElement !== "undefined" && node instanceof HTMLCanvasElement) ||
5381
+ (typeof HTMLVideoElement !== "undefined" && node instanceof HTMLVideoElement) ||
5382
+ (typeof HTMLImageElement !== "undefined" && node instanceof HTMLImageElement)) {
5247
5383
  this.#backgroundElement = node;
5248
5384
  }
5249
5385
  else if (node) {
@@ -5254,10 +5390,10 @@
5254
5390
  }
5255
5391
  }
5256
5392
  }
5257
- else if (background.element instanceof HTMLCanvasElement ||
5258
- background.element instanceof OffscreenCanvas ||
5259
- background.element instanceof HTMLVideoElement ||
5260
- background.element instanceof HTMLImageElement) {
5393
+ else if ((typeof HTMLCanvasElement !== "undefined" && background.element instanceof HTMLCanvasElement) ||
5394
+ (typeof OffscreenCanvas !== "undefined" && background.element instanceof OffscreenCanvas) ||
5395
+ (typeof HTMLVideoElement !== "undefined" && background.element instanceof HTMLVideoElement) ||
5396
+ (typeof HTMLImageElement !== "undefined" && background.element instanceof HTMLImageElement)) {
5261
5397
  this.#backgroundElement = background.element;
5262
5398
  }
5263
5399
  }
@@ -5325,6 +5461,7 @@
5325
5461
  zoom = defaultZoom;
5326
5462
  #container;
5327
5463
  #generated;
5464
+ #hdrMediaListeners;
5328
5465
  #mutationObserver;
5329
5466
  #originalStyle;
5330
5467
  #pluginManager;
@@ -5389,7 +5526,6 @@
5389
5526
  });
5390
5527
  this.resize();
5391
5528
  this.#initStyle();
5392
- this.initBackground();
5393
5529
  this.#safeMutationObserver(obs => {
5394
5530
  const element = this.domElement;
5395
5531
  if (!element || !(element instanceof Node)) {
@@ -5399,6 +5535,8 @@
5399
5535
  });
5400
5536
  this.initPlugins();
5401
5537
  this.#initContext();
5538
+ this.initBackground();
5539
+ this.#initHdrListeners();
5402
5540
  this.render.init();
5403
5541
  }
5404
5542
  initBackground() {
@@ -5408,7 +5546,8 @@
5408
5546
  }
5409
5547
  const elementStyle = element.style, color = rangeColorToRgb(this.#pluginManager, background.color);
5410
5548
  if (color) {
5411
- elementStyle.backgroundColor = getStyleFromRgb(color, container.actualOptions.hdr, background.opacity);
5549
+ const hdrOptions = container.actualOptions.hdr;
5550
+ elementStyle.backgroundColor = getStyleFromRgb(color, container.hdr, background.opacity, hdrOptions.peakNits, hdrOptions.mode);
5412
5551
  }
5413
5552
  else {
5414
5553
  elementStyle.backgroundColor = "";
@@ -5505,6 +5644,7 @@
5505
5644
  obs.disconnect();
5506
5645
  });
5507
5646
  this.#mutationObserver = undefined;
5647
+ this.#removeHdrListeners();
5508
5648
  this.render.stop();
5509
5649
  }
5510
5650
  async windowResize() {
@@ -5524,9 +5664,16 @@
5524
5664
  }
5525
5665
  }
5526
5666
  #initContext() {
5527
- const container = this.#container, canSupportHdr = container.actualOptions.hdr &&
5667
+ const container = this.#container, canSupportHdr = container.actualOptions.hdr.enable &&
5528
5668
  safeMatchMedia("(color-gamut: p3)")?.matches &&
5529
5669
  safeMatchMedia("(dynamic-range: high)")?.matches;
5670
+ container.hdr = canSupportHdr ?? false;
5671
+ container.hdrMode = container.actualOptions.hdr.mode;
5672
+ container.peakNits = container.actualOptions.hdr.peakNits;
5673
+ const renderCanvas = this.renderCanvas;
5674
+ if (!renderCanvas) {
5675
+ return;
5676
+ }
5530
5677
  this.render.setContextSettings({
5531
5678
  alpha: true,
5532
5679
  desynchronized: true,
@@ -5535,11 +5682,47 @@
5535
5682
  ? { colorSpace: "display-p3", colorType: "float16" }
5536
5683
  : { colorSpace: "srgb" }),
5537
5684
  });
5538
- const renderCanvas = this.renderCanvas;
5539
- if (!renderCanvas) {
5540
- return;
5685
+ let context;
5686
+ try {
5687
+ context = renderCanvas.getContext("2d", this.render.settings);
5688
+ }
5689
+ catch {
5690
+ context = null;
5691
+ }
5692
+ if (canSupportHdr && !context) {
5693
+ container.hdr = false;
5694
+ const sdrSettings = {
5695
+ alpha: true,
5696
+ desynchronized: true,
5697
+ willReadFrequently: false,
5698
+ colorSpace: "srgb",
5699
+ };
5700
+ this.render.setContextSettings(sdrSettings);
5701
+ try {
5702
+ context = renderCanvas.getContext("2d", sdrSettings);
5703
+ }
5704
+ catch {
5705
+ context = null;
5706
+ }
5541
5707
  }
5542
- this.render.setContext(renderCanvas.getContext("2d", this.render.settings));
5708
+ this.render.setContext(context);
5709
+ }
5710
+ #initHdrListeners() {
5711
+ this.#removeHdrListeners();
5712
+ const p3Query = safeMatchMedia("(color-gamut: p3)"), hdrQuery = safeMatchMedia("(dynamic-range: high)"), handleChange = () => {
5713
+ this.#recreateRenderCanvas();
5714
+ this.#initContext();
5715
+ this.initBackground();
5716
+ }, listeners = [];
5717
+ if (p3Query) {
5718
+ p3Query.addEventListener("change", handleChange);
5719
+ listeners.push({ handler: handleChange, mql: p3Query });
5720
+ }
5721
+ if (hdrQuery) {
5722
+ hdrQuery.addEventListener("change", handleChange);
5723
+ listeners.push({ handler: handleChange, mql: hdrQuery });
5724
+ }
5725
+ this.#hdrMediaListeners = listeners;
5543
5726
  }
5544
5727
  #initStyle() {
5545
5728
  const element = this.domElement, options = this.#container.actualOptions;
@@ -5563,6 +5746,25 @@
5563
5746
  element.style.setProperty(key, value, "important");
5564
5747
  }
5565
5748
  }
5749
+ #recreateRenderCanvas() {
5750
+ const renderCanvas = this.renderCanvas;
5751
+ if (!renderCanvas) {
5752
+ return;
5753
+ }
5754
+ if (this.domElement) {
5755
+ return;
5756
+ }
5757
+ this.renderCanvas = new OffscreenCanvas(renderCanvas.width, renderCanvas.height);
5758
+ }
5759
+ #removeHdrListeners() {
5760
+ if (!this.#hdrMediaListeners) {
5761
+ return;
5762
+ }
5763
+ for (const { handler, mql } of this.#hdrMediaListeners) {
5764
+ mql.removeEventListener("change", handler);
5765
+ }
5766
+ this.#hdrMediaListeners = undefined;
5767
+ }
5566
5768
  #repairStyle() {
5567
5769
  const element = this.domElement;
5568
5770
  if (!element) {
@@ -5947,9 +6149,9 @@
5947
6149
  }
5948
6150
  getOpacity() {
5949
6151
  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;
5950
- this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
6152
+ this.#cachedOpacityData.fillOpacity = fillOpacity;
5951
6153
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
5952
- this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
6154
+ this.#cachedOpacityData.strokeOpacity = strokeOpacity;
5953
6155
  return this.#cachedOpacityData;
5954
6156
  }
5955
6157
  getPosition() {
@@ -6804,6 +7006,7 @@
6804
7006
  effectDrawers;
6805
7007
  fpsLimit;
6806
7008
  hdr;
7009
+ hdrMode;
6807
7010
  id;
6808
7011
  pageHidden;
6809
7012
  particleCreatedPlugins;
@@ -6811,6 +7014,7 @@
6811
7014
  particlePositionPlugins;
6812
7015
  particleUpdaters;
6813
7016
  particles;
7017
+ peakNits;
6814
7018
  plugins;
6815
7019
  retina;
6816
7020
  shapeDrawers;
@@ -6841,6 +7045,8 @@
6841
7045
  this.id = Symbol(id);
6842
7046
  this.fpsLimit = 120;
6843
7047
  this.hdr = false;
7048
+ this.hdrMode = exports.HdrMode.standard;
7049
+ this.peakNits = 400;
6844
7050
  this.#smooth = false;
6845
7051
  this.#delay = 0;
6846
7052
  this.#duration = 0;
@@ -6980,8 +7186,9 @@
6980
7186
  this.updateActualOptions();
6981
7187
  this.canvas.initBackground();
6982
7188
  this.canvas.resize();
6983
- const { delay, duration, fpsLimit, hdr, smooth, zLayers } = this.actualOptions;
6984
- this.hdr = hdr;
7189
+ const { delay, duration, fpsLimit, smooth, zLayers } = this.actualOptions, hdrOptions = this.actualOptions.hdr;
7190
+ this.hdrMode = hdrOptions.mode;
7191
+ this.peakNits = hdrOptions.peakNits;
6985
7192
  this.zLayers = zLayers;
6986
7193
  this.#duration = getRangeValue(duration) * millisecondsToSeconds;
6987
7194
  this.#delay = getRangeValue(delay) * millisecondsToSeconds;
@@ -8403,6 +8610,7 @@
8403
8610
  exports.ColorAnimation = ColorAnimation;
8404
8611
  exports.Fill = Fill;
8405
8612
  exports.FullScreen = FullScreen;
8613
+ exports.HDROptions = HDROptions;
8406
8614
  exports.HslAnimation = HslAnimation;
8407
8615
  exports.Move = Move;
8408
8616
  exports.MoveAngle = MoveAngle;