@tsparticles/engine 3.0.0-beta.3 → 3.0.0-beta.4

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 (177) hide show
  1. package/browser/Core/Canvas.js +2 -2
  2. package/browser/Core/Container.js +36 -19
  3. package/browser/Core/Engine.js +18 -5
  4. package/browser/Core/Particle.js +75 -40
  5. package/browser/Core/Particles.js +51 -26
  6. package/browser/Core/Retina.js +0 -2
  7. package/browser/Core/Utils/QuadTree.js +1 -1
  8. package/browser/Options/Classes/BackgroundMask/BackgroundMask.js +1 -2
  9. package/browser/Options/Classes/ColorAnimation.js +4 -24
  10. package/browser/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js +0 -1
  11. package/browser/Options/Classes/Particles/Effect/Effect.js +32 -0
  12. package/browser/Options/Classes/Particles/Number/ParticlesNumber.js +3 -5
  13. package/browser/Options/Classes/Particles/Number/ParticlesNumberLimit.js +17 -0
  14. package/browser/Options/Classes/Particles/Opacity/Opacity.js +2 -3
  15. package/browser/Options/Classes/Particles/ParticlesOptions.js +3 -0
  16. package/browser/Options/Classes/Particles/Size/Size.js +2 -3
  17. package/browser/Options/Classes/ValueWithRandom.js +1 -10
  18. package/browser/Utils/CanvasUtils.js +23 -18
  19. package/browser/Utils/ColorUtils.js +24 -38
  20. package/browser/Utils/NumberUtils.js +7 -16
  21. package/browser/Utils/Utils.js +7 -7
  22. package/browser/export-types.js +4 -0
  23. package/browser/exports.js +2 -3
  24. package/cjs/Core/Canvas.js +2 -2
  25. package/cjs/Core/Container.js +36 -19
  26. package/cjs/Core/Engine.js +18 -5
  27. package/cjs/Core/Particle.js +74 -39
  28. package/cjs/Core/Particles.js +51 -26
  29. package/cjs/Core/Retina.js +0 -2
  30. package/cjs/Core/Utils/QuadTree.js +1 -1
  31. package/cjs/Options/Classes/BackgroundMask/BackgroundMask.js +1 -2
  32. package/cjs/Options/Classes/ColorAnimation.js +4 -24
  33. package/cjs/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js +0 -1
  34. package/cjs/Options/Classes/Particles/Effect/Effect.js +36 -0
  35. package/cjs/Options/Classes/Particles/Number/ParticlesNumber.js +3 -5
  36. package/cjs/Options/Classes/Particles/Number/ParticlesNumberLimit.js +21 -0
  37. package/cjs/Options/Classes/Particles/Opacity/Opacity.js +1 -2
  38. package/cjs/Options/Classes/Particles/ParticlesOptions.js +3 -0
  39. package/cjs/Options/Classes/Particles/Size/Size.js +2 -3
  40. package/cjs/Options/Classes/ValueWithRandom.js +1 -10
  41. package/cjs/Options/Interfaces/Particles/Number/IParticlesNumberLimit.js +2 -0
  42. package/cjs/Utils/CanvasUtils.js +26 -21
  43. package/cjs/Utils/ColorUtils.js +24 -38
  44. package/cjs/Utils/NumberUtils.js +8 -18
  45. package/cjs/Utils/Utils.js +6 -6
  46. package/cjs/export-types.js +4 -0
  47. package/cjs/exports.js +2 -3
  48. package/esm/Core/Canvas.js +2 -2
  49. package/esm/Core/Container.js +36 -19
  50. package/esm/Core/Engine.js +18 -5
  51. package/esm/Core/Particle.js +75 -40
  52. package/esm/Core/Particles.js +51 -26
  53. package/esm/Core/Retina.js +0 -2
  54. package/esm/Core/Utils/QuadTree.js +1 -1
  55. package/esm/Options/Classes/BackgroundMask/BackgroundMask.js +1 -2
  56. package/esm/Options/Classes/ColorAnimation.js +4 -24
  57. package/esm/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js +0 -1
  58. package/esm/Options/Classes/Particles/Effect/Effect.js +32 -0
  59. package/esm/Options/Classes/Particles/Number/ParticlesNumber.js +3 -5
  60. package/esm/Options/Classes/Particles/Number/ParticlesNumberLimit.js +17 -0
  61. package/esm/Options/Classes/Particles/Opacity/Opacity.js +2 -3
  62. package/esm/Options/Classes/Particles/ParticlesOptions.js +3 -0
  63. package/esm/Options/Classes/Particles/Size/Size.js +2 -3
  64. package/esm/Options/Classes/ValueWithRandom.js +1 -10
  65. package/esm/Options/Interfaces/Particles/Effect/IEffect.js +1 -0
  66. package/esm/Options/Interfaces/Particles/Number/IParticlesNumberLimit.js +1 -0
  67. package/esm/Utils/CanvasUtils.js +23 -18
  68. package/esm/Utils/ColorUtils.js +24 -38
  69. package/esm/Utils/NumberUtils.js +7 -16
  70. package/esm/Utils/Utils.js +7 -7
  71. package/esm/export-types.js +4 -0
  72. package/esm/exports.js +2 -3
  73. package/package.json +1 -1
  74. package/report.html +4 -22
  75. package/tsparticles.engine.js +387 -283
  76. package/tsparticles.engine.min.js +1 -1
  77. package/tsparticles.engine.min.js.LICENSE.txt +1 -1
  78. package/types/Core/Canvas.d.ts +0 -1
  79. package/types/Core/Container.d.ts +8 -7
  80. package/types/Core/Engine.d.ts +7 -2
  81. package/types/Core/Interfaces/IContainerPlugin.d.ts +2 -3
  82. package/types/Core/Interfaces/IEffectDrawer.d.ts +10 -0
  83. package/types/Core/Interfaces/IExternalInteractor.d.ts +3 -4
  84. package/types/Core/Interfaces/IInteractor.d.ts +3 -3
  85. package/types/Core/Interfaces/IParticleRetinaProps.d.ts +0 -1
  86. package/types/Core/Interfaces/IParticlesInteractor.d.ts +3 -3
  87. package/types/Core/Interfaces/IShapeDrawData.d.ts +10 -0
  88. package/types/Core/Interfaces/IShapeDrawer.d.ts +2 -10
  89. package/types/Core/Particle.d.ts +6 -2
  90. package/types/Core/Particles.d.ts +10 -7
  91. package/types/Core/Retina.d.ts +0 -1
  92. package/types/Core/Utils/ExternalInteractorBase.d.ts +4 -4
  93. package/types/Core/Utils/InteractionManager.d.ts +1 -2
  94. package/types/Core/Utils/ParticlesInteractorBase.d.ts +5 -5
  95. package/types/Enums/Modes/LimitMode.d.ts +4 -0
  96. package/types/Enums/Types/EasingType.d.ts +3 -0
  97. package/types/Options/Classes/BackgroundMask/BackgroundMask.d.ts +1 -1
  98. package/types/Options/Classes/ColorAnimation.d.ts +2 -7
  99. package/types/Options/Classes/Interactivity/Events/ClickEvent.d.ts +1 -2
  100. package/types/Options/Classes/Interactivity/Events/DivEvent.d.ts +1 -2
  101. package/types/Options/Classes/Interactivity/Events/Events.d.ts +3 -3
  102. package/types/Options/Classes/Interactivity/Events/HoverEvent.d.ts +2 -3
  103. package/types/Options/Classes/Interactivity/Interactivity.d.ts +2 -2
  104. package/types/Options/Classes/Options.d.ts +6 -6
  105. package/types/Options/Classes/Particles/Bounce/ParticlesBounce.d.ts +2 -2
  106. package/types/Options/Classes/Particles/Collisions/Collisions.d.ts +3 -3
  107. package/types/Options/Classes/Particles/Effect/Effect.d.ts +13 -0
  108. package/types/Options/Classes/Particles/Move/Move.d.ts +8 -8
  109. package/types/Options/Classes/Particles/Move/MoveTrail.d.ts +1 -1
  110. package/types/Options/Classes/Particles/Number/ParticlesNumber.d.ts +3 -2
  111. package/types/Options/Classes/Particles/Number/ParticlesNumberLimit.d.ts +10 -0
  112. package/types/Options/Classes/Particles/Opacity/Opacity.d.ts +3 -3
  113. package/types/Options/Classes/Particles/ParticlesOptions.d.ts +12 -10
  114. package/types/Options/Classes/Particles/Size/Size.d.ts +3 -3
  115. package/types/Options/Classes/Theme/Theme.d.ts +1 -1
  116. package/types/Options/Classes/ValueWithRandom.d.ts +2 -4
  117. package/types/Options/Interfaces/IValueWithRandom.d.ts +0 -2
  118. package/types/Options/Interfaces/Interactivity/Events/IClickEvent.d.ts +1 -2
  119. package/types/Options/Interfaces/Interactivity/Events/IDivEvent.d.ts +1 -2
  120. package/types/Options/Interfaces/Interactivity/Events/IHoverEvent.d.ts +1 -2
  121. package/types/Options/Interfaces/Particles/Effect/IEffect.d.ts +8 -0
  122. package/types/Options/Interfaces/Particles/IParticlesOptions.d.ts +2 -0
  123. package/types/Options/Interfaces/Particles/Number/IParticlesNumber.d.ts +2 -1
  124. package/types/Options/Interfaces/Particles/Number/IParticlesNumberLimit.d.ts +5 -0
  125. package/types/Utils/CanvasUtils.d.ts +2 -2
  126. package/types/Utils/NumberUtils.d.ts +0 -2
  127. package/types/Utils/Utils.d.ts +2 -3
  128. package/types/export-types.d.ts +5 -0
  129. package/types/exports.d.ts +2 -3
  130. package/umd/Core/Canvas.js +2 -2
  131. package/umd/Core/Container.js +36 -19
  132. package/umd/Core/Engine.js +18 -5
  133. package/umd/Core/Particle.js +74 -39
  134. package/umd/Core/Particles.js +51 -26
  135. package/umd/Core/Retina.js +0 -2
  136. package/umd/Core/Utils/QuadTree.js +1 -1
  137. package/umd/Options/Classes/BackgroundMask/BackgroundMask.js +1 -2
  138. package/umd/Options/Classes/ColorAnimation.js +5 -25
  139. package/umd/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js +0 -1
  140. package/umd/Options/Classes/Particles/Effect/Effect.js +46 -0
  141. package/umd/Options/Classes/Particles/Number/ParticlesNumber.js +4 -6
  142. package/umd/Options/Classes/{Random.js → Particles/Number/ParticlesNumberLimit.js} +9 -9
  143. package/umd/Options/Classes/Particles/Opacity/Opacity.js +1 -2
  144. package/umd/Options/Classes/Particles/ParticlesOptions.js +4 -1
  145. package/umd/Options/Classes/Particles/Size/Size.js +3 -4
  146. package/umd/Options/Classes/ValueWithRandom.js +2 -11
  147. package/umd/Options/Interfaces/Particles/Number/IParticlesNumberLimit.js +12 -0
  148. package/umd/Utils/CanvasUtils.js +26 -21
  149. package/umd/Utils/ColorUtils.js +24 -38
  150. package/umd/Utils/NumberUtils.js +9 -19
  151. package/umd/Utils/Utils.js +6 -6
  152. package/umd/export-types.js +5 -1
  153. package/umd/exports.js +3 -4
  154. package/browser/Options/Classes/Random.js +0 -17
  155. package/cjs/Options/Classes/Random.js +0 -21
  156. package/esm/Options/Classes/Random.js +0 -17
  157. package/types/Enums/Modes/ClickMode.d.ts +0 -9
  158. package/types/Enums/Modes/DivMode.d.ts +0 -5
  159. package/types/Enums/Modes/HoverMode.d.ts +0 -11
  160. package/types/Options/Classes/Random.d.ts +0 -9
  161. package/types/Options/Interfaces/IRandom.d.ts +0 -4
  162. /package/browser/{Enums/Modes/ClickMode.js → Core/Interfaces/IEffectDrawer.js} +0 -0
  163. /package/browser/{Enums/Modes/DivMode.js → Core/Interfaces/IShapeDrawData.js} +0 -0
  164. /package/browser/Enums/Modes/{HoverMode.js → LimitMode.js} +0 -0
  165. /package/browser/Options/Interfaces/{IRandom.js → Particles/Effect/IEffect.js} +0 -0
  166. /package/{esm/Enums/Modes/ClickMode.js → browser/Options/Interfaces/Particles/Number/IParticlesNumberLimit.js} +0 -0
  167. /package/cjs/{Enums/Modes/ClickMode.js → Core/Interfaces/IEffectDrawer.js} +0 -0
  168. /package/cjs/{Enums/Modes/DivMode.js → Core/Interfaces/IShapeDrawData.js} +0 -0
  169. /package/cjs/Enums/Modes/{HoverMode.js → LimitMode.js} +0 -0
  170. /package/cjs/Options/Interfaces/{IRandom.js → Particles/Effect/IEffect.js} +0 -0
  171. /package/esm/{Enums/Modes/DivMode.js → Core/Interfaces/IEffectDrawer.js} +0 -0
  172. /package/esm/{Enums/Modes/HoverMode.js → Core/Interfaces/IShapeDrawData.js} +0 -0
  173. /package/esm/{Options/Interfaces/IRandom.js → Enums/Modes/LimitMode.js} +0 -0
  174. /package/umd/{Enums/Modes/ClickMode.js → Core/Interfaces/IEffectDrawer.js} +0 -0
  175. /package/umd/{Enums/Modes/DivMode.js → Core/Interfaces/IShapeDrawData.js} +0 -0
  176. /package/umd/Enums/Modes/{HoverMode.js → LimitMode.js} +0 -0
  177. /package/umd/Options/Interfaces/{IRandom.js → Particles/Effect/IEffect.js} +0 -0
