@tsparticles/preset-confetti 4.2.1 → 4.3.1

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.2.1 */
2
+ /* Preset v4.3.1 */
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) :
@@ -371,29 +371,27 @@
371
371
  }
372
372
  }
373
373
  else if (!isObject(destination) || Array.isArray(destination)) {
374
- destination = {};
374
+ destination = Object.create(null);
375
375
  }
376
- const sourceKeys = Object.keys(source), dangerousKeys = new Set(["__proto__", "constructor", "prototype"]), hasNested = sourceKeys.some(k => {
376
+ const sourceKeys = Object.keys(source), hasNested = sourceKeys.some(k => {
377
377
  const v = source[k];
378
378
  return isObject(v) || Array.isArray(v);
379
379
  });
380
380
  if (!hasNested) {
381
381
  const sourceDict = source, destDict = destination;
382
382
  for (const key of sourceKeys) {
383
- if (dangerousKeys.has(key)) {
383
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
384
384
  continue;
385
385
  }
386
- if (key in sourceDict) {
387
- const v = sourceDict[key];
388
- if (v !== undefined) {
389
- destDict[key] = v;
390
- }
386
+ const v = sourceDict[key];
387
+ if (v !== undefined) {
388
+ destDict[key] = v;
391
389
  }
392
390
  }
393
391
  continue;
394
392
  }
395
393
  for (const key of sourceKeys) {
396
- if (dangerousKeys.has(key)) {
394
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
397
395
  continue;
398
396
  }
399
397
  const sourceDict = source, destDict = destination, value = sourceDict[key];
@@ -809,7 +807,7 @@
809
807
  return this.#domArray;
810
808
  }
811
809
  get version() {
812
- return "4.2.1";
810
+ return "4.3.1";
813
811
  }
814
812
  addEventListener(type, listener) {
815
813
  this.#eventDispatcher.addEventListener(type, listener);
@@ -1042,6 +1040,18 @@
1042
1040
  AnimationStatus["decreasing"] = "decreasing";
1043
1041
  })(AnimationStatus || (AnimationStatus = {}));
1044
1042
 
1043
+ var DrawLayer;
1044
+ (function (DrawLayer) {
1045
+ DrawLayer[DrawLayer["BackgroundElement"] = 0] = "BackgroundElement";
1046
+ DrawLayer[DrawLayer["BackgroundDraw"] = 1] = "BackgroundDraw";
1047
+ DrawLayer[DrawLayer["BackgroundMask"] = 2] = "BackgroundMask";
1048
+ DrawLayer[DrawLayer["CanvasSetup"] = 3] = "CanvasSetup";
1049
+ DrawLayer[DrawLayer["PluginContent"] = 4] = "PluginContent";
1050
+ DrawLayer[DrawLayer["Particles"] = 5] = "Particles";
1051
+ DrawLayer[DrawLayer["CanvasCleanup"] = 6] = "CanvasCleanup";
1052
+ DrawLayer[DrawLayer["Foreground"] = 7] = "Foreground";
1053
+ })(DrawLayer || (DrawLayer = {}));
1054
+
1045
1055
  class OptionLoader {
1046
1056
  load(data) {
1047
1057
  if (isNull(data)) {
@@ -1195,6 +1205,8 @@
1195
1205
 
1196
1206
  class Background extends OptionLoader {
1197
1207
  color;
1208
+ draw;
1209
+ element;
1198
1210
  image = "";
1199
1211
  opacity = 1;
1200
1212
  position = "";
@@ -1209,6 +1221,8 @@
1209
1221
  if (data.color !== undefined) {
1210
1222
  this.color = OptionsColor.create(this.color, data.color);
1211
1223
  }
1224
+ loadProperty(this, "element", data.element);
1225
+ loadProperty(this, "draw", data.draw);
1212
1226
  loadProperty(this, "image", data.image);
1213
1227
  loadProperty(this, "position", data.position);
1214
1228
  loadProperty(this, "repeat", data.repeat);
@@ -1754,7 +1768,7 @@
1754
1768
  }
1755
1769
  }
1756
1770
 
1757
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
1771
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1758
1772
  function getCachedStyle(key, generator) {
1759
1773
  let cached = styleCache.get(key);
1760
1774
  if (!cached) {
@@ -1894,6 +1908,17 @@
1894
1908
  : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized - phaseThird));
1895
1909
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
1896
1910
  }
1911
+ function hslToRgbFloat(hsl) {
1912
+ const h = ((hsl.h % hMax) + hMax) % hMax, s = Math.max(sMin, Math.min(sMax, hsl.s)), l = Math.max(lMin, Math.min(lMax, hsl.l)), hNormalized = h / hMax, sNormalized = s / sMax, lNormalized = l / lMax;
1913
+ if (s === sMin) {
1914
+ const grayscaleValue = lNormalized * rgbMax;
1915
+ return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
1916
+ }
1917
+ const temp1 = lNormalized < half
1918
+ ? lNormalized * (sNormalizedOffset + sNormalized)
1919
+ : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized)), blue = Math.min(rgbMax, rgbMax * hslChannel(temp2, temp1, hNormalized - phaseThird));
1920
+ return { r: red, g: green, b: blue };
1921
+ }
1897
1922
  function hslaToRgba(hsla) {
1898
1923
  const rgbResult = hslToRgb(hsla);
1899
1924
  return {
@@ -1903,8 +1928,9 @@
1903
1928
  r: rgbResult.r,
1904
1929
  };
1905
1930
  }
1906
- function getRandomRgbColor(min) {
1907
- const fixedMin = defaultRgbMin, fixedMax = rgbMax + identity$2, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1931
+ function getRandomRgbColor(min, hdr) {
1932
+ const fixedMin = defaultRgbMin;
1933
+ const fixedMax = rgbMax + identity$2, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1908
1934
  return {
1909
1935
  b: getRgbInRangeValue(),
1910
1936
  g: getRgbInRangeValue(),
@@ -1912,7 +1938,7 @@
1912
1938
  };
1913
1939
  }
1914
1940
  function getStyleFromRgb(color, hdr, opacity) {
1915
- const op = opacity ?? defaultOpacity$1, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
1941
+ 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()}`;
1916
1942
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
1917
1943
  }
1918
1944
  function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
@@ -1923,9 +1949,9 @@
1923
1949
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$1).toString()})`;
1924
1950
  }
1925
1951
  function getStyleFromHsl(color, hdr, opacity) {
1926
- const op = opacity ?? defaultOpacity$1, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
1952
+ 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()}`;
1927
1953
  return getCachedStyle(key, () => hdr
1928
- ? getStyleFromRgb(hslToRgb(color), true, opacity)
1954
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
1929
1955
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
1930
1956
  }
1931
1957
  function getHslFromAnimation(animation) {
@@ -1988,7 +2014,7 @@
1988
2014
  colorValue.velocity = defaultVelocity;
1989
2015
  }
1990
2016
  }
1991
- function updateColorValue(data, decrease, delta) {
2017
+ function updateColorValue(data, decrease, delta, hdr) {
1992
2018
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
1993
2019
  if (!data.enable ||
1994
2020
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2001,7 +2027,7 @@
2001
2027
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2002
2028
  return;
2003
2029
  }
2004
- 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;
2030
+ 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;
2005
2031
  if (!decrease || data.status === AnimationStatus.increasing) {
2006
2032
  data.value += velocity;
2007
2033
  if (data.value > max) {
@@ -2028,14 +2054,14 @@
2028
2054
  }
2029
2055
  data.value = clamp(data.value, min, max);
2030
2056
  }
2031
- function updateColor(color, delta) {
2057
+ function updateColor(color, delta, hdr) {
2032
2058
  if (!color) {
2033
2059
  return;
2034
2060
  }
2035
2061
  const { h, s, l } = color;
2036
- updateColorValue(h, false, delta);
2037
- updateColorValue(s, true, delta);
2038
- updateColorValue(l, true, delta);
2062
+ updateColorValue(h, false, delta, hdr);
2063
+ updateColorValue(s, true, delta, hdr);
2064
+ updateColorValue(l, true, delta, hdr);
2039
2065
  }
2040
2066
  function alterHsl(color, type, value) {
2041
2067
  return {
@@ -2085,7 +2111,7 @@
2085
2111
  }
2086
2112
 
2087
2113
  async function loadBlendPlugin(engine) {
2088
- engine.checkVersion("4.2.1");
2114
+ engine.checkVersion("4.3.1");
2089
2115
  await engine.pluginManager.register(e => {
2090
2116
  e.pluginManager.addPlugin(new BlendPlugin());
2091
2117
  });
@@ -2122,7 +2148,7 @@
2122
2148
  }
2123
2149
 
2124
2150
  async function loadCircleShape(engine) {
2125
- engine.checkVersion("4.2.1");
2151
+ engine.checkVersion("4.3.1");
2126
2152
  await engine.pluginManager.register(e => {
2127
2153
  e.pluginManager.addShape(["circle"], () => {
2128
2154
  return Promise.resolve(new CircleDrawer());
@@ -2170,7 +2196,7 @@
2170
2196
  }
2171
2197
 
2172
2198
  async function loadHexColorPlugin(engine) {
2173
- engine.checkVersion("4.2.1");
2199
+ engine.checkVersion("4.3.1");
2174
2200
  await engine.pluginManager.register(e => {
2175
2201
  e.pluginManager.addColorManager("hex", new HexColorManager());
2176
2202
  });
@@ -2223,7 +2249,7 @@
2223
2249
  }
2224
2250
 
2225
2251
  async function loadHslColorPlugin(engine) {
2226
- engine.checkVersion("4.2.1");
2252
+ engine.checkVersion("4.3.1");
2227
2253
  await engine.pluginManager.register(e => {
2228
2254
  e.pluginManager.addColorManager("hsl", new HslColorManager());
2229
2255
  });
@@ -2247,7 +2273,7 @@
2247
2273
  }
2248
2274
 
2249
2275
  async function loadMovePlugin(engine) {
2250
- engine.checkVersion("4.2.1");
2276
+ engine.checkVersion("4.3.1");
2251
2277
  await engine.pluginManager.register(e => {
2252
2278
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
2253
2279
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -2463,7 +2489,7 @@
2463
2489
  }
2464
2490
 
2465
2491
  async function loadOpacityUpdater(engine) {
2466
- engine.checkVersion("4.2.1");
2492
+ engine.checkVersion("4.3.1");
2467
2493
  await engine.pluginManager.register(e => {
2468
2494
  e.pluginManager.addParticleUpdater("opacity", container => {
2469
2495
  return Promise.resolve(new OpacityUpdater(container));
@@ -2808,7 +2834,7 @@
2808
2834
  }
2809
2835
 
2810
2836
  async function loadOutModesUpdater(engine) {
2811
- engine.checkVersion("4.2.1");
2837
+ engine.checkVersion("4.3.1");
2812
2838
  await engine.pluginManager.register(e => {
2813
2839
  e.pluginManager.addParticleUpdater("outModes", container => {
2814
2840
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -2873,13 +2899,13 @@
2873
2899
  if (!this.isEnabled(particle)) {
2874
2900
  return;
2875
2901
  }
2876
- updateColor(particle.fillColor, delta);
2877
- updateColor(particle.strokeColor, delta);
2902
+ updateColor(particle.fillColor, delta, this.#container.hdr);
2903
+ updateColor(particle.strokeColor, delta, this.#container.hdr);
2878
2904
  }
2879
2905
  }
2880
2906
 
2881
2907
  async function loadPaintUpdater(engine) {
2882
- engine.checkVersion("4.2.1");
2908
+ engine.checkVersion("4.3.1");
2883
2909
  await engine.pluginManager.register(e => {
2884
2910
  e.pluginManager.addParticleUpdater("paint", container => {
2885
2911
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -2934,7 +2960,7 @@
2934
2960
  }
2935
2961
 
2936
2962
  async function loadRgbColorPlugin(engine) {
2937
- engine.checkVersion("4.2.1");
2963
+ engine.checkVersion("4.3.1");
2938
2964
  await engine.pluginManager.register(e => {
2939
2965
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
2940
2966
  });
@@ -3019,7 +3045,7 @@
3019
3045
  }
3020
3046
 
3021
3047
  async function loadSizeUpdater(engine) {
3022
- engine.checkVersion("4.2.1");
3048
+ engine.checkVersion("4.3.1");
3023
3049
  await engine.pluginManager.register(e => {
3024
3050
  e.pluginManager.addParticleUpdater("size", container => {
3025
3051
  return Promise.resolve(new SizeUpdater(container));
@@ -3028,7 +3054,7 @@
3028
3054
  }
3029
3055
 
3030
3056
  async function loadBasic(engine) {
3031
- engine.checkVersion("4.2.1");
3057
+ engine.checkVersion("4.3.1");
3032
3058
  await engine.pluginManager.register(async (e) => {
3033
3059
  await Promise.all([
3034
3060
  loadBlendPlugin(e),
@@ -3281,7 +3307,7 @@
3281
3307
  })(EmitterClickMode || (EmitterClickMode = {}));
3282
3308
 
3283
3309
  async function loadEmittersPluginSimple(engine) {
3284
- engine.checkVersion("4.2.1");
3310
+ engine.checkVersion("4.3.1");
3285
3311
  await engine.pluginManager.register(async (e) => {
3286
3312
  const instancesManager = await getEmittersInstancesManager(e);
3287
3313
  await addEmittersShapesManager(e);
@@ -3426,7 +3452,7 @@
3426
3452
  }
3427
3453
 
3428
3454
  async function loadLifeUpdater(engine) {
3429
- engine.checkVersion("4.2.1");
3455
+ engine.checkVersion("4.3.1");
3430
3456
  await engine.pluginManager.register(e => {
3431
3457
  e.pluginManager.addParticleUpdater("life", container => {
3432
3458
  return Promise.resolve(new LifeUpdater(container));
@@ -3480,7 +3506,7 @@
3480
3506
  }
3481
3507
 
3482
3508
  async function loadMotionPlugin(engine) {
3483
- engine.checkVersion("4.2.1");
3509
+ engine.checkVersion("4.3.1");
3484
3510
  await engine.pluginManager.register(e => {
3485
3511
  e.pluginManager.addPlugin(new MotionPlugin());
3486
3512
  });
@@ -3613,7 +3639,7 @@
3613
3639
  }
3614
3640
 
3615
3641
  async function loadRollUpdater(engine) {
3616
- engine.checkVersion("4.2.1");
3642
+ engine.checkVersion("4.3.1");
3617
3643
  await engine.pluginManager.register(e => {
3618
3644
  e.pluginManager.addParticleUpdater("roll", () => {
3619
3645
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -3719,7 +3745,7 @@
3719
3745
  }
3720
3746
 
3721
3747
  async function loadRotateUpdater(engine) {
3722
- engine.checkVersion("4.2.1");
3748
+ engine.checkVersion("4.3.1");
3723
3749
  await engine.pluginManager.register(e => {
3724
3750
  e.pluginManager.addParticleUpdater("rotate", container => {
3725
3751
  return Promise.resolve(new RotateUpdater(container));
@@ -3743,7 +3769,7 @@
3743
3769
  }
3744
3770
 
3745
3771
  async function loadSquareShape(engine) {
3746
- engine.checkVersion("4.2.1");
3772
+ engine.checkVersion("4.3.1");
3747
3773
  await engine.pluginManager.register(e => {
3748
3774
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
3749
3775
  });
@@ -3852,7 +3878,7 @@
3852
3878
  }
3853
3879
 
3854
3880
  async function loadTiltUpdater(engine) {
3855
- engine.checkVersion("4.2.1");
3881
+ engine.checkVersion("4.3.1");
3856
3882
  await engine.pluginManager.register(e => {
3857
3883
  e.pluginManager.addParticleUpdater("tilt", container => {
3858
3884
  return Promise.resolve(new TiltUpdater(container));
@@ -3954,7 +3980,7 @@
3954
3980
  }
3955
3981
 
3956
3982
  async function loadWobbleUpdater(engine) {
3957
- engine.checkVersion("4.2.1");
3983
+ engine.checkVersion("4.3.1");
3958
3984
  await engine.pluginManager.register(e => {
3959
3985
  e.pluginManager.addParticleUpdater("wobble", container => {
3960
3986
  return Promise.resolve(new WobbleUpdater(container));
@@ -4123,10 +4149,10 @@
4123
4149
  }
4124
4150
  }
4125
4151
  class RenderManager {
4152
+ #backgroundElement;
4153
+ #backgroundWarnings;
4126
4154
  #canvasClearPlugins;
4127
4155
  #canvasManager;
4128
- #canvasPaintPlugins;
4129
- #clearDrawPlugins;
4130
4156
  #colorPlugins;
4131
4157
  #container;
4132
4158
  #context;
@@ -4134,9 +4160,7 @@
4134
4160
  #drawParticlePlugins;
4135
4161
  #drawParticlesCleanupPlugins;
4136
4162
  #drawParticlesSetupPlugins;
4137
- #drawPlugins;
4138
- #drawSettingsCleanupPlugins;
4139
- #drawSettingsSetupPlugins;
4163
+ #layers;
4140
4164
  #pluginManager;
4141
4165
  #postDrawUpdaters;
4142
4166
  #preDrawUpdaters;
@@ -4148,18 +4172,25 @@
4148
4172
  this.#container = container;
4149
4173
  this.#canvasManager = canvasManager;
4150
4174
  this.#context = null;
4175
+ this.#backgroundElement = null;
4176
+ this.#backgroundWarnings = new Set();
4151
4177
  this.#preDrawUpdaters = [];
4152
4178
  this.#postDrawUpdaters = [];
4153
- this.#colorPlugins = [];
4154
4179
  this.#canvasClearPlugins = [];
4155
- this.#canvasPaintPlugins = [];
4156
- this.#clearDrawPlugins = [];
4180
+ this.#colorPlugins = [];
4157
4181
  this.#drawParticlePlugins = [];
4158
4182
  this.#drawParticlesCleanupPlugins = [];
4159
4183
  this.#drawParticlesSetupPlugins = [];
4160
- this.#drawPlugins = [];
4161
- this.#drawSettingsSetupPlugins = [];
4162
- this.#drawSettingsCleanupPlugins = [];
4184
+ this.#layers = {
4185
+ 0: [],
4186
+ 1: [],
4187
+ 2: [],
4188
+ 3: [],
4189
+ 4: [],
4190
+ 5: [],
4191
+ 6: [],
4192
+ 7: [],
4193
+ };
4163
4194
  }
4164
4195
  get settings() {
4165
4196
  return this.#contextSettings;
@@ -4173,32 +4204,38 @@
4173
4204
  });
4174
4205
  }
4175
4206
  clear() {
4176
- let pluginHandled = false;
4177
4207
  for (const plugin of this.#canvasClearPlugins) {
4178
- pluginHandled = plugin.canvasClear?.() ?? false;
4179
- if (pluginHandled) {
4180
- break;
4208
+ if (plugin.canvasClear?.() ?? false) {
4209
+ return;
4181
4210
  }
4182
4211
  }
4183
- if (pluginHandled) {
4184
- return;
4212
+ for (const layer of Object.values(DrawLayer)) {
4213
+ if (typeof layer === "number") {
4214
+ for (const plugin of this.#getLayerPlugins(layer)) {
4215
+ if (plugin.canvasClear?.() ?? false) {
4216
+ return;
4217
+ }
4218
+ }
4219
+ }
4185
4220
  }
4186
4221
  this.canvasClear();
4187
4222
  }
4188
4223
  destroy() {
4189
4224
  this.stop();
4225
+ this.#backgroundElement = null;
4226
+ this.#backgroundWarnings.clear();
4190
4227
  this.#preDrawUpdaters = [];
4191
4228
  this.#postDrawUpdaters = [];
4192
- this.#colorPlugins = [];
4193
4229
  this.#canvasClearPlugins = [];
4194
- this.#canvasPaintPlugins = [];
4195
- this.#clearDrawPlugins = [];
4230
+ this.#colorPlugins = [];
4196
4231
  this.#drawParticlePlugins = [];
4197
4232
  this.#drawParticlesCleanupPlugins = [];
4198
4233
  this.#drawParticlesSetupPlugins = [];
4199
- this.#drawPlugins = [];
4200
- this.#drawSettingsSetupPlugins = [];
4201
- this.#drawSettingsCleanupPlugins = [];
4234
+ for (const layer of Object.values(DrawLayer)) {
4235
+ if (typeof layer === "number") {
4236
+ this.#layers[layer] = [];
4237
+ }
4238
+ }
4202
4239
  }
4203
4240
  draw(cb) {
4204
4241
  const ctx = this.#context;
@@ -4255,21 +4292,40 @@
4255
4292
  });
4256
4293
  }
4257
4294
  drawParticles(delta) {
4258
- const { particles } = this.#container;
4295
+ const { particles, actualOptions } = this.#container;
4259
4296
  this.clear();
4260
4297
  particles.update(delta);
4261
4298
  this.draw(ctx => {
4262
- for (const plugin of this.#drawSettingsSetupPlugins) {
4299
+ const width = this.#canvasManager.size.width, height = this.#canvasManager.size.height;
4300
+ if (this.#backgroundElement) {
4301
+ try {
4302
+ ctx.drawImage(this.#backgroundElement, originPoint.x, originPoint.y, width, height);
4303
+ }
4304
+ catch {
4305
+ this.#warnOnce("background-element-draw-error", "Error drawing background element onto canvas");
4306
+ }
4307
+ }
4308
+ const background = actualOptions.background;
4309
+ if (background.draw) {
4310
+ try {
4311
+ background.draw(ctx, delta);
4312
+ }
4313
+ catch {
4314
+ this.#warnOnce("background-draw-error", "Error in background.draw callback");
4315
+ }
4316
+ }
4317
+ for (const plugin of this.#getLayerPlugins(DrawLayer.BackgroundMask)) {
4318
+ plugin.canvasPaint?.();
4319
+ }
4320
+ for (const plugin of this.#getLayerPlugins(DrawLayer.CanvasSetup)) {
4263
4321
  plugin.drawSettingsSetup?.(ctx, delta);
4264
4322
  }
4265
- for (const plugin of this.#drawPlugins) {
4323
+ for (const plugin of this.#getLayerPlugins(DrawLayer.PluginContent)) {
4266
4324
  plugin.draw?.(ctx, delta);
4267
4325
  }
4268
4326
  particles.drawParticles(delta);
4269
- for (const plugin of this.#clearDrawPlugins) {
4327
+ for (const plugin of this.#getLayerPlugins(DrawLayer.CanvasCleanup)) {
4270
4328
  plugin.clearDraw?.(ctx, delta);
4271
- }
4272
- for (const plugin of this.#drawSettingsCleanupPlugins) {
4273
4329
  plugin.drawSettingsCleanup?.(ctx, delta);
4274
4330
  }
4275
4331
  });
@@ -4277,29 +4333,24 @@
4277
4333
  init() {
4278
4334
  this.initUpdaters();
4279
4335
  this.initPlugins();
4336
+ this.#resolveBackgroundElement();
4280
4337
  this.paint();
4281
4338
  }
4282
4339
  initPlugins() {
4283
- this.#colorPlugins = [];
4284
4340
  this.#canvasClearPlugins = [];
4285
- this.#canvasPaintPlugins = [];
4286
- this.#clearDrawPlugins = [];
4341
+ this.#colorPlugins = [];
4287
4342
  this.#drawParticlePlugins = [];
4288
4343
  this.#drawParticlesSetupPlugins = [];
4289
4344
  this.#drawParticlesCleanupPlugins = [];
4290
- this.#drawPlugins = [];
4291
- this.#drawSettingsSetupPlugins = [];
4292
- this.#drawSettingsCleanupPlugins = [];
4345
+ for (const layer of Object.values(DrawLayer)) {
4346
+ if (typeof layer === "number") {
4347
+ this.#layers[layer] = [];
4348
+ }
4349
+ }
4293
4350
  for (const plugin of this.#container.plugins) {
4294
4351
  if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
4295
4352
  this.#colorPlugins.push(plugin);
4296
4353
  }
4297
- if (plugin.canvasClear) {
4298
- this.#canvasClearPlugins.push(plugin);
4299
- }
4300
- if (plugin.canvasPaint) {
4301
- this.#canvasPaintPlugins.push(plugin);
4302
- }
4303
4354
  if (plugin.drawParticle) {
4304
4355
  this.#drawParticlePlugins.push(plugin);
4305
4356
  }
@@ -4309,17 +4360,20 @@
4309
4360
  if (plugin.drawParticleCleanup) {
4310
4361
  this.#drawParticlesCleanupPlugins.push(plugin);
4311
4362
  }
4312
- if (plugin.draw) {
4313
- this.#drawPlugins.push(plugin);
4363
+ if (plugin.canvasClear) {
4364
+ this.#canvasClearPlugins.push(plugin);
4365
+ }
4366
+ if (plugin.canvasPaint) {
4367
+ this.#getLayerPlugins(DrawLayer.BackgroundMask).push(plugin);
4314
4368
  }
4315
4369
  if (plugin.drawSettingsSetup) {
4316
- this.#drawSettingsSetupPlugins.push(plugin);
4370
+ this.#getLayerPlugins(DrawLayer.CanvasSetup).push(plugin);
4317
4371
  }
4318
- if (plugin.drawSettingsCleanup) {
4319
- this.#drawSettingsCleanupPlugins.push(plugin);
4372
+ if (plugin.draw) {
4373
+ this.#getLayerPlugins(DrawLayer.PluginContent).push(plugin);
4320
4374
  }
4321
- if (plugin.clearDraw) {
4322
- this.#clearDrawPlugins.push(plugin);
4375
+ if (plugin.clearDraw ?? plugin.drawSettingsCleanup) {
4376
+ this.#getLayerPlugins(DrawLayer.CanvasCleanup).push(plugin);
4323
4377
  }
4324
4378
  }
4325
4379
  }
@@ -4337,7 +4391,7 @@
4337
4391
  }
4338
4392
  paint() {
4339
4393
  let handled = false;
4340
- for (const plugin of this.#canvasPaintPlugins) {
4394
+ for (const plugin of this.#getLayerPlugins(DrawLayer.BackgroundMask)) {
4341
4395
  handled = plugin.canvasPaint?.() ?? false;
4342
4396
  if (handled) {
4343
4397
  break;
@@ -4510,6 +4564,9 @@
4510
4564
  }
4511
4565
  drawer.beforeDraw(data);
4512
4566
  }
4567
+ #getLayerPlugins(layer) {
4568
+ return this.#layers[layer];
4569
+ }
4513
4570
  #getPluginParticleColors(particle) {
4514
4571
  let fColor, sColor;
4515
4572
  for (const plugin of this.#colorPlugins) {
@@ -4527,6 +4584,39 @@
4527
4584
  this.#reusablePluginColors[sColorIndex] = sColor;
4528
4585
  return this.#reusablePluginColors;
4529
4586
  }
4587
+ #resolveBackgroundElement() {
4588
+ const background = this.#container.actualOptions.background;
4589
+ this.#backgroundElement = null;
4590
+ if (!background.element) {
4591
+ return;
4592
+ }
4593
+ if (typeof background.element === "string") {
4594
+ if (typeof document !== "undefined") {
4595
+ const node = document.querySelector(background.element);
4596
+ if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
4597
+ this.#backgroundElement = node;
4598
+ }
4599
+ else if (node) {
4600
+ this.#warnOnce("background-element-not-supported", `Background element "${background.element}" is not a supported drawable element (canvas, video, or img)`);
4601
+ }
4602
+ else {
4603
+ this.#warnOnce("background-element-not-found", `Background element selector "${background.element}" not found`);
4604
+ }
4605
+ }
4606
+ }
4607
+ else if (background.element instanceof HTMLCanvasElement ||
4608
+ background.element instanceof OffscreenCanvas ||
4609
+ background.element instanceof HTMLVideoElement ||
4610
+ background.element instanceof HTMLImageElement) {
4611
+ this.#backgroundElement = background.element;
4612
+ }
4613
+ }
4614
+ #warnOnce(key, message) {
4615
+ if (!this.#backgroundWarnings.has(key)) {
4616
+ this.#backgroundWarnings.add(key);
4617
+ getLogger().warning(message);
4618
+ }
4619
+ }
4530
4620
  }
4531
4621
 
4532
4622
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -5103,7 +5193,6 @@
5103
5193
  }
5104
5194
  class Particle {
5105
5195
  backColor;
5106
- bubble;
5107
5196
  destroyed;
5108
5197
  direction;
5109
5198
  effect;
@@ -5137,7 +5226,6 @@
5137
5226
  shapeData;
5138
5227
  sides;
5139
5228
  size;
5140
- slow;
5141
5229
  spawning;
5142
5230
  strokeColor;
5143
5231
  strokeOpacity;
@@ -5159,18 +5247,25 @@
5159
5247
  d: 1,
5160
5248
  };
5161
5249
  #container;
5250
+ #modifiers = [];
5162
5251
  #pluginManager;
5163
5252
  constructor(pluginManager, container) {
5164
5253
  this.#pluginManager = pluginManager;
5165
5254
  this.#container = container;
5166
5255
  }
5256
+ addModifier(modifier) {
5257
+ this.#modifiers.push(modifier);
5258
+ this.#modifiers.sort((a, b) => a.priority - b.priority);
5259
+ }
5260
+ clearModifiers() {
5261
+ this.#modifiers.length = 0;
5262
+ }
5167
5263
  destroy(override) {
5168
5264
  if (this.unbreakable || this.destroyed) {
5169
5265
  return;
5170
5266
  }
5171
5267
  this.destroyed = true;
5172
- this.bubble.inRange = false;
5173
- this.slow.inRange = false;
5268
+ this.clearModifiers();
5174
5269
  const container = this.#container, shapeDrawer = this.shape ? container.shapeDrawers.get(this.shape) : undefined;
5175
5270
  shapeDrawer?.particleDestroy?.(this);
5176
5271
  for (const plugin of container.particleDestroyedPlugins) {
@@ -5192,13 +5287,16 @@
5192
5287
  return this.rotation + (this.pathRotation ? this.velocity.angle : defaultAngle);
5193
5288
  }
5194
5289
  getFillColor() {
5195
- return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.fillColor));
5290
+ return this.#getRollColor(this.#applyModifiers(getHslFromAnimation(this.fillColor), m => m.fillColor));
5196
5291
  }
5197
5292
  getMass() {
5198
5293
  return this.getRadius() ** squareExp * Math.PI * half;
5199
5294
  }
5295
+ getModifier(id) {
5296
+ return this.#modifiers.find(m => m.id === id);
5297
+ }
5200
5298
  getOpacity() {
5201
- const zIndexOptions = this.options.zIndex, zIndexFactor = zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, opacity = this.bubble.opacity ?? getRangeValue(this.opacity?.value ?? defaultOpacity$1), fillOpacity = this.fillOpacity ?? defaultOpacity$1, strokeOpacity = this.strokeOpacity ?? defaultOpacity$1;
5299
+ 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;
5202
5300
  this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
5203
5301
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
5204
5302
  this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
@@ -5211,7 +5309,7 @@
5211
5309
  return this.#cachedPosition;
5212
5310
  }
5213
5311
  getRadius() {
5214
- return this.bubble.radius ?? this.size.value;
5312
+ return this.#applyModifiers(this.size.value, m => m.radius);
5215
5313
  }
5216
5314
  getRotateData() {
5217
5315
  const angle = this.getAngle();
@@ -5220,7 +5318,7 @@
5220
5318
  return this.#cachedRotateData;
5221
5319
  }
5222
5320
  getStrokeColor() {
5223
- return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.strokeColor));
5321
+ return this.#getRollColor(this.#applyModifiers(getHslFromAnimation(this.strokeColor), m => m.strokeColor));
5224
5322
  }
5225
5323
  getTransformData(externalTransform) {
5226
5324
  const rotateData = this.getRotateData(), rotating = this.isRotating;
@@ -5240,13 +5338,6 @@
5240
5338
  this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
5241
5339
  container.retina.initParticle(this);
5242
5340
  runUpdaterPreInit(container.particleUpdaters, this);
5243
- this.bubble = {
5244
- inRange: false,
5245
- };
5246
- this.slow = {
5247
- inRange: false,
5248
- factor: 1,
5249
- };
5250
5341
  this.#initPosition(position);
5251
5342
  this.initialVelocity = this.#calculateVelocity();
5252
5343
  this.velocity = this.initialVelocity.copy();
@@ -5286,11 +5377,29 @@
5286
5377
  isVisible() {
5287
5378
  return !this.destroyed && !this.spawning && this.isInsideCanvas();
5288
5379
  }
5380
+ removeModifier(id) {
5381
+ const idx = this.#modifiers.findIndex(m => m.id === id);
5382
+ if (idx >= defaultAngle) {
5383
+ this.#modifiers.splice(idx, identity$2);
5384
+ }
5385
+ }
5289
5386
  reset() {
5290
5387
  for (const updater of this.#container.particleUpdaters) {
5291
5388
  updater.reset?.(this);
5292
5389
  }
5293
5390
  }
5391
+ #applyModifiers(base, getter) {
5392
+ let value = base;
5393
+ for (const mod of this.#modifiers) {
5394
+ if (mod.enabled) {
5395
+ const override = getter(mod);
5396
+ if (override !== undefined) {
5397
+ value = override;
5398
+ }
5399
+ }
5400
+ }
5401
+ return value;
5402
+ }
5294
5403
  #calcPosition(position, zIndex) {
5295
5404
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
5296
5405
  const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
@@ -6392,6 +6501,7 @@
6392
6501
  });
6393
6502
 
6394
6503
  class BlendPluginInstance {
6504
+ layer = DrawLayer.CanvasSetup;
6395
6505
  #container;
6396
6506
  #defaultCompositeValue;
6397
6507
  constructor(container) {
@@ -6537,7 +6647,8 @@
6537
6647
  particle.lastPathTime -= pathDelay;
6538
6648
  }
6539
6649
  function getProximitySpeedFactor(particle) {
6540
- return particle.slow.inRange ? particle.slow.factor : identity$2;
6650
+ const mod = particle.getModifier("slow");
6651
+ return mod?.enabled ? (mod.speedFactor ?? identity$2) : identity$2;
6541
6652
  }
6542
6653
  function initSpin(container, particle) {
6543
6654
  const options = particle.options, spinOptions = options.move.spin;