@tsparticles/preset-confetti-explosions 4.2.0 → 4.3.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.2.0 */
2
+ /* Preset v4.3.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) :
@@ -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.0";
810
+ return "4.3.0";
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$1, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1931
+ function getRandomRgbColor(min, hdr) {
1932
+ const fixedMin = defaultRgbMin;
1933
+ const fixedMax = rgbMax + identity$1, 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.0");
2114
+ engine.checkVersion("4.3.0");
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.0");
2151
+ engine.checkVersion("4.3.0");
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.0");
2199
+ engine.checkVersion("4.3.0");
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.0");
2252
+ engine.checkVersion("4.3.0");
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.0");
2276
+ engine.checkVersion("4.3.0");
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.0");
2492
+ engine.checkVersion("4.3.0");
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.0");
2837
+ engine.checkVersion("4.3.0");
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.0");
2908
+ engine.checkVersion("4.3.0");
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.0");
2963
+ engine.checkVersion("4.3.0");
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.0");
3048
+ engine.checkVersion("4.3.0");
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.0");
3057
+ engine.checkVersion("4.3.0");
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.0");
3310
+ engine.checkVersion("4.3.0");
3285
3311
  await engine.pluginManager.register(async (e) => {
3286
3312
  const instancesManager = await getEmittersInstancesManager(e);
3287
3313
  await addEmittersShapesManager(e);
@@ -3335,7 +3361,7 @@
3335
3361
  }
3336
3362
 
3337
3363
  async function loadMotionPlugin(engine) {
3338
- engine.checkVersion("4.2.0");
3364
+ engine.checkVersion("4.3.0");
3339
3365
  await engine.pluginManager.register(e => {
3340
3366
  e.pluginManager.addPlugin(new MotionPlugin());
3341
3367
  });
@@ -3468,7 +3494,7 @@
3468
3494
  }
3469
3495
 
3470
3496
  async function loadRollUpdater(engine) {
3471
- engine.checkVersion("4.2.0");
3497
+ engine.checkVersion("4.3.0");
3472
3498
  await engine.pluginManager.register(e => {
3473
3499
  e.pluginManager.addParticleUpdater("roll", () => {
3474
3500
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -3574,7 +3600,7 @@
3574
3600
  }
3575
3601
 
3576
3602
  async function loadRotateUpdater(engine) {
3577
- engine.checkVersion("4.2.0");
3603
+ engine.checkVersion("4.3.0");
3578
3604
  await engine.pluginManager.register(e => {
3579
3605
  e.pluginManager.addParticleUpdater("rotate", container => {
3580
3606
  return Promise.resolve(new RotateUpdater(container));
@@ -3598,7 +3624,7 @@
3598
3624
  }
3599
3625
 
3600
3626
  async function loadSquareShape(engine) {
3601
- engine.checkVersion("4.2.0");
3627
+ engine.checkVersion("4.3.0");
3602
3628
  await engine.pluginManager.register(e => {
3603
3629
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
3604
3630
  });
@@ -3707,7 +3733,7 @@
3707
3733
  }
3708
3734
 
3709
3735
  async function loadTiltUpdater(engine) {
3710
- engine.checkVersion("4.2.0");
3736
+ engine.checkVersion("4.3.0");
3711
3737
  await engine.pluginManager.register(e => {
3712
3738
  e.pluginManager.addParticleUpdater("tilt", container => {
3713
3739
  return Promise.resolve(new TiltUpdater(container));
@@ -3809,7 +3835,7 @@
3809
3835
  }
3810
3836
 
3811
3837
  async function loadWobbleUpdater(engine) {
3812
- engine.checkVersion("4.2.0");
3838
+ engine.checkVersion("4.3.0");
3813
3839
  await engine.pluginManager.register(e => {
3814
3840
  e.pluginManager.addParticleUpdater("wobble", container => {
3815
3841
  return Promise.resolve(new WobbleUpdater(container));
@@ -3979,10 +4005,10 @@
3979
4005
  }
3980
4006
  }
3981
4007
  class RenderManager {
4008
+ #backgroundElement;
4009
+ #backgroundWarnings;
3982
4010
  #canvasClearPlugins;
3983
4011
  #canvasManager;
3984
- #canvasPaintPlugins;
3985
- #clearDrawPlugins;
3986
4012
  #colorPlugins;
3987
4013
  #container;
3988
4014
  #context;
@@ -3990,9 +4016,7 @@
3990
4016
  #drawParticlePlugins;
3991
4017
  #drawParticlesCleanupPlugins;
3992
4018
  #drawParticlesSetupPlugins;
3993
- #drawPlugins;
3994
- #drawSettingsCleanupPlugins;
3995
- #drawSettingsSetupPlugins;
4019
+ #layers;
3996
4020
  #pluginManager;
3997
4021
  #postDrawUpdaters;
3998
4022
  #preDrawUpdaters;
@@ -4004,18 +4028,25 @@
4004
4028
  this.#container = container;
4005
4029
  this.#canvasManager = canvasManager;
4006
4030
  this.#context = null;
4031
+ this.#backgroundElement = null;
4032
+ this.#backgroundWarnings = new Set();
4007
4033
  this.#preDrawUpdaters = [];
4008
4034
  this.#postDrawUpdaters = [];
4009
- this.#colorPlugins = [];
4010
4035
  this.#canvasClearPlugins = [];
4011
- this.#canvasPaintPlugins = [];
4012
- this.#clearDrawPlugins = [];
4036
+ this.#colorPlugins = [];
4013
4037
  this.#drawParticlePlugins = [];
4014
4038
  this.#drawParticlesCleanupPlugins = [];
4015
4039
  this.#drawParticlesSetupPlugins = [];
4016
- this.#drawPlugins = [];
4017
- this.#drawSettingsSetupPlugins = [];
4018
- this.#drawSettingsCleanupPlugins = [];
4040
+ this.#layers = {
4041
+ 0: [],
4042
+ 1: [],
4043
+ 2: [],
4044
+ 3: [],
4045
+ 4: [],
4046
+ 5: [],
4047
+ 6: [],
4048
+ 7: [],
4049
+ };
4019
4050
  }
4020
4051
  get settings() {
4021
4052
  return this.#contextSettings;
@@ -4029,32 +4060,38 @@
4029
4060
  });
4030
4061
  }
4031
4062
  clear() {
4032
- let pluginHandled = false;
4033
4063
  for (const plugin of this.#canvasClearPlugins) {
4034
- pluginHandled = plugin.canvasClear?.() ?? false;
4035
- if (pluginHandled) {
4036
- break;
4064
+ if (plugin.canvasClear?.() ?? false) {
4065
+ return;
4037
4066
  }
4038
4067
  }
4039
- if (pluginHandled) {
4040
- return;
4068
+ for (const layer of Object.values(DrawLayer)) {
4069
+ if (typeof layer === "number") {
4070
+ for (const plugin of this.#getLayerPlugins(layer)) {
4071
+ if (plugin.canvasClear?.() ?? false) {
4072
+ return;
4073
+ }
4074
+ }
4075
+ }
4041
4076
  }
4042
4077
  this.canvasClear();
4043
4078
  }
4044
4079
  destroy() {
4045
4080
  this.stop();
4081
+ this.#backgroundElement = null;
4082
+ this.#backgroundWarnings.clear();
4046
4083
  this.#preDrawUpdaters = [];
4047
4084
  this.#postDrawUpdaters = [];
4048
- this.#colorPlugins = [];
4049
4085
  this.#canvasClearPlugins = [];
4050
- this.#canvasPaintPlugins = [];
4051
- this.#clearDrawPlugins = [];
4086
+ this.#colorPlugins = [];
4052
4087
  this.#drawParticlePlugins = [];
4053
4088
  this.#drawParticlesCleanupPlugins = [];
4054
4089
  this.#drawParticlesSetupPlugins = [];
4055
- this.#drawPlugins = [];
4056
- this.#drawSettingsSetupPlugins = [];
4057
- this.#drawSettingsCleanupPlugins = [];
4090
+ for (const layer of Object.values(DrawLayer)) {
4091
+ if (typeof layer === "number") {
4092
+ this.#layers[layer] = [];
4093
+ }
4094
+ }
4058
4095
  }
4059
4096
  draw(cb) {
4060
4097
  const ctx = this.#context;
@@ -4111,21 +4148,40 @@
4111
4148
  });
4112
4149
  }
4113
4150
  drawParticles(delta) {
4114
- const { particles } = this.#container;
4151
+ const { particles, actualOptions } = this.#container;
4115
4152
  this.clear();
4116
4153
  particles.update(delta);
4117
4154
  this.draw(ctx => {
4118
- for (const plugin of this.#drawSettingsSetupPlugins) {
4155
+ const width = this.#canvasManager.size.width, height = this.#canvasManager.size.height;
4156
+ if (this.#backgroundElement) {
4157
+ try {
4158
+ ctx.drawImage(this.#backgroundElement, originPoint.x, originPoint.y, width, height);
4159
+ }
4160
+ catch {
4161
+ this.#warnOnce("background-element-draw-error", "Error drawing background element onto canvas");
4162
+ }
4163
+ }
4164
+ const background = actualOptions.background;
4165
+ if (background.draw) {
4166
+ try {
4167
+ background.draw(ctx, delta);
4168
+ }
4169
+ catch {
4170
+ this.#warnOnce("background-draw-error", "Error in background.draw callback");
4171
+ }
4172
+ }
4173
+ for (const plugin of this.#getLayerPlugins(DrawLayer.BackgroundMask)) {
4174
+ plugin.canvasPaint?.();
4175
+ }
4176
+ for (const plugin of this.#getLayerPlugins(DrawLayer.CanvasSetup)) {
4119
4177
  plugin.drawSettingsSetup?.(ctx, delta);
4120
4178
  }
4121
- for (const plugin of this.#drawPlugins) {
4179
+ for (const plugin of this.#getLayerPlugins(DrawLayer.PluginContent)) {
4122
4180
  plugin.draw?.(ctx, delta);
4123
4181
  }
4124
4182
  particles.drawParticles(delta);
4125
- for (const plugin of this.#clearDrawPlugins) {
4183
+ for (const plugin of this.#getLayerPlugins(DrawLayer.CanvasCleanup)) {
4126
4184
  plugin.clearDraw?.(ctx, delta);
4127
- }
4128
- for (const plugin of this.#drawSettingsCleanupPlugins) {
4129
4185
  plugin.drawSettingsCleanup?.(ctx, delta);
4130
4186
  }
4131
4187
  });
@@ -4133,29 +4189,24 @@
4133
4189
  init() {
4134
4190
  this.initUpdaters();
4135
4191
  this.initPlugins();
4192
+ this.#resolveBackgroundElement();
4136
4193
  this.paint();
4137
4194
  }
4138
4195
  initPlugins() {
4139
- this.#colorPlugins = [];
4140
4196
  this.#canvasClearPlugins = [];
4141
- this.#canvasPaintPlugins = [];
4142
- this.#clearDrawPlugins = [];
4197
+ this.#colorPlugins = [];
4143
4198
  this.#drawParticlePlugins = [];
4144
4199
  this.#drawParticlesSetupPlugins = [];
4145
4200
  this.#drawParticlesCleanupPlugins = [];
4146
- this.#drawPlugins = [];
4147
- this.#drawSettingsSetupPlugins = [];
4148
- this.#drawSettingsCleanupPlugins = [];
4201
+ for (const layer of Object.values(DrawLayer)) {
4202
+ if (typeof layer === "number") {
4203
+ this.#layers[layer] = [];
4204
+ }
4205
+ }
4149
4206
  for (const plugin of this.#container.plugins) {
4150
4207
  if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
4151
4208
  this.#colorPlugins.push(plugin);
4152
4209
  }
4153
- if (plugin.canvasClear) {
4154
- this.#canvasClearPlugins.push(plugin);
4155
- }
4156
- if (plugin.canvasPaint) {
4157
- this.#canvasPaintPlugins.push(plugin);
4158
- }
4159
4210
  if (plugin.drawParticle) {
4160
4211
  this.#drawParticlePlugins.push(plugin);
4161
4212
  }
@@ -4165,17 +4216,20 @@
4165
4216
  if (plugin.drawParticleCleanup) {
4166
4217
  this.#drawParticlesCleanupPlugins.push(plugin);
4167
4218
  }
4168
- if (plugin.draw) {
4169
- this.#drawPlugins.push(plugin);
4219
+ if (plugin.canvasClear) {
4220
+ this.#canvasClearPlugins.push(plugin);
4221
+ }
4222
+ if (plugin.canvasPaint) {
4223
+ this.#getLayerPlugins(DrawLayer.BackgroundMask).push(plugin);
4170
4224
  }
4171
4225
  if (plugin.drawSettingsSetup) {
4172
- this.#drawSettingsSetupPlugins.push(plugin);
4226
+ this.#getLayerPlugins(DrawLayer.CanvasSetup).push(plugin);
4173
4227
  }
4174
- if (plugin.drawSettingsCleanup) {
4175
- this.#drawSettingsCleanupPlugins.push(plugin);
4228
+ if (plugin.draw) {
4229
+ this.#getLayerPlugins(DrawLayer.PluginContent).push(plugin);
4176
4230
  }
4177
- if (plugin.clearDraw) {
4178
- this.#clearDrawPlugins.push(plugin);
4231
+ if (plugin.clearDraw ?? plugin.drawSettingsCleanup) {
4232
+ this.#getLayerPlugins(DrawLayer.CanvasCleanup).push(plugin);
4179
4233
  }
4180
4234
  }
4181
4235
  }
@@ -4193,7 +4247,7 @@
4193
4247
  }
4194
4248
  paint() {
4195
4249
  let handled = false;
4196
- for (const plugin of this.#canvasPaintPlugins) {
4250
+ for (const plugin of this.#getLayerPlugins(DrawLayer.BackgroundMask)) {
4197
4251
  handled = plugin.canvasPaint?.() ?? false;
4198
4252
  if (handled) {
4199
4253
  break;
@@ -4366,6 +4420,9 @@
4366
4420
  }
4367
4421
  drawer.beforeDraw(data);
4368
4422
  }
4423
+ #getLayerPlugins(layer) {
4424
+ return this.#layers[layer];
4425
+ }
4369
4426
  #getPluginParticleColors(particle) {
4370
4427
  let fColor, sColor;
4371
4428
  for (const plugin of this.#colorPlugins) {
@@ -4383,6 +4440,39 @@
4383
4440
  this.#reusablePluginColors[sColorIndex] = sColor;
4384
4441
  return this.#reusablePluginColors;
4385
4442
  }
4443
+ #resolveBackgroundElement() {
4444
+ const background = this.#container.actualOptions.background;
4445
+ this.#backgroundElement = null;
4446
+ if (!background.element) {
4447
+ return;
4448
+ }
4449
+ if (typeof background.element === "string") {
4450
+ if (typeof document !== "undefined") {
4451
+ const node = document.querySelector(background.element);
4452
+ if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
4453
+ this.#backgroundElement = node;
4454
+ }
4455
+ else if (node) {
4456
+ this.#warnOnce("background-element-not-supported", `Background element "${background.element}" is not a supported drawable element (canvas, video, or img)`);
4457
+ }
4458
+ else {
4459
+ this.#warnOnce("background-element-not-found", `Background element selector "${background.element}" not found`);
4460
+ }
4461
+ }
4462
+ }
4463
+ else if (background.element instanceof HTMLCanvasElement ||
4464
+ background.element instanceof OffscreenCanvas ||
4465
+ background.element instanceof HTMLVideoElement ||
4466
+ background.element instanceof HTMLImageElement) {
4467
+ this.#backgroundElement = background.element;
4468
+ }
4469
+ }
4470
+ #warnOnce(key, message) {
4471
+ if (!this.#backgroundWarnings.has(key)) {
4472
+ this.#backgroundWarnings.add(key);
4473
+ getLogger().warning(message);
4474
+ }
4475
+ }
4386
4476
  }
4387
4477
 
4388
4478
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -4959,7 +5049,6 @@
4959
5049
  }
4960
5050
  class Particle {
4961
5051
  backColor;
4962
- bubble;
4963
5052
  destroyed;
4964
5053
  direction;
4965
5054
  effect;
@@ -4993,7 +5082,6 @@
4993
5082
  shapeData;
4994
5083
  sides;
4995
5084
  size;
4996
- slow;
4997
5085
  spawning;
4998
5086
  strokeColor;
4999
5087
  strokeOpacity;
@@ -5015,18 +5103,25 @@
5015
5103
  d: 1,
5016
5104
  };
5017
5105
  #container;
5106
+ #modifiers = [];
5018
5107
  #pluginManager;
5019
5108
  constructor(pluginManager, container) {
5020
5109
  this.#pluginManager = pluginManager;
5021
5110
  this.#container = container;
5022
5111
  }
5112
+ addModifier(modifier) {
5113
+ this.#modifiers.push(modifier);
5114
+ this.#modifiers.sort((a, b) => a.priority - b.priority);
5115
+ }
5116
+ clearModifiers() {
5117
+ this.#modifiers.length = 0;
5118
+ }
5023
5119
  destroy(override) {
5024
5120
  if (this.unbreakable || this.destroyed) {
5025
5121
  return;
5026
5122
  }
5027
5123
  this.destroyed = true;
5028
- this.bubble.inRange = false;
5029
- this.slow.inRange = false;
5124
+ this.clearModifiers();
5030
5125
  const container = this.#container, shapeDrawer = this.shape ? container.shapeDrawers.get(this.shape) : undefined;
5031
5126
  shapeDrawer?.particleDestroy?.(this);
5032
5127
  for (const plugin of container.particleDestroyedPlugins) {
@@ -5048,13 +5143,16 @@
5048
5143
  return this.rotation + (this.pathRotation ? this.velocity.angle : defaultAngle);
5049
5144
  }
5050
5145
  getFillColor() {
5051
- return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.fillColor));
5146
+ return this.#getRollColor(this.#applyModifiers(getHslFromAnimation(this.fillColor), m => m.fillColor));
5052
5147
  }
5053
5148
  getMass() {
5054
5149
  return this.getRadius() ** squareExp * Math.PI * half;
5055
5150
  }
5151
+ getModifier(id) {
5152
+ return this.#modifiers.find(m => m.id === id);
5153
+ }
5056
5154
  getOpacity() {
5057
- 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;
5155
+ 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;
5058
5156
  this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
5059
5157
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
5060
5158
  this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
@@ -5067,7 +5165,7 @@
5067
5165
  return this.#cachedPosition;
5068
5166
  }
5069
5167
  getRadius() {
5070
- return this.bubble.radius ?? this.size.value;
5168
+ return this.#applyModifiers(this.size.value, m => m.radius);
5071
5169
  }
5072
5170
  getRotateData() {
5073
5171
  const angle = this.getAngle();
@@ -5076,7 +5174,7 @@
5076
5174
  return this.#cachedRotateData;
5077
5175
  }
5078
5176
  getStrokeColor() {
5079
- return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.strokeColor));
5177
+ return this.#getRollColor(this.#applyModifiers(getHslFromAnimation(this.strokeColor), m => m.strokeColor));
5080
5178
  }
5081
5179
  getTransformData(externalTransform) {
5082
5180
  const rotateData = this.getRotateData(), rotating = this.isRotating;
@@ -5096,13 +5194,6 @@
5096
5194
  this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
5097
5195
  container.retina.initParticle(this);
5098
5196
  runUpdaterPreInit(container.particleUpdaters, this);
5099
- this.bubble = {
5100
- inRange: false,
5101
- };
5102
- this.slow = {
5103
- inRange: false,
5104
- factor: 1,
5105
- };
5106
5197
  this.#initPosition(position);
5107
5198
  this.initialVelocity = this.#calculateVelocity();
5108
5199
  this.velocity = this.initialVelocity.copy();
@@ -5142,11 +5233,29 @@
5142
5233
  isVisible() {
5143
5234
  return !this.destroyed && !this.spawning && this.isInsideCanvas();
5144
5235
  }
5236
+ removeModifier(id) {
5237
+ const idx = this.#modifiers.findIndex(m => m.id === id);
5238
+ if (idx >= defaultAngle) {
5239
+ this.#modifiers.splice(idx, identity$1);
5240
+ }
5241
+ }
5145
5242
  reset() {
5146
5243
  for (const updater of this.#container.particleUpdaters) {
5147
5244
  updater.reset?.(this);
5148
5245
  }
5149
5246
  }
5247
+ #applyModifiers(base, getter) {
5248
+ let value = base;
5249
+ for (const mod of this.#modifiers) {
5250
+ if (mod.enabled) {
5251
+ const override = getter(mod);
5252
+ if (override !== undefined) {
5253
+ value = override;
5254
+ }
5255
+ }
5256
+ }
5257
+ return value;
5258
+ }
5150
5259
  #calcPosition(position, zIndex) {
5151
5260
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
5152
5261
  const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
@@ -6248,6 +6357,7 @@
6248
6357
  });
6249
6358
 
6250
6359
  class BlendPluginInstance {
6360
+ layer = DrawLayer.CanvasSetup;
6251
6361
  #container;
6252
6362
  #defaultCompositeValue;
6253
6363
  constructor(container) {
@@ -6393,7 +6503,8 @@
6393
6503
  particle.lastPathTime -= pathDelay;
6394
6504
  }
6395
6505
  function getProximitySpeedFactor(particle) {
6396
- return particle.slow.inRange ? particle.slow.factor : identity$1;
6506
+ const mod = particle.getModifier("slow");
6507
+ return mod?.enabled ? (mod.speedFactor ?? identity$1) : identity$1;
6397
6508
  }
6398
6509
  function initSpin(container, particle) {
6399
6510
  const options = particle.options, spinOptions = options.move.spin;