@tsparticles/engine 3.7.0 → 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 +51 -36
  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 +52 -37
  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 +51 -36
  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 +53 -38
  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,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);
@@ -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,46 @@ 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
+ top: "0",
463
+ left: "0",
464
+ };
465
+ for (const key in style) {
466
+ const value = style[key];
467
+ fullScreenStyle.setProperty(key, value);
420
468
  }
421
- throw new Error(`The tsParticles version is different from the loaded plugins version. Engine version: ${engine.version}. Plugins version: ${pluginVersion}`);
469
+ return fullScreenStyle;
422
470
  }
471
+ 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,23 +425,23 @@ 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;
423
- const pxRatio = this.container.retina.pixelRatio;
424
- const retinaSize = this.size;
425
- retinaSize.height = standardSize.height * pxRatio;
426
- retinaSize.width = standardSize.width * pxRatio;
432
+ const pxRatio = this.container.retina.pixelRatio, retinaSize = this.size;
433
+ canvas.height = retinaSize.height = standardSize.height * pxRatio;
434
+ canvas.width = retinaSize.width = standardSize.width * pxRatio;
427
435
  this._context = this.element.getContext("2d");
436
+ this._safeMutationObserver(obs => obs.disconnect());
437
+ this.container.retina.init();
438
+ this.initBackground();
428
439
  this._safeMutationObserver(obs => {
429
440
  if (!this.element || !(this.element instanceof Node)) {
430
441
  return;
431
442
  }
432
443
  obs.observe(this.element, { attributes: true });
433
444
  });
434
- this.container.retina.init();
435
- this.initBackground();
436
445
  }
437
446
  paint() {
438
447
  const options = this.container.actualOptions;
@@ -461,16 +470,22 @@ class Canvas {
461
470
  const container = this.container, currentSize = container.canvas._standardSize, newSize = {
462
471
  width: this.element.offsetWidth,
463
472
  height: this.element.offsetHeight,
473
+ }, pxRatio = container.retina.pixelRatio, retinaSize = {
474
+ width: newSize.width * pxRatio,
475
+ height: newSize.height * pxRatio,
464
476
  };
465
- if (newSize.height === currentSize.height && newSize.width === currentSize.width) {
477
+ if (newSize.height === currentSize.height &&
478
+ newSize.width === currentSize.width &&
479
+ retinaSize.height === this.element.height &&
480
+ retinaSize.width === this.element.width) {
466
481
  return false;
467
482
  }
468
- const oldSize = { ...currentSize }, pxRatio = container.retina.pixelRatio;
483
+ const oldSize = { ...currentSize };
469
484
  currentSize.height = newSize.height;
470
485
  currentSize.width = newSize.width;
471
- const retinaSize = this.size;
472
- this.element.width = retinaSize.width = currentSize.width * pxRatio;
473
- this.element.height = retinaSize.height = currentSize.height * pxRatio;
486
+ const canvasSize = this.size;
487
+ this.element.width = canvasSize.width = retinaSize.width;
488
+ this.element.height = canvasSize.height = retinaSize.height;
474
489
  if (this.container.started) {
475
490
  container.particles.setResizeFactor({
476
491
  width: currentSize.width / oldSize.width,