@tsparticles/engine 3.7.1 → 3.8.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.
Files changed (78) hide show
  1. package/browser/Core/Canvas.js +37 -27
  2. package/browser/Core/Container.js +10 -13
  3. package/browser/Core/Engine.js +15 -11
  4. package/browser/Core/Particle.js +8 -11
  5. package/browser/Core/Particles.js +10 -14
  6. package/browser/Core/Retina.js +1 -1
  7. package/browser/Core/Utils/Constants.js +10 -16
  8. package/browser/Core/Utils/EventListeners.js +5 -8
  9. package/browser/Core/Utils/QuadTree.js +1 -1
  10. package/browser/Core/Utils/Ranges.js +1 -1
  11. package/browser/Core/Utils/Vectors.js +10 -15
  12. package/browser/Options/Classes/ManualParticle.js +3 -3
  13. package/browser/Utils/CanvasUtils.js +8 -14
  14. package/browser/Utils/ColorUtils.js +12 -17
  15. package/browser/Utils/EventDispatcher.js +2 -2
  16. package/browser/Utils/NumberUtils.js +2 -4
  17. package/browser/Utils/Utils.js +58 -9
  18. package/cjs/Core/Canvas.js +38 -28
  19. package/cjs/Core/Container.js +14 -17
  20. package/cjs/Core/Engine.js +21 -17
  21. package/cjs/Core/Particle.js +18 -21
  22. package/cjs/Core/Particles.js +22 -26
  23. package/cjs/Core/Retina.js +5 -5
  24. package/cjs/Core/Utils/Constants.js +12 -17
  25. package/cjs/Core/Utils/EventListeners.js +8 -11
  26. package/cjs/Core/Utils/QuadTree.js +4 -4
  27. package/cjs/Core/Utils/Ranges.js +4 -4
  28. package/cjs/Core/Utils/Vectors.js +11 -16
  29. package/cjs/Options/Classes/ManualParticle.js +3 -3
  30. package/cjs/Utils/CanvasUtils.js +14 -20
  31. package/cjs/Utils/ColorUtils.js +47 -52
  32. package/cjs/Utils/EventDispatcher.js +5 -5
  33. package/cjs/Utils/NumberUtils.js +11 -13
  34. package/cjs/Utils/Utils.js +60 -10
  35. package/esm/Core/Canvas.js +37 -27
  36. package/esm/Core/Container.js +10 -13
  37. package/esm/Core/Engine.js +15 -11
  38. package/esm/Core/Particle.js +8 -11
  39. package/esm/Core/Particles.js +10 -14
  40. package/esm/Core/Retina.js +1 -1
  41. package/esm/Core/Utils/Constants.js +10 -16
  42. package/esm/Core/Utils/EventListeners.js +5 -8
  43. package/esm/Core/Utils/QuadTree.js +1 -1
  44. package/esm/Core/Utils/Ranges.js +1 -1
  45. package/esm/Core/Utils/Vectors.js +10 -15
  46. package/esm/Options/Classes/ManualParticle.js +3 -3
  47. package/esm/Utils/CanvasUtils.js +8 -14
  48. package/esm/Utils/ColorUtils.js +12 -17
  49. package/esm/Utils/EventDispatcher.js +2 -2
  50. package/esm/Utils/NumberUtils.js +2 -4
  51. package/esm/Utils/Utils.js +58 -9
  52. package/package.json +1 -1
  53. package/report.html +1 -1
  54. package/tsparticles.engine.js +20 -20
  55. package/tsparticles.engine.min.js +1 -1
  56. package/tsparticles.engine.min.js.LICENSE.txt +1 -1
  57. package/types/Core/Canvas.d.ts +1 -1
  58. package/types/Core/Engine.d.ts +5 -4
  59. package/types/Core/Utils/Constants.d.ts +7 -16
  60. package/types/Utils/ColorUtils.d.ts +1 -1
  61. package/types/Utils/Utils.d.ts +2 -2
  62. package/umd/Core/Canvas.js +39 -29
  63. package/umd/Core/Container.js +14 -17
  64. package/umd/Core/Engine.js +21 -17
  65. package/umd/Core/Particle.js +19 -22
  66. package/umd/Core/Particles.js +23 -27
  67. package/umd/Core/Retina.js +6 -6
  68. package/umd/Core/Utils/Constants.js +11 -17
  69. package/umd/Core/Utils/EventListeners.js +9 -12
  70. package/umd/Core/Utils/QuadTree.js +5 -5
  71. package/umd/Core/Utils/Ranges.js +5 -5
  72. package/umd/Core/Utils/Vectors.js +11 -16
  73. package/umd/Options/Classes/ManualParticle.js +4 -4
  74. package/umd/Utils/CanvasUtils.js +15 -21
  75. package/umd/Utils/ColorUtils.js +48 -53
  76. package/umd/Utils/EventDispatcher.js +6 -6
  77. package/umd/Utils/NumberUtils.js +12 -14
  78. package/umd/Utils/Utils.js +60 -10
@@ -1,11 +1,11 @@
1
1
  import { clear, drawParticle, drawParticlePlugin, drawPlugin, paintBase, paintImage } from "../Utils/CanvasUtils.js";
