@tsparticles/engine 3.7.1 → 3.8.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.
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 +59 -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 +61 -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 +59 -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 +61 -10
@@ -1,7 +1,7 @@
1
1
  import { PixelMode } from "../../Enums/Modes/PixelMode.js";
2
2
  import { deepExtend } from "../../Utils/Utils.js";
3
3
  import { isNull } from "../../Utils/TypeUtils.js";
4
- const defaultPosition = 50;
4
+ import { manualDefaultPosition } from "../../Core/Utils/Constants.js";
5
5
  export class ManualParticle {
6
6
  load(data) {
7
7
  if (isNull(data)) {
@@ -9,8 +9,8 @@ export class ManualParticle {
9
9
  }
10
10
  if (data.position) {
11
11
  this.position = {
12
- x: data.position.x ?? defaultPosition,
13
- y: data.position.y ?? defaultPosition,
12
+ x: data.position.x ?? manualDefaultPosition,
13
+ y: data.position.y ?? manualDefaultPosition,
14
14
  mode: data.position.mode ?? PixelMode.percent,
15
15
  };
16
16
  }
@@ -1,11 +1,6 @@
1
+ import { defaultAngle, defaultTransform, identity, lFactor, minStrokeWidth, originPoint, } from "../Core/Utils/Constants.js";
1
2
  import { AlterType } from "../Enums/Types/AlterType.js";
2
3
  import { getStyleFromRgb } from "./ColorUtils.js";
3
- const origin = { x: 0, y: 0 }, defaultTransform = {
4
- a: 1,
5
- b: 0,
6
- c: 0,
7
- d: 1,
8
- };
9
4
  export function drawLine(context, begin, end) {
10
5
  context.beginPath();
11
6
  context.moveTo(begin.x, begin.y);
@@ -14,24 +9,24 @@ export function drawLine(context, begin, end) {
14
9
  }
15
10
  export function paintBase(context, dimension, baseColor) {
16
11
  context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
17
- context.fillRect(origin.x, origin.y, dimension.width, dimension.height);
12
+ context.fillRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
18
13
  }
19
14
  export function paintImage(context, dimension, image, opacity) {
20
15
  if (!image) {
21
16
  return;
22
17
  }
23
18
  context.globalAlpha = opacity;
24
- context.drawImage(image, origin.x, origin.y, dimension.width, dimension.height);
19
+ context.drawImage(image, originPoint.x, originPoint.y, dimension.width, dimension.height);
25
20
  context.globalAlpha = 1;
26
21
  }
27
22
  export function clear(context, dimension) {
28
- context.clearRect(origin.x, origin.y, dimension.width, dimension.height);
23
+ context.clearRect(originPoint.x, originPoint.y, dimension.width, dimension.height);
29
24
  }
30
25
  export function drawParticle(data) {
31
- const { container, context, particle, delta, colorStyles, backgroundMask, composite, radius, opacity, shadow, transform, } = data, pos = particle.getPosition(), defaultAngle = 0, angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : defaultAngle), rotateData = {
26
+ const { container, context, particle, delta, colorStyles, backgroundMask, composite, radius, opacity, shadow, transform, } = data, pos = particle.getPosition(), angle = particle.rotation + (particle.pathRotation ? particle.velocity.angle : defaultAngle), rotateData = {
32
27
  sin: Math.sin(angle),
33
28
  cos: Math.cos(angle),
34
- }, rotating = !!angle, identity = 1, transformData = {
29
+ }, rotating = !!angle, transformData = {
35
30
  a: rotateData.cos * (transform.a ?? defaultTransform.a),
36
31
  b: rotating ? rotateData.sin * (transform.b ?? identity) : (transform.b ?? defaultTransform.b),
37
32
  c: rotating ? -rotateData.sin * (transform.c ?? identity) : (transform.c ?? defaultTransform.c),
@@ -51,7 +46,7 @@ export function drawParticle(data) {
51
46
  if (colorStyles.fill) {
52
47
  context.fillStyle = colorStyles.fill;
53
48
  }
54
- const minStrokeWidth = 0, strokeWidth = particle.strokeWidth ?? minStrokeWidth;
49
+ const strokeWidth = particle.strokeWidth ?? minStrokeWidth;
55
50
  context.lineWidth = strokeWidth;
56
51
  if (colorStyles.stroke) {
57
52
  context.strokeStyle = colorStyles.stroke;
@@ -92,7 +87,7 @@ export function drawEffect(data) {
92
87
  });
93
88
  }
94
89
  export function drawShape(data) {
95
- const { container, context, particle, radius, opacity, delta, strokeWidth, transformData } = data, minStrokeWidth = 0;
90
+ const { container, context, particle, radius, opacity, delta, strokeWidth, transformData } = data;
96
91
  if (!particle.shape) {
97
92
  return;
98
93
  }
@@ -152,7 +147,6 @@ export function drawParticlePlugin(context, plugin, particle, delta) {
152
147
  plugin.drawParticle(context, particle, delta);
153
148
  }
154
149
  export function alterHsl(color, type, value) {
155
- const lFactor = 1;
156
150
  return {
157
151
  h: color.h,
158
152
  s: color.s,
@@ -1,9 +1,8 @@
1
1
  import { clamp, getRandom, getRangeMax, getRangeMin, getRangeValue, mix, randomInRange, setRangeValue, } from "./NumberUtils.js";
2
+ import { decayOffset, defaultLoops, defaultOpacity, defaultRgbMin, defaultTime, defaultVelocity, double, hMax, hMin, hPhase, half, identity, lMax, lMin, midColorValue, millisecondsToSeconds, percentDenominator, phaseNumerator, randomColorValue, rgbFactor, rgbMax, sMax, sMin, sNormalizedOffset, sextuple, triple, } from "../Core/Utils/Constants.js";
2
3
  import { isArray, isString } from "./TypeUtils.js";
3
- import { millisecondsToSeconds, percentDenominator } from "../Core/Utils/Constants.js";
4
4
  import { AnimationStatus } from "../Enums/AnimationStatus.js";
5
5
  import { itemFromArray } from "./Utils.js";
6
- const randomColorValue = "random", midColorValue = "mid";
7
6
  function stringToRgba(engine, input) {
8
7
  if (!input) {
9
8
  return;
@@ -63,7 +62,7 @@ export function rangeColorToHsl(engine, color, index, useIndex = true) {
63
62
  return rgb ? rgbToHsl(rgb) : undefined;
64
63
  }
65
64
  export function rgbToHsl(color) {
66
- const rgbMax = 255, hMax = 360, sMax = 100, lMax = 100, hMin = 0, sMin = 0, hPhase = 60, half = 0.5, double = 2, r1 = color.r / rgbMax, g1 = color.g / rgbMax, b1 = color.b / rgbMax, max = Math.max(r1, g1, b1), min = Math.min(r1, g1, b1), res = {
65
+ const r1 = color.r / rgbMax, g1 = color.g / rgbMax, b1 = color.b / rgbMax, max = Math.max(r1, g1, b1), min = Math.min(r1, g1, b1), res = {
67
66
  h: hMin,
68
67
  l: (max + min) * half,
69
68
  s: sMin,
@@ -93,13 +92,13 @@ export function stringToRgb(engine, input) {
93
92
  return stringToRgba(engine, input);
94
93
  }
95
94
  export function hslToRgb(hsl) {
96
- const hMax = 360, sMax = 100, lMax = 100, sMin = 0, lMin = 0, 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, rgbFactor = 255, triple = 3;
95
+ 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;
97
96
  if (s === sMin) {
98
97
  const grayscaleValue = Math.round(lNormalized * rgbFactor);
99
98
  return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
100
99
  }
101
- const half = 0.5, double = 2, channel = (temp1, temp2, temp3) => {
102
- const temp3Min = 0, temp3Max = 1, sextuple = 6;
100
+ const channel = (temp1, temp2, temp3) => {
101
+ const temp3Min = 0, temp3Max = 1;
103
102
  if (temp3 < temp3Min) {
104
103
  temp3++;
105
104
  }
@@ -117,9 +116,9 @@ export function hslToRgb(hsl) {
117
116
  return temp1 + (temp2 - temp1) * (temp3Offset - temp3) * sextuple;
118
117
  }
119
118
  return temp1;
120
- }, sNormalizedOffset = 1, temp1 = lNormalized < half
119
+ }, temp1 = lNormalized < half
121
120
  ? lNormalized * (sNormalizedOffset + sNormalized)
122
- : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseNumerator = 1, phaseThird = phaseNumerator / triple, red = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized)), blue = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized - phaseThird));
121
+ : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = double * lNormalized - temp1, phaseThird = phaseNumerator / triple, red = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized + phaseThird)), green = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized)), blue = Math.min(rgbFactor, rgbFactor * channel(temp2, temp1, hNormalized - phaseThird));
123
122
  return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
124
123
  }
125
124
  export function hslaToRgba(hsla) {
@@ -132,19 +131,17 @@ export function hslaToRgba(hsla) {
132
131
  };
133
132
  }
134
133
  export function getRandomRgbColor(min) {
135
- const defaultMin = 0, fixedMin = min ?? defaultMin, rgbMax = 256;
134
+ const fixedMin = min ?? defaultRgbMin, fixedMax = rgbMax + identity;
136
135
  return {
137
- b: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
138
- g: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
139
- r: Math.floor(randomInRange(setRangeValue(fixedMin, rgbMax))),
136
+ b: Math.floor(randomInRange(setRangeValue(fixedMin, fixedMax))),
137
+ g: Math.floor(randomInRange(setRangeValue(fixedMin, fixedMax))),
138
+ r: Math.floor(randomInRange(setRangeValue(fixedMin, fixedMax))),
140
139
  };
141
140
  }
142
141
  export function getStyleFromRgb(color, opacity) {
143
- const defaultOpacity = 1;
144
142
  return `rgba(${color.r}, ${color.g}, ${color.b}, ${opacity ?? defaultOpacity})`;
145
143
  }
146
144
  export function getStyleFromHsl(color, opacity) {
147
- const defaultOpacity = 1;
148
145
  return `hsla(${color.h}, ${color.s}%, ${color.l}%, ${opacity ?? defaultOpacity})`;
149
146
  }
150
147
  export function colorMix(color1, color2, size1, size2) {
@@ -236,7 +233,6 @@ export function getHslAnimationFromHsl(hsl, animationOptions, reduceFactor) {
236
233
  }
237
234
  function setColorAnimation(colorValue, colorAnimation, reduceFactor) {
238
235
  colorValue.enable = colorAnimation.enable;
239
- const defaultVelocity = 0, decayOffset = 1, defaultLoops = 0, defaultTime = 0;
240
236
  if (colorValue.enable) {
241
237
  colorValue.velocity = (getRangeValue(colorAnimation.speed) / percentDenominator) * reduceFactor;
242
238
  colorValue.decay = decayOffset - getRangeValue(colorAnimation.decay);
@@ -308,8 +304,7 @@ export function updateColor(color, delta) {
308
304
  if (!color) {
309
305
  return;
310
306
  }
311
- const { h, s, l } = color;
312
- const ranges = {
307
+ const { h, s, l } = color, ranges = {
313
308
  h: { min: 0, max: 360 },
314
309
  s: { min: 0, max: 100 },
315
310
  l: { min: 0, max: 100 },
@@ -1,3 +1,4 @@
1
+ import { deleteCount, minIndex } from "../Core/Utils/Constants.js";
1
2
  export class EventDispatcher {
2
3
  constructor() {
3
4
  this._listeners = new Map();
@@ -31,11 +32,10 @@ export class EventDispatcher {
31
32
  if (!arr) {
32
33
  return;
33
34
  }
34
- const length = arr.length, idx = arr.indexOf(listener), minIndex = 0;
35
+ const length = arr.length, idx = arr.indexOf(listener);
35
36
  if (idx < minIndex) {
36
37
  return;
37
38
  }
38
- const deleteCount = 1;
39
39
  if (length === deleteCount) {
40
40
  this._listeners.delete(type);
41
41
  }
@@ -1,12 +1,12 @@
1
1
  import { MoveDirection } from "../Enums/Directions/MoveDirection.js";
2
+ import { double, doublePI, empty, half, percentDenominator, quarter, threeQuarter } from "../Core/Utils/Constants.js";
2
3
  import { Vector } from "../Core/Utils/Vectors.js";
3
4
  import { isNumber } from "./TypeUtils.js";
4
- import { percentDenominator } from "../Core/Utils/Constants.js";
5
5
  let _random = Math.random;
6
6
  const _animationLoop = {
7
7
  nextFrame: (cb) => requestAnimationFrame(cb),
8
8
  cancel: (idx) => cancelAnimationFrame(idx),
9
- }, double = 2, doublePI = Math.PI * double;
9
+ };
10
10
  export function setRandom(rnd = Math.random) {
11
11
  _random = rnd;
12
12
  }
@@ -74,7 +74,6 @@ export function getParticleDirectionAngle(direction, position, center) {
74
74
  if (isNumber(direction)) {
75
75
  return degToRad(direction);
76
76
  }
77
- const empty = 0, half = 0.5, quarter = 0.25, threeQuarter = half + quarter;
78
77
  switch (direction) {
79
78
  case MoveDirection.top:
80
79
  return -Math.PI * half;
@@ -107,7 +106,6 @@ export function getParticleBaseVelocity(direction) {
107
106
  return baseVelocity;
108
107
  }
109
108
  export function collisionVelocity(v1, v2, m1, m2) {
110
- const double = 2;
111
109
  return Vector.create((v1.x * (m1 - m2)) / (m1 + m2) + (v2.x * double * m2) / (m1 + m2), v1.y);
112
110
  }
113
111
  export function calcPositionFromSize(data) {
@@ -1,6 +1,6 @@
1
1
  import { clamp, collisionVelocity, getDistances, getRandom, getRangeMax, getRangeMin, getRangeValue, randomInRange, } from "./NumberUtils.js";
2
- import { halfRandom, millisecondsToSeconds, percentDenominator } from "../Core/Utils/Constants.js";
3
- import { isArray, isObject } from "./TypeUtils.js";
2
+ import { half, millisecondsToSeconds, minVelocity, percentDenominator } from "../Core/Utils/Constants.js";
3
+ import { isArray, isNull, isObject } from "./TypeUtils.js";
4
4
  import { AnimationMode } from "../Enums/Modes/AnimationMode.js";
5
5
  import { AnimationStatus } from "../Enums/AnimationStatus.js";
6
6
  import { DestroyType } from "../Enums/Types/DestroyType.js";
@@ -27,8 +27,20 @@ export function setLogger(logger) {
27
27
  export function getLogger() {
28
28
  return _logger;
29
29
  }
30
+ function memoize(fn) {
31
+ const cache = new Map();
32
+ return (...args) => {
33
+ const key = JSON.stringify(args);
34
+ if (cache.has(key)) {
35
+ return cache.get(key);
36
+ }
37
+ const result = fn(...args);
38
+ cache.set(key, result);
39
+ return result;
40
+ };
41
+ }
30
42
  function rectSideBounce(data) {
31
- const res = { bounced: false }, { pSide, pOtherSide, rectSide, rectOtherSide, velocity, factor } = data, half = 0.5, minVelocity = 0;
43
+ const res = { bounced: false }, { pSide, pOtherSide, rectSide, rectOtherSide, velocity, factor } = data;
32
44
  if (pOtherSide.min < rectOtherSide.min ||
33
45
  pOtherSide.min > rectOtherSide.max ||
34
46
  pOtherSide.max < rectOtherSide.min ||
@@ -284,7 +296,7 @@ export function initParticleNumericAnimationValue(options, pxRatio) {
284
296
  res.status = AnimationStatus.decreasing;
285
297
  break;
286
298
  case AnimationMode.random:
287
- res.status = getRandom() >= halfRandom ? AnimationStatus.increasing : AnimationStatus.decreasing;
299
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
288
300
  break;
289
301
  }
290
302
  const autoStatus = animationOptions.mode === AnimationMode.auto;
@@ -305,7 +317,7 @@ export function initParticleNumericAnimationValue(options, pxRatio) {
305
317
  default:
306
318
  res.value = randomInRange(res);
307
319
  if (autoStatus) {
308
- res.status = getRandom() >= halfRandom ? AnimationStatus.increasing : AnimationStatus.decreasing;
320
+ res.status = getRandom() >= half ? AnimationStatus.increasing : AnimationStatus.decreasing;
309
321
  }
310
322
  break;
311
323
  }
@@ -414,9 +426,47 @@ export function updateAnimation(particle, data, changeDirection, destroyType, de
414
426
  data.value = clamp(data.value, minValue, maxValue);
415
427
  }
416
428
  }
417
- export function assertValidVersion(engine, pluginVersion) {
418
- if (engine.version === pluginVersion) {
419
- return;
429
+ export function cloneStyle(style) {
430
+ const clonedStyle = document.createElement("div").style;
431
+ if (!style) {
432
+ return clonedStyle;
433
+ }
434
+ for (const key in style) {
435
+ const styleKey = style[key];
436
+ if (!Object.prototype.hasOwnProperty.call(style, key) || isNull(styleKey)) {
437
+ continue;
438
+ }
439
+ const styleValue = style.getPropertyValue?.(styleKey);
440
+ if (!styleValue) {
441
+ continue;
442
+ }
443
+ const stylePriority = style.getPropertyPriority?.(styleKey);
444
+ if (!stylePriority) {
445
+ clonedStyle.setProperty?.(styleKey, styleValue);
446
+ }
447
+ else {
448
+ clonedStyle.setProperty?.(styleKey, styleValue, stylePriority);
449
+ }
450
+ }
451
+ return clonedStyle;
452
+ }
453
+ function computeFullScreenStyle(zIndex) {
454
+ const fullScreenStyle = document.createElement("div").style, radix = 10, style = {
455
+ width: "100%",
456
+ height: "100%",
457
+ margin: "0",
458
+ padding: "0",
459
+ borderWidth: "0",
460
+ position: "fixed",
461
+ zIndex: zIndex.toString(radix),
462
+ "z-index": zIndex.toString(radix),
463
+ top: "0",
464
+ left: "0",
465
+ };
466
+ for (const key in style) {
467
+ const value = style[key];
468
+ fullScreenStyle.setProperty(key, value);
420
469
  }
421
- throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${engine.version}. Plugins version: ${pluginVersion}`);
470
+ return fullScreenStyle;
422
471
  }
472
+ export const getFullScreenStyle = memoize(computeFullScreenStyle);
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Canvas = void 0;
4
4
  const CanvasUtils_js_1 = require("../Utils/CanvasUtils.js");
5
5
  const Utils_js_1 = require("../Utils/Utils.js");
6
- const ColorUtils_js_1 = require("../Utils/ColorUtils.js");
7
6
  const Constants_js_1 = require("./Utils/Constants.js");
7
+ const ColorUtils_js_1 = require("../Utils/ColorUtils.js");
8
8
  function setTransformValue(factor, newFactor, key) {
9
- const newValue = newFactor[key], defaultValue = 1;
9
+ const newValue = newFactor[key];
10
10
  if (newValue !== undefined) {
11
- factor[key] = (factor[key] ?? defaultValue) * newValue;
11
+ factor[key] = (factor[key] ?? Constants_js_1.defaultTransformValue) * newValue;
12
12
  }
13
13
  }
14
14
  function setStyle(canvas, style, important = false) {
@@ -23,9 +23,27 @@ function setStyle(canvas, style, important = false) {
23
23
  if (!elementStyle) {
24
24
  return;
25
25
  }
26
+ const keys = new Set();
27
+ for (const key in elementStyle) {
28
+ if (!Object.prototype.hasOwnProperty.call(elementStyle, key)) {
29
+ continue;
30
+ }
31
+ keys.add(elementStyle[key]);
32
+ }
26
33
  for (const key in style) {
27
- const value = style[key];
28
- elementStyle.setProperty(key, value, important ? "important" : "");
34
+ if (!Object.prototype.hasOwnProperty.call(style, key)) {
35
+ continue;
36
+ }
37
+ keys.add(style[key]);
38
+ }
39
+ for (const key of keys) {
40
+ const value = style.getPropertyValue(key);
41
+ if (!value) {
42
+ elementStyle.removeProperty(key);
43
+ }
44
+ else {
45
+ elementStyle.setProperty(key, value, important ? "important" : "");
46
+ }
29
47
  }
30
48
  }
31
49
  class Canvas {
@@ -114,14 +132,13 @@ class Canvas {
114
132
  return;
115
133
  }
116
134
  if (this._fullScreen) {
117
- this._originalStyle = (0, Utils_js_1.deepExtend)({}, element.style);
118
135
  this._setFullScreenStyle();
119
136
  }
120
137
  else {
121
138
  this._resetOriginalStyle();
122
139
  }
123
140
  for (const key in options.style) {
124
- if (!key || !options.style) {
141
+ if (!key || !options.style || !Object.prototype.hasOwnProperty.call(options.style, key)) {
125
142
  continue;
126
143
  }
127
144
  const value = options.style[key];
@@ -136,7 +153,7 @@ class Canvas {
136
153
  if (!trail.enable) {
137
154
  return;
138
155
  }
139
- const factorNumerator = 1, opacity = factorNumerator / trail.length;
156
+ const opacity = Constants_js_1.inverseFactorNumerator / trail.length;
140
157
  if (trailFill.color) {
141
158
  const fillColor = (0, ColorUtils_js_1.rangeColorToRgb)(this._engine, trailFill.color);
142
159
  if (!fillColor) {
@@ -192,10 +209,10 @@ class Canvas {
192
209
  };
193
210
  this._resetOriginalStyle = () => {
194
211
  const element = this.element, originalStyle = this._originalStyle;
195
- if (!(element && originalStyle)) {
212
+ if (!element || !originalStyle) {
196
213
  return;
197
214
  }
198
- setStyle(element, originalStyle);
215
+ setStyle(element, originalStyle, true);
199
216
  };
200
217
  this._safeMutationObserver = callback => {
201
218
  if (!this._mutationObserver) {
@@ -208,16 +225,7 @@ class Canvas {
208
225
  if (!element) {
209
226
  return;
210
227
  }
211
- const radix = 10, zIndex = this.container.actualOptions.fullScreen.zIndex.toString(radix);
212
- setStyle(element, {
213
- position: "fixed",
214
- "z-index": zIndex,
215
- zIndex: zIndex,
216
- top: "0",
217
- left: "0",
218
- width: "100%",
219
- height: "100%",
220
- }, true);
228
+ setStyle(element, (0, Utils_js_1.getFullScreenStyle)(this.container.actualOptions.fullScreen.zIndex), true);
221
229
  };
222
230
  this._engine = engine;
223
231
  this._standardSize = {
@@ -240,11 +248,11 @@ class Canvas {
240
248
  return this.container.actualOptions.fullScreen.enable;
241
249
  }
242
250
  clear() {
243
- const options = this.container.actualOptions, trail = options.particles.move.trail, trailFill = this._trailFill, minimumLength = 0;
251
+ const options = this.container.actualOptions, trail = options.particles.move.trail, trailFill = this._trailFill;
244
252
  if (options.backgroundMask.enable) {
245
253
  this.paint();
246
254
  }
247
- else if (trail.enable && trail.length > minimumLength && trailFill) {
255
+ else if (trail.enable && trail.length > Constants_js_1.minimumLength && trailFill) {
248
256
  if (trailFill.color) {
249
257
  this._paintBase((0, ColorUtils_js_1.getStyleFromRgb)(trailFill.color, trailFill.opacity));
250
258
  }
@@ -263,6 +271,7 @@ class Canvas {
263
271
  if (this._generated) {
264
272
  const element = this.element;
265
273
  element?.remove();
274
+ this.element = undefined;
266
275
  }
267
276
  else {
268
277
  this._resetOriginalStyle();
@@ -290,8 +299,8 @@ class Canvas {
290
299
  if (particle.spawning || particle.destroyed) {
291
300
  return;
292
301
  }
293
- const radius = particle.getRadius(), minimumSize = 0;
294
- if (radius <= minimumSize) {
302
+ const radius = particle.getRadius();
303
+ if (radius <= Constants_js_1.minimumSize) {
295
304
  return;
296
305
  }
297
306
  const pfColor = particle.getFillColor(), psColor = particle.getStrokeColor() ?? pfColor;
@@ -306,7 +315,7 @@ class Canvas {
306
315
  return;
307
316
  }
308
317
  this.draw((ctx) => {
309
- 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 = {
318
+ const container = this.container, options = container.actualOptions, zIndexOptions = particle.options.zIndex, zIndexFactor = Constants_js_1.zIndexFactorOffset - particle.zIndexFactor, zOpacityFactor = zIndexFactor ** zIndexOptions.opacityRate, opacity = particle.bubble.opacity ?? particle.opacity?.value ?? Constants_js_1.defaultOpacity, strokeOpacity = particle.strokeOpacity ?? opacity, zOpacity = opacity * zOpacityFactor, zStrokeOpacity = strokeOpacity * zOpacityFactor, transform = {}, colorStyles = {
310
319
  fill: fColor ? (0, ColorUtils_js_1.getStyleFromHsl)(fColor, zOpacity) : undefined,
311
320
  };
312
321
  colorStyles.stroke = sColor ? (0, ColorUtils_js_1.getStyleFromHsl)(sColor, zStrokeOpacity) : colorStyles.fill;
@@ -416,7 +425,7 @@ class Canvas {
416
425
  : this._generated;
417
426
  this.element = canvas;
418
427
  this.element.ariaHidden = "true";
419
- this._originalStyle = (0, Utils_js_1.deepExtend)({}, this.element.style);
428
+ this._originalStyle = (0, Utils_js_1.cloneStyle)(this.element.style);
420
429
  const standardSize = this._standardSize;
421
430
  standardSize.height = canvas.offsetHeight;
422
431
  standardSize.width = canvas.offsetWidth;
@@ -424,14 +433,15 @@ class Canvas {
424
433
  canvas.height = retinaSize.height = standardSize.height * pxRatio;
425
434
  canvas.width = retinaSize.width = standardSize.width * pxRatio;
426
435
  this._context = this.element.getContext("2d");
436
+ this._safeMutationObserver(obs => obs.disconnect());
437
+ this.container.retina.init();
438
+ this.initBackground();
427
439
  this._safeMutationObserver(obs => {
428
440
  if (!this.element || !(this.element instanceof Node)) {
429
441
  return;
430
442
  }
431
443
  obs.observe(this.element, { attributes: true });
432
444
  });
433
- this.container.retina.init();
434
- this.initBackground();
435
445
  }
436
446
  paint() {
437
447
  const options = this.container.actualOptions;
@@ -14,11 +14,10 @@ const OptionsUtils_js_1 = require("../Utils/OptionsUtils.js");
14
14
  function guardCheck(container) {
15
15
  return container && !container.destroyed;
16
16
  }
17
- const defaultFps = 60;
18
- function initDelta(value, fpsLimit = defaultFps, smooth = false) {
17
+ function initDelta(value, fpsLimit = Constants_js_1.defaultFps, smooth = false) {
19
18
  return {
20
19
  value,
21
- factor: smooth ? defaultFps / fpsLimit : (defaultFps * value) / Constants_js_1.millisecondsToSeconds,
20
+ factor: smooth ? Constants_js_1.defaultFps / fpsLimit : (Constants_js_1.defaultFps * value) / Constants_js_1.millisecondsToSeconds,
22
21
  };
23
22
  }
24
23
  function loadContainerOptions(engine, container, ...sourceOptionsArr) {
@@ -142,8 +141,8 @@ class Container {
142
141
  const mouseEvent = e, pos = {
143
142
  x: mouseEvent.offsetX || mouseEvent.clientX,
144
143
  y: mouseEvent.offsetY || mouseEvent.clientY,
145
- }, radius = 1;
146
- clickOrTouchHandler(e, pos, radius);
144
+ };
145
+ clickOrTouchHandler(e, pos, Constants_js_1.clickRadius);
147
146
  }, touchStartHandler = () => {
148
147
  if (!guardCheck(this)) {
149
148
  return;
@@ -160,17 +159,17 @@ class Container {
160
159
  return;
161
160
  }
162
161
  if (touched && !touchMoved) {
163
- const touchEvent = e, lengthOffset = 1;
164
- let lastTouch = touchEvent.touches[touchEvent.touches.length - lengthOffset];
162
+ const touchEvent = e;
163
+ let lastTouch = touchEvent.touches[touchEvent.touches.length - Constants_js_1.touchEndLengthOffset];
165
164
  if (!lastTouch) {
166
- lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - lengthOffset];
165
+ lastTouch = touchEvent.changedTouches[touchEvent.changedTouches.length - Constants_js_1.touchEndLengthOffset];
167
166
  if (!lastTouch) {
168
167
  return;
169
168
  }
170
169
  }
171
- const element = this.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, minCoordinate = 0, pos = {
172
- x: lastTouch.clientX - (canvasRect ? canvasRect.left : minCoordinate),
173
- y: lastTouch.clientY - (canvasRect ? canvasRect.top : minCoordinate),
170
+ const element = this.canvas.element, canvasRect = element ? element.getBoundingClientRect() : undefined, pos = {
171
+ x: lastTouch.clientX - (canvasRect ? canvasRect.left : Constants_js_1.minCoordinate),
172
+ y: lastTouch.clientY - (canvasRect ? canvasRect.top : Constants_js_1.minCoordinate),
174
173
  };
175
174
  clickOrTouchHandler(e, pos, Math.max(lastTouch.radiusX, lastTouch.radiusY));
176
175
  }
@@ -238,10 +237,9 @@ class Container {
238
237
  this._engine.clearPlugins(this);
239
238
  this.destroyed = true;
240
239
  if (remove) {
241
- const mainArr = this._engine.items, idx = mainArr.findIndex(t => t === this), minIndex = 0;
242
- if (idx >= minIndex) {
243
- const deleteCount = 1;
244
- mainArr.splice(idx, deleteCount);
240
+ const mainArr = this._engine.items, idx = mainArr.findIndex(t => t === this);
241
+ if (idx >= Constants_js_1.removeMinIndex) {
242
+ mainArr.splice(idx, Constants_js_1.removeDeleteCount);
245
243
  }
246
244
  }
247
245
  this._engine.dispatchEvent(EventType_js_1.EventType.containerDestroyed, { container: this });
@@ -317,8 +315,7 @@ class Container {
317
315
  this._duration = (0, NumberUtils_js_1.getRangeValue)(duration) * Constants_js_1.millisecondsToSeconds;
318
316
  this._delay = (0, NumberUtils_js_1.getRangeValue)(delay) * Constants_js_1.millisecondsToSeconds;
319
317
  this._lifeTime = 0;
320
- const defaultFpsLimit = 120, minFpsLimit = 0;
321
- this.fpsLimit = fpsLimit > minFpsLimit ? fpsLimit : defaultFpsLimit;
318
+ this.fpsLimit = fpsLimit > Constants_js_1.minFpsLimit ? fpsLimit : Constants_js_1.defaultFpsLimit;
322
319
  this._smooth = smooth;
323
320
  for (const drawer of this.effectDrawers.values()) {
324
321
  await drawer.init?.(this);
@@ -27,24 +27,23 @@ async function getDataFromUrl(data) {
27
27
  (0, Utils_js_1.getLogger)().error(`${Constants_js_1.errorPrefix} ${response.status} while retrieving config file`);
28
28
  return data.fallback;
29
29
  }
30
- const generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", getCanvasFromContainer = (domContainer) => {
30
+ const getCanvasFromContainer = (domContainer) => {
31
31
  let canvasEl;
32
- if (domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === canvasTag) {
32
+ if (domContainer instanceof HTMLCanvasElement || domContainer.tagName.toLowerCase() === Constants_js_1.canvasTag) {
33
33
  canvasEl = domContainer;
34
34
  if (!canvasEl.dataset[Constants_js_1.generatedAttribute]) {
35
- canvasEl.dataset[Constants_js_1.generatedAttribute] = generatedFalse;
35
+ canvasEl.dataset[Constants_js_1.generatedAttribute] = Constants_js_1.generatedFalse;
36
36
  }
37
37
  }
38
38
  else {
39
- const existingCanvases = domContainer.getElementsByTagName(canvasTag);
39
+ const existingCanvases = domContainer.getElementsByTagName(Constants_js_1.canvasTag);
40
40
  if (existingCanvases.length) {
41
- const firstIndex = 0;
42
- canvasEl = existingCanvases[firstIndex];
43
- canvasEl.dataset[Constants_js_1.generatedAttribute] = generatedFalse;
41
+ canvasEl = existingCanvases[Constants_js_1.canvasFirstIndex];
42
+ canvasEl.dataset[Constants_js_1.generatedAttribute] = Constants_js_1.generatedFalse;
44
43
  }
45
44
  else {
46
- canvasEl = document.createElement(canvasTag);
47
- canvasEl.dataset[Constants_js_1.generatedAttribute] = generatedTrue;
45
+ canvasEl = document.createElement(Constants_js_1.canvasTag);
46
+ canvasEl.dataset[Constants_js_1.generatedAttribute] = Constants_js_1.generatedTrue;
48
47
  domContainer.appendChild(canvasEl);
49
48
  }
50
49
  }
@@ -63,7 +62,7 @@ const generatedTrue = "true", generatedFalse = "false", canvasTag = "canvas", ge
63
62
  }
64
63
  domContainer = document.createElement("div");
65
64
  domContainer.id = id;
66
- domContainer.dataset[Constants_js_1.generatedAttribute] = generatedTrue;
65
+ domContainer.dataset[Constants_js_1.generatedAttribute] = Constants_js_1.generatedTrue;
67
66
  document.body.append(domContainer);
68
67
  return domContainer;
69
68
  };
@@ -100,7 +99,7 @@ class Engine {
100
99
  return this._domArray;
101
100
  }
102
101
  get version() {
103
- return "3.7.1";
102
+ return "3.8.1";
104
103
  }
105
104
  async addColorManager(manager, refresh = true) {
106
105
  this.colorManagers.set(manager.key, manager);
@@ -168,6 +167,12 @@ class Engine {
168
167
  }
169
168
  await this.refresh(refresh);
170
169
  }
170
+ checkVersion(pluginVersion) {
171
+ if (this.version === pluginVersion) {
172
+ return;
173
+ }
174
+ throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${this.version}. Plugin version: ${pluginVersion}`);
175
+ }
171
176
  clearPlugins(container) {
172
177
  this.updaters.delete(container);
173
178
  this.movers.delete(container);
@@ -233,17 +238,16 @@ class Engine {
233
238
  item(index) {
234
239
  const { items } = this, item = items[index];
235
240
  if (!item || item.destroyed) {
236
- const deleteCount = 1;
237
- items.splice(index, deleteCount);
241
+ items.splice(index, Constants_js_1.removeDeleteCount);
238
242
  return;
239
243
  }
240
244
  return item;
241
245
  }
242
246
  async load(params) {
243
- const randomFactor = 10000, id = params.id ?? params.element?.id ?? `tsparticles${Math.floor((0, NumberUtils_js_1.getRandom)() * randomFactor)}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options;
244
- const currentOptions = (0, Utils_js_1.itemFromSingleOrMultiple)(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), minIndex = 0, newItem = new Container_js_1.Container(this, id, currentOptions);
245
- if (oldIndex >= minIndex) {
246
- const old = this.item(oldIndex), one = 1, none = 0, deleteCount = old ? one : none;
247
+ const id = params.id ?? params.element?.id ?? `tsparticles${Math.floor((0, NumberUtils_js_1.getRandom)() * Constants_js_1.loadRandomFactor)}`, { index, url } = params, options = url ? await getDataFromUrl({ fallback: params.options, url, index }) : params.options;
248
+ const currentOptions = (0, Utils_js_1.itemFromSingleOrMultiple)(options, index), { items } = this, oldIndex = items.findIndex(v => v.id.description === id), newItem = new Container_js_1.Container(this, id, currentOptions);
249
+ if (oldIndex >= Constants_js_1.loadMinIndex) {
250
+ const old = this.item(oldIndex), deleteCount = old ? Constants_js_1.one : Constants_js_1.none;
247
251
  if (old && !old.destroyed) {
248
252
  old.destroy(false);
249
253
  }