@@ -0,0 +1,32 @@
1
+ import { deepExtend } from "../../../../Utils/Utils.js";
2
+ export class Effect {
3
+ constructor() {
4
+ this.close = true;
5
+ this.fill = true;
6
+ this.options = {};
7
+ this.type = [];
8
+ }
9
+ load(data) {
10
+ if (!data) {
11
+ return;
12
+ }
13
+ const options = data.options;
14
+ if (options !== undefined) {
15
+ for (const effect in options) {
16
+ const item = options[effect];
17
+ if (item) {
18
+ this.options[effect] = deepExtend(this.options[effect] ?? {}, item);
19
+ }
20
+ }
21
+ }
22
+ if (data.close !== undefined) {
23
+ this.close = data.close;
24
+ }
25
+ if (data.fill !== undefined) {
26
+ this.fill = data.fill;
27
+ }
28
+ if (data.type !== undefined) {
29
+ this.type = data.type;
30
+ }
31
+ }
32
+ }
@@ -1,8 +1,9 @@
1
1
  import { ParticlesDensity } from "./ParticlesDensity.js";
2
+ import { ParticlesNumberLimit } from "./ParticlesNumberLimit.js";
2
3
  export class ParticlesNumber {
3
4
  constructor() {
4
5
  this.density = new ParticlesDensity();
5
- this.limit = 0;
6
+ this.limit = new ParticlesNumberLimit();
6
7
  this.value = 0;
7
8
  }
8
9
  load(data) {
@@ -10,10 +11,7 @@ export class ParticlesNumber {
10
11
  return;
11
12
  }
12
13
  this.density.load(data.density);
13
- const limit = data.limit;
14
- if (limit !== undefined) {
15
- this.limit = limit;
16
- }
14
+ this.limit.load(data.limit);
17
15
  if (data.value !== undefined) {
18
16
  this.value = data.value;
19
17
  }
@@ -0,0 +1,17 @@
1
+ export class ParticlesNumberLimit {
2
+ constructor() {
3
+ this.mode = "delete";
4
+ this.value = 0;
5
+ }
6
+ load(data) {
7
+ if (!data) {
8
+ return;
9
+ }
10
+ if (data.mode !== undefined) {
11
+ this.mode = data.mode;
12
+ }
13
+ if (data.value !== undefined) {
14
+ this.value = data.value;
15
+ }
16
+ }
17
+ }
@@ -1,10 +1,9 @@
1
1
  import { OpacityAnimation } from "./OpacityAnimation.js";
2
- import { ValueWithRandom } from "../../ValueWithRandom.js";
3
- export class Opacity extends ValueWithRandom {
2
+ import { RangedAnimationValueWithRandom } from "../../ValueWithRandom.js";
3
+ export class Opacity extends RangedAnimationValueWithRandom {
4
4
  constructor() {
5
5
  super();
6
6
  this.animation = new OpacityAnimation();
7
- this.random.minimumValue = 0.1;
8
7
  this.value = 1;
9
8
  }
10
9
  load(data) {
@@ -1,6 +1,7 @@
1
1
  import { deepExtend, executeOnSingleOrMultiple } from "../../../Utils/Utils.js";
2
2
  import { AnimatableColor } from "../AnimatableColor.js";
3
3
  import { Collisions } from "./Collisions/Collisions.js";
4
+ import { Effect } from "./Effect/Effect.js";
4
5
  import { Move } from "./Move/Move.js";
5
6
  import { Opacity } from "./Opacity/Opacity.js";
6
7
  import { ParticlesBounce } from "./Bounce/ParticlesBounce.js";
@@ -18,6 +19,7 @@ export class ParticlesOptions {
18
19
  this.collisions = new Collisions();
19
20
  this.color = new AnimatableColor();
20
21
  this.color.value = "#fff";
22
+ this.effect = new Effect();
21
23
  this.groups = {};
22
24
  this.move = new Move();
23
25
  this.number = new ParticlesNumber();
@@ -35,6 +37,7 @@ export class ParticlesOptions {
35
37
  }
36
38
  this.bounce.load(data.bounce);
37
39
  this.color.load(AnimatableColor.create(this.color, data.color));
40
+ this.effect.load(data.effect);
38
41
  if (data.groups !== undefined) {
39
42
  for (const group in data.groups) {
40
43
  const item = data.groups[group];
@@ -1,10 +1,9 @@
1
+ import { RangedAnimationValueWithRandom } from "../../ValueWithRandom.js";
1
2
  import { SizeAnimation } from "./SizeAnimation.js";
2
- import { ValueWithRandom } from "../../ValueWithRandom.js";
3
- export class Size extends ValueWithRandom {
3
+ export class Size extends RangedAnimationValueWithRandom {
4
4
  constructor() {
5
5
  super();
6
6
  this.animation = new SizeAnimation();
7
- this.random.minimumValue = 1;
8
7
  this.value = 3;
9
8
  }
10
9
  load(data) {
@@ -1,24 +1,15 @@
1
1
  import { AnimationOptions, RangedAnimationOptions } from "./AnimationOptions.js";
2
- import { Random } from "./Random.js";
3
- import { isBoolean } from "../../Utils/Utils.js";
4
2
  import { setRangeValue } from "../../Utils/NumberUtils.js";
5
3
  export class ValueWithRandom {
6
4
  constructor() {
7
- this.random = new Random();
8
5
  this.value = 0;
9
6
  }
10
7
  load(data) {
11
8
  if (!data) {
12
9
  return;
13
10
  }
14
- if (isBoolean(data.random)) {
15
- this.random.enable = data.random;
16
- }
17
- else {
18
- this.random.load(data.random);
19
- }
20
11
  if (data.value !== undefined) {
21
- this.value = setRangeValue(data.value, this.random.enable ? this.random.minimumValue : undefined);
12
+ this.value = setRangeValue(data.value);
22
13
  }
23
14
  }
24
15
  }
@@ -5,13 +5,6 @@ export function drawLine(context, begin, end) {
5
5
  context.lineTo(end.x, end.y);
6
6
  context.closePath();
7
7
  }
8
- export function drawTriangle(context, p1, p2, p3) {
9
- context.beginPath();
10
- context.moveTo(p1.x, p1.y);
11
- context.lineTo(p2.x, p2.y);
12
- context.lineTo(p3.x, p3.y);
13
- context.closePath();
14
- }
15
8
  export function paintBase(context, dimension, baseColor) {
16
9
  context.fillStyle = baseColor ?? "rgba(0,0,0,0)";
17
10
  context.fillRect(0, 0, dimension.width, dimension.height);
@@ -39,7 +32,6 @@ export function drawParticle(data) {
39
32
  d: rotateData.cos * (transform.d ?? 1),
40
33
  };
41
34
  context.setTransform(transformData.a, transformData.b, transformData.c, transformData.d, pos.x, pos.y);
42
- context.beginPath();
43
35
  if (backgroundMask) {
44
36
  context.globalCompositeOperation = composite;
45
37
  }
@@ -59,41 +51,54 @@ export function drawParticle(data) {
59
51
  context.strokeStyle = colorStyles.stroke;
60
52
  }
61
53
  const drawData = { container, context, particle, radius, opacity, delta };
54
+ context.beginPath();
62
55
  drawShape(drawData);
56
+ if (particle.shapeClose) {
57
+ context.closePath();
58
+ }
63
59
  if (strokeWidth > 0) {
64
60
  context.stroke();
65
61
  }
66
- if (particle.close) {
67
- context.closePath();
68
- }
69
- if (particle.fill) {
62
+ if (particle.shapeFill) {
70
63
  context.fill();
71
64
  }
72
- drawShapeAfterEffect(drawData);
65
+ drawShapeAfterDraw(drawData);
66
+ drawEffect(drawData);
73
67
  context.globalCompositeOperation = "source-over";
74
68
  context.setTransform(1, 0, 0, 1, 0, 0);
75
69
  }
70
+ export function drawEffect(data) {
71
+ const { container, context, particle, radius, opacity, delta } = data;
72
+ if (!particle.effect) {
73
+ return;
74
+ }
75
+ const drawer = container.effectDrawers.get(particle.effect);
76
+ if (!drawer) {
77
+ return;
78
+ }
79
+ drawer.draw({ context, particle, radius, opacity, delta, pixelRatio: container.retina.pixelRatio });
80
+ }
76
81
  export function drawShape(data) {
77
82
  const { container, context, particle, radius, opacity, delta } = data;
78
83
  if (!particle.shape) {
79
84
  return;
80
85
  }
81
- const drawer = container.drawers.get(particle.shape);
86
+ const drawer = container.shapeDrawers.get(particle.shape);
82
87
  if (!drawer) {
83
88
  return;
84
89
  }
85
90
  drawer.draw({ context, particle, radius, opacity, delta, pixelRatio: container.retina.pixelRatio });
86
91
  }
87
- export function drawShapeAfterEffect(data) {
92
+ export function drawShapeAfterDraw(data) {
88
93
  const { container, context, particle, radius, opacity, delta } = data;
89
94
  if (!particle.shape) {
90
95
  return;
91
96
  }
92
- const drawer = container.drawers.get(particle.shape);
93
- if (!drawer || !drawer.afterEffect) {
97
+ const drawer = container.shapeDrawers.get(particle.shape);
98
+ if (!drawer || !drawer.afterDraw) {
94
99
  return;
95
100
  }
96
- drawer.afterEffect({ context, particle, radius, opacity, delta, pixelRatio: container.retina.pixelRatio });
101
+ drawer.afterDraw({ context, particle, radius, opacity, delta, pixelRatio: container.retina.pixelRatio });
97
102
  }
98
103
  export function drawPlugin(context, plugin, delta) {
99
104
  if (!plugin.draw) {
@@ -4,24 +4,6 @@ const randomColorValue = "random", midColorValue = "mid", colorManagers = new Ma
4
4
  export function addColorManager(manager) {
5
5
  colorManagers.set(manager.key, manager);
6
6
  }
7
- function hue2rgb(p, q, t) {
8
- if (t < 0) {
9
- t += 1;
10
- }
11
- if (t > 1) {
12
- t -= 1;
13
- }
14
- if (t < 1 / 6) {
15
- return p + (q - p) * 6 * t;
16
- }
17
- if (t < 1 / 2) {
18
- return q;
19
- }
20
- if (t < 2 / 3) {
21
- return p + (q - p) * (2 / 3 - t) * 6;
22
- }
23
- return p;
24
- }
25
7
  function stringToRgba(input) {
26
8
  for (const [, manager] of colorManagers) {
27
9
  if (input.startsWith(manager.stringPrefix)) {
@@ -91,7 +73,7 @@ export function rangeColorToHsl(color, index, useIndex = true) {
91
73
  export function rgbToHsl(color) {
92
74
  const r1 = color.r / 255, g1 = color.g / 255, b1 = color.b / 255, max = Math.max(r1, g1, b1), min = Math.min(r1, g1, b1), res = {
93
75
  h: 0,
94
- l: (max + min) / 2,
76
+ l: (max + min) * 0.5,
95
77
  s: 0,
96
78
  };
97
79
  if (max !== min) {
@@ -119,26 +101,30 @@ export function stringToRgb(input) {
119
101
  return stringToRgba(input);
120
102
  }
121
103
  export function hslToRgb(hsl) {
122
- const result = { b: 0, g: 0, r: 0 }, hslPercent = {
123
- h: hsl.h / 360,
124
- l: hsl.l / 100,
125
- s: hsl.s / 100,
126
- };
127
- if (!hslPercent.s) {
128
- result.r = result.g = result.b = hslPercent.l;
104
+ const h = ((hsl.h % 360) + 360) % 360, s = Math.max(0, Math.min(100, hsl.s)), l = Math.max(0, Math.min(100, hsl.l)), hNormalized = h / 360, sNormalized = s / 100, lNormalized = l / 100;
105
+ if (s === 0) {
106
+ const grayscaleValue = Math.round(lNormalized * 255);
107
+ return { r: grayscaleValue, g: grayscaleValue, b: grayscaleValue };
129
108
  }
130
- else {
131
- const q = hslPercent.l < 0.5
132
- ? hslPercent.l * (1 + hslPercent.s)
133
- : hslPercent.l + hslPercent.s - hslPercent.l * hslPercent.s, p = 2 * hslPercent.l - q;
134
- result.r = hue2rgb(p, q, hslPercent.h + 1 / 3);
135
- result.g = hue2rgb(p, q, hslPercent.h);
136
- result.b = hue2rgb(p, q, hslPercent.h - 1 / 3);
137
- }
138
- result.r = Math.floor(result.r * 255);
139
- result.g = Math.floor(result.g * 255);
140
- result.b = Math.floor(result.b * 255);
141
- return result;
109
+ const channel = (temp1, temp2, temp3) => {
110
+ if (temp3 < 0) {
111
+ temp3 += 1;
112
+ }
113
+ if (temp3 > 1) {
114
+ temp3 -= 1;
115
+ }
116
+ if (temp3 * 6 < 1) {
117
+ return temp1 + (temp2 - temp1) * 6 * temp3;
118
+ }
119
+ if (temp3 * 2 < 1) {
120
+ return temp2;
121
+ }
122
+ if (temp3 * 3 < 2) {
123
+ return temp1 + (temp2 - temp1) * (2 / 3 - temp3) * 6;
124
+ }
125
+ return temp1;
126
+ }, temp1 = lNormalized < 0.5 ? lNormalized * (1 + sNormalized) : lNormalized + sNormalized - lNormalized * sNormalized, temp2 = 2 * lNormalized - temp1, red = Math.min(255, 255 * channel(temp2, temp1, hNormalized + 1 / 3)), green = Math.min(255, 255 * channel(temp2, temp1, hNormalized)), blue = Math.min(255, 255 * channel(temp2, temp1, hNormalized - 1 / 3));
127
+ return { r: Math.round(red), g: Math.round(green), b: Math.round(blue) };
142
128
  }
143
129
  export function hslaToRgba(hsla) {
144
130
  const rgbResult = hslToRgb(hsla);
@@ -1,5 +1,5 @@
1
- import { isBoolean, isNumber } from "./Utils.js";
2
1
  import { Vector } from "../Core/Utils/Vector.js";
2
+ import { isNumber } from "./Utils.js";
3
3
  let _random = Math.random;
4
4
  const easings = new Map();
5
5
  export function addEasing(name, easing) {
@@ -52,15 +52,6 @@ export function setRangeValue(source, value) {
52
52
  }
53
53
  : setRangeValue(min, max);
54
54
  }
55
- export function getValue(options) {
56
- const random = options.random, { enable, minimumValue } = isBoolean(random)
57
- ? {
58
- enable: random,
59
- minimumValue: 0,
60
- }
61
- : random;
62
- return enable ? getRangeValue(setRangeValue(options.value, minimumValue)) : getRangeValue(options.value);
63
- }
64
55
  export function getDistances(pointA, pointB) {
65
56
  const dx = pointA.x - pointB.x, dy = pointA.y - pointB.y;
66
57
  return { dx: dx, dy: dy, distance: Math.sqrt(dx ** 2 + dy ** 2) };
@@ -74,21 +65,21 @@ export function getParticleDirectionAngle(direction, position, center) {
74
65
  }
75
66
  switch (direction) {
76
67
  case "top":
77
- return -Math.PI / 2;
68
+ return -Math.PI * 0.5;
78
69
  case "top-right":
79
- return -Math.PI / 4;
70
+ return -Math.PI * 0.25;
80
71
  case "right":
81
72
  return 0;
82
73
  case "bottom-right":
83
- return Math.PI / 4;
74
+ return Math.PI * 0.25;
84
75
  case "bottom":
85
- return Math.PI / 2;
76
+ return Math.PI * 0.5;
86
77
  case "bottom-left":
87
- return (3 * Math.PI) / 4;
78
+ return Math.PI * 0.75;
88
79
  case "left":
89
80
  return Math.PI;
90
81
  case "top-left":
91
- return (-3 * Math.PI) / 4;
82
+ return -Math.PI * 0.75;
92
83
  case "inside":
93
84
  return Math.atan2(center.y - position.y, center.x - position.x);
94
85
  case "outside":
@@ -1,4 +1,4 @@
1
- import { collisionVelocity, getDistances, getRandom, getRangeMax, getRangeMin, getRangeValue, getValue, randomInRange, } from "./NumberUtils.js";
1
+ import { collisionVelocity, getDistances, getRandom, getRangeMax, getRangeMin, getRangeValue, randomInRange, } from "./NumberUtils.js";
2
2
  import { Vector } from "../Core/Utils/Vector.js";
3
3
  const _logger = {
4
4
  debug: console.debug,
@@ -27,8 +27,8 @@ function rectSideBounce(data) {
27
27
  pOtherSide.max > rectOtherSide.max) {
28
28
  return res;
29
29
  }
30
- if ((pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) / 2 && velocity > 0) ||
31
- (pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) / 2 && velocity < 0)) {
30
+ if ((pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * 0.5 && velocity > 0) ||
31
+ (pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * 0.5 && velocity < 0)) {
32
32
  res.velocity = velocity * -factor;
33
33
  res.bounced = true;
34
34
  }
@@ -167,7 +167,7 @@ export function circleBounceDataFromParticle(p) {
167
167
  radius: p.getRadius(),
168
168
  mass: p.getMass(),
169
169
  velocity: p.velocity,
170
- factor: Vector.create(getValue(p.options.bounce.horizontal), getValue(p.options.bounce.vertical)),
170
+ factor: Vector.create(getRangeValue(p.options.bounce.horizontal.value), getRangeValue(p.options.bounce.vertical.value)),
171
171
  };
172
172
  }
173
173
  export function circleBounce(p1, p2) {
@@ -182,7 +182,7 @@ export function circleBounce(p1, p2) {
182
182
  p2.velocity.y = vFinal2.y * p2.factor.y;
183
183
  }
184
184
  export function rectBounce(particle, divBounds) {
185
- const pPos = particle.getPosition(), size = particle.getRadius(), bounds = calculateBounds(pPos, size), resH = rectSideBounce({
185
+ const pPos = particle.getPosition(), size = particle.getRadius(), bounds = calculateBounds(pPos, size), bounceOptions = particle.options.bounce, resH = rectSideBounce({
186
186
  pSide: {
187
187
  min: bounds.left,
188
188
  max: bounds.right,
@@ -200,7 +200,7 @@ export function rectBounce(particle, divBounds) {
200
200
  max: divBounds.bottom,
201
201
  },
202
202
  velocity: particle.velocity.x,
203
- factor: getValue(particle.options.bounce.horizontal),
203
+ factor: getRangeValue(bounceOptions.horizontal.value),
204
204
  });
205
205
  if (resH.bounced) {
206
206
  if (resH.velocity !== undefined) {
@@ -228,7 +228,7 @@ export function rectBounce(particle, divBounds) {
228
228
  max: divBounds.right,
229
229
  },
230
230
  velocity: particle.velocity.y,
231
- factor: getValue(particle.options.bounce.vertical),
231
+ factor: getRangeValue(bounceOptions.vertical.value),
232
232
  });
233
233
  if (resV.bounced) {
234
234
  if (resV.velocity !== undefined) {
@@ -10,6 +10,7 @@ export * from "./Core/Interfaces/IDelta.js";
10
10
  export * from "./Core/Interfaces/IDimension.js";
11
11
  export * from "./Core/Interfaces/IDistance.js";
12
12
  export * from "./Core/Interfaces/IDrawParticleParams.js";
13
+ export * from "./Core/Interfaces/IEffectDrawer.js";
13
14
  export * from "./Core/Interfaces/IExternalInteractor.js";
14
15
  export * from "./Core/Interfaces/IInteractor.js";
15
16
  export * from "./Core/Interfaces/ILoadParams.js";
@@ -29,6 +30,7 @@ export * from "./Core/Interfaces/IPlugin.js";
29
30
  export * from "./Core/Interfaces/IPositionFromSizeParams.js";
30
31
  export * from "./Core/Interfaces/IRangeValue.js";
31
32
  export * from "./Core/Interfaces/IRectSideResult.js";
33
+ export * from "./Core/Interfaces/IShapeDrawData.js";
32
34
  export * from "./Core/Interfaces/IShapeDrawer.js";
33
35
  export * from "./Core/Interfaces/IShapeValues.js";
34
36
  export * from "./Core/Interfaces/ISlowParticleData.js";
@@ -61,6 +63,7 @@ export * from "./Options/Interfaces/Particles/Bounce/IParticlesBounce.js";
61
63
  export * from "./Options/Interfaces/Particles/Collisions/ICollisions.js";
62
64
  export * from "./Options/Interfaces/Particles/Collisions/ICollisionsAbsorb.js";
63
65
  export * from "./Options/Interfaces/Particles/Collisions/ICollisionsOverlap.js";
66
+ export * from "./Options/Interfaces/Particles/Effect/IEffect.js";
64
67
  export * from "./Options/Interfaces/Particles/IParticlesOptions.js";
65
68
  export * from "./Options/Interfaces/Particles/IShadow.js";
66
69
  export * from "./Options/Interfaces/Particles/IStroke.js";
@@ -75,6 +78,7 @@ export * from "./Options/Interfaces/Particles/Move/ISpin.js";
75
78
  export * from "./Options/Interfaces/Particles/Move/IMoveTrail.js";
76
79
  export * from "./Options/Interfaces/Particles/Number/IParticlesDensity.js";
77
80
  export * from "./Options/Interfaces/Particles/Number/IParticlesNumber.js";
81
+ export * from "./Options/Interfaces/Particles/Number/IParticlesNumberLimit.js";
78
82
  export * from "./Options/Interfaces/Particles/Opacity/IOpacity.js";
79
83
  export * from "./Options/Interfaces/Particles/Opacity/IOpacityAnimation.js";
80
84
  export * from "./Options/Interfaces/Particles/Shape/IShape.js";
@@ -11,10 +11,8 @@ export * from "./Enums/Directions/MoveDirection.js";
11
11
  export * from "./Enums/Directions/RotateDirection.js";
12
12
  export * from "./Enums/Directions/OutModeDirection.js";
13
13
  export * from "./Enums/Modes/AnimationMode.js";
14
- export * from "./Enums/Modes/ClickMode.js";
15
- export * from "./Enums/Modes/DivMode.js";
16
- export * from "./Enums/Modes/HoverMode.js";
17
14
  export * from "./Enums/Modes/CollisionMode.js";
15
+ export * from "./Enums/Modes/LimitMode.js";
18
16
  export * from "./Enums/Modes/OutMode.js";
19
17
  export * from "./Enums/Modes/PixelMode.js";
20
18
  export * from "./Enums/Modes/ThemeMode.js";
@@ -69,6 +67,7 @@ export * from "./Options/Classes/Particles/Move/Path/MovePath.js";
69
67
  export * from "./Options/Classes/Particles/Move/Spin.js";
70
68
  export * from "./Options/Classes/Particles/Move/MoveTrail.js";
71
69
  export * from "./Options/Classes/Particles/Number/ParticlesNumber.js";
70
+ export * from "./Options/Classes/Particles/Number/ParticlesNumberLimit.js";
72
71
  export * from "./Options/Classes/Particles/Number/ParticlesDensity.js";
73
72
  export * from "./Options/Classes/Particles/Opacity/Opacity.js";
74
73
  export * from "./Options/Classes/Particles/Opacity/OpacityAnimation.js";
@@ -405,10 +405,10 @@ class Canvas {
405
405
  this.element.width = size.width = this.element.offsetWidth * pxRatio;
406
406
  this.element.height = size.height = this.element.offsetHeight * pxRatio;
407
407
  if (this.container.started) {
408
- this.resizeFactor = {
408
+ container.particles.setResizeFactor({
409
409
  width: size.width / oldSize.width,
410
410
  height: size.height / oldSize.height,
411
- };
411
+ });
412
412
  }
413
413
  return true;
414
414
  }
@@ -39,16 +39,16 @@ class Container {
39
39
  };
40
40
  this._nextFrame = async (timestamp) => {
41
41
  try {
42
- if (!this.smooth &&
43
- this.lastFrameTime !== undefined &&
44
- timestamp < this.lastFrameTime + 1000 / this.fpsLimit) {
42
+ if (!this._smooth &&
43
+ this._lastFrameTime !== undefined &&
44
+ timestamp < this._lastFrameTime + 1000 / this.fpsLimit) {
45
45
  this.draw(false);
46
46
  return;
47
47
  }
48
- this.lastFrameTime ??= timestamp;
49
- const delta = initDelta(timestamp - this.lastFrameTime, this.fpsLimit, this.smooth);
48
+ this._lastFrameTime ??= timestamp;
49
+ const delta = initDelta(timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
50
50
  this.addLifeTime(delta.value);
51
- this.lastFrameTime = timestamp;
51
+ this._lastFrameTime = timestamp;
52
52
  if (delta.value > 1000) {
53
53
  this.draw(false);
54
54
  return;
@@ -69,7 +69,7 @@ class Container {
69
69
  this._engine = engine;
70
70
  this.id = Symbol(id);
71
71
  this.fpsLimit = 120;
72
- this.smooth = false;
72
+ this._smooth = false;
73
73
  this._delay = 0;
74
74
  this._duration = 0;
75
75
  this._lifeTime = 0;
@@ -77,7 +77,7 @@ class Container {
77
77
  this.started = false;
78
78
  this.destroyed = false;
79
79
  this._paused = true;
80
- this.lastFrameTime = 0;
80
+ this._lastFrameTime = 0;
81
81
  this.zLayers = 100;
82
82
  this.pageHidden = false;
83
83
  this._sourceOptions = sourceOptions;
@@ -93,7 +93,8 @@ class Container {
93
93
  },
94
94
  };
95
95
  this.plugins = new Map();
96
- this.drawers = new Map();
96
+ this.effectDrawers = new Map();
97
+ this.shapeDrawers = new Map();
97
98
  this._options = loadContainerOptions(this._engine, this);
98
99
  this.actualOptions = loadContainerOptions(this._engine, this);
99
100
  this._eventListeners = new EventListeners_js_1.EventListeners(this);
@@ -203,11 +204,17 @@ class Container {
203
204
  this.stop();
204
205
  this.particles.destroy();
205
206
  this.canvas.destroy();
206
- for (const [, drawer] of this.drawers) {
207
- drawer.destroy && drawer.destroy(this);
207
+ for (const [, effectDrawer] of this.effectDrawers) {
208
+ effectDrawer.destroy && effectDrawer.destroy(this);
208
209
  }
209
- for (const key of this.drawers.keys()) {
210
- this.drawers.delete(key);
210
+ for (const [, shapeDrawer] of this.shapeDrawers) {
211
+ shapeDrawer.destroy && shapeDrawer.destroy(this);
212
+ }
213
+ for (const key of this.effectDrawers.keys()) {
214
+ this.effectDrawers.delete(key);
215
+ }
216
+ for (const key of this.shapeDrawers.keys()) {
217
+ this.shapeDrawers.delete(key);
211
218
  }
212
219
  this._engine.clearPlugins(this);
213
220
  this.destroyed = true;
@@ -224,7 +231,7 @@ class Container {
224
231
  let refreshTime = force;
225
232
  this._drawAnimationFrame = requestAnimationFrame(async (timestamp) => {
226
233
  if (refreshTime) {
227
- this.lastFrameTime = undefined;
234
+ this._lastFrameTime = undefined;
228
235
  refreshTime = false;
229
236
  }
230
237
  await this._nextFrame(timestamp);
@@ -259,11 +266,18 @@ class Container {
259
266
  if (!guardCheck(this)) {
260
267
  return;
261
268
  }
269
+ const effects = this._engine.getSupportedEffects();
270
+ for (const type of effects) {
271
+ const drawer = this._engine.getEffectDrawer(type);
272
+ if (drawer) {
273
+ this.effectDrawers.set(type, drawer);
274
+ }
275
+ }
262
276
  const shapes = this._engine.getSupportedShapes();
263
277
  for (const type of shapes) {
264
278
  const drawer = this._engine.getShapeDrawer(type);
265
279
  if (drawer) {
266
- this.drawers.set(type, drawer);
280
+ this.shapeDrawers.set(type, drawer);
267
281
  }
268
282
  }
269
283
  this._options = loadContainerOptions(this._engine, this, this._initialSourceOptions, this.sourceOptions);
@@ -282,8 +296,11 @@ class Container {
282
296
  this._delay = (0, NumberUtils_js_1.getRangeValue)(this.actualOptions.delay) * 1000;
283
297
  this._lifeTime = 0;
284
298
  this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 120;
285
- this.smooth = this.actualOptions.smooth;
286
- for (const [, drawer] of this.drawers) {
299
+ this._smooth = this.actualOptions.smooth;
300
+ for (const [, drawer] of this.effectDrawers) {
301
+ drawer.init && (await drawer.init(this));
302
+ }
303
+ for (const [, drawer] of this.shapeDrawers) {
287
304
  drawer.init && (await drawer.init(this));
288
305
  }
289
306
  for (const [, plugin] of this.plugins) {
@@ -412,10 +429,10 @@ class Container {
412
429
  this.actualOptions.responsive = [];
413
430
  const newMaxWidth = this.actualOptions.setResponsive(this.canvas.size.width, this.retina.pixelRatio, this._options);
414
431
  this.actualOptions.setTheme(this._currentTheme);
415
- if (this.responsiveMaxWidth === newMaxWidth) {
432
+ if (this._responsiveMaxWidth === newMaxWidth) {
416
433
  return false;
417
434
  }
418
- this.responsiveMaxWidth = newMaxWidth;
435
+ this._responsiveMaxWidth = newMaxWidth;
419
436
  return true;
420
437
  }
421
438
  }