2
- import { deepExtend, getLogger, safeMutationObserver } from "../Utils/Utils.js";
2
+ import { cloneStyle, getFullScreenStyle, getLogger, safeMutationObserver } from "../Utils/Utils.js";
3
+ import { defaultOpacity, defaultTransformValue, generatedAttribute, inverseFactorNumerator, minimumLength, minimumSize, zIndexFactorOffset, } from "./Utils/Constants.js";
3
4
  import { getStyleFromHsl, getStyleFromRgb, rangeColorToHsl, rangeColorToRgb } from "../Utils/ColorUtils.js";
4
- import { generatedAttribute } from "./Utils/Constants.js";
5
5
  function setTransformValue(factor, newFactor, key) {
6
- const newValue = newFactor[key], defaultValue = 1;
6
+ const newValue = newFactor[key];
7
7
  if (newValue !== undefined) {
8
- factor[key] = (factor[key] ?? defaultValue) * newValue;
8
+ factor[key] = (factor[key] ?? defaultTransformValue) * newValue;
9
9
  }
10
10
  }
11
11
  function setStyle(canvas, style, important = false) {
@@ -20,9 +20,27 @@ function setStyle(canvas, style, important = false) {
20
20
  if (!elementStyle) {
21
21
  return;
22
22
  }
23
+ const keys = new Set();
24
+ for (const key in elementStyle) {
25
+ if (!Object.prototype.hasOwnProperty.call(elementStyle, key)) {
26
+ continue;
27
+ }
28
+ keys.add(elementStyle[key]);
29
+ }
23
30
  for (const key in style) {
24
- const value = style[key];
25
- elementStyle.setProperty(key, value, important ? "important" : "");
31
+ if (!Object.prototype.hasOwnProperty.call(style, key)) {
32
+ continue;
33
+ }
34
+ keys.add(style[key]);
35
+ }
36
+ for (const key of keys) {
37
+ const value = style.getPropertyValue(key);
38
+ if (!value) {
39
+ elementStyle.removeProperty(key);
40
+ }
41
+ else {
42
+ elementStyle.setProperty(key, value, important ? "important" : "");
43
+ }
26
44
  }
27
45
  }
28
46
  export class Canvas {
@@ -111,14 +129,13 @@ export class Canvas {
111
129
  return;
112
130
  }
113
131
  if (this._fullScreen) {
114
- this._originalStyle = deepExtend({}, element.style);
115
132
  this._setFullScreenStyle();
116
133
  }
117
134
  else {
118
135
  this._resetOriginalStyle();
119
136
  }
120
137
  for (const key in options.style) {
121
- if (!key || !options.style) {
138
+ if (!key || !options.style || !Object.prototype.hasOwnProperty.call(options.style, key)) {
122
139
  continue;
123
140
  }
124
141
  const value = options.style[key];
@@ -133,7 +150,7 @@ export class Canvas {
133
150
  if (!trail.enable) {
134
151
  return;
135
152
  }
136
- const factorNumerator = 1, opacity = factorNumerator / trail.length;
153
+ const opacity = inverseFactorNumerator / trail.length;
137
154
  if (trailFill.color) {
138
155
  const fillColor = rangeColorToRgb(this._engine, trailFill.color);
139
156
  if (!fillColor) {
@@ -189,10 +206,10 @@ export class Canvas {
189
206
  };
190
207
  this._resetOriginalStyle = () => {
191
208
  const element = this.element, originalStyle = this._originalStyle;
192
- if (!(element && originalStyle)) {
209
+ if (!element || !originalStyle) {
193
210
  return;
194
211
  }
195
- setStyle(element, originalStyle);
212
+ setStyle(element, originalStyle, true);
196
213
  };
197
214
  this._safeMutationObserver = callback => {
198
215
  if (!this._mutationObserver) {
@@ -205,16 +222,7 @@ export class Canvas {
205
222
  if (!element) {
206
223
  return;
207
224
  }
208
- const radix = 10, zIndex = this.container.actualOptions.fullScreen.zIndex.toString(radix);
209
- setStyle(element, {
210
- position: "fixed",
211
- "z-index": zIndex,
212
- zIndex: zIndex,
213
- top: "0",
214
- left: "0",
215
- width: "100%",
216
- height: "100%",
217
- }, true);
225
+ setStyle(element, getFullScreenStyle(this.container.actualOptions.fullScreen.zIndex), true);
218
226
  };
219
227
  this._engine = engine;
220
228
  this._standardSize = {
@@ -237,7 +245,7 @@ export class Canvas {
237
245
  return this.container.actualOptions.fullScreen.enable;
238
246
  }
239
247
  clear() {
240
- const options = this.container.actualOptions, trail = options.particles.move.trail, trailFill = this._trailFill, minimumLength = 0;
248
+ const options = this.container.actualOptions, trail = options.particles.move.trail, trailFill = this._trailFill;
241
249
  if (options.backgroundMask.enable) {
242
250
  this.paint();
243
251
  }
@@ -260,6 +268,7 @@ export class Canvas {
260
268
  if (this._generated) {
261
269
  const element = this.element;
262
270
  element?.remove();
271
+ this.element = undefined;
263
272
  }
264
273
  else {
265
274
  this._resetOriginalStyle();
@@ -287,7 +296,7 @@ export class Canvas {
287
296
  if (particle.spawning || particle.destroyed) {
288
297
  return;
289
298
  }
290
- const radius = particle.getRadius(), minimumSize = 0;
299
+ const radius = particle.getRadius();
291
300
  if (radius <= minimumSize) {
292
301
  return;
293
302
  }
@@ -303,7 +312,7 @@ export class Canvas {
303
312
  return;
304
313
  }
305
314
  this.draw((ctx) => {
306
- const container = this.container, options = container.actualOptions, zIndexOptions = particle.options.zIndex, zIndexFactorOffset = 1, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, defaultOpacity = 1, opacity = particle.bubble.opacity ?? particle.opacity?.value ?? defaultOpacity, strokeOpacity = particle.strokeOpacity ?? opacity, zOpacity = opacity * zOpacityFactor, zStrokeOpacity = strokeOpacity * zOpacityFactor, transform = {}, colorStyles = {
315
+ const container = this.container, options = container.actualOptions, zIndexOptions = particle.options.zIndex, zIndexFactor = zIndexFactorOffset - particle.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, opacity = particle.bubble.opacity ?? particle.opacity?.value ?? defaultOpacity, strokeOpacity = particle.strokeOpacity ?? opacity, zOpacity = opacity * zOpacityFactor, zStrokeOpacity = strokeOpacity * zOpacityFactor, transform = {}, colorStyles = {
307
316
  fill: fColor ? getStyleFromHsl(fColor, zOpacity) : undefined,
308
317
  };
309
318
  colorStyles.stroke = sColor ? getStyleFromHsl(sColor, zStrokeOpacity) : colorStyles.fill;
@@ -413,7 +422,7 @@ export class Canvas {
413
422
  : this._generated;
414
423
  this.element = canvas;
415
424
  this.element.ariaHidden = "true";
416
- this._originalStyle = deepExtend({}, this.element.style);
425
+ this._originalStyle = cloneStyle(this.element.style);
417
426
  const standardSize = this._standardSize;
418
427
  standardSize.height = canvas.offsetHeight;
419
428
  standardSize.width = canvas.offsetWidth;
@@ -421,14 +430,15 @@ export class Canvas {
421
430
  canvas.height = retinaSize.height = standardSize.height * pxRatio;
422
431
  canvas.width = retinaSize.width = standardSize.width * pxRatio;
423
432
  this._context = this.element.getContext("2d");
433
+ this._safeMutationObserver(obs => obs.disconnect());
434
+ this.container.retina.init();
435
+ this.initBackground();
424
436
  this._safeMutationObserver(obs => {
425
437
  if (!this.element || !(this.element instanceof Node)) {
426
438
  return;
427
439
  }
428
440
  obs.observe(this.element, { attributes: true });
429
441
  });
430
- this.container.retina.init();
431
- this.initBackground();
432
442
  }
433
443
  paint() {
434
444
  const options = this.container.actualOptions;
@@ -1,5 +1,5 @@
1
1
  import { animate, cancelAnimation, getRangeValue } from "../Utils/NumberUtils.js";
2
- import { errorPrefix, millisecondsToSeconds } from "./Utils/Constants.js";
2
+ import { clickRadius, defaultFps, defaultFpsLimit, errorPrefix, millisecondsToSeconds, minCoordinate, minFpsLimit, removeDeleteCount, removeMinIndex, touchEndLengthOffset, } from "./Utils/Constants.js";
3
3
  import { getLogger, safeIntersectionObserver } from "../Utils/Utils.js";
4
4
  import { Canvas } from "./Canvas.js";
5
5
  import { EventListeners } from "./Utils/EventListeners.js";
@@ -11,7 +11,6 @@ import { loadOptions } from "../Utils/OptionsUtils.js";
11
11
  function guardCheck(container) {
12
12
  return container && !container.destroyed;
13
13
  }
14
- const defaultFps = 60;
15
14
  function initDelta(value, fpsLimit = defaultFps, smooth = false) {
16
15
  return {
17
16
  value,
@@ -139,8 +138,8 @@ export class Container {
139
138
  const mouseEvent = e, pos = {
140
139
  x: mouseEvent.offsetX || mouseEvent.clientX,
141
140
  y: mouseEvent.offsetY || mouseEvent.clientY,
142
- }, radius = 1;
143
- clickOrTouchHandler(e, pos, radius);
141
+ };
142
+ clickOrTouchHandler(e, pos, clickRadius);
144
143
  }, touchStartHandler = () => {
145
144
  if (!guardCheck(this)) {
146
145
  return;
@@ -157,15 +156,15 @@ export class Container {
157
156
  return;
158
157
  }
159
158
  if (touched && !touchMoved) {
160
- const touchEvent = e, lengthOffset = 1;
161
- let lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset];
159
+ const touchEvent = e;
160
+ let lastTouch = touchEvent.touches[touchEvent.touches.length - touchEndLengthOffset];
162
161
  if (!lastTouch) {
163
- lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - lengthOffset];
162
+ lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - touchEndLengthOffset];
164
163
  if (!lastTouch) {
165
164
  return;
166
165
  }
167
166
  }
168
- const element = this.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, minCoordinate = 0, pos = {
167
+ const element = this.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
169
168
  x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
170
169
  y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate),
171
170
  };
@@ -235,10 +234,9 @@ export class Container {
235
234
  this._engine.clearPlugins(this);
236
235
  this.destroyed = true;
237
236
  if (remove) {
238
- const mainArr = this._engine.items, idx = mainArr.findIndex(t => t === this), minIndex = 0;
239
- if (idx >= minIndex) {
240
- const deleteCount = 1;
241
- mainArr.splice(idx, deleteCount);
237
+ const mainArr = this._engine.items, idx = mainArr.findIndex(t => t === this);
238
+ if (idx >= removeMinIndex) {
239
+ mainArr.splice(idx, removeDeleteCount);
242
240
  }
243
241
  }
244
242
  this._engine.dispatchEvent(EventType.containerDestroyed, { container: this });
@@ -314,7 +312,6 @@ export class Container {
314
312
  this._duration = getRangeValue(duration) * millisecondsToSeconds;
315
313
  this._delay = getRangeValue(delay) * millisecondsToSeconds;
316
314
  this._lifeTime = 0;
317
- const defaultFpsLimit = 120, minFpsLimit = 0;
318
315
  this.fpsLimit = fpsLimit > minFpsLimit ? fpsLimit : defaultFpsLimit;
319
316
  this._smooth = smooth;
320
317
  for (const drawer of this.effectDrawers.values()) {
@@ -1,4 +1,4 @@
1
- import { errorPrefix, generatedAttribute } from "./Utils/Constants.js";
1
+ import { canvasFirstIndex, canvasTag, errorPrefix, generatedAttribute, generatedFalse, generatedTrue, loadMinIndex, loadRandomFactor, none, one, removeDeleteCount, } from "./Utils/Constants.js";
2
2
  import { executeOnSingleOrMultiple, getLogger, itemFromSingleOrMultiple } from "../Utils/Utils.js";
3
3
  import { Container } from "./Container.js";
4
4
  import { EventDispatcher } from "../Utils/EventDispatcher.js";
@@ -24,7 +24,7 @@ async function getDataFromUrl(data) {
24
24
  getLogger().error(`${errorPrefix} ${response.status} while retrieving config file`);
25
25
  return data.fallback;
26
26
  }
27
- const generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", getCanvasFromContainer = (domContainer) => {
27
+ const getCanvasFromContainer = (domContainer) => {
28
28
  let canvasEl;
29
29
  if (domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag) {
30
30
  canvasEl = domContainer;
@@ -35,8 +35,7 @@ const generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", ge
35
35
  else {
36
36
  const existingCanvases = domContainer.getElementsByTagName(canvasTag);
37
37
  if (existingCanvases.length) {
38
- const firstIndex = 0;
39
- canvasEl = existingCanvases[firstIndex];
38
+ canvasEl = existingCanvases[canvasFirstIndex];
40
39
  canvasEl.dataset[generatedAttribute] = generatedFalse;
41
40
  }
42
41
  else {
@@ -97,7 +96,7 @@ export class Engine {
97
96
  return this._domArray;
98
97
  }
99
98
  get version() {
100
- return "3.7.1";
99
+ return "3.8.0";
101
100
  }
102
101
  async addColorManager(manager, refresh = true) {
103
102
  this.colorManagers.set(manager.key, manager);
@@ -165,6 +164,12 @@ export class Engine {
165
164
  }
166
165
  await this.refresh(refresh);
167
166
  }
167
+ checkVersion(pluginVersion) {
168
+ if (this.version === pluginVersion) {
169
+ return;
170
+ }
171
+ throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${this.version}. Plugin version: ${pluginVersion}`);
172
+ }
168
173
  clearPlugins(container) {
169
174
  this.updaters.delete(container);
170
175
  this.movers.delete(container);
@@ -230,17 +235,16 @@ export class Engine {
230
235
  item(index) {
231
236
  const { items } = this, item = items[index];
232
237
  if (!item || item.destroyed) {
233
- const deleteCount = 1;
234
- items.splice(index, deleteCount);
238
+ items.splice(index, removeDeleteCount);
235
239
  return;
236
240
  }
237
241
  return item;
238
242
  }
239
243
  async load(params) {
240
- const randomFactor = 10000, id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * randomFactor)}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options;
241
- const currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), minIndex = 0, newItem = new Container(this, id, currentOptions);
242
- if (oldIndex >= minIndex) {
243
- const old = this.item(oldIndex), one = 1, none = 0, deleteCount = old ? one : none;
244
+ const id = params.id ?? params.element?.id ?? `tsparticles${Math.floor(getRandom() * loadRandomFactor)}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options;
245
+ const currentOptions = itemFromSingleOrMultiple(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container(this, id, currentOptions);
246
+ if (oldIndex >= loadMinIndex) {
247
+ const old = this.item(oldIndex), deleteCount = old ? one : none;
244
248
  if (old && !old.destroyed) {
245
249
  old.destroy(false);
246
250
  }
@@ -1,7 +1,7 @@
1
1
  import { Vector, Vector3d } from "./Utils/Vectors.js";
2
2
  import { calcExactPositionOrRandomFromSize, clamp, degToRad, getDistance, getParticleBaseVelocity, getParticleDirectionAngle, getRandom, getRangeValue, randomInRange, setRangeValue, } from "../Utils/NumberUtils.js";
3
+ import { decayOffset, defaultRadius, defaultRetryCount, double, errorPrefix, half, millisecondsToSeconds, minRetries, minZ, none, randomColorValue, rollFactor, squareExp, tryCountIncrement, } from "./Utils/Constants.js";
3
4
  import { deepExtend, getPosition, initParticleNumericAnimationValue, isInArray, itemFromSingleOrMultiple, } from "../Utils/Utils.js";
4
- import { errorPrefix, millisecondsToSeconds } from "./Utils/Constants.js";
5
5
  import { getHslFromAnimation, rangeColorToRgb } from "../Utils/ColorUtils.js";
6
6
  import { EventType } from "../Enums/Types/EventType.js";
7
7
  import { Interactivity } from "../Options/Classes/Interactivity/Interactivity.js";
@@ -11,7 +11,6 @@ import { ParticleOutType } from "../Enums/Types/ParticleOutType.js";
11
11
  import { PixelMode } from "../Enums/Modes/PixelMode.js";
12
12
  import { alterHsl } from "../Utils/CanvasUtils.js";
13
13
  import { loadParticlesOptions } from "../Utils/OptionsUtils.js";
14
- const defaultRetryCount = 0, double = 2, half = 0.5, squareExp = 2, randomString = "random";
15
14
  function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
16
15
  const effectData = effectOptions.options[effect];
17
16
  if (!effectData) {
@@ -81,8 +80,7 @@ export class Particle {
81
80
  fixVertical(outModes.top ?? outModes.default);
82
81
  fixVertical(outModes.bottom ?? outModes.default);
83
82
  if (this._checkOverlap(pos, tryCount)) {
84
- const increment = 1;
85
- return this._calcPosition(container, undefined, zIndex, tryCount + increment);
83
+ return this._calcPosition(container, undefined, zIndex, tryCount + tryCountIncrement);
86
84
  }
87
85
  return pos;
88
86
  };
@@ -112,7 +110,7 @@ export class Particle {
112
110
  if (overlapOptions.enable) {
113
111
  return false;
114
112
  }
115
- const retries = overlapOptions.retries, minRetries = 0;
113
+ const retries = overlapOptions.retries;
116
114
  if (retries >= minRetries && tryCount > retries) {
117
115
  throw new Error(`${errorPrefix} particle is overlapping and can't be placed`);
118
116
  }
@@ -122,7 +120,7 @@ export class Particle {
122
120
  if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
123
121
  return color;
124
122
  }
125
- const rollFactor = 1, none = 0, backFactor = this.roll.horizontal && this.roll.vertical ? double * rollFactor : rollFactor, backSum = this.roll.horizontal ? Math.PI * half : none, rolled = Math.floor(((this.roll.angle ?? none) + backSum) / (Math.PI / backFactor)) % double;
123
+ const backFactor = this.roll.horizontal && this.roll.vertical ? double * rollFactor : rollFactor, backSum = this.roll.horizontal ? Math.PI * half : none, rolled = Math.floor(((this.roll.angle ?? none) + backSum) / (Math.PI / backFactor)) % double;
126
124
  if (!rolled) {
127
125
  return color;
128
126
  }
@@ -135,10 +133,10 @@ export class Particle {
135
133
  return color;
136
134
  };
137
135
  this._initPosition = position => {
138
- const container = this.container, zIndexValue = getRangeValue(this.options.zIndex.value), minZ = 0;
136
+ const container = this.container, zIndexValue = getRangeValue(this.options.zIndex.value);
139
137
  this.position = this._calcPosition(container, position, clamp(zIndexValue, minZ, container.zLayers));
140
138
  this.initialPosition = this.position.copy();
141
- const canvasSize = container.canvas.size, defaultRadius = 0;
139
+ const canvasSize = container.canvas.size;
142
140
  this.moveCenter = {
143
141
  ...getPosition(this.options.move.center, canvasSize),
144
142
  radius: this.options.move.center.radius ?? defaultRadius,
@@ -246,11 +244,11 @@ export class Particle {
246
244
  }
247
245
  }
248
246
  }
249
- if (this.effect === randomString) {
247
+ if (this.effect === randomColorValue) {
250
248
  const availableEffects = [...this.container.effectDrawers.keys()];
251
249
  this.effect = availableEffects[Math.floor(Math.random() * availableEffects.length)];
252
250
  }
253
- if (this.shape === randomString) {
251
+ if (this.shape === randomColorValue) {
254
252
  const availableShapes = [...this.container.shapeDrawers.keys()];
255
253
  this.shape = availableShapes[Math.floor(Math.random() * availableShapes.length)];
256
254
  }
@@ -294,7 +292,6 @@ export class Particle {
294
292
  this._initPosition(position);
295
293
  this.initialVelocity = this._calculateVelocity();
296
294
  this.velocity = this.initialVelocity.copy();
297
- const decayOffset = 1;
298
295
  this.moveDecay = decayOffset - getRangeValue(this.options.move.decay);
299
296
  const particles = container.particles;
300
297
  particles.setLastZIndex(this.position.z);
@@ -1,3 +1,4 @@
1
+ import { countOffset, defaultDensityFactor, defaultRemoveQuantity, deleteCount, errorPrefix, lengthOffset, manualCount, minCount, minIndex, minLimit, posOffset, qTreeCapacity, sizeFactor, squareExp, } from "./Utils/Constants.js";
1
2
  import { getLogger, getPosition } from "../Utils/Utils.js";
2
3
  import { EventType } from "../Enums/Types/EventType.js";
3
4
  import { InteractionManager } from "./Utils/InteractionManager.js";
@@ -6,10 +7,8 @@ import { Particle } from "./Particle.js";
6
7
  import { Point } from "./Utils/Point.js";
7
8
  import { QuadTree } from "./Utils/QuadTree.js";
8
9
  import { Rectangle } from "./Utils/Ranges.js";
9
- import { errorPrefix } from "./Utils/Constants.js";
10
- const qTreeCapacity = 4, squareExp = 2, defaultRemoveQuantity = 1;
11
10
  const qTreeRectangle = (canvasSize) => {
12
- const { height, width } = canvasSize, posOffset = -0.25, sizeFactor = 1.5;
11
+ const { height, width } = canvasSize;
13
12
  return new Rectangle(posOffset * width, posOffset * height, sizeFactor * width, sizeFactor * height);
14
13
  };
15
14
  export class Particles {
@@ -28,7 +27,7 @@ export class Particles {
28
27
  }
29
28
  return;
30
29
  }
31
- const densityFactor = this._initDensityFactor(numberOptions.density), optParticlesNumber = numberOptions.value, minLimit = 0, optParticlesLimit = numberOptions.limit.value > minLimit ? numberOptions.limit.value : optParticlesNumber, particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount, particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
30
+ const densityFactor = this._initDensityFactor(numberOptions.density), optParticlesNumber = numberOptions.value, optParticlesLimit = numberOptions.limit.value > minLimit ? numberOptions.limit.value : optParticlesNumber, particlesNumber = Math.min(optParticlesNumber, optParticlesLimit) * densityFactor + manualCount, particlesCount = Math.min(this.count, this.filter(t => t.group === group).length);
32
31
  if (group === undefined) {
33
32
  this._limit = numberOptions.limit.value * densityFactor;
34
33
  }
@@ -43,9 +42,9 @@ export class Particles {
43
42
  }
44
43
  };
45
44
  this._initDensityFactor = densityOptions => {
46
- const container = this._container, defaultFactor = 1;
45
+ const container = this._container;
47
46
  if (!container.canvas.element || !densityOptions.enable) {
48
- return defaultFactor;
47
+ return defaultDensityFactor;
49
48
  }
50
49
  const canvas = container.canvas.element, pxRatio = container.retina.pixelRatio;
51
50
  return (canvas.width * canvas.height) / (densityOptions.height * densityOptions.width * pxRatio ** squareExp);
@@ -84,7 +83,7 @@ export class Particles {
84
83
  if (!particle || particle.group !== group) {
85
84
  return false;
86
85
  }
87
- const zIdx = this._zArray.indexOf(particle), deleteCount = 1;
86
+ const zIdx = this._zArray.indexOf(particle);
88
87
  this._array.splice(index, deleteCount);
89
88
  this._zArray.splice(zIdx, deleteCount);
90
89
  particle.destroy(override);
@@ -122,11 +121,11 @@ export class Particles {
122
121
  options.manualParticles.forEach(p => this.addParticle(p.position ? getPosition(p.position, container.canvas.size) : undefined, p.options));
123
122
  }
124
123
  addParticle(position, overrideOptions, group, initializer) {
125
- const limitMode = this._container.actualOptions.particles.number.limit.mode, limit = group === undefined ? this._limit : (this._groupLimits.get(group) ?? this._limit), currentCount = this.count, minLimit = 0;
124
+ const limitMode = this._container.actualOptions.particles.number.limit.mode, limit = group === undefined ? this._limit : (this._groupLimits.get(group) ?? this._limit), currentCount = this.count;
126
125
  if (limit > minLimit) {
127
126
  switch (limitMode) {
128
127
  case LimitMode.delete: {
129
- const countOffset = 1, minCount = 0, countToRemove = currentCount + countOffset - limit;
128
+ const countToRemove = currentCount + countOffset - limit;
130
129
  if (countToRemove > minCount) {
131
130
  this.removeQuantity(countToRemove);
132
131
  }
@@ -227,7 +226,6 @@ export class Particles {
227
226
  this.removeAt(this._array.indexOf(particle), undefined, group, override);
228
227
  }
229
228
  removeAt(index, quantity = defaultRemoveQuantity, group, override) {
230
- const minIndex = 0;
231
229
  if (index < minIndex || index > this.count) {
232
230
  return;
233
231
  }
@@ -240,11 +238,10 @@ export class Particles {
240
238
  }
241
239
  }
242
240
  removeQuantity(quantity, group) {
243
- const defaultIndex = 0;
244
- this.removeAt(defaultIndex, quantity, group);
241
+ this.removeAt(minIndex, quantity, group);
245
242
  }
246
243
  setDensity() {
247
- const options = this._container.actualOptions, groups = options.particles.groups, manualCount = 0;
244
+ const options = this._container.actualOptions, groups = options.particles.groups;
248
245
  for (const group in groups) {
249
246
  this._applyDensity(groups[group], manualCount, group);
250
247
  }
@@ -320,7 +317,6 @@ export class Particles {
320
317
  if (this._needsSort) {
321
318
  const zArray = this._zArray;
322
319
  zArray.sort((a, b) => b.position.z - a.position.z || a.id - b.id);
323
- const lengthOffset = 1;
324
320
  this._lastZIndex = zArray[zArray.length - lengthOffset].position.z;
325
321
  this._needsSort = false;
326
322
  }
@@ -1,6 +1,6 @@
1
+ import { defaultRatio, defaultReduceFactor } from "./Utils/Constants.js";
1
2
  import { getRangeValue } from "../Utils/NumberUtils.js";
2
3
  import { isSsr } from "../Utils/Utils.js";
3
- const defaultRatio = 1, defaultReduceFactor = 1;
4
4
  export class Retina {
5
5
  constructor(container) {
6
6
  this.container = container;
@@ -1,16 +1,10 @@
1
- export const generatedAttribute = "generated";
2
- export const mouseDownEvent = "pointerdown";
3
- export const mouseUpEvent = "pointerup";
4
- export const mouseLeaveEvent = "pointerleave";
5
- export const mouseOutEvent = "pointerout";
6
- export const mouseMoveEvent = "pointermove";
7
- export const touchStartEvent = "touchstart";
8
- export const touchEndEvent = "touchend";
9
- export const touchMoveEvent = "touchmove";
10
- export const touchCancelEvent = "touchcancel";
11
- export const resizeEvent = "resize";
12
- export const visibilityChangeEvent = "visibilitychange";
13
- export const errorPrefix = "tsParticles - Error";
14
- export const percentDenominator = 100;
15
- export const halfRandom = 0.5;
16
- export const millisecondsToSeconds = 1000;
1
+ export const generatedAttribute = "generated", mouseDownEvent = "pointerdown", mouseUpEvent = "pointerup", mouseLeaveEvent = "pointerleave", mouseOutEvent = "pointerout", mouseMoveEvent = "pointermove", touchStartEvent = "touchstart", touchEndEvent = "touchend", touchMoveEvent = "touchmove", touchCancelEvent = "touchcancel", resizeEvent = "resize", visibilityChangeEvent = "visibilitychange", errorPrefix = "tsParticles - Error", percentDenominator = 100, half = 0.5, millisecondsToSeconds = 1000, originPoint = {
2
+ x: 0,
3
+ y: 0,
4
+ z: 0,
5
+ }, defaultTransform = {
6
+ a: 1,
7
+ b: 0,
8
+ c: 0,
9
+ d: 1,
10
+ }, randomColorValue = "random", midColorValue = "mid", double = 2, doublePI = Math.PI * double, defaultFps = 60, defaultAlpha = 1, generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", defaultRetryCount = 0, squareExp = 2, qTreeCapacity = 4, defaultRemoveQuantity = 1, defaultRatio = 1, defaultReduceFactor = 1, subdivideCount = 4, inverseFactorNumerator = 1.0, rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, empty = 0, quarter = 0.25, threeQuarter = half + quarter, minVelocity = 0, defaultTransformValue = 1, minimumSize = 0, minimumLength = 0, zIndexFactorOffset = 1, defaultOpacity = 1, clickRadius = 1, touchEndLengthOffset = 1, minCoordinate = 0, removeDeleteCount = 1, removeMinIndex = 0, defaultFpsLimit = 120, minFpsLimit = 0, canvasFirstIndex = 0, loadRandomFactor = 10000, loadMinIndex = 0, one = 1, none = 0, decayOffset = 1, tryCountIncrement = 1, minRetries = 0, rollFactor = 1, minZ = 0, defaultRadius = 0, posOffset = -quarter, sizeFactor = 1.5, minLimit = 0, countOffset = 1, minCount = 0, minIndex = 0, manualCount = 0, lengthOffset = 1, defaultDensityFactor = 1, deleteCount = 1, touchDelay = 500, manualDefaultPosition = 50, defaultAngle = 0, identity = 1, minStrokeWidth = 0, lFactor = 1, lMin = 0, rgbFactor = 255, triple = 3, sextuple = 6, sNormalizedOffset = 1, phaseNumerator = 1, defaultRgbMin = 0, defaultVelocity = 0, defaultLoops = 0, defaultTime = 0;
@@ -1,8 +1,7 @@
1
+ import { double, lengthOffset, millisecondsToSeconds, minCoordinate, mouseDownEvent, mouseLeaveEvent, mouseMoveEvent, mouseOutEvent, mouseUpEvent, resizeEvent, touchCancelEvent, touchDelay, touchEndEvent, touchMoveEvent, touchStartEvent, visibilityChangeEvent, } from "./Constants.js";
1
2
  import { executeOnSingleOrMultiple, safeMatchMedia } from "../../Utils/Utils.js";
2
- import { millisecondsToSeconds, mouseDownEvent, mouseLeaveEvent, mouseMoveEvent, mouseOutEvent, mouseUpEvent, resizeEvent, touchCancelEvent, touchEndEvent, touchMoveEvent, touchStartEvent, visibilityChangeEvent, } from "./Constants.js";
3
3
  import { InteractivityDetect } from "../../Enums/InteractivityDetect.js";
4
4
  import { isBoolean } from "../../Utils/TypeUtils.js";
5
- const double = 2;
6
5
  function manageListener(element, event, handler, add, options) {
7
6
  if (add) {
8
7
  let addOptions = { passive: true };
@@ -35,7 +34,6 @@ export class EventListeners {
35
34
  executeOnSingleOrMultiple(onClick.mode, mode => this.container.handleClickMode(mode));
36
35
  }
37
36
  if (e.type === "touchend") {
38
- const touchDelay = 500;
39
37
  setTimeout(() => this._mouseTouchFinish(), touchDelay);
40
38
  }
41
39
  };
@@ -77,8 +75,7 @@ export class EventListeners {
77
75
  this._resizeTimeout = setTimeout(() => void handleResize(), this.container.actualOptions.interactivity.events.resize.delay * millisecondsToSeconds);
78
76
  };
79
77
  this._manageInteractivityListeners = (mouseLeaveTmpEvent, add) => {
80
- const handlers = this._handlers, container = this.container, options = container.actualOptions;
81
- const interactivityEl = container.interactivity.element;
78
+ const handlers = this._handlers, container = this.container, options = container.actualOptions, interactivityEl = container.interactivity.element;
82
79
  if (!interactivityEl) {
83
80
  return;
84
81
  }
@@ -259,10 +256,10 @@ export class EventListeners {
259
256
  else {
260
257
  this._canPush = e.type !== "touchmove";
261
258
  if (canvasEl) {
262
- const touchEvent = e, lengthOffset = 1, lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset], canvasRect = canvasEl.getBoundingClientRect(), defaultCoordinate = 0;
259
+ const touchEvent = e, lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset], canvasRect = canvasEl.getBoundingClientRect();
263
260
  pos = {
264
- x: lastTouch.clientX - (canvasRect.left ?? defaultCoordinate),
265
- y: lastTouch.clientY - (canvasRect.top ?? defaultCoordinate),
261
+ x: lastTouch.clientX - (canvasRect.left ?? minCoordinate),
262
+ y: lastTouch.clientY - (canvasRect.top ?? minCoordinate),
266
263
  };
267
264
  }
268
265
  }
@@ -1,6 +1,6 @@
1
1
  import { Circle, Rectangle } from "./Ranges.js";
2
+ import { double, half, subdivideCount } from "./Constants.js";
2
3
  import { getDistance } from "../../Utils/NumberUtils.js";
3
- const half = 0.5, double = 2, subdivideCount = 4;
4
4
  export class QuadTree {
5
5
  constructor(rectangle, capacity) {
6
6
  this.rectangle = rectangle;
@@ -1,6 +1,6 @@
1
1
  import { RangeType } from "../../Types/RangeType.js";
2
2
  import { getDistance } from "../../Utils/NumberUtils.js";
3
- const squareExp = 2;
3
+ import { squareExp } from "./Constants.js";
4
4
  export class BaseRange {
5
5
  constructor(x, y, type) {
6
6
  this.position = {
@@ -1,10 +1,5 @@
1
- import { errorPrefix } from "./Constants.js";
1
+ import { errorPrefix, inverseFactorNumerator, none, originPoint, squareExp } from "./Constants.js";
2
2
  import { isNumber } from "../../Utils/TypeUtils.js";
3
- const origin = {
4
- x: 0,
5
- y: 0,
6
- z: 0,
7
- }, squareExp = 2, inverseFactorNumerator = 1.0;
8
3
  export class Vector3d {
9
4
  constructor(xOrCoords, y, z) {
10
5
  this._updateFromAngle = (angle, length) => {
@@ -15,19 +10,19 @@ export class Vector3d {
15
10
  this.x = xOrCoords.x;
16
11
  this.y = xOrCoords.y;
17
12
  const coords3d = xOrCoords;
18
- this.z = coords3d.z ? coords3d.z : origin.z;
13
+ this.z = coords3d.z ? coords3d.z : originPoint.z;
19
14
  }
20
15
  else if (xOrCoords !== undefined && y !== undefined) {
21
16
  this.x = xOrCoords;
22
17
  this.y = y;
23
- this.z = z ?? origin.z;
18
+ this.z = z ?? originPoint.z;
24
19
  }
25
20
  else {
26
21
  throw new Error(`${errorPrefix} Vector3d not initialized correctly`);
27
22
  }
28
23
  }
29
24
  static get origin() {
30
- return Vector3d.create(origin.x, origin.y, origin.z);
25
+ return Vector3d.create(originPoint.x, originPoint.y, originPoint.z);
31
26
  }
32
27
  get angle() {
33
28
  return Math.atan2(this.y, this.x);
@@ -84,19 +79,19 @@ export class Vector3d {
84
79
  this.z *= n;
85
80
  }
86
81
  normalize() {
87
- const length = this.length, noLength = 0;
88
- if (length != noLength) {
82
+ const length = this.length;
83
+ if (length != none) {
89
84
  this.multTo(inverseFactorNumerator / length);
90
85
  }
91
86
  }
92
87
  rotate(angle) {
93
- return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), origin.z);
88
+ return Vector3d.create(this.x * Math.cos(angle) - this.y * Math.sin(angle), this.x * Math.sin(angle) + this.y * Math.cos(angle), originPoint.z);
94
89
  }
95
90
  setTo(c) {
96
91
  this.x = c.x;
97
92
  this.y = c.y;
98
93
  const v3d = c;
99
- this.z = v3d.z ? v3d.z : origin.z;
94
+ this.z = v3d.z ? v3d.z : originPoint.z;
100
95
  }
101
96
  sub(v) {
102
97
  return Vector3d.create(this.x - v.x, this.y - v.y, this.z - v.z);
@@ -109,10 +104,10 @@ export class Vector3d {
109
104
  }
110
105
  export class Vector extends Vector3d {
111
106
  constructor(xOrCoords, y) {
112
- super(xOrCoords, y, origin.z);
107
+ super(xOrCoords, y, originPoint.z);
113
108
  }
114
109
  static get origin() {
115
- return Vector.create(origin.x, origin.y);
110
+ return Vector.create(originPoint.x, originPoint.y);
116
111
  }
117
112
  static clone(source) {
118
113
  return Vector.create(source.x, source.y);