@tsparticles/stencil 4.2.1 → 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,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-BIoj1BEO.js');
3
+ var index = require('./index-CoHtf-OM.js');
4
4
 
5
5
  class BaseRange {
6
6
  position;
@@ -206,6 +206,8 @@ class AnimatableColor extends OptionsColor {
206
206
 
207
207
  class Background extends OptionLoader {
208
208
  color;
209
+ draw;
210
+ element;
209
211
  image = "";
210
212
  opacity = 1;
211
213
  position = "";
@@ -220,6 +222,8 @@ class Background extends OptionLoader {
220
222
  if (data.color !== undefined) {
221
223
  this.color = OptionsColor.create(this.color, data.color);
222
224
  }
225
+ loadProperty(this, "element", data.element);
226
+ loadProperty(this, "draw", data.draw);
223
227
  loadProperty(this, "image", data.image);
224
228
  loadProperty(this, "position", data.position);
225
229
  loadProperty(this, "repeat", data.repeat);
@@ -755,7 +759,7 @@ class Options extends OptionLoader {
755
759
  }
756
760
  }
757
761
 
758
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
762
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203;
759
763
  function getCachedStyle(key, generator) {
760
764
  let cached = styleCache.get(key);
761
765
  if (!cached) {
@@ -884,19 +888,20 @@ function hslChannel(temp1, temp2, temp3) {
884
888
  }
885
889
  return temp1;
886
890
  }
887
- function hslToRgb(hsl) {
891
+ function hslToRgbFloat(hsl) {
888
892
  const h = ((hsl.h % index.hMax) + index.hMax) % index.hMax, s = Math.max(index.sMin, Math.min(index.sMax, hsl.s)), l = Math.max(index.lMin, Math.min(index.lMax, hsl.l)), hNormalized = h / index.hMax, sNormalized = s / index.sMax, lNormalized = l / index.lMax;
889
893
  if (s === index.sMin) {
890
- const grayscaleValue = Math.round(lNormalized * index.rgbMax);
894
+ const grayscaleValue = lNormalized * index.rgbMax;
891
895
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
892
896
  }
893
897
  const temp1 = lNormalized < index.half
894
898
  ? lNormalized * (index.sNormalizedOffset + sNormalized)
895
899
  : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = index.double * lNormalized - temp1, phaseThird = index.phaseNumerator / index.triple, red = Math.min(index.rgbMax, index.rgbMax * hslChannel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(index.rgbMax, index.rgbMax * hslChannel(temp2, temp1, hNormalized)), blue = Math.min(index.rgbMax, index.rgbMax * hslChannel(temp2, temp1, hNormalized - phaseThird));
896
- return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
900
+ return { r: red, g: green, b: blue };
897
901
  }
898
- function getRandomRgbColor(min) {
899
- const fixedMin = index.defaultRgbMin, fixedMax = index.rgbMax + index.identity, getRgbInRangeValue = () => Math.floor(index.getRandomInRange(fixedMin, fixedMax));
902
+ function getRandomRgbColor(min, hdr) {
903
+ const fixedMin = index.defaultRgbMin;
904
+ const fixedMax = index.rgbMax + index.identity, getRgbInRangeValue = () => Math.floor(index.getRandomInRange(fixedMin, fixedMax));
900
905
  return {
901
906
  b: getRgbInRangeValue(),
902
907
  g: getRgbInRangeValue(),
@@ -904,7 +909,7 @@ function getRandomRgbColor(min) {
904
909
  };
905
910
  }
906
911
  function getStyleFromRgb(color, hdr, opacity) {
907
- const op = opacity ?? index.defaultOpacity, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
912
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? index.defaultOpacity, key = `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
908
913
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
909
914
  }
910
915
  function getHdrStyleFromRgb(color, opacity, peakNits = index.maxNits) {
@@ -915,9 +920,9 @@ function getSdrStyleFromRgb(color, opacity) {
915
920
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? index.defaultOpacity).toString()})`;
916
921
  }
917
922
  function getStyleFromHsl(color, hdr, opacity) {
918
- const op = opacity ?? index.defaultOpacity, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
923
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? index.defaultOpacity, key = `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
919
924
  return getCachedStyle(key, () => hdr
920
- ? getStyleFromRgb(hslToRgb(color), true, opacity)
925
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
921
926
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
922
927
  }
923
928
  function getHslFromAnimation(animation) {
@@ -945,10 +950,10 @@ function setTransformValue(factor, newFactor, key) {
945
950
  }
946
951
  }
947
952
  class RenderManager {
953
+ #backgroundElement;
954
+ #backgroundWarnings;
948
955
  #canvasClearPlugins;
949
956
  #canvasManager;
950
- #canvasPaintPlugins;
951
- #clearDrawPlugins;
952
957
  #colorPlugins;
953
958
  #container;
954
959
  #context;
@@ -956,9 +961,7 @@ class RenderManager {
956
961
  #drawParticlePlugins;
957
962
  #drawParticlesCleanupPlugins;
958
963
  #drawParticlesSetupPlugins;
959
- #drawPlugins;
960
- #drawSettingsCleanupPlugins;
961
- #drawSettingsSetupPlugins;
964
+ #layers;
962
965
  #pluginManager;
963
966
  #postDrawUpdaters;
964
967
  #preDrawUpdaters;
@@ -970,18 +973,25 @@ class RenderManager {
970
973
  this.#container = container;
971
974
  this.#canvasManager = canvasManager;
972
975
  this.#context = null;
976
+ this.#backgroundElement = null;
977
+ this.#backgroundWarnings = new Set();
973
978
  this.#preDrawUpdaters = [];
974
979
  this.#postDrawUpdaters = [];
975
- this.#colorPlugins = [];
976
980
  this.#canvasClearPlugins = [];
977
- this.#canvasPaintPlugins = [];
978
- this.#clearDrawPlugins = [];
981
+ this.#colorPlugins = [];
979
982
  this.#drawParticlePlugins = [];
980
983
  this.#drawParticlesCleanupPlugins = [];
981
984
  this.#drawParticlesSetupPlugins = [];
982
- this.#drawPlugins = [];
983
- this.#drawSettingsSetupPlugins = [];
984
- this.#drawSettingsCleanupPlugins = [];
985
+ this.#layers = {
986
+ 0: [],
987
+ 1: [],
988
+ 2: [],
989
+ 3: [],
990
+ 4: [],
991
+ 5: [],
992
+ 6: [],
993
+ 7: [],
994
+ };
985
995
  }
986
996
  get settings() {
987
997
  return this.#contextSettings;
@@ -995,32 +1005,38 @@ class RenderManager {
995
1005
  });
996
1006
  }
997
1007
  clear() {
998
- let pluginHandled = false;
999
1008
  for (const plugin of this.#canvasClearPlugins) {
1000
- pluginHandled = plugin.canvasClear?.() ?? false;
1001
- if (pluginHandled) {
1002
- break;
1009
+ if (plugin.canvasClear?.() ?? false) {
1010
+ return;
1003
1011
  }
1004
1012
  }
1005
- if (pluginHandled) {
1006
- return;
1013
+ for (const layer of Object.values(index.DrawLayer)) {
1014
+ if (typeof layer === "number") {
1015
+ for (const plugin of this.#getLayerPlugins(layer)) {
1016
+ if (plugin.canvasClear?.() ?? false) {
1017
+ return;
1018
+ }
1019
+ }
1020
+ }
1007
1021
  }
1008
1022
  this.canvasClear();
1009
1023
  }
1010
1024
  destroy() {
1011
1025
  this.stop();
1026
+ this.#backgroundElement = null;
1027
+ this.#backgroundWarnings.clear();
1012
1028
  this.#preDrawUpdaters = [];
1013
1029
  this.#postDrawUpdaters = [];
1014
- this.#colorPlugins = [];
1015
1030
  this.#canvasClearPlugins = [];
1016
- this.#canvasPaintPlugins = [];
1017
- this.#clearDrawPlugins = [];
1031
+ this.#colorPlugins = [];
1018
1032
  this.#drawParticlePlugins = [];
1019
1033
  this.#drawParticlesCleanupPlugins = [];
1020
1034
  this.#drawParticlesSetupPlugins = [];
1021
- this.#drawPlugins = [];
1022
- this.#drawSettingsSetupPlugins = [];
1023
- this.#drawSettingsCleanupPlugins = [];
1035
+ for (const layer of Object.values(index.DrawLayer)) {
1036
+ if (typeof layer === "number") {
1037
+ this.#layers[layer] = [];
1038
+ }
1039
+ }
1024
1040
  }
1025
1041
  draw(cb) {
1026
1042
  const ctx = this.#context;
@@ -1077,21 +1093,40 @@ class RenderManager {
1077
1093
  });
1078
1094
  }
1079
1095
  drawParticles(delta) {
1080
- const { particles } = this.#container;
1096
+ const { particles, actualOptions } = this.#container;
1081
1097
  this.clear();
1082
1098
  particles.update(delta);
1083
1099
  this.draw(ctx => {
1084
- for (const plugin of this.#drawSettingsSetupPlugins) {
1100
+ const width = this.#canvasManager.size.width, height = this.#canvasManager.size.height;
1101
+ if (this.#backgroundElement) {
1102
+ try {
1103
+ ctx.drawImage(this.#backgroundElement, index.originPoint.x, index.originPoint.y, width, height);
1104
+ }
1105
+ catch {
1106
+ this.#warnOnce("background-element-draw-error", "Error drawing background element onto canvas");
1107
+ }
1108
+ }
1109
+ const background = actualOptions.background;
1110
+ if (background.draw) {
1111
+ try {
1112
+ background.draw(ctx, delta);
1113
+ }
1114
+ catch {
1115
+ this.#warnOnce("background-draw-error", "Error in background.draw callback");
1116
+ }
1117
+ }
1118
+ for (const plugin of this.#getLayerPlugins(index.DrawLayer.BackgroundMask)) {
1119
+ plugin.canvasPaint?.();
1120
+ }
1121
+ for (const plugin of this.#getLayerPlugins(index.DrawLayer.CanvasSetup)) {
1085
1122
  plugin.drawSettingsSetup?.(ctx, delta);
1086
1123
  }
1087
- for (const plugin of this.#drawPlugins) {
1124
+ for (const plugin of this.#getLayerPlugins(index.DrawLayer.PluginContent)) {
1088
1125
  plugin.draw?.(ctx, delta);
1089
1126
  }
1090
1127
  particles.drawParticles(delta);
1091
- for (const plugin of this.#clearDrawPlugins) {
1128
+ for (const plugin of this.#getLayerPlugins(index.DrawLayer.CanvasCleanup)) {
1092
1129
  plugin.clearDraw?.(ctx, delta);
1093
- }
1094
- for (const plugin of this.#drawSettingsCleanupPlugins) {
1095
1130
  plugin.drawSettingsCleanup?.(ctx, delta);
1096
1131
  }
1097
1132
  });
@@ -1099,29 +1134,24 @@ class RenderManager {
1099
1134
  init() {
1100
1135
  this.initUpdaters();
1101
1136
  this.initPlugins();
1137
+ this.#resolveBackgroundElement();
1102
1138
  this.paint();
1103
1139
  }
1104
1140
  initPlugins() {
1105
- this.#colorPlugins = [];
1106
1141
  this.#canvasClearPlugins = [];
1107
- this.#canvasPaintPlugins = [];
1108
- this.#clearDrawPlugins = [];
1142
+ this.#colorPlugins = [];
1109
1143
  this.#drawParticlePlugins = [];
1110
1144
  this.#drawParticlesSetupPlugins = [];
1111
1145
  this.#drawParticlesCleanupPlugins = [];
1112
- this.#drawPlugins = [];
1113
- this.#drawSettingsSetupPlugins = [];
1114
- this.#drawSettingsCleanupPlugins = [];
1146
+ for (const layer of Object.values(index.DrawLayer)) {
1147
+ if (typeof layer === "number") {
1148
+ this.#layers[layer] = [];
1149
+ }
1150
+ }
1115
1151
  for (const plugin of this.#container.plugins) {
1116
1152
  if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
1117
1153
  this.#colorPlugins.push(plugin);
1118
1154
  }
1119
- if (plugin.canvasClear) {
1120
- this.#canvasClearPlugins.push(plugin);
1121
- }
1122
- if (plugin.canvasPaint) {
1123
- this.#canvasPaintPlugins.push(plugin);
1124
- }
1125
1155
  if (plugin.drawParticle) {
1126
1156
  this.#drawParticlePlugins.push(plugin);
1127
1157
  }
@@ -1131,17 +1161,20 @@ class RenderManager {
1131
1161
  if (plugin.drawParticleCleanup) {
1132
1162
  this.#drawParticlesCleanupPlugins.push(plugin);
1133
1163
  }
1134
- if (plugin.draw) {
1135
- this.#drawPlugins.push(plugin);
1164
+ if (plugin.canvasClear) {
1165
+ this.#canvasClearPlugins.push(plugin);
1166
+ }
1167
+ if (plugin.canvasPaint) {
1168
+ this.#getLayerPlugins(index.DrawLayer.BackgroundMask).push(plugin);
1136
1169
  }
1137
1170
  if (plugin.drawSettingsSetup) {
1138
- this.#drawSettingsSetupPlugins.push(plugin);
1171
+ this.#getLayerPlugins(index.DrawLayer.CanvasSetup).push(plugin);
1139
1172
  }
1140
- if (plugin.drawSettingsCleanup) {
1141
- this.#drawSettingsCleanupPlugins.push(plugin);
1173
+ if (plugin.draw) {
1174
+ this.#getLayerPlugins(index.DrawLayer.PluginContent).push(plugin);
1142
1175
  }
1143
- if (plugin.clearDraw) {
1144
- this.#clearDrawPlugins.push(plugin);
1176
+ if (plugin.clearDraw ?? plugin.drawSettingsCleanup) {
1177
+ this.#getLayerPlugins(index.DrawLayer.CanvasCleanup).push(plugin);
1145
1178
  }
1146
1179
  }
1147
1180
  }
@@ -1159,7 +1192,7 @@ class RenderManager {
1159
1192
  }
1160
1193
  paint() {
1161
1194
  let handled = false;
1162
- for (const plugin of this.#canvasPaintPlugins) {
1195
+ for (const plugin of this.#getLayerPlugins(index.DrawLayer.BackgroundMask)) {
1163
1196
  handled = plugin.canvasPaint?.() ?? false;
1164
1197
  if (handled) {
1165
1198
  break;
@@ -1332,6 +1365,9 @@ class RenderManager {
1332
1365
  }
1333
1366
  drawer.beforeDraw(data);
1334
1367
  }
1368
+ #getLayerPlugins(layer) {
1369
+ return this.#layers[layer];
1370
+ }
1335
1371
  #getPluginParticleColors(particle) {
1336
1372
  let fColor, sColor;
1337
1373
  for (const plugin of this.#colorPlugins) {
@@ -1349,6 +1385,39 @@ class RenderManager {
1349
1385
  this.#reusablePluginColors[sColorIndex] = sColor;
1350
1386
  return this.#reusablePluginColors;
1351
1387
  }
1388
+ #resolveBackgroundElement() {
1389
+ const background = this.#container.actualOptions.background;
1390
+ this.#backgroundElement = null;
1391
+ if (!background.element) {
1392
+ return;
1393
+ }
1394
+ if (typeof background.element === "string") {
1395
+ if (typeof document !== "undefined") {
1396
+ const node = document.querySelector(background.element);
1397
+ if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
1398
+ this.#backgroundElement = node;
1399
+ }
1400
+ else if (node) {
1401
+ this.#warnOnce("background-element-not-supported", `Background element "${background.element}" is not a supported drawable element (canvas, video, or img)`);
1402
+ }
1403
+ else {
1404
+ this.#warnOnce("background-element-not-found", `Background element selector "${background.element}" not found`);
1405
+ }
1406
+ }
1407
+ }
1408
+ else if (background.element instanceof HTMLCanvasElement ||
1409
+ background.element instanceof OffscreenCanvas ||
1410
+ background.element instanceof HTMLVideoElement ||
1411
+ background.element instanceof HTMLImageElement) {
1412
+ this.#backgroundElement = background.element;
1413
+ }
1414
+ }
1415
+ #warnOnce(key, message) {
1416
+ if (!this.#backgroundWarnings.has(key)) {
1417
+ this.#backgroundWarnings.add(key);
1418
+ index.getLogger().warning(message);
1419
+ }
1420
+ }
1352
1421
  }
1353
1422
 
1354
1423
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -1925,7 +1994,6 @@ function runParticleCreatedPlugins(container, particle) {
1925
1994
  }
1926
1995
  class Particle {
1927
1996
  backColor;
1928
- bubble;
1929
1997
  destroyed;
1930
1998
  direction;
1931
1999
  effect;
@@ -1959,7 +2027,6 @@ class Particle {
1959
2027
  shapeData;
1960
2028
  sides;
1961
2029
  size;
1962
- slow;
1963
2030
  spawning;
1964
2031
  strokeColor;
1965
2032
  strokeOpacity;
@@ -1981,18 +2048,25 @@ class Particle {
1981
2048
  d: 1,
1982
2049
  };
1983
2050
  #container;
2051
+ #modifiers = [];
1984
2052
  #pluginManager;
1985
2053
  constructor(pluginManager, container) {
1986
2054
  this.#pluginManager = pluginManager;
1987
2055
  this.#container = container;
1988
2056
  }
2057
+ addModifier(modifier) {
2058
+ this.#modifiers.push(modifier);
2059
+ this.#modifiers.sort((a, b) => a.priority - b.priority);
2060
+ }
2061
+ clearModifiers() {
2062
+ this.#modifiers.length = 0;
2063
+ }
1989
2064
  destroy(override) {
1990
2065
  if (this.unbreakable || this.destroyed) {
1991
2066
  return;
1992
2067
  }
1993
2068
  this.destroyed = true;
1994
- this.bubble.inRange = false;
1995
- this.slow.inRange = false;
2069
+ this.clearModifiers();
1996
2070
  const container = this.#container, shapeDrawer = this.shape ? container.shapeDrawers.get(this.shape) : undefined;
1997
2071
  shapeDrawer?.particleDestroy?.(this);
1998
2072
  for (const plugin of container.particleDestroyedPlugins) {
@@ -2014,13 +2088,16 @@ class Particle {
2014
2088
  return this.rotation + (this.pathRotation ? this.velocity.angle : index.defaultAngle);
2015
2089
  }
2016
2090
  getFillColor() {
2017
- return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.fillColor));
2091
+ return this.#getRollColor(this.#applyModifiers(getHslFromAnimation(this.fillColor), m => m.fillColor));
2018
2092
  }
2019
2093
  getMass() {
2020
2094
  return this.getRadius() ** index.squareExp * Math.PI * index.half;
2021
2095
  }
2096
+ getModifier(id) {
2097
+ return this.#modifiers.find(m => m.id === id);
2098
+ }
2022
2099
  getOpacity() {
2023
- const zIndexOptions = this.options.zIndex, zIndexFactor = index.zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, opacity = this.bubble.opacity ?? index.getRangeValue(this.opacity?.value ?? index.defaultOpacity), fillOpacity = this.fillOpacity ?? index.defaultOpacity, strokeOpacity = this.strokeOpacity ?? index.defaultOpacity;
2100
+ const zIndexOptions = this.options.zIndex, zIndexFactor = index.zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, baseOpacity = index.getRangeValue(this.opacity?.value ?? index.defaultOpacity), modifierOpacity = this.#applyModifiers(undefined, m => m.opacity), opacity = modifierOpacity ?? baseOpacity, fillOpacity = this.fillOpacity ?? index.defaultOpacity, strokeOpacity = this.strokeOpacity ?? index.defaultOpacity;
2024
2101
  this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
2025
2102
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
2026
2103
  this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
@@ -2033,7 +2110,7 @@ class Particle {
2033
2110
  return this.#cachedPosition;
2034
2111
  }
2035
2112
  getRadius() {
2036
- return this.bubble.radius ?? this.size.value;
2113
+ return this.#applyModifiers(this.size.value, m => m.radius);
2037
2114
  }
2038
2115
  getRotateData() {
2039
2116
  const angle = this.getAngle();
@@ -2042,7 +2119,7 @@ class Particle {
2042
2119
  return this.#cachedRotateData;
2043
2120
  }
2044
2121
  getStrokeColor() {
2045
- return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.strokeColor));
2122
+ return this.#getRollColor(this.#applyModifiers(getHslFromAnimation(this.strokeColor), m => m.strokeColor));
2046
2123
  }
2047
2124
  getTransformData(externalTransform) {
2048
2125
  const rotateData = this.getRotateData(), rotating = this.isRotating;
@@ -2062,13 +2139,6 @@ class Particle {
2062
2139
  this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
2063
2140
  container.retina.initParticle(this);
2064
2141
  runUpdaterPreInit(container.particleUpdaters, this);
2065
- this.bubble = {
2066
- inRange: false,
2067
- };
2068
- this.slow = {
2069
- inRange: false,
2070
- factor: 1,
2071
- };
2072
2142
  this.#initPosition(position);
2073
2143
  this.initialVelocity = this.#calculateVelocity();
2074
2144
  this.velocity = this.initialVelocity.copy();
@@ -2108,11 +2178,29 @@ class Particle {
2108
2178
  isVisible() {
2109
2179
  return !this.destroyed && !this.spawning && this.isInsideCanvas();
2110
2180
  }
2181
+ removeModifier(id) {
2182
+ const idx = this.#modifiers.findIndex(m => m.id === id);
2183
+ if (idx >= index.defaultAngle) {
2184
+ this.#modifiers.splice(idx, index.identity);
2185
+ }
2186
+ }
2111
2187
  reset() {
2112
2188
  for (const updater of this.#container.particleUpdaters) {
2113
2189
  updater.reset?.(this);
2114
2190
  }
2115
2191
  }
2192
+ #applyModifiers(base, getter) {
2193
+ let value = base;
2194
+ for (const mod of this.#modifiers) {
2195
+ if (mod.enabled) {
2196
+ const override = getter(mod);
2197
+ if (override !== undefined) {
2198
+ value = override;
2199
+ }
2200
+ }
2201
+ }
2202
+ return value;
2203
+ }
2116
2204
  #calcPosition(position, zIndex) {
2117
2205
  let tryCount = index.defaultRetryCount, posVec = position ? index.Vector3d.create(position.x, position.y, zIndex) : undefined;
2118
2206
  const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
@@ -310,29 +310,27 @@ function deepExtend(destination, ...sources) {
310
310
  }
311
311
  }
312
312
  else if (!isObject(destination) || Array.isArray(destination)) {
313
- destination = {};
313
+ destination = Object.create(null);
314
314
  }
315
- const sourceKeys = Object.keys(source), dangerousKeys = new Set(["__proto__", "constructor", "prototype"]), hasNested = sourceKeys.some(k => {
315
+ const sourceKeys = Object.keys(source), hasNested = sourceKeys.some(k => {
316
316
  const v = source[k];
317
317
  return isObject(v) || Array.isArray(v);
318
318
  });
319
319
  if (!hasNested) {
320
320
  const sourceDict = source, destDict = destination;
321
321
  for (const key of sourceKeys) {
322
- if (dangerousKeys.has(key)) {
322
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
323
323
  continue;
324
324
  }
325
- if (key in sourceDict) {
326
- const v = sourceDict[key];
327
- if (v !== undefined) {
328
- destDict[key] = v;
329
- }
325
+ const v = sourceDict[key];
326
+ if (v !== undefined) {
327
+ destDict[key] = v;
330
328
  }
331
329
  }
332
330
  continue;
333
331
  }
334
332
  for (const key of sourceKeys) {
335
- if (dangerousKeys.has(key)) {
333
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
336
334
  continue;
337
335
  }
338
336
  const sourceDict = source, destDict = destination, value = sourceDict[key];
@@ -748,7 +746,7 @@ class Engine {
748
746
  return this.#domArray;
749
747
  }
750
748
  get version() {
751
- return "4.2.1";
749
+ return "4.3.0";
752
750
  }
753
751
  addEventListener(type, listener) {
754
752
  this.#eventDispatcher.addEventListener(type, listener);
@@ -783,7 +781,7 @@ class Engine {
783
781
  if (typeof HTMLElement !== "undefined" && params.element instanceof HTMLElement) {
784
782
  domSourceElement = params.element;
785
783
  }
786
- const { Container } = await Promise.resolve().then(function () { return require('./Container-BIhHE6mu.js'); }), id = params.id ?? domSourceElement?.id ?? `tsparticles${Math.floor(getRandom() * loadRandomFactor).toString()}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options, currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container({
784
+ const { Container } = await Promise.resolve().then(function () { return require('./Container-lKWlltNc.js'); }), id = params.id ?? domSourceElement?.id ?? `tsparticles${Math.floor(getRandom() * loadRandomFactor).toString()}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options, currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container({
787
785
  dispatchCallback: (eventType, args) => {
788
786
  this.dispatchEvent(eventType, args);
789
787
  },
@@ -908,6 +906,18 @@ var AnimationStatus;
908
906
  AnimationStatus["decreasing"] = "decreasing";
909
907
  })(AnimationStatus || (AnimationStatus = {}));
910
908
 
909
+ exports.DrawLayer = void 0;
910
+ (function (DrawLayer) {
911
+ DrawLayer[DrawLayer["BackgroundElement"] = 0] = "BackgroundElement";
912
+ DrawLayer[DrawLayer["BackgroundDraw"] = 1] = "BackgroundDraw";
913
+ DrawLayer[DrawLayer["BackgroundMask"] = 2] = "BackgroundMask";
914
+ DrawLayer[DrawLayer["CanvasSetup"] = 3] = "CanvasSetup";
915
+ DrawLayer[DrawLayer["PluginContent"] = 4] = "PluginContent";
916
+ DrawLayer[DrawLayer["Particles"] = 5] = "Particles";
917
+ DrawLayer[DrawLayer["CanvasCleanup"] = 6] = "CanvasCleanup";
918
+ DrawLayer[DrawLayer["Foreground"] = 7] = "Foreground";
919
+ })(exports.DrawLayer || (exports.DrawLayer = {}));
920
+
911
921
  const tsParticles = initEngine();
912
922
 
913
923
  let initialized = false;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-BIoj1BEO.js');
3
+ var index = require('./index-CoHtf-OM.js');
4
4
 
5
5
 
6
6
 
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var index = require('./index-BjS63OiI.js');
4
- var index$1 = require('./index-BIoj1BEO.js');
4
+ var index$1 = require('./index-CoHtf-OM.js');
5
5
 
6
6
  const StencilParticles = class {
7
7
  constructor(hostRef) {