@tsparticles/pjs 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
- /* tsParticles v4.2.1 */
2
+ /* tsParticles 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) :
@@ -398,29 +398,27 @@
398
398
  }
399
399
  }
400
400
  else if (!isObject(destination) || Array.isArray(destination)) {
401
- destination = {};
401
+ destination = Object.create(null);
402
402
  }
403
- const sourceKeys = Object.keys(source), dangerousKeys = new Set(["__proto__", "constructor", "prototype"]), hasNested = sourceKeys.some(k => {
403
+ const sourceKeys = Object.keys(source), hasNested = sourceKeys.some(k => {
404
404
  const v = source[k];
405
405
  return isObject(v) || Array.isArray(v);
406
406
  });
407
407
  if (!hasNested) {
408
408
  const sourceDict = source, destDict = destination;
409
409
  for (const key of sourceKeys) {
410
- if (dangerousKeys.has(key)) {
410
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
411
411
  continue;
412
412
  }
413
- if (key in sourceDict) {
414
- const v = sourceDict[key];
415
- if (v !== undefined) {
416
- destDict[key] = v;
417
- }
413
+ const v = sourceDict[key];
414
+ if (v !== undefined) {
415
+ destDict[key] = v;
418
416
  }
419
417
  }
420
418
  continue;
421
419
  }
422
420
  for (const key of sourceKeys) {
423
- if (dangerousKeys.has(key)) {
421
+ if (key === "__proto__" || key === "constructor" || key === "prototype") {
424
422
  continue;
425
423
  }
426
424
  const sourceDict = source, destDict = destination, value = sourceDict[key];
@@ -879,7 +877,7 @@
879
877
  return this.#domArray;
880
878
  }
881
879
  get version() {
882
- return "4.2.1";
880
+ return "4.3.1";
883
881
  }
884
882
  addEventListener(type, listener) {
885
883
  this.#eventDispatcher.addEventListener(type, listener);
@@ -1112,6 +1110,18 @@
1112
1110
  AnimationStatus["decreasing"] = "decreasing";
1113
1111
  })(exports.AnimationStatus || (exports.AnimationStatus = {}));
1114
1112
 
1113
+ exports.DrawLayer = void 0;
1114
+ (function (DrawLayer) {
1115
+ DrawLayer[DrawLayer["BackgroundElement"] = 0] = "BackgroundElement";
1116
+ DrawLayer[DrawLayer["BackgroundDraw"] = 1] = "BackgroundDraw";
1117
+ DrawLayer[DrawLayer["BackgroundMask"] = 2] = "BackgroundMask";
1118
+ DrawLayer[DrawLayer["CanvasSetup"] = 3] = "CanvasSetup";
1119
+ DrawLayer[DrawLayer["PluginContent"] = 4] = "PluginContent";
1120
+ DrawLayer[DrawLayer["Particles"] = 5] = "Particles";
1121
+ DrawLayer[DrawLayer["CanvasCleanup"] = 6] = "CanvasCleanup";
1122
+ DrawLayer[DrawLayer["Foreground"] = 7] = "Foreground";
1123
+ })(exports.DrawLayer || (exports.DrawLayer = {}));
1124
+
1115
1125
  class OptionLoader {
1116
1126
  load(data) {
1117
1127
  if (isNull(data)) {
@@ -1270,6 +1280,8 @@
1270
1280
 
1271
1281
  class Background extends OptionLoader {
1272
1282
  color;
1283
+ draw;
1284
+ element;
1273
1285
  image = "";
1274
1286
  opacity = 1;
1275
1287
  position = "";
@@ -1284,6 +1296,8 @@
1284
1296
  if (data.color !== undefined) {
1285
1297
  this.color = OptionsColor.create(this.color, data.color);
1286
1298
  }
1299
+ loadProperty(this, "element", data.element);
1300
+ loadProperty(this, "draw", data.draw);
1287
1301
  loadProperty(this, "image", data.image);
1288
1302
  loadProperty(this, "position", data.position);
1289
1303
  loadProperty(this, "repeat", data.repeat);
@@ -1829,7 +1843,7 @@
1829
1843
  }
1830
1844
  }
1831
1845
 
1832
- const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, sdrReferenceWhiteNits = 203;
1846
+ const styleCache = new Map(), maxStyleCacheSize = 2000, rgbFixedPrecision = 2, hslFixedPrecision = 2, hdrRgbFixedPrecision = 4, hdrHslFixedPrecision = 4, sdrReferenceWhiteNits = 203, hdrAnimationScale = sdrReferenceWhiteNits / maxNits;
1833
1847
  function getCachedStyle(key, generator) {
1834
1848
  let cached = styleCache.get(key);
1835
1849
  if (!cached) {
@@ -1972,6 +1986,17 @@
1972
1986
  : 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));
1973
1987
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
1974
1988
  }
1989
+ function hslToRgbFloat(hsl) {
1990
+ 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;
1991
+ if (s === sMin) {
1992
+ const grayscaleValue = lNormalized * rgbMax;
1993
+ return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
1994
+ }
1995
+ const temp1 = lNormalized < half
1996
+ ? lNormalized * (sNormalizedOffset + sNormalized)
1997
+ : 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));
1998
+ return { r: red, g: green, b: blue };
1999
+ }
1975
2000
  function hslaToRgba(hsla) {
1976
2001
  const rgbResult = hslToRgb(hsla);
1977
2002
  return {
@@ -1981,8 +2006,16 @@
1981
2006
  r: rgbResult.r,
1982
2007
  };
1983
2008
  }
1984
- function getRandomRgbColor(min) {
1985
- const fixedMin = min ?? defaultRgbMin, fixedMax = rgbMax + identity$2, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
2009
+ function getRandomRgbColor(min, hdr) {
2010
+ const fixedMin = min ?? defaultRgbMin;
2011
+ if (hdr) {
2012
+ return {
2013
+ r: getRandomInRange(fixedMin, rgbMax),
2014
+ g: getRandomInRange(fixedMin, rgbMax),
2015
+ b: getRandomInRange(fixedMin, rgbMax),
2016
+ };
2017
+ }
2018
+ const fixedMax = rgbMax + identity$2, getRgbInRangeValue = () => Math.floor(getRandomInRange(fixedMin, fixedMax));
1986
2019
  return {
1987
2020
  b: getRgbInRangeValue(),
1988
2021
  g: getRgbInRangeValue(),
@@ -1990,7 +2023,7 @@
1990
2023
  };
1991
2024
  }
1992
2025
  function getStyleFromRgb(color, hdr, opacity) {
1993
- const op = opacity ?? defaultOpacity$3, key = `rgb-${color.r.toFixed(rgbFixedPrecision)}-${color.g.toFixed(rgbFixedPrecision)}-${color.b.toFixed(rgbFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2026
+ const rgbPrecision = hdr ? hdrRgbFixedPrecision : rgbFixedPrecision, op = opacity ?? defaultOpacity$3, key = `rgb-${color.r.toFixed(rgbPrecision)}-${color.g.toFixed(rgbPrecision)}-${color.b.toFixed(rgbPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
1994
2027
  return getCachedStyle(key, () => (hdr ? getHdrStyleFromRgb(color, opacity) : getSdrStyleFromRgb(color, opacity)));
1995
2028
  }
1996
2029
  function getHdrStyleFromRgb(color, opacity, peakNits = maxNits) {
@@ -2001,9 +2034,9 @@
2001
2034
  return `rgba(${color.r.toString()}, ${color.g.toString()}, ${color.b.toString()}, ${(opacity ?? defaultOpacity$3).toString()})`;
2002
2035
  }
2003
2036
  function getStyleFromHsl(color, hdr, opacity) {
2004
- const op = opacity ?? defaultOpacity$3, key = `hsl-${color.h.toFixed(hslFixedPrecision)}-${color.s.toFixed(hslFixedPrecision)}-${color.l.toFixed(hslFixedPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2037
+ const hslPrecision = hdr ? hdrHslFixedPrecision : hslFixedPrecision, op = opacity ?? defaultOpacity$3, key = `hsl-${color.h.toFixed(hslPrecision)}-${color.s.toFixed(hslPrecision)}-${color.l.toFixed(hslPrecision)}-${hdr ? "hdr" : "sdr"}-${op.toString()}`;
2005
2038
  return getCachedStyle(key, () => hdr
2006
- ? getStyleFromRgb(hslToRgb(color), true, opacity)
2039
+ ? getStyleFromRgb(hslToRgbFloat(color), true, opacity)
2007
2040
  : `hsla(${color.h.toString()}, ${color.s.toString()}%, ${color.l.toString()}%, ${op.toString()})`);
2008
2041
  }
2009
2042
  function colorMix(color1, color2, size1, size2) {
@@ -2123,7 +2156,7 @@
2123
2156
  colorValue.velocity = defaultVelocity;
2124
2157
  }
2125
2158
  }
2126
- function updateColorValue(data, decrease, delta) {
2159
+ function updateColorValue(data, decrease, delta, hdr) {
2127
2160
  const minLoops = 0, minDelay = 0, identity = 1, minVelocity = 0, minOffset = 0, velocityFactor = 3.6;
2128
2161
  if (!data.enable ||
2129
2162
  ((data.maxLoops ?? minLoops) > minLoops && (data.loops ?? minLoops) > (data.maxLoops ?? minLoops))) {
@@ -2136,7 +2169,7 @@
2136
2169
  if ((data.delayTime ?? minDelay) > minDelay && data.time < (data.delayTime ?? minDelay)) {
2137
2170
  return;
2138
2171
  }
2139
- 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;
2172
+ const offset = data.offset ? randomInRangeValue(data.offset) : minOffset, velocity = ((data.velocity ?? minVelocity) * delta.factor + offset * velocityFactor) * (hdr ? hdrAnimationScale : identity), decay = data.decay ?? identity, max = data.max, min = data.min;
2140
2173
  if (!decrease || data.status === exports.AnimationStatus.increasing) {
2141
2174
  data.value += velocity;
2142
2175
  if (data.value > max) {
@@ -2163,14 +2196,14 @@
2163
2196
  }
2164
2197
  data.value = clamp(data.value, min, max);
2165
2198
  }
2166
- function updateColor(color, delta) {
2199
+ function updateColor(color, delta, hdr) {
2167
2200
  if (!color) {
2168
2201
  return;
2169
2202
  }
2170
2203
  const { h, s, l } = color;
2171
- updateColorValue(h, false, delta);
2172
- updateColorValue(s, true, delta);
2173
- updateColorValue(l, true, delta);
2204
+ updateColorValue(h, false, delta, hdr);
2205
+ updateColorValue(s, true, delta, hdr);
2206
+ updateColorValue(l, true, delta, hdr);
2174
2207
  }
2175
2208
  function alterHsl(color, type, value) {
2176
2209
  return {
@@ -2767,7 +2800,7 @@
2767
2800
  }
2768
2801
 
2769
2802
  async function loadInteractivityPlugin(engine) {
2770
- engine.checkVersion("4.2.1");
2803
+ engine.checkVersion("4.3.1");
2771
2804
  await engine.pluginManager.register(e => {
2772
2805
  const interactivityEngine = e, interactivityPluginManager = interactivityEngine.pluginManager;
2773
2806
  interactivityPluginManager.addPlugin(new InteractivityPlugin(interactivityPluginManager));
@@ -3007,7 +3040,7 @@
3007
3040
  }
3008
3041
 
3009
3042
  async function loadAbsorbersInteraction(engine) {
3010
- engine.checkVersion("4.2.1");
3043
+ engine.checkVersion("4.3.1");
3011
3044
  await engine.pluginManager.register(async (e) => {
3012
3045
  const pluginManager = e.pluginManager, instancesManager = await getAbsorbersInstancesManager(e);
3013
3046
  ensureInteractivityPluginLoaded(e);
@@ -3055,7 +3088,7 @@
3055
3088
  }
3056
3089
 
3057
3090
  async function loadAbsorbersPluginSimple(engine) {
3058
- engine.checkVersion("4.2.1");
3091
+ engine.checkVersion("4.3.1");
3059
3092
  await engine.pluginManager.register(async (e) => {
3060
3093
  const pluginManager = e.pluginManager, instancesManager = await getAbsorbersInstancesManager(e);
3061
3094
  pluginManager.addPlugin(new AbsorbersPlugin(instancesManager));
@@ -3381,7 +3414,7 @@
3381
3414
  }
3382
3415
 
3383
3416
  async function loadDestroyUpdater(engine) {
3384
- engine.checkVersion("4.2.1");
3417
+ engine.checkVersion("4.3.1");
3385
3418
  await engine.pluginManager.register(e => {
3386
3419
  e.pluginManager.addParticleUpdater("destroy", container => {
3387
3420
  return Promise.resolve(new DestroyUpdater(e.pluginManager, container));
@@ -3699,7 +3732,7 @@
3699
3732
  })(EmitterClickMode || (EmitterClickMode = {}));
3700
3733
 
3701
3734
  async function loadEmittersInteraction(engine) {
3702
- engine.checkVersion("4.2.1");
3735
+ engine.checkVersion("4.3.1");
3703
3736
  await engine.pluginManager.register(async (e) => {
3704
3737
  const instancesManager = await getEmittersInstancesManager(e);
3705
3738
  ensureInteractivityPluginLoaded(e);
@@ -3742,7 +3775,7 @@
3742
3775
  }
3743
3776
 
3744
3777
  async function loadEmittersPluginSimple(engine) {
3745
- engine.checkVersion("4.2.1");
3778
+ engine.checkVersion("4.3.1");
3746
3779
  await engine.pluginManager.register(async (e) => {
3747
3780
  const instancesManager = await getEmittersInstancesManager(e);
3748
3781
  await addEmittersShapesManager(e);
@@ -3799,7 +3832,7 @@
3799
3832
  }
3800
3833
 
3801
3834
  async function loadEmittersShapeCircle(engine) {
3802
- engine.checkVersion("4.2.1");
3835
+ engine.checkVersion("4.3.1");
3803
3836
  await engine.pluginManager.register((e) => {
3804
3837
  ensureEmittersPluginLoaded(e);
3805
3838
  e.pluginManager.addEmitterShapeGenerator?.("circle", new EmittersCircleShapeGenerator());
@@ -3880,7 +3913,7 @@
3880
3913
  }
3881
3914
 
3882
3915
  async function loadEmittersShapeSquare(engine) {
3883
- engine.checkVersion("4.2.1");
3916
+ engine.checkVersion("4.3.1");
3884
3917
  await engine.pluginManager.register((e) => {
3885
3918
  ensureEmittersPluginLoaded(e);
3886
3919
  e.pluginManager.addEmitterShapeGenerator?.("square", new EmittersSquareShapeGenerator());
@@ -4062,7 +4095,7 @@
4062
4095
  }
4063
4096
 
4064
4097
  async function loadExternalDragInteraction(engine) {
4065
- engine.checkVersion("4.2.1");
4098
+ engine.checkVersion("4.3.1");
4066
4099
  await engine.pluginManager.register((e) => {
4067
4100
  ensureInteractivityPluginLoaded(e);
4068
4101
  e.pluginManager.addInteractor?.("externalDrag", container => {
@@ -4235,7 +4268,7 @@
4235
4268
  }
4236
4269
 
4237
4270
  async function loadExternalTrailInteraction(engine) {
4238
- engine.checkVersion("4.2.1");
4271
+ engine.checkVersion("4.3.1");
4239
4272
  await engine.pluginManager.register((e) => {
4240
4273
  ensureInteractivityPluginLoaded(e);
4241
4274
  e.pluginManager.addInteractor?.("externalTrail", container => {
@@ -4371,7 +4404,7 @@
4371
4404
  }
4372
4405
 
4373
4406
  async function loadRollUpdater(engine) {
4374
- engine.checkVersion("4.2.1");
4407
+ engine.checkVersion("4.3.1");
4375
4408
  await engine.pluginManager.register(e => {
4376
4409
  e.pluginManager.addParticleUpdater("roll", () => {
4377
4410
  return Promise.resolve(new RollUpdater(e.pluginManager));
@@ -4417,7 +4450,7 @@
4417
4450
  }
4418
4451
 
4419
4452
  async function loadBlendPlugin(engine) {
4420
- engine.checkVersion("4.2.1");
4453
+ engine.checkVersion("4.3.1");
4421
4454
  await engine.pluginManager.register(e => {
4422
4455
  e.pluginManager.addPlugin(new BlendPlugin());
4423
4456
  });
@@ -4454,7 +4487,7 @@
4454
4487
  }
4455
4488
 
4456
4489
  async function loadCircleShape(engine) {
4457
- engine.checkVersion("4.2.1");
4490
+ engine.checkVersion("4.3.1");
4458
4491
  await engine.pluginManager.register(e => {
4459
4492
  e.pluginManager.addShape(["circle"], () => {
4460
4493
  return Promise.resolve(new CircleDrawer());
@@ -4502,7 +4535,7 @@
4502
4535
  }
4503
4536
 
4504
4537
  async function loadHexColorPlugin(engine) {
4505
- engine.checkVersion("4.2.1");
4538
+ engine.checkVersion("4.3.1");
4506
4539
  await engine.pluginManager.register(e => {
4507
4540
  e.pluginManager.addColorManager("hex", new HexColorManager());
4508
4541
  });
@@ -4555,7 +4588,7 @@
4555
4588
  }
4556
4589
 
4557
4590
  async function loadHslColorPlugin(engine) {
4558
- engine.checkVersion("4.2.1");
4591
+ engine.checkVersion("4.3.1");
4559
4592
  await engine.pluginManager.register(e => {
4560
4593
  e.pluginManager.addColorManager("hsl", new HslColorManager());
4561
4594
  });
@@ -4579,7 +4612,7 @@
4579
4612
  }
4580
4613
 
4581
4614
  async function loadMovePlugin(engine) {
4582
- engine.checkVersion("4.2.1");
4615
+ engine.checkVersion("4.3.1");
4583
4616
  await engine.pluginManager.register(e => {
4584
4617
  const moveEngine = e, movePluginManager = moveEngine.pluginManager;
4585
4618
  movePluginManager.initializers.pathGenerators ??= new Map();
@@ -4795,7 +4828,7 @@
4795
4828
  }
4796
4829
 
4797
4830
  async function loadOpacityUpdater(engine) {
4798
- engine.checkVersion("4.2.1");
4831
+ engine.checkVersion("4.3.1");
4799
4832
  await engine.pluginManager.register(e => {
4800
4833
  e.pluginManager.addParticleUpdater("opacity", container => {
4801
4834
  return Promise.resolve(new OpacityUpdater(container));
@@ -5140,7 +5173,7 @@
5140
5173
  }
5141
5174
 
5142
5175
  async function loadOutModesUpdater(engine) {
5143
- engine.checkVersion("4.2.1");
5176
+ engine.checkVersion("4.3.1");
5144
5177
  await engine.pluginManager.register(e => {
5145
5178
  e.pluginManager.addParticleUpdater("outModes", container => {
5146
5179
  return Promise.resolve(new OutOfCanvasUpdater(container));
@@ -5205,13 +5238,13 @@
5205
5238
  if (!this.isEnabled(particle)) {
5206
5239
  return;
5207
5240
  }
5208
- updateColor(particle.fillColor, delta);
5209
- updateColor(particle.strokeColor, delta);
5241
+ updateColor(particle.fillColor, delta, this.#container.hdr);
5242
+ updateColor(particle.strokeColor, delta, this.#container.hdr);
5210
5243
  }
5211
5244
  }
5212
5245
 
5213
5246
  async function loadPaintUpdater(engine) {
5214
- engine.checkVersion("4.2.1");
5247
+ engine.checkVersion("4.3.1");
5215
5248
  await engine.pluginManager.register(e => {
5216
5249
  e.pluginManager.addParticleUpdater("paint", container => {
5217
5250
  return Promise.resolve(new PaintUpdater(e.pluginManager, container));
@@ -5266,7 +5299,7 @@
5266
5299
  }
5267
5300
 
5268
5301
  async function loadRgbColorPlugin(engine) {
5269
- engine.checkVersion("4.2.1");
5302
+ engine.checkVersion("4.3.1");
5270
5303
  await engine.pluginManager.register(e => {
5271
5304
  e.pluginManager.addColorManager("rgb", new RgbColorManager());
5272
5305
  });
@@ -5351,7 +5384,7 @@
5351
5384
  }
5352
5385
 
5353
5386
  async function loadSizeUpdater(engine) {
5354
- engine.checkVersion("4.2.1");
5387
+ engine.checkVersion("4.3.1");
5355
5388
  await engine.pluginManager.register(e => {
5356
5389
  e.pluginManager.addParticleUpdater("size", container => {
5357
5390
  return Promise.resolve(new SizeUpdater(container));
@@ -5360,7 +5393,7 @@
5360
5393
  }
5361
5394
 
5362
5395
  async function loadBasic(engine) {
5363
- engine.checkVersion("4.2.1");
5396
+ engine.checkVersion("4.3.1");
5364
5397
  await engine.pluginManager.register(async (e) => {
5365
5398
  await Promise.all([
5366
5399
  loadBlendPlugin(e),
@@ -5383,7 +5416,7 @@
5383
5416
  easingsFunctions.set("ease-in-out-quad", value => (value < 0.5 ? 2 * value ** 2 : 1 - (-2 * value + 2) ** 2 / 2));
5384
5417
 
5385
5418
  async function loadEasingQuadPlugin(engine) {
5386
- engine.checkVersion("4.2.1");
5419
+ engine.checkVersion("4.3.1");
5387
5420
  await engine.pluginManager.register(e => {
5388
5421
  for (const [easing, easingFn] of easingsFunctions) {
5389
5422
  e.pluginManager.addEasing(easing, easingFn);
@@ -5491,7 +5524,7 @@
5491
5524
  }
5492
5525
 
5493
5526
  async function loadEmojiShape(engine) {
5494
- engine.checkVersion("4.2.1");
5527
+ engine.checkVersion("4.3.1");
5495
5528
  await engine.pluginManager.register(e => {
5496
5529
  e.pluginManager.addShape(validTypes$1, () => Promise.resolve(new EmojiDrawer()));
5497
5530
  });
@@ -5724,7 +5757,7 @@
5724
5757
  };
5725
5758
 
5726
5759
  async function loadExternalAttractInteraction(engine) {
5727
- engine.checkVersion("4.2.1");
5760
+ engine.checkVersion("4.3.1");
5728
5761
  await engine.pluginManager.register((e) => {
5729
5762
  ensureInteractivityPluginLoaded(e);
5730
5763
  e.pluginManager.addInteractor?.("externalAttract", container => {
@@ -5913,7 +5946,7 @@
5913
5946
  }
5914
5947
 
5915
5948
  async function loadExternalBounceInteraction(engine) {
5916
- engine.checkVersion("4.2.1");
5949
+ engine.checkVersion("4.3.1");
5917
5950
  await engine.pluginManager.register((e) => {
5918
5951
  ensureInteractivityPluginLoaded(e);
5919
5952
  e.pluginManager.addInteractor?.("externalBounce", container => {
@@ -5973,6 +6006,19 @@
5973
6006
  }
5974
6007
  }
5975
6008
 
6009
+ class BubbleModifier {
6010
+ div;
6011
+ enabled = false;
6012
+ fillColor;
6013
+ finalColor;
6014
+ id = "bubble";
6015
+ inRange = false;
6016
+ opacity;
6017
+ priority = 100;
6018
+ radius;
6019
+ strokeColor;
6020
+ }
6021
+
5976
6022
  var ProcessBubbleType;
5977
6023
  (function (ProcessBubbleType) {
5978
6024
  ProcessBubbleType["color"] = "color";
@@ -5996,6 +6042,7 @@
5996
6042
  class Bubbler extends ExternalInteractorBase {
5997
6043
  handleClickMode;
5998
6044
  #maxDistance;
6045
+ #modifiers = new WeakMap();
5999
6046
  #pluginManager;
6000
6047
  constructor(pluginManager, container) {
6001
6048
  super(container);
@@ -6014,13 +6061,21 @@
6014
6061
  return this.#maxDistance;
6015
6062
  }
6016
6063
  clear(particle, _delta, force) {
6017
- if (particle.bubble.inRange && !force) {
6064
+ const mod = this.#modifiers.get(particle);
6065
+ if (mod?.inRange && !force) {
6018
6066
  return;
6019
6067
  }
6020
- delete particle.bubble.div;
6021
- delete particle.bubble.opacity;
6022
- delete particle.bubble.radius;
6023
- delete particle.bubble.color;
6068
+ particle.removeModifier(bubbleMode);
6069
+ this.#modifiers.delete(particle);
6070
+ }
6071
+ getOrCreateModifier(particle) {
6072
+ let mod = this.#modifiers.get(particle);
6073
+ if (!mod) {
6074
+ mod = new BubbleModifier();
6075
+ this.#modifiers.set(particle, mod);
6076
+ particle.addModifier(mod);
6077
+ }
6078
+ return mod;
6024
6079
  }
6025
6080
  init() {
6026
6081
  const container = this.container, bubble = container.actualOptions.interactivity?.modes.bubble;
@@ -6066,7 +6121,11 @@
6066
6121
  loadOptionProperty(options, "bubble", Bubble, ...sources);
6067
6122
  }
6068
6123
  reset(_interactivityData, particle) {
6069
- particle.bubble.inRange = false;
6124
+ const mod = this.#modifiers.get(particle);
6125
+ if (mod) {
6126
+ mod.enabled = false;
6127
+ mod.inRange = false;
6128
+ }
6070
6129
  }
6071
6130
  #clickBubble(interactivityData) {
6072
6131
  const container = this.container, options = container.actualOptions, mouseClickPos = interactivityData.mouse.clickPosition, bubbleOptions = options.interactivity?.modes.bubble;
@@ -6083,7 +6142,9 @@
6083
6142
  if (!bubble.clicking) {
6084
6143
  continue;
6085
6144
  }
6086
- particle.bubble.inRange = !bubble.durationEnd;
6145
+ const mod = this.getOrCreateModifier(particle);
6146
+ mod.enabled = !bubble.durationEnd;
6147
+ mod.inRange = !bubble.durationEnd;
6087
6148
  const pos = particle.getPosition(), distMouse = getDistance(pos, mouseClickPos), timeSpent = (performance.now() - (interactivityData.mouse.clickTime ?? defaultClickTime)) / millisecondsToSeconds;
6088
6149
  if (timeSpent > bubbleOptions.duration) {
6089
6150
  bubble.durationEnd = true;
@@ -6095,7 +6156,7 @@
6095
6156
  const sizeData = {
6096
6157
  bubbleObj: {
6097
6158
  optValue: container.retina.bubbleModeSize,
6098
- value: particle.bubble.radius,
6159
+ value: mod.radius,
6099
6160
  },
6100
6161
  particlesObj: {
6101
6162
  optValue: particle.size.max,
@@ -6107,7 +6168,7 @@
6107
6168
  const opacityData = {
6108
6169
  bubbleObj: {
6109
6170
  optValue: bubbleOptions.opacity,
6110
- value: particle.bubble.opacity,
6171
+ value: mod.opacity,
6111
6172
  },
6112
6173
  particlesObj: {
6113
6174
  optValue: particle.opacity?.max ?? defaultOpacity$1,
@@ -6120,7 +6181,8 @@
6120
6181
  this.#hoverBubbleColor(particle, distMouse);
6121
6182
  }
6122
6183
  else {
6123
- delete particle.bubble.color;
6184
+ mod.fillColor = undefined;
6185
+ mod.strokeColor = undefined;
6124
6186
  }
6125
6187
  }
6126
6188
  }
@@ -6131,7 +6193,9 @@
6131
6193
  }
6132
6194
  const query = container.particles.grid.queryCircle(mousePos, distance, p => this.isEnabled(interactivityData, p));
6133
6195
  for (const particle of query) {
6134
- particle.bubble.inRange = true;
6196
+ const mod = this.getOrCreateModifier(particle);
6197
+ mod.enabled = true;
6198
+ mod.inRange = true;
6135
6199
  const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos), ratio = ratioOffset - pointDistance / distance;
6136
6200
  if (pointDistance <= distance) {
6137
6201
  if (ratio >= minRatio && interactivityData.status === mouseMoveEvent) {
@@ -6149,30 +6213,38 @@
6149
6213
  }
6150
6214
  }
6151
6215
  #hoverBubbleColor(particle, ratio, divBubble) {
6152
- const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity?.modes.bubble;
6216
+ const options = this.container.actualOptions, bubbleOptions = divBubble ?? options.interactivity?.modes.bubble, mod = this.getOrCreateModifier(particle);
6153
6217
  if (!bubbleOptions) {
6154
6218
  return;
6155
6219
  }
6156
- if (!particle.bubble.finalColor) {
6220
+ if (!mod.finalColor) {
6157
6221
  const modeColor = bubbleOptions.color;
6158
6222
  if (!modeColor) {
6159
6223
  return;
6160
6224
  }
6161
6225
  const bubbleColor = itemFromSingleOrMultiple(modeColor);
6162
- particle.bubble.finalColor = rangeColorToHsl(this.#pluginManager, bubbleColor);
6226
+ mod.finalColor = rangeColorToHsl(this.#pluginManager, bubbleColor);
6163
6227
  }
6164
- if (!particle.bubble.finalColor) {
6228
+ if (!mod.finalColor) {
6165
6229
  return;
6166
6230
  }
6167
6231
  if (bubbleOptions.mix) {
6168
- particle.bubble.color = undefined;
6232
+ mod.fillColor = undefined;
6233
+ mod.strokeColor = undefined;
6169
6234
  const pColor = particle.getFillColor();
6170
- particle.bubble.color = pColor
6171
- ? rgbToHsl(colorMix(pColor, particle.bubble.finalColor, ratioOffset - ratio, ratio))
6172
- : particle.bubble.finalColor;
6235
+ if (pColor) {
6236
+ const mixedColor = rgbToHsl(colorMix(pColor, mod.finalColor, ratioOffset - ratio, ratio));
6237
+ mod.fillColor = mixedColor;
6238
+ mod.strokeColor = mixedColor;
6239
+ }
6240
+ else {
6241
+ mod.fillColor = mod.finalColor;
6242
+ mod.strokeColor = mod.finalColor;
6243
+ }
6173
6244
  }
6174
6245
  else {
6175
- particle.bubble.color = particle.bubble.finalColor;
6246
+ mod.fillColor = mod.finalColor;
6247
+ mod.strokeColor = mod.finalColor;
6176
6248
  }
6177
6249
  }
6178
6250
  #hoverBubbleOpacity(particle, ratio, divBubble) {
@@ -6182,7 +6254,8 @@
6182
6254
  }
6183
6255
  const pOpacity = particle.opacity?.value ?? defaultOpacity$1, opacity = calculateBubbleValue(pOpacity, modeOpacity, particle.opacity?.max ?? defaultOpacity$1, ratio);
6184
6256
  if (opacity !== undefined) {
6185
- particle.bubble.opacity = opacity;
6257
+ const mod = this.getOrCreateModifier(particle);
6258
+ mod.opacity = opacity;
6186
6259
  }
6187
6260
  }
6188
6261
  #hoverBubbleSize(particle, ratio, divBubble) {
@@ -6192,7 +6265,8 @@
6192
6265
  }
6193
6266
  const pSize = particle.size.value, size = calculateBubbleValue(pSize, modeSize, particle.size.max, ratio);
6194
6267
  if (size !== undefined) {
6195
- particle.bubble.radius = size;
6268
+ const mod = this.getOrCreateModifier(particle);
6269
+ mod.radius = size;
6196
6270
  }
6197
6271
  }
6198
6272
  #process(particle, distMouse, timeSpent, data) {
@@ -6205,13 +6279,14 @@
6205
6279
  return;
6206
6280
  }
6207
6281
  container.bubble ??= {};
6282
+ const mod = this.getOrCreateModifier(particle);
6208
6283
  if (container.bubble.durationEnd) {
6209
6284
  if (pObjBubble) {
6210
6285
  if (type === ProcessBubbleType.size) {
6211
- delete particle.bubble.radius;
6286
+ mod.radius = undefined;
6212
6287
  }
6213
6288
  if (type === ProcessBubbleType.opacity) {
6214
- delete particle.bubble.opacity;
6289
+ mod.opacity = undefined;
6215
6290
  }
6216
6291
  }
6217
6292
  }
@@ -6221,19 +6296,19 @@
6221
6296
  if (obj !== bubbleParam) {
6222
6297
  const value = pObj - (timeSpent * (pObj - bubbleParam)) / bubbleDuration;
6223
6298
  if (type === ProcessBubbleType.size) {
6224
- particle.bubble.radius = value;
6299
+ mod.radius = value;
6225
6300
  }
6226
6301
  if (type === ProcessBubbleType.opacity) {
6227
- particle.bubble.opacity = value;
6302
+ mod.opacity = value;
6228
6303
  }
6229
6304
  }
6230
6305
  }
6231
6306
  else {
6232
6307
  if (type === ProcessBubbleType.size) {
6233
- delete particle.bubble.radius;
6308
+ mod.radius = undefined;
6234
6309
  }
6235
6310
  if (type === ProcessBubbleType.opacity) {
6236
- delete particle.bubble.opacity;
6311
+ mod.opacity = undefined;
6237
6312
  }
6238
6313
  }
6239
6314
  }
@@ -6254,11 +6329,13 @@
6254
6329
  if (!area.contains(particle.getPosition())) {
6255
6330
  continue;
6256
6331
  }
6257
- particle.bubble.inRange = true;
6332
+ const mod = this.getOrCreateModifier(particle);
6333
+ mod.enabled = true;
6334
+ mod.inRange = true;
6258
6335
  const divs = bubble.divs, divBubble = divMode(divs, elem);
6259
- if (!particle.bubble.div || particle.bubble.div !== elem) {
6336
+ if (!mod.div || mod.div !== elem) {
6260
6337
  this.clear(particle, delta, true);
6261
- particle.bubble.div = elem;
6338
+ mod.div = elem;
6262
6339
  }
6263
6340
  this.#hoverBubbleSize(particle, defaultRatio, divBubble);
6264
6341
  this.#hoverBubbleOpacity(particle, defaultRatio, divBubble);
@@ -6269,7 +6346,7 @@
6269
6346
  }
6270
6347
 
6271
6348
  async function loadExternalBubbleInteraction(engine) {
6272
- engine.checkVersion("4.2.1");
6349
+ engine.checkVersion("4.3.1");
6273
6350
  await engine.pluginManager.register((e) => {
6274
6351
  ensureInteractivityPluginLoaded(e);
6275
6352
  e.pluginManager.addInteractor?.("externalBubble", container => {
@@ -6397,7 +6474,7 @@
6397
6474
  }
6398
6475
 
6399
6476
  async function loadExternalConnectInteraction(engine) {
6400
- engine.checkVersion("4.2.1");
6477
+ engine.checkVersion("4.3.1");
6401
6478
  await engine.pluginManager.register((e) => {
6402
6479
  ensureInteractivityPluginLoaded(e);
6403
6480
  e.pluginManager.addInteractor?.("externalConnect", container => {
@@ -6501,7 +6578,7 @@
6501
6578
  }
6502
6579
 
6503
6580
  async function loadExternalDestroyInteraction(engine) {
6504
- engine.checkVersion("4.2.1");
6581
+ engine.checkVersion("4.3.1");
6505
6582
  await engine.pluginManager.register((e) => {
6506
6583
  ensureInteractivityPluginLoaded(e);
6507
6584
  e.pluginManager.addInteractor?.("externalDestroy", async (container) => {
@@ -6625,7 +6702,7 @@
6625
6702
  }
6626
6703
 
6627
6704
  async function loadExternalGrabInteraction(engine) {
6628
- engine.checkVersion("4.2.1");
6705
+ engine.checkVersion("4.3.1");
6629
6706
  await engine.pluginManager.register((e) => {
6630
6707
  ensureInteractivityPluginLoaded(e);
6631
6708
  e.pluginManager.addInteractor?.("externalGrab", container => {
@@ -6695,7 +6772,7 @@
6695
6772
  }
6696
6773
 
6697
6774
  async function loadExternalParallaxInteraction(engine) {
6698
- engine.checkVersion("4.2.1");
6775
+ engine.checkVersion("4.3.1");
6699
6776
  await engine.pluginManager.register((e) => {
6700
6777
  ensureInteractivityPluginLoaded(e);
6701
6778
  e.pluginManager.addInteractor?.("externalParallax", container => {
@@ -6738,7 +6815,7 @@
6738
6815
  }
6739
6816
 
6740
6817
  async function loadExternalPauseInteraction(engine) {
6741
- engine.checkVersion("4.2.1");
6818
+ engine.checkVersion("4.3.1");
6742
6819
  await engine.pluginManager.register((e) => {
6743
6820
  ensureInteractivityPluginLoaded(e);
6744
6821
  e.pluginManager.addInteractor?.("externalPause", container => {
@@ -6810,7 +6887,7 @@
6810
6887
  }
6811
6888
 
6812
6889
  async function loadExternalPushInteraction(engine) {
6813
- engine.checkVersion("4.2.1");
6890
+ engine.checkVersion("4.3.1");
6814
6891
  await engine.pluginManager.register((e) => {
6815
6892
  ensureInteractivityPluginLoaded(e);
6816
6893
  e.pluginManager.addInteractor?.("externalPush", container => {
@@ -6864,7 +6941,7 @@
6864
6941
  }
6865
6942
 
6866
6943
  async function loadExternalRemoveInteraction(engine) {
6867
- engine.checkVersion("4.2.1");
6944
+ engine.checkVersion("4.3.1");
6868
6945
  await engine.pluginManager.register((e) => {
6869
6946
  ensureInteractivityPluginLoaded(e);
6870
6947
  e.pluginManager.addInteractor?.("externalRemove", container => {
@@ -7170,7 +7247,7 @@
7170
7247
  }
7171
7248
 
7172
7249
  async function loadExternalRepulseInteraction(engine) {
7173
- engine.checkVersion("4.2.1");
7250
+ engine.checkVersion("4.3.1");
7174
7251
  await engine.pluginManager.register((e) => {
7175
7252
  ensureInteractivityPluginLoaded(e);
7176
7253
  const pluginManager = e.pluginManager;
@@ -7192,9 +7269,17 @@
7192
7269
  }
7193
7270
  }
7194
7271
 
7272
+ class SlowModifier {
7273
+ enabled = false;
7274
+ id = "slow";
7275
+ priority = 100;
7276
+ speedFactor = 1;
7277
+ }
7278
+
7195
7279
  const slowMode = "slow", minRadius$1 = 0;
7196
7280
  class Slower extends ExternalInteractorBase {
7197
7281
  #maxDistance;
7282
+ #modifiers = new WeakMap();
7198
7283
  constructor(container) {
7199
7284
  super(container);
7200
7285
  this.#maxDistance = 0;
@@ -7203,10 +7288,21 @@
7203
7288
  return this.#maxDistance;
7204
7289
  }
7205
7290
  clear(particle, _delta, force) {
7206
- if (particle.slow.inRange && !force) {
7291
+ const mod = this.#modifiers.get(particle);
7292
+ if (mod?.enabled && !force) {
7207
7293
  return;
7208
7294
  }
7209
- particle.slow.factor = 1;
7295
+ particle.removeModifier(slowMode);
7296
+ this.#modifiers.delete(particle);
7297
+ }
7298
+ getOrCreateModifier(particle) {
7299
+ let mod = this.#modifiers.get(particle);
7300
+ if (!mod) {
7301
+ mod = new SlowModifier();
7302
+ this.#modifiers.set(particle, mod);
7303
+ particle.addModifier(mod);
7304
+ }
7305
+ return mod;
7210
7306
  }
7211
7307
  init() {
7212
7308
  const container = this.container, slow = container.actualOptions.interactivity?.modes.slow;
@@ -7226,22 +7322,26 @@
7226
7322
  loadOptionProperty(options, "slow", Slow, ...sources);
7227
7323
  }
7228
7324
  reset(interactivityData, particle) {
7229
- particle.slow.inRange = false;
7325
+ const mod = this.#modifiers.get(particle);
7326
+ if (mod) {
7327
+ mod.enabled = false;
7328
+ }
7230
7329
  const container = this.container, options = container.actualOptions, mousePos = interactivityData.mouse.position, radius = container.retina.slowModeRadius, slowOptions = options.interactivity?.modes.slow;
7231
7330
  if (!slowOptions || !radius || radius < minRadius$1 || !mousePos) {
7232
7331
  return;
7233
7332
  }
7234
- const particlePos = particle.getPosition(), dist = getDistance(mousePos, particlePos), proximityFactor = dist / radius, slowFactor = slowOptions.factor, { slow } = particle;
7333
+ const particlePos = particle.getPosition(), dist = getDistance(mousePos, particlePos), proximityFactor = dist / radius, slowFactor = slowOptions.factor;
7235
7334
  if (dist > radius) {
7236
7335
  return;
7237
7336
  }
7238
- slow.inRange = true;
7239
- slow.factor = proximityFactor / slowFactor;
7337
+ const activeMod = this.getOrCreateModifier(particle);
7338
+ activeMod.enabled = true;
7339
+ activeMod.speedFactor = proximityFactor / slowFactor;
7240
7340
  }
7241
7341
  }
7242
7342
 
7243
7343
  async function loadExternalSlowInteraction(engine) {
7244
- engine.checkVersion("4.2.1");
7344
+ engine.checkVersion("4.3.1");
7245
7345
  await engine.pluginManager.register((e) => {
7246
7346
  ensureInteractivityPluginLoaded(e);
7247
7347
  e.pluginManager.addInteractor?.("externalSlow", container => {
@@ -7303,7 +7403,6 @@
7303
7403
  function replaceImageColor(image, imageData, color, particle, hdr = false) {
7304
7404
  const svgColoredData = replaceColorSvg(image, color, particle.opacity?.value ?? defaultOpacity, hdr), imageRes = {
7305
7405
  color,
7306
- gif: imageData.gif,
7307
7406
  data: {
7308
7407
  ...image,
7309
7408
  svgData: svgColoredData,
@@ -7338,495 +7437,6 @@
7338
7437
  });
7339
7438
  }
7340
7439
 
7341
- const InterlaceOffsets = [0, 4, 2, 1];
7342
- const InterlaceSteps = [8, 8, 4, 2];
7343
-
7344
- class ByteStream {
7345
- data;
7346
- pos;
7347
- constructor(bytes) {
7348
- this.pos = 0;
7349
- this.data = new Uint8ClampedArray(bytes);
7350
- }
7351
- getString(count) {
7352
- const slice = this.data.slice(this.pos, this.pos + count);
7353
- this.pos += slice.length;
7354
- return slice.reduce((acc, curr) => acc + String.fromCharCode(curr), "");
7355
- }
7356
- nextByte() {
7357
- return this.data[this.pos++];
7358
- }
7359
- nextTwoBytes() {
7360
- const increment = 2, previous = 1, shift = 8;
7361
- this.pos += increment;
7362
- return this.data[this.pos - increment] + (this.data[this.pos - previous] << shift);
7363
- }
7364
- readSubBlocks() {
7365
- let blockString = "", size;
7366
- const minCount = 0, emptySize = 0;
7367
- do {
7368
- size = this.data[this.pos++];
7369
- for (let count = size; --count >= minCount; blockString += String.fromCharCode(this.data[this.pos++])) {
7370
- }
7371
- } while (size !== emptySize);
7372
- return blockString;
7373
- }
7374
- readSubBlocksBin() {
7375
- let size = this.data[this.pos], len = 0;
7376
- const emptySize = 0, increment = 1;
7377
- for (let offset = 0; size !== emptySize; offset += size + increment, size = this.data[this.pos + offset]) {
7378
- len += size;
7379
- }
7380
- const blockData = new Uint8Array(len);
7381
- size = this.data[this.pos++];
7382
- for (let i = 0; size !== emptySize; size = this.data[this.pos++]) {
7383
- for (let count = size; --count >= emptySize; blockData[i++] = this.data[this.pos++]) {
7384
- }
7385
- }
7386
- return blockData;
7387
- }
7388
- skipSubBlocks() {
7389
- for (const increment = 1, noData = 0; this.data[this.pos] !== noData; this.pos += this.data[this.pos] + increment) {
7390
- }
7391
- this.pos++;
7392
- }
7393
- }
7394
-
7395
- var DisposalMethod;
7396
- (function (DisposalMethod) {
7397
- DisposalMethod[DisposalMethod["Replace"] = 0] = "Replace";
7398
- DisposalMethod[DisposalMethod["Combine"] = 1] = "Combine";
7399
- DisposalMethod[DisposalMethod["RestoreBackground"] = 2] = "RestoreBackground";
7400
- DisposalMethod[DisposalMethod["RestorePrevious"] = 3] = "RestorePrevious";
7401
- DisposalMethod[DisposalMethod["UndefinedA"] = 4] = "UndefinedA";
7402
- DisposalMethod[DisposalMethod["UndefinedB"] = 5] = "UndefinedB";
7403
- DisposalMethod[DisposalMethod["UndefinedC"] = 6] = "UndefinedC";
7404
- DisposalMethod[DisposalMethod["UndefinedD"] = 7] = "UndefinedD";
7405
- })(DisposalMethod || (DisposalMethod = {}));
7406
-
7407
- var GIFDataHeaders;
7408
- (function (GIFDataHeaders) {
7409
- GIFDataHeaders[GIFDataHeaders["Extension"] = 33] = "Extension";
7410
- GIFDataHeaders[GIFDataHeaders["ApplicationExtension"] = 255] = "ApplicationExtension";
7411
- GIFDataHeaders[GIFDataHeaders["GraphicsControlExtension"] = 249] = "GraphicsControlExtension";
7412
- GIFDataHeaders[GIFDataHeaders["PlainTextExtension"] = 1] = "PlainTextExtension";
7413
- GIFDataHeaders[GIFDataHeaders["CommentExtension"] = 254] = "CommentExtension";
7414
- GIFDataHeaders[GIFDataHeaders["Image"] = 44] = "Image";
7415
- GIFDataHeaders[GIFDataHeaders["EndOfFile"] = 59] = "EndOfFile";
7416
- })(GIFDataHeaders || (GIFDataHeaders = {}));
7417
-
7418
- const defaultFrame = 0, initialTime = 0, firstIndex$2 = 0, defaultLoopCount = 0;
7419
- function parseColorTable(byteStream, count) {
7420
- const colors = [];
7421
- for (let i = 0; i < count; i++) {
7422
- colors.push({
7423
- r: byteStream.data[byteStream.pos],
7424
- g: byteStream.data[byteStream.pos + 1],
7425
- b: byteStream.data[byteStream.pos + 2],
7426
- });
7427
- byteStream.pos += 3;
7428
- }
7429
- return colors;
7430
- }
7431
- function parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex) {
7432
- switch (byteStream.nextByte()) {
7433
- case GIFDataHeaders.GraphicsControlExtension: {
7434
- const frame = gif.frames[getFrameIndex(false)];
7435
- byteStream.pos++;
7436
- const packedByte = byteStream.nextByte();
7437
- frame.GCreserved = (packedByte & 0xe0) >>> 5;
7438
- frame.disposalMethod = (packedByte & 0x1c) >>> 2;
7439
- frame.userInputDelayFlag = (packedByte & 2) === 2;
7440
- const transparencyFlag = (packedByte & 1) === 1;
7441
- frame.delayTime = byteStream.nextTwoBytes() * 0xa;
7442
- const transparencyIndex = byteStream.nextByte();
7443
- if (transparencyFlag) {
7444
- getTransparencyIndex(transparencyIndex);
7445
- }
7446
- byteStream.pos++;
7447
- break;
7448
- }
7449
- case GIFDataHeaders.ApplicationExtension: {
7450
- byteStream.pos++;
7451
- const applicationExtension = {
7452
- identifier: byteStream.getString(8),
7453
- authenticationCode: byteStream.getString(3),
7454
- data: byteStream.readSubBlocksBin(),
7455
- };
7456
- gif.applicationExtensions.push(applicationExtension);
7457
- break;
7458
- }
7459
- case GIFDataHeaders.CommentExtension: {
7460
- gif.comments.push([getFrameIndex(false), byteStream.readSubBlocks()]);
7461
- break;
7462
- }
7463
- case GIFDataHeaders.PlainTextExtension: {
7464
- if (gif.globalColorTable.length === 0) {
7465
- throw new EvalError("plain text extension without global color table");
7466
- }
7467
- byteStream.pos++;
7468
- gif.frames[getFrameIndex(false)].plainTextData = {
7469
- left: byteStream.nextTwoBytes(),
7470
- top: byteStream.nextTwoBytes(),
7471
- width: byteStream.nextTwoBytes(),
7472
- height: byteStream.nextTwoBytes(),
7473
- charSize: {
7474
- width: byteStream.nextTwoBytes(),
7475
- height: byteStream.nextTwoBytes(),
7476
- },
7477
- foregroundColor: byteStream.nextByte(),
7478
- backgroundColor: byteStream.nextByte(),
7479
- text: byteStream.readSubBlocks(),
7480
- };
7481
- break;
7482
- }
7483
- default:
7484
- byteStream.skipSubBlocks();
7485
- break;
7486
- }
7487
- }
7488
- function readBits(imageData, pos, len) {
7489
- const bytePos = pos >>> 3, bitPos = pos & 7;
7490
- return (((imageData[bytePos] + (imageData[bytePos + 1] << 8) + (imageData[bytePos + 2] << 16)) &
7491
- (((1 << len) - 1) << bitPos)) >>>
7492
- bitPos);
7493
- }
7494
- async function parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {
7495
- const frame = gif.frames[getFrameIndex(true)];
7496
- frame.left = byteStream.nextTwoBytes();
7497
- frame.top = byteStream.nextTwoBytes();
7498
- frame.width = byteStream.nextTwoBytes();
7499
- frame.height = byteStream.nextTwoBytes();
7500
- const packedByte = byteStream.nextByte(), localColorTableFlag = (packedByte & 0x80) === 0x80, interlacedFlag = (packedByte & 0x40) === 0x40;
7501
- frame.sortFlag = (packedByte & 0x20) === 0x20;
7502
- frame.reserved = (packedByte & 0x18) >>> 3;
7503
- const localColorCount = 1 << ((packedByte & 7) + 1);
7504
- if (localColorTableFlag) {
7505
- frame.localColorTable = parseColorTable(byteStream, localColorCount);
7506
- }
7507
- const getColor = (index) => {
7508
- const { r, g, b } = (localColorTableFlag ? frame.localColorTable : gif.globalColorTable)[index];
7509
- if (index !== getTransparencyIndex(null)) {
7510
- return { r, g, b, a: 255 };
7511
- }
7512
- return { r, g, b, a: avgAlpha ? Math.trunc((r + g + b) / 3) : 0 };
7513
- }, image = (() => {
7514
- try {
7515
- return new ImageData(frame.width, frame.height, canvasSettings);
7516
- }
7517
- catch (error) {
7518
- if (error instanceof DOMException && error.name === "IndexSizeError") {
7519
- return null;
7520
- }
7521
- throw error;
7522
- }
7523
- })();
7524
- if (image == null) {
7525
- throw new EvalError("GIF frame size is to large");
7526
- }
7527
- const minCodeSize = byteStream.nextByte(), imageData = byteStream.readSubBlocksBin(), clearCode = 1 << minCodeSize;
7528
- if (interlacedFlag) {
7529
- for (let code = 0, size = minCodeSize + 1, pos = 0, dic = [[0]], pass = 0; pass < 4; pass++) {
7530
- if (InterlaceOffsets[pass] < frame.height) {
7531
- let pixelPos = 0, lineIndex = 0, exit = false;
7532
- while (!exit) {
7533
- const last = code;
7534
- code = readBits(imageData, pos, size);
7535
- pos += size + 1;
7536
- if (code === clearCode) {
7537
- size = minCodeSize + 1;
7538
- dic.length = clearCode + 2;
7539
- for (let i = 0; i < dic.length; i++) {
7540
- dic[i] = i < clearCode ? [i] : [];
7541
- }
7542
- }
7543
- else {
7544
- if (code >= dic.length) {
7545
- dic.push(dic[last].concat(dic[last][0]));
7546
- }
7547
- else if (last !== clearCode) {
7548
- dic.push(dic[last].concat(dic[code][0]));
7549
- }
7550
- for (const item of dic[code]) {
7551
- const { r, g, b, a } = getColor(item);
7552
- image.data.set([r, g, b, a], InterlaceOffsets[pass] * frame.width +
7553
- InterlaceSteps[pass] * lineIndex +
7554
- (pixelPos % (frame.width * 4)));
7555
- pixelPos += 4;
7556
- }
7557
- if (dic.length === 1 << size && size < 0xc) {
7558
- size++;
7559
- }
7560
- }
7561
- if (pixelPos === frame.width * 4 * (lineIndex + 1)) {
7562
- lineIndex++;
7563
- if (InterlaceOffsets[pass] + InterlaceSteps[pass] * lineIndex >= frame.height) {
7564
- exit = true;
7565
- }
7566
- }
7567
- }
7568
- }
7569
- }
7570
- frame.image = image;
7571
- frame.bitmap = await createImageBitmap(image);
7572
- }
7573
- else {
7574
- let code = 0, size = minCodeSize + 1, pos = 0, pixelPos = -4;
7575
- const dic = [[0]];
7576
- for (;;) {
7577
- const last = code;
7578
- code = readBits(imageData, pos, size);
7579
- pos += size;
7580
- if (code === clearCode) {
7581
- size = minCodeSize + 1;
7582
- dic.length = clearCode + 2;
7583
- for (let i = 0; i < dic.length; i++) {
7584
- dic[i] = i < clearCode ? [i] : [];
7585
- }
7586
- }
7587
- else {
7588
- if (code === clearCode + 1) {
7589
- break;
7590
- }
7591
- if (code >= dic.length) {
7592
- dic.push(dic[last].concat(dic[last][0]));
7593
- }
7594
- else if (last !== clearCode) {
7595
- dic.push(dic[last].concat(dic[code][0]));
7596
- }
7597
- for (const item of dic[code]) {
7598
- const { r, g, b, a } = getColor(item);
7599
- pixelPos += 4;
7600
- image.data.set([r, g, b, a], pixelPos);
7601
- }
7602
- if (dic.length >= 1 << size && size < 0xc) {
7603
- size++;
7604
- }
7605
- }
7606
- }
7607
- frame.image = image;
7608
- frame.bitmap = await createImageBitmap(image);
7609
- }
7610
- }
7611
- async function parseBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings, progressCallback) {
7612
- switch (byteStream.nextByte()) {
7613
- case GIFDataHeaders.EndOfFile:
7614
- return true;
7615
- case GIFDataHeaders.Image:
7616
- await parseImageBlock(byteStream, gif, avgAlpha, getFrameIndex, getTransparencyIndex, canvasSettings);
7617
- break;
7618
- case GIFDataHeaders.Extension:
7619
- parseExtensionBlock(byteStream, gif, getFrameIndex, getTransparencyIndex);
7620
- break;
7621
- default:
7622
- throw new EvalError("undefined block found");
7623
- }
7624
- return false;
7625
- }
7626
- function getGIFLoopAmount(gif) {
7627
- for (const extension of gif.applicationExtensions) {
7628
- if (extension.identifier + extension.authenticationCode !== "NETSCAPE2.0") {
7629
- continue;
7630
- }
7631
- return extension.data[1] + (extension.data[2] << 8);
7632
- }
7633
- return Number.NaN;
7634
- }
7635
- async function decodeGIF(gifURL, canvasSettings, progressCallback, avgAlpha) {
7636
- avgAlpha ??= false;
7637
- const res = await fetch(gifURL);
7638
- if (!res.ok && res.status === 404) {
7639
- throw new EvalError("file not found");
7640
- }
7641
- const buffer = await res.arrayBuffer(), gif = {
7642
- width: 0,
7643
- height: 0,
7644
- totalTime: 0,
7645
- colorRes: 0,
7646
- pixelAspectRatio: 0,
7647
- frames: [],
7648
- sortFlag: false,
7649
- globalColorTable: [],
7650
- backgroundImage: new ImageData(1, 1, canvasSettings),
7651
- comments: [],
7652
- applicationExtensions: [],
7653
- }, byteStream = new ByteStream(new Uint8ClampedArray(buffer));
7654
- if (byteStream.getString(6) !== "GIF89a") {
7655
- throw new Error("not a supported GIF file");
7656
- }
7657
- gif.width = byteStream.nextTwoBytes();
7658
- gif.height = byteStream.nextTwoBytes();
7659
- const packedByte = byteStream.nextByte(), globalColorTableFlag = (packedByte & 0x80) === 0x80;
7660
- gif.colorRes = (packedByte & 0x70) >>> 4;
7661
- gif.sortFlag = (packedByte & 8) === 8;
7662
- const globalColorCount = 1 << ((packedByte & 7) + 1), backgroundColorIndex = byteStream.nextByte();
7663
- gif.pixelAspectRatio = byteStream.nextByte();
7664
- if (gif.pixelAspectRatio !== 0) {
7665
- gif.pixelAspectRatio = (gif.pixelAspectRatio + 0xf) / 0x40;
7666
- }
7667
- if (globalColorTableFlag) {
7668
- gif.globalColorTable = parseColorTable(byteStream, globalColorCount);
7669
- }
7670
- const backgroundImage = (() => {
7671
- try {
7672
- return new ImageData(gif.width, gif.height, canvasSettings);
7673
- }
7674
- catch (error) {
7675
- if (error instanceof DOMException && error.name === "IndexSizeError") {
7676
- return null;
7677
- }
7678
- throw error;
7679
- }
7680
- })();
7681
- if (backgroundImage == null) {
7682
- throw new Error("GIF frame size is to large");
7683
- }
7684
- const { r, g, b } = gif.globalColorTable[backgroundColorIndex];
7685
- backgroundImage.data.set(globalColorTableFlag ? [r, g, b, 255] : [0, 0, 0, 0]);
7686
- for (let i = 4; i < backgroundImage.data.length; i *= 2) {
7687
- backgroundImage.data.copyWithin(i, 0, i);
7688
- }
7689
- gif.backgroundImage = backgroundImage;
7690
- let frameIndex = -1, incrementFrameIndex = true, transparencyIndex = -1;
7691
- const getframeIndex = (increment) => {
7692
- if (increment) {
7693
- incrementFrameIndex = true;
7694
- }
7695
- return frameIndex;
7696
- }, getTransparencyIndex = (newValue) => {
7697
- if (newValue != null) {
7698
- transparencyIndex = newValue;
7699
- }
7700
- return transparencyIndex;
7701
- };
7702
- try {
7703
- do {
7704
- if (incrementFrameIndex) {
7705
- gif.frames.push({
7706
- left: 0,
7707
- top: 0,
7708
- width: 0,
7709
- height: 0,
7710
- disposalMethod: DisposalMethod.Replace,
7711
- image: new ImageData(1, 1, canvasSettings),
7712
- plainTextData: null,
7713
- userInputDelayFlag: false,
7714
- delayTime: 0,
7715
- sortFlag: false,
7716
- localColorTable: [],
7717
- reserved: 0,
7718
- GCreserved: 0,
7719
- });
7720
- frameIndex++;
7721
- transparencyIndex = -1;
7722
- incrementFrameIndex = false;
7723
- }
7724
- } while (!(await parseBlock(byteStream, gif, avgAlpha, getframeIndex, getTransparencyIndex, canvasSettings, progressCallback)));
7725
- gif.frames.length--;
7726
- for (const frame of gif.frames) {
7727
- if (frame.userInputDelayFlag && frame.delayTime === 0) {
7728
- gif.totalTime = Infinity;
7729
- break;
7730
- }
7731
- gif.totalTime += frame.delayTime;
7732
- }
7733
- return gif;
7734
- }
7735
- catch (error) {
7736
- if (error instanceof EvalError) {
7737
- throw new Error(`error while parsing frame ${frameIndex.toString()} "${error.message}"`, { cause: error });
7738
- }
7739
- throw error;
7740
- }
7741
- }
7742
- function drawGif(data, canvasSettings) {
7743
- const { context, radius, particle, delta } = data, image = particle.image;
7744
- if (!image?.gifData || !image.gif) {
7745
- return;
7746
- }
7747
- const offscreenCanvas = new OffscreenCanvas(image.gifData.width, image.gifData.height), offscreenContext = offscreenCanvas.getContext("2d", canvasSettings);
7748
- if (!offscreenContext) {
7749
- throw new Error("could not create offscreen canvas context");
7750
- }
7751
- offscreenContext.imageSmoothingQuality = "low";
7752
- offscreenContext.imageSmoothingEnabled = false;
7753
- offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
7754
- particle.gifLoopCount ??= image.gifLoopCount ?? defaultLoopCount;
7755
- let frameIndex = particle.gifFrame ?? defaultFrame;
7756
- const pos = { x: -image.gifData.width * half, y: -image.gifData.height * half }, frame = image.gifData.frames[frameIndex];
7757
- particle.gifTime ??= initialTime;
7758
- if (!frame.bitmap) {
7759
- return;
7760
- }
7761
- context.scale(radius / image.gifData.width, radius / image.gifData.height);
7762
- switch (frame.disposalMethod) {
7763
- case DisposalMethod.UndefinedA:
7764
- case DisposalMethod.UndefinedB:
7765
- case DisposalMethod.UndefinedC:
7766
- case DisposalMethod.UndefinedD:
7767
- case DisposalMethod.Replace:
7768
- offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
7769
- context.drawImage(offscreenCanvas, pos.x, pos.y);
7770
- offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
7771
- break;
7772
- case DisposalMethod.Combine:
7773
- offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
7774
- context.drawImage(offscreenCanvas, pos.x, pos.y);
7775
- break;
7776
- case DisposalMethod.RestoreBackground:
7777
- offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
7778
- context.drawImage(offscreenCanvas, pos.x, pos.y);
7779
- offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
7780
- if (!image.gifData.globalColorTable.length) {
7781
- offscreenContext.putImageData(image.gifData.frames[firstIndex$2].image, pos.x + frame.left, pos.y + frame.top);
7782
- }
7783
- else {
7784
- offscreenContext.putImageData(image.gifData.backgroundImage, pos.x, pos.y);
7785
- }
7786
- break;
7787
- case DisposalMethod.RestorePrevious:
7788
- {
7789
- const previousImageData = offscreenContext.getImageData(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
7790
- offscreenContext.drawImage(frame.bitmap, frame.left, frame.top);
7791
- context.drawImage(offscreenCanvas, pos.x, pos.y);
7792
- offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
7793
- offscreenContext.putImageData(previousImageData, originPoint.x, originPoint.y);
7794
- }
7795
- break;
7796
- }
7797
- particle.gifTime += delta.value;
7798
- if (particle.gifTime > frame.delayTime) {
7799
- particle.gifTime -= frame.delayTime;
7800
- if (++frameIndex >= image.gifData.frames.length) {
7801
- if (--particle.gifLoopCount <= defaultLoopCount) {
7802
- return;
7803
- }
7804
- frameIndex = firstIndex$2;
7805
- offscreenContext.clearRect(originPoint.x, originPoint.y, offscreenCanvas.width, offscreenCanvas.height);
7806
- }
7807
- particle.gifFrame = frameIndex;
7808
- }
7809
- context.scale(image.gifData.width / radius, image.gifData.height / radius);
7810
- }
7811
- async function loadGifImage(image, canvasSettings) {
7812
- if (image.type !== "gif") {
7813
- await loadImage(image);
7814
- return;
7815
- }
7816
- image.loading = true;
7817
- try {
7818
- image.gifData = await decodeGIF(image.source, canvasSettings);
7819
- image.gifLoopCount = getGIFLoopAmount(image.gifData);
7820
- if (!image.gifLoopCount) {
7821
- image.gifLoopCount = Infinity;
7822
- }
7823
- }
7824
- catch {
7825
- image.error = true;
7826
- }
7827
- image.loading = false;
7828
- }
7829
-
7830
7440
  const sides$3 = 12;
7831
7441
  class ImageDrawer {
7832
7442
  #container;
@@ -7841,10 +7451,7 @@
7841
7451
  return;
7842
7452
  }
7843
7453
  context.globalAlpha = opacity;
7844
- if (image.gif && image.gifData) {
7845
- drawGif(data, this.#container.canvas.render.settings);
7846
- }
7847
- else if (element) {
7454
+ if (element) {
7848
7455
  const ratio = image.ratio, pos = {
7849
7456
  x: -radius,
7850
7457
  y: -radius,
@@ -7913,9 +7520,6 @@
7913
7520
  color,
7914
7521
  data: image,
7915
7522
  element: image.element,
7916
- gif: image.gif,
7917
- gifData: image.gifData,
7918
- gifLoopCount: image.gifLoopCount,
7919
7523
  loaded: true,
7920
7524
  ratio: imageData.width && imageData.height ? imageData.width / imageData.height : (image.ratio ?? defaultRatio$1),
7921
7525
  replaceColor: replaceColor,
@@ -7938,7 +7542,6 @@
7938
7542
  throw new Error(`Image shape not initialized`);
7939
7543
  }
7940
7544
  await this.#engine.loadImage(container, {
7941
- gif: imageShape.gif,
7942
7545
  name: imageShape.name,
7943
7546
  replaceColor: imageShape.replaceColor,
7944
7547
  src: imageShape.src,
@@ -7947,7 +7550,6 @@
7947
7550
  }
7948
7551
 
7949
7552
  class Preload {
7950
- gif = false;
7951
7553
  height;
7952
7554
  name;
7953
7555
  replaceColor;
@@ -7957,7 +7559,6 @@
7957
7559
  if (isNull(data)) {
7958
7560
  return;
7959
7561
  }
7960
- loadProperty(this, "gif", data.gif);
7961
7562
  loadProperty(this, "height", data.height);
7962
7563
  loadProperty(this, "name", data.name);
7963
7564
  loadProperty(this, "replaceColor", data.replaceColor);
@@ -8024,7 +7625,6 @@
8024
7625
  }
8025
7626
  try {
8026
7627
  const image = {
8027
- gif: data.gif,
8028
7628
  name: data.name ?? data.src,
8029
7629
  source: data.src,
8030
7630
  type: data.src.substring(data.src.length - extLength),
@@ -8036,10 +7636,7 @@
8036
7636
  containerImages.push(image);
8037
7637
  engine.images.set(container, containerImages);
8038
7638
  let imageFunc;
8039
- if (data.gif) {
8040
- imageFunc = (img) => loadGifImage(img, { colorSpace: "srgb" });
8041
- }
8042
- else if (data.replaceColor) {
7639
+ if (data.replaceColor) {
8043
7640
  imageFunc = downloadSvgImage;
8044
7641
  }
8045
7642
  else {
@@ -8053,7 +7650,7 @@
8053
7650
  };
8054
7651
  }
8055
7652
  async function loadImageShape(engine) {
8056
- engine.checkVersion("4.2.1");
7653
+ engine.checkVersion("4.3.1");
8057
7654
  await engine.pluginManager.register(e => {
8058
7655
  addLoadImageToEngine(e);
8059
7656
  e.pluginManager.addPlugin(new ImagePreloaderPlugin(e));
@@ -8198,7 +7795,7 @@
8198
7795
  }
8199
7796
 
8200
7797
  async function loadLifeUpdater(engine) {
8201
- engine.checkVersion("4.2.1");
7798
+ engine.checkVersion("4.3.1");
8202
7799
  await engine.pluginManager.register(e => {
8203
7800
  e.pluginManager.addParticleUpdater("life", container => {
8204
7801
  return Promise.resolve(new LifeUpdater(container));
@@ -8224,7 +7821,7 @@
8224
7821
  }
8225
7822
 
8226
7823
  async function loadLineShape(engine) {
8227
- engine.checkVersion("4.2.1");
7824
+ engine.checkVersion("4.3.1");
8228
7825
  await engine.pluginManager.register(e => {
8229
7826
  e.pluginManager.addShape(["line"], () => Promise.resolve(new LineDrawer()));
8230
7827
  });
@@ -8308,7 +7905,7 @@
8308
7905
  }
8309
7906
 
8310
7907
  async function loadParticlesAttractInteraction(engine) {
8311
- engine.checkVersion("4.2.1");
7908
+ engine.checkVersion("4.3.1");
8312
7909
  await engine.pluginManager.register((e) => {
8313
7910
  ensureInteractivityPluginLoaded(e);
8314
7911
  e.pluginManager.addInteractor?.("particlesAttract", container => {
@@ -8518,7 +8115,7 @@
8518
8115
  }
8519
8116
 
8520
8117
  async function loadParticlesCollisionsInteraction(engine) {
8521
- engine.checkVersion("4.2.1");
8118
+ engine.checkVersion("4.3.1");
8522
8119
  await engine.pluginManager.register((e) => {
8523
8120
  ensureInteractivityPluginLoaded(e);
8524
8121
  e.pluginManager.addPlugin(new OverlapPlugin());
@@ -8772,7 +8369,7 @@
8772
8369
  }
8773
8370
 
8774
8371
  async function loadParticlesLinksInteraction(engine) {
8775
- engine.checkVersion("4.2.1");
8372
+ engine.checkVersion("4.3.1");
8776
8373
  await engine.pluginManager.register((e) => {
8777
8374
  const pluginManager = e.pluginManager;
8778
8375
  ensureInteractivityPluginLoaded(e);
@@ -8862,19 +8459,19 @@
8862
8459
  }
8863
8460
 
8864
8461
  async function loadGenericPolygonShape(engine) {
8865
- engine.checkVersion("4.2.1");
8462
+ engine.checkVersion("4.3.1");
8866
8463
  await engine.pluginManager.register(e => {
8867
8464
  e.pluginManager.addShape(["polygon"], () => Promise.resolve(new PolygonDrawer()));
8868
8465
  });
8869
8466
  }
8870
8467
  async function loadTriangleShape(engine) {
8871
- engine.checkVersion("4.2.1");
8468
+ engine.checkVersion("4.3.1");
8872
8469
  await engine.pluginManager.register(e => {
8873
8470
  e.pluginManager.addShape(["triangle"], () => Promise.resolve(new TriangleDrawer()));
8874
8471
  });
8875
8472
  }
8876
8473
  async function loadPolygonShape(engine) {
8877
- engine.checkVersion("4.2.1");
8474
+ engine.checkVersion("4.3.1");
8878
8475
  await Promise.all([
8879
8476
  loadGenericPolygonShape(engine),
8880
8477
  loadTriangleShape(engine),
@@ -8979,7 +8576,7 @@
8979
8576
  }
8980
8577
 
8981
8578
  async function loadRotateUpdater(engine) {
8982
- engine.checkVersion("4.2.1");
8579
+ engine.checkVersion("4.3.1");
8983
8580
  await engine.pluginManager.register(e => {
8984
8581
  e.pluginManager.addParticleUpdater("rotate", container => {
8985
8582
  return Promise.resolve(new RotateUpdater(container));
@@ -9003,7 +8600,7 @@
9003
8600
  }
9004
8601
 
9005
8602
  async function loadSquareShape(engine) {
9006
- engine.checkVersion("4.2.1");
8603
+ engine.checkVersion("4.3.1");
9007
8604
  await engine.pluginManager.register(e => {
9008
8605
  e.pluginManager.addShape(["edge", "square"], () => Promise.resolve(new SquareDrawer()));
9009
8606
  });
@@ -9037,14 +8634,14 @@
9037
8634
  }
9038
8635
 
9039
8636
  async function loadStarShape(engine) {
9040
- engine.checkVersion("4.2.1");
8637
+ engine.checkVersion("4.3.1");
9041
8638
  await engine.pluginManager.register(e => {
9042
8639
  e.pluginManager.addShape(["star"], () => Promise.resolve(new StarDrawer()));
9043
8640
  });
9044
8641
  }
9045
8642
 
9046
8643
  async function loadSlim(engine) {
9047
- engine.checkVersion("4.2.1");
8644
+ engine.checkVersion("4.3.1");
9048
8645
  await engine.pluginManager.register(async (e) => {
9049
8646
  const loadInteractivityForSlim = async (e) => {
9050
8647
  await loadInteractivityPlugin(e);
@@ -9161,7 +8758,7 @@
9161
8758
  }
9162
8759
 
9163
8760
  async function loadTextShape(engine) {
9164
- engine.checkVersion("4.2.1");
8761
+ engine.checkVersion("4.3.1");
9165
8762
  await engine.pluginManager.register(e => {
9166
8763
  e.pluginManager.addShape(validTypes, () => Promise.resolve(new TextDrawer()));
9167
8764
  });
@@ -9270,7 +8867,7 @@
9270
8867
  }
9271
8868
 
9272
8869
  async function loadTiltUpdater(engine) {
9273
- engine.checkVersion("4.2.1");
8870
+ engine.checkVersion("4.3.1");
9274
8871
  await engine.pluginManager.register(e => {
9275
8872
  e.pluginManager.addParticleUpdater("tilt", container => {
9276
8873
  return Promise.resolve(new TiltUpdater(container));
@@ -9374,7 +8971,7 @@
9374
8971
  }
9375
8972
 
9376
8973
  async function loadTwinkleUpdater(engine) {
9377
- engine.checkVersion("4.2.1");
8974
+ engine.checkVersion("4.3.1");
9378
8975
  await engine.pluginManager.register(e => {
9379
8976
  e.pluginManager.addParticleUpdater("twinkle", container => {
9380
8977
  return Promise.resolve(new TwinkleUpdater(e.pluginManager, container));
@@ -9476,7 +9073,7 @@
9476
9073
  }
9477
9074
 
9478
9075
  async function loadWobbleUpdater(engine) {
9479
- engine.checkVersion("4.2.1");
9076
+ engine.checkVersion("4.3.1");
9480
9077
  await engine.pluginManager.register(e => {
9481
9078
  e.pluginManager.addParticleUpdater("wobble", container => {
9482
9079
  return Promise.resolve(new WobbleUpdater(container));
@@ -9485,7 +9082,7 @@
9485
9082
  }
9486
9083
 
9487
9084
  async function loadFull(engine) {
9488
- engine.checkVersion("4.2.1");
9085
+ engine.checkVersion("4.3.1");
9489
9086
  await engine.pluginManager.register(async (e) => {
9490
9087
  const loadEmittersPluginBundle = async (e) => {
9491
9088
  await loadEmittersPlugin(e);
@@ -9585,14 +9182,14 @@
9585
9182
  }
9586
9183
 
9587
9184
  async function loadResponsivePlugin(engine) {
9588
- engine.checkVersion("4.2.1");
9185
+ engine.checkVersion("4.3.1");
9589
9186
  await engine.pluginManager.register(e => {
9590
9187
  e.pluginManager.addPlugin(new ResponsivePlugin());
9591
9188
  });
9592
9189
  }
9593
9190
 
9594
9191
  const initPjs = async (engine) => {
9595
- engine.checkVersion("4.2.1");
9192
+ engine.checkVersion("4.3.1");
9596
9193
  await engine.pluginManager.register(async (e) => {
9597
9194
  await Promise.all([loadFull(e), loadResponsivePlugin(e)]);
9598
9195
  });
@@ -9614,10 +9211,10 @@
9614
9211
  }
9615
9212
  }
9616
9213
  class RenderManager {
9214
+ #backgroundElement;
9215
+ #backgroundWarnings;
9617
9216
  #canvasClearPlugins;
9618
9217
  #canvasManager;
9619
- #canvasPaintPlugins;
9620
- #clearDrawPlugins;
9621
9218
  #colorPlugins;
9622
9219
  #container;
9623
9220
  #context;
@@ -9625,9 +9222,7 @@
9625
9222
  #drawParticlePlugins;
9626
9223
  #drawParticlesCleanupPlugins;
9627
9224
  #drawParticlesSetupPlugins;
9628
- #drawPlugins;
9629
- #drawSettingsCleanupPlugins;
9630
- #drawSettingsSetupPlugins;
9225
+ #layers;
9631
9226
  #pluginManager;
9632
9227
  #postDrawUpdaters;
9633
9228
  #preDrawUpdaters;
@@ -9639,18 +9234,25 @@
9639
9234
  this.#container = container;
9640
9235
  this.#canvasManager = canvasManager;
9641
9236
  this.#context = null;
9237
+ this.#backgroundElement = null;
9238
+ this.#backgroundWarnings = new Set();
9642
9239
  this.#preDrawUpdaters = [];
9643
9240
  this.#postDrawUpdaters = [];
9644
- this.#colorPlugins = [];
9645
9241
  this.#canvasClearPlugins = [];
9646
- this.#canvasPaintPlugins = [];
9647
- this.#clearDrawPlugins = [];
9242
+ this.#colorPlugins = [];
9648
9243
  this.#drawParticlePlugins = [];
9649
9244
  this.#drawParticlesCleanupPlugins = [];
9650
9245
  this.#drawParticlesSetupPlugins = [];
9651
- this.#drawPlugins = [];
9652
- this.#drawSettingsSetupPlugins = [];
9653
- this.#drawSettingsCleanupPlugins = [];
9246
+ this.#layers = {
9247
+ 0: [],
9248
+ 1: [],
9249
+ 2: [],
9250
+ 3: [],
9251
+ 4: [],
9252
+ 5: [],
9253
+ 6: [],
9254
+ 7: [],
9255
+ };
9654
9256
  }
9655
9257
  get settings() {
9656
9258
  return this.#contextSettings;
@@ -9664,32 +9266,38 @@
9664
9266
  });
9665
9267
  }
9666
9268
  clear() {
9667
- let pluginHandled = false;
9668
9269
  for (const plugin of this.#canvasClearPlugins) {
9669
- pluginHandled = plugin.canvasClear?.() ?? false;
9670
- if (pluginHandled) {
9671
- break;
9270
+ if (plugin.canvasClear?.() ?? false) {
9271
+ return;
9672
9272
  }
9673
9273
  }
9674
- if (pluginHandled) {
9675
- return;
9274
+ for (const layer of Object.values(exports.DrawLayer)) {
9275
+ if (typeof layer === "number") {
9276
+ for (const plugin of this.#getLayerPlugins(layer)) {
9277
+ if (plugin.canvasClear?.() ?? false) {
9278
+ return;
9279
+ }
9280
+ }
9281
+ }
9676
9282
  }
9677
9283
  this.canvasClear();
9678
9284
  }
9679
9285
  destroy() {
9680
9286
  this.stop();
9287
+ this.#backgroundElement = null;
9288
+ this.#backgroundWarnings.clear();
9681
9289
  this.#preDrawUpdaters = [];
9682
9290
  this.#postDrawUpdaters = [];
9683
- this.#colorPlugins = [];
9684
9291
  this.#canvasClearPlugins = [];
9685
- this.#canvasPaintPlugins = [];
9686
- this.#clearDrawPlugins = [];
9292
+ this.#colorPlugins = [];
9687
9293
  this.#drawParticlePlugins = [];
9688
9294
  this.#drawParticlesCleanupPlugins = [];
9689
9295
  this.#drawParticlesSetupPlugins = [];
9690
- this.#drawPlugins = [];
9691
- this.#drawSettingsSetupPlugins = [];
9692
- this.#drawSettingsCleanupPlugins = [];
9296
+ for (const layer of Object.values(exports.DrawLayer)) {
9297
+ if (typeof layer === "number") {
9298
+ this.#layers[layer] = [];
9299
+ }
9300
+ }
9693
9301
  }
9694
9302
  draw(cb) {
9695
9303
  const ctx = this.#context;
@@ -9746,21 +9354,40 @@
9746
9354
  });
9747
9355
  }
9748
9356
  drawParticles(delta) {
9749
- const { particles } = this.#container;
9357
+ const { particles, actualOptions } = this.#container;
9750
9358
  this.clear();
9751
9359
  particles.update(delta);
9752
9360
  this.draw(ctx => {
9753
- for (const plugin of this.#drawSettingsSetupPlugins) {
9361
+ const width = this.#canvasManager.size.width, height = this.#canvasManager.size.height;
9362
+ if (this.#backgroundElement) {
9363
+ try {
9364
+ ctx.drawImage(this.#backgroundElement, originPoint.x, originPoint.y, width, height);
9365
+ }
9366
+ catch {
9367
+ this.#warnOnce("background-element-draw-error", "Error drawing background element onto canvas");
9368
+ }
9369
+ }
9370
+ const background = actualOptions.background;
9371
+ if (background.draw) {
9372
+ try {
9373
+ background.draw(ctx, delta);
9374
+ }
9375
+ catch {
9376
+ this.#warnOnce("background-draw-error", "Error in background.draw callback");
9377
+ }
9378
+ }
9379
+ for (const plugin of this.#getLayerPlugins(exports.DrawLayer.BackgroundMask)) {
9380
+ plugin.canvasPaint?.();
9381
+ }
9382
+ for (const plugin of this.#getLayerPlugins(exports.DrawLayer.CanvasSetup)) {
9754
9383
  plugin.drawSettingsSetup?.(ctx, delta);
9755
9384
  }
9756
- for (const plugin of this.#drawPlugins) {
9385
+ for (const plugin of this.#getLayerPlugins(exports.DrawLayer.PluginContent)) {
9757
9386
  plugin.draw?.(ctx, delta);
9758
9387
  }
9759
9388
  particles.drawParticles(delta);
9760
- for (const plugin of this.#clearDrawPlugins) {
9389
+ for (const plugin of this.#getLayerPlugins(exports.DrawLayer.CanvasCleanup)) {
9761
9390
  plugin.clearDraw?.(ctx, delta);
9762
- }
9763
- for (const plugin of this.#drawSettingsCleanupPlugins) {
9764
9391
  plugin.drawSettingsCleanup?.(ctx, delta);
9765
9392
  }
9766
9393
  });
@@ -9768,29 +9395,24 @@
9768
9395
  init() {
9769
9396
  this.initUpdaters();
9770
9397
  this.initPlugins();
9398
+ this.#resolveBackgroundElement();
9771
9399
  this.paint();
9772
9400
  }
9773
9401
  initPlugins() {
9774
- this.#colorPlugins = [];
9775
9402
  this.#canvasClearPlugins = [];
9776
- this.#canvasPaintPlugins = [];
9777
- this.#clearDrawPlugins = [];
9403
+ this.#colorPlugins = [];
9778
9404
  this.#drawParticlePlugins = [];
9779
9405
  this.#drawParticlesSetupPlugins = [];
9780
9406
  this.#drawParticlesCleanupPlugins = [];
9781
- this.#drawPlugins = [];
9782
- this.#drawSettingsSetupPlugins = [];
9783
- this.#drawSettingsCleanupPlugins = [];
9407
+ for (const layer of Object.values(exports.DrawLayer)) {
9408
+ if (typeof layer === "number") {
9409
+ this.#layers[layer] = [];
9410
+ }
9411
+ }
9784
9412
  for (const plugin of this.#container.plugins) {
9785
9413
  if (plugin.particleFillColor ?? plugin.particleStrokeColor) {
9786
9414
  this.#colorPlugins.push(plugin);
9787
9415
  }
9788
- if (plugin.canvasClear) {
9789
- this.#canvasClearPlugins.push(plugin);
9790
- }
9791
- if (plugin.canvasPaint) {
9792
- this.#canvasPaintPlugins.push(plugin);
9793
- }
9794
9416
  if (plugin.drawParticle) {
9795
9417
  this.#drawParticlePlugins.push(plugin);
9796
9418
  }
@@ -9800,17 +9422,20 @@
9800
9422
  if (plugin.drawParticleCleanup) {
9801
9423
  this.#drawParticlesCleanupPlugins.push(plugin);
9802
9424
  }
9803
- if (plugin.draw) {
9804
- this.#drawPlugins.push(plugin);
9425
+ if (plugin.canvasClear) {
9426
+ this.#canvasClearPlugins.push(plugin);
9427
+ }
9428
+ if (plugin.canvasPaint) {
9429
+ this.#getLayerPlugins(exports.DrawLayer.BackgroundMask).push(plugin);
9805
9430
  }
9806
9431
  if (plugin.drawSettingsSetup) {
9807
- this.#drawSettingsSetupPlugins.push(plugin);
9432
+ this.#getLayerPlugins(exports.DrawLayer.CanvasSetup).push(plugin);
9808
9433
  }
9809
- if (plugin.drawSettingsCleanup) {
9810
- this.#drawSettingsCleanupPlugins.push(plugin);
9434
+ if (plugin.draw) {
9435
+ this.#getLayerPlugins(exports.DrawLayer.PluginContent).push(plugin);
9811
9436
  }
9812
- if (plugin.clearDraw) {
9813
- this.#clearDrawPlugins.push(plugin);
9437
+ if (plugin.clearDraw ?? plugin.drawSettingsCleanup) {
9438
+ this.#getLayerPlugins(exports.DrawLayer.CanvasCleanup).push(plugin);
9814
9439
  }
9815
9440
  }
9816
9441
  }
@@ -9828,7 +9453,7 @@
9828
9453
  }
9829
9454
  paint() {
9830
9455
  let handled = false;
9831
- for (const plugin of this.#canvasPaintPlugins) {
9456
+ for (const plugin of this.#getLayerPlugins(exports.DrawLayer.BackgroundMask)) {
9832
9457
  handled = plugin.canvasPaint?.() ?? false;
9833
9458
  if (handled) {
9834
9459
  break;
@@ -10001,6 +9626,9 @@
10001
9626
  }
10002
9627
  drawer.beforeDraw(data);
10003
9628
  }
9629
+ #getLayerPlugins(layer) {
9630
+ return this.#layers[layer];
9631
+ }
10004
9632
  #getPluginParticleColors(particle) {
10005
9633
  let fColor, sColor;
10006
9634
  for (const plugin of this.#colorPlugins) {
@@ -10018,6 +9646,39 @@
10018
9646
  this.#reusablePluginColors[sColorIndex] = sColor;
10019
9647
  return this.#reusablePluginColors;
10020
9648
  }
9649
+ #resolveBackgroundElement() {
9650
+ const background = this.#container.actualOptions.background;
9651
+ this.#backgroundElement = null;
9652
+ if (!background.element) {
9653
+ return;
9654
+ }
9655
+ if (typeof background.element === "string") {
9656
+ if (typeof document !== "undefined") {
9657
+ const node = document.querySelector(background.element);
9658
+ if (node instanceof HTMLCanvasElement || node instanceof HTMLVideoElement || node instanceof HTMLImageElement) {
9659
+ this.#backgroundElement = node;
9660
+ }
9661
+ else if (node) {
9662
+ this.#warnOnce("background-element-not-supported", `Background element "${background.element}" is not a supported drawable element (canvas, video, or img)`);
9663
+ }
9664
+ else {
9665
+ this.#warnOnce("background-element-not-found", `Background element selector "${background.element}" not found`);
9666
+ }
9667
+ }
9668
+ }
9669
+ else if (background.element instanceof HTMLCanvasElement ||
9670
+ background.element instanceof OffscreenCanvas ||
9671
+ background.element instanceof HTMLVideoElement ||
9672
+ background.element instanceof HTMLImageElement) {
9673
+ this.#backgroundElement = background.element;
9674
+ }
9675
+ }
9676
+ #warnOnce(key, message) {
9677
+ if (!this.#backgroundWarnings.has(key)) {
9678
+ this.#backgroundWarnings.add(key);
9679
+ getLogger().warning(message);
9680
+ }
9681
+ }
10021
9682
  }
10022
9683
 
10023
9684
  const transferredCanvases = new WeakMap(), getTransferredCanvas = (canvas) => {
@@ -10594,7 +10255,6 @@
10594
10255
  }
10595
10256
  class Particle {
10596
10257
  backColor;
10597
- bubble;
10598
10258
  destroyed;
10599
10259
  direction;
10600
10260
  effect;
@@ -10628,7 +10288,6 @@
10628
10288
  shapeData;
10629
10289
  sides;
10630
10290
  size;
10631
- slow;
10632
10291
  spawning;
10633
10292
  strokeColor;
10634
10293
  strokeOpacity;
@@ -10650,18 +10309,25 @@
10650
10309
  d: 1,
10651
10310
  };
10652
10311
  #container;
10312
+ #modifiers = [];
10653
10313
  #pluginManager;
10654
10314
  constructor(pluginManager, container) {
10655
10315
  this.#pluginManager = pluginManager;
10656
10316
  this.#container = container;
10657
10317
  }
10318
+ addModifier(modifier) {
10319
+ this.#modifiers.push(modifier);
10320
+ this.#modifiers.sort((a, b) => a.priority - b.priority);
10321
+ }
10322
+ clearModifiers() {
10323
+ this.#modifiers.length = 0;
10324
+ }
10658
10325
  destroy(override) {
10659
10326
  if (this.unbreakable || this.destroyed) {
10660
10327
  return;
10661
10328
  }
10662
10329
  this.destroyed = true;
10663
- this.bubble.inRange = false;
10664
- this.slow.inRange = false;
10330
+ this.clearModifiers();
10665
10331
  const container = this.#container, shapeDrawer = this.shape ? container.shapeDrawers.get(this.shape) : undefined;
10666
10332
  shapeDrawer?.particleDestroy?.(this);
10667
10333
  for (const plugin of container.particleDestroyedPlugins) {
@@ -10683,13 +10349,16 @@
10683
10349
  return this.rotation + (this.pathRotation ? this.velocity.angle : defaultAngle);
10684
10350
  }
10685
10351
  getFillColor() {
10686
- return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.fillColor));
10352
+ return this.#getRollColor(this.#applyModifiers(getHslFromAnimation(this.fillColor), m => m.fillColor));
10687
10353
  }
10688
10354
  getMass() {
10689
10355
  return this.getRadius() ** squareExp * Math.PI * half;
10690
10356
  }
10357
+ getModifier(id) {
10358
+ return this.#modifiers.find(m => m.id === id);
10359
+ }
10691
10360
  getOpacity() {
10692
- const zIndexOptions = this.options.zIndex, zIndexFactor = zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, opacity = this.bubble.opacity ?? getRangeValue(this.opacity?.value ?? defaultOpacity$3), fillOpacity = this.fillOpacity ?? defaultOpacity$3, strokeOpacity = this.strokeOpacity ?? defaultOpacity$3;
10361
+ const zIndexOptions = this.options.zIndex, zIndexFactor = zIndexFactorOffset - this.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, baseOpacity = getRangeValue(this.opacity?.value ?? defaultOpacity$3), modifierOpacity = this.#applyModifiers(undefined, m => m.opacity), opacity = modifierOpacity ?? baseOpacity, fillOpacity = this.fillOpacity ?? defaultOpacity$3, strokeOpacity = this.strokeOpacity ?? defaultOpacity$3;
10693
10362
  this.#cachedOpacityData.fillOpacity = opacity * fillOpacity * zOpacityFactor;
10694
10363
  this.#cachedOpacityData.opacity = opacity * zOpacityFactor;
10695
10364
  this.#cachedOpacityData.strokeOpacity = opacity * strokeOpacity * zOpacityFactor;
@@ -10702,7 +10371,7 @@
10702
10371
  return this.#cachedPosition;
10703
10372
  }
10704
10373
  getRadius() {
10705
- return this.bubble.radius ?? this.size.value;
10374
+ return this.#applyModifiers(this.size.value, m => m.radius);
10706
10375
  }
10707
10376
  getRotateData() {
10708
10377
  const angle = this.getAngle();
@@ -10711,7 +10380,7 @@
10711
10380
  return this.#cachedRotateData;
10712
10381
  }
10713
10382
  getStrokeColor() {
10714
- return this.#getRollColor(this.bubble.color ?? getHslFromAnimation(this.strokeColor));
10383
+ return this.#getRollColor(this.#applyModifiers(getHslFromAnimation(this.strokeColor), m => m.strokeColor));
10715
10384
  }
10716
10385
  getTransformData(externalTransform) {
10717
10386
  const rotateData = this.getRotateData(), rotating = this.isRotating;
@@ -10731,13 +10400,6 @@
10731
10400
  this.options = resolveParticleOptions(this, container, this.#pluginManager, overrideOptions);
10732
10401
  container.retina.initParticle(this);
10733
10402
  runUpdaterPreInit(container.particleUpdaters, this);
10734
- this.bubble = {
10735
- inRange: false,
10736
- };
10737
- this.slow = {
10738
- inRange: false,
10739
- factor: 1,
10740
- };
10741
10403
  this.#initPosition(position);
10742
10404
  this.initialVelocity = this.#calculateVelocity();
10743
10405
  this.velocity = this.initialVelocity.copy();
@@ -10777,11 +10439,29 @@
10777
10439
  isVisible() {
10778
10440
  return !this.destroyed && !this.spawning && this.isInsideCanvas();
10779
10441
  }
10442
+ removeModifier(id) {
10443
+ const idx = this.#modifiers.findIndex(m => m.id === id);
10444
+ if (idx >= defaultAngle) {
10445
+ this.#modifiers.splice(idx, identity$2);
10446
+ }
10447
+ }
10780
10448
  reset() {
10781
10449
  for (const updater of this.#container.particleUpdaters) {
10782
10450
  updater.reset?.(this);
10783
10451
  }
10784
10452
  }
10453
+ #applyModifiers(base, getter) {
10454
+ let value = base;
10455
+ for (const mod of this.#modifiers) {
10456
+ if (mod.enabled) {
10457
+ const override = getter(mod);
10458
+ if (override !== undefined) {
10459
+ value = override;
10460
+ }
10461
+ }
10462
+ }
10463
+ return value;
10464
+ }
10785
10465
  #calcPosition(position, zIndex) {
10786
10466
  let tryCount = defaultRetryCount, posVec = position ? Vector3d.create(position.x, position.y, zIndex) : undefined;
10787
10467
  const container = this.#container, plugins = container.particlePositionPlugins, outModes = this.options.move.outModes, radius = this.getRadius(), canvasSize = container.canvas.size;
@@ -12667,6 +12347,7 @@
12667
12347
  });
12668
12348
 
12669
12349
  class BlendPluginInstance {
12350
+ layer = exports.DrawLayer.CanvasSetup;
12670
12351
  #container;
12671
12352
  #defaultCompositeValue;
12672
12353
  constructor(container) {
@@ -12812,7 +12493,8 @@
12812
12493
  particle.lastPathTime -= pathDelay;
12813
12494
  }
12814
12495
  function getProximitySpeedFactor(particle) {
12815
- return particle.slow.inRange ? particle.slow.factor : identity$2;
12496
+ const mod = particle.getModifier("slow");
12497
+ return mod?.enabled ? (mod.speedFactor ?? identity$2) : identity$2;
12816
12498
  }
12817
12499
  function initSpin(container, particle) {
12818
12500
  const options = particle.options, spinOptions = options.move.spin;
@@ -13851,6 +13533,7 @@
13851
13533
  exports.hPhase = hPhase;
13852
13534
  exports.half = half;
13853
13535
  exports.hslToRgb = hslToRgb;
13536
+ exports.hslToRgbFloat = hslToRgbFloat;
13854
13537
  exports.hslaToRgba = hslaToRgba;
13855
13538
  exports.identity = identity$2;
13856
13539
  exports.initPjs = initPjs;