@tsparticles/plugin-absorbers 4.0.0-alpha.2 → 4.0.0-alpha.20

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 (83) hide show
  1. package/295.min.js +1 -0
  2. package/415.min.js +1 -0
  3. package/776.min.js +1 -0
  4. package/830.min.js +1 -0
  5. package/991.min.js +1 -0
  6. package/README.md +5 -0
  7. package/browser/AbsorberInstance.js +130 -75
  8. package/browser/AbsorbersInstancesManager.js +49 -0
  9. package/browser/AbsorbersInteractor.js +93 -0
  10. package/browser/AbsorbersPlugin.js +8 -17
  11. package/browser/AbsorbersPluginInstance.js +42 -0
  12. package/browser/Options/Classes/Absorber.js +14 -0
  13. package/browser/Options/Classes/AbsorberLife.js +27 -0
  14. package/browser/Options/Classes/AbsorberSize.js +2 -0
  15. package/browser/Options/Classes/AbsorberSizeLimit.js +2 -0
  16. package/browser/Options/Interfaces/IAbsorberLife.js +1 -0
  17. package/browser/index.js +14 -6
  18. package/cjs/AbsorberInstance.js +130 -75
  19. package/cjs/AbsorbersInstancesManager.js +49 -0
  20. package/cjs/AbsorbersInteractor.js +93 -0
  21. package/cjs/AbsorbersPlugin.js +8 -17
  22. package/cjs/AbsorbersPluginInstance.js +42 -0
  23. package/cjs/Options/Classes/Absorber.js +14 -0
  24. package/cjs/Options/Classes/AbsorberLife.js +27 -0
  25. package/cjs/Options/Classes/AbsorberSize.js +2 -0
  26. package/cjs/Options/Classes/AbsorberSizeLimit.js +2 -0
  27. package/cjs/Options/Interfaces/IAbsorberLife.js +1 -0
  28. package/cjs/index.js +14 -6
  29. package/dist_browser_AbsorberInstance_js.js +70 -0
  30. package/dist_browser_AbsorbersInstancesManager_js.js +30 -0
  31. package/dist_browser_AbsorbersInteractor_js.js +70 -0
  32. package/dist_browser_AbsorbersPluginInstance_js.js +30 -0
  33. package/dist_browser_AbsorbersPlugin_js.js +15 -25
  34. package/esm/AbsorberInstance.js +130 -75
  35. package/esm/AbsorbersInstancesManager.js +49 -0
  36. package/esm/AbsorbersInteractor.js +93 -0
  37. package/esm/AbsorbersPlugin.js +8 -17
  38. package/esm/AbsorbersPluginInstance.js +42 -0
  39. package/esm/Options/Classes/Absorber.js +14 -0
  40. package/esm/Options/Classes/AbsorberLife.js +27 -0
  41. package/esm/Options/Classes/AbsorberSize.js +2 -0
  42. package/esm/Options/Classes/AbsorberSizeLimit.js +2 -0
  43. package/esm/Options/Interfaces/IAbsorberLife.js +1 -0
  44. package/esm/index.js +14 -6
  45. package/package.json +3 -2
  46. package/report.html +3 -3
  47. package/tsparticles.plugin.absorbers.js +52 -22
  48. package/tsparticles.plugin.absorbers.min.js +2 -2
  49. package/types/AbsorberContainer.d.ts +5 -4
  50. package/types/AbsorberInstance.d.ts +15 -5
  51. package/types/AbsorbersInstancesManager.d.ts +14 -0
  52. package/types/AbsorbersInteractor.d.ts +18 -0
  53. package/types/AbsorbersPlugin.d.ts +7 -7
  54. package/types/AbsorbersPluginInstance.d.ts +13 -0
  55. package/types/Options/Classes/Absorber.d.ts +2 -0
  56. package/types/Options/Classes/AbsorberLife.d.ts +10 -0
  57. package/types/Options/Interfaces/IAbsorber.d.ts +2 -0
  58. package/types/Options/Interfaces/IAbsorberLife.d.ts +7 -0
  59. package/types/index.d.ts +1 -2
  60. package/types/types.d.ts +12 -9
  61. package/umd/AbsorberInstance.js +129 -74
  62. package/umd/AbsorbersInstancesManager.js +97 -0
  63. package/umd/AbsorbersInteractor.js +107 -0
  64. package/umd/AbsorbersPlugin.js +42 -17
  65. package/umd/AbsorbersPluginInstance.js +56 -0
  66. package/umd/Options/Classes/Absorber.js +15 -1
  67. package/umd/Options/Classes/AbsorberLife.js +41 -0
  68. package/umd/Options/Classes/AbsorberSize.js +2 -0
  69. package/umd/Options/Classes/AbsorberSizeLimit.js +2 -0
  70. package/umd/{Enums/AbsorberClickMode.js → Options/Interfaces/IAbsorberLife.js} +0 -5
  71. package/umd/index.js +15 -10
  72. package/47.min.js +0 -2
  73. package/47.min.js.LICENSE.txt +0 -1
  74. package/browser/Absorbers.js +0 -70
  75. package/browser/Enums/AbsorberClickMode.js +0 -4
  76. package/cjs/Absorbers.js +0 -70
  77. package/cjs/Enums/AbsorberClickMode.js +0 -4
  78. package/esm/Absorbers.js +0 -70
  79. package/esm/Enums/AbsorberClickMode.js +0 -4
  80. package/tsparticles.plugin.absorbers.min.js.LICENSE.txt +0 -1
  81. package/types/Absorbers.d.ts +0 -21
  82. package/types/Enums/AbsorberClickMode.d.ts +0 -3
  83. package/umd/Absorbers.js +0 -84
@@ -1,61 +1,30 @@
1
- import { RotateDirection, Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, originPoint, percentDenominator, rangeColorToRgb, } from "@tsparticles/engine";
1
+ import { RotateDirection, Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, doublePI, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, millisecondsToSeconds, originPoint, percentDenominator, rangeColorToRgb, } from "@tsparticles/engine";
2
2
  import { Absorber } from "./Options/Classes/Absorber.js";
3
- const squareExp = 2, absorbFactor = 0.033, minOrbitLength = 0, minRadius = 0, minMass = 0, minAngle = 0, double = 2, maxAngle = Math.PI * double, minVelocity = 0;
3
+ const squareExp = 2, absorbFactor = 0.033, minOrbitLength = 0, minRadius = 0, minMass = 0, minAngle = 0, maxAngle = doublePI, minVelocity = 0, defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultLifeCount = -1;
4
4
  export class AbsorberInstance {
5
- constructor(container, engine, options, position) {
6
- this._calcPosition = () => {
7
- const exactPosition = calcPositionOrRandomFromSizeRanged({
8
- size: this._container.canvas.size,
9
- position: this.options.position,
10
- });
11
- return Vector.create(exactPosition.x, exactPosition.y);
12
- };
13
- this._updateParticlePosition = (particle, v) => {
14
- if (particle.destroyed) {
15
- return;
16
- }
17
- const container = this._container, canvasSize = container.canvas.size;
18
- if (particle.needsNewPosition) {
19
- const newPosition = calcPositionOrRandomFromSize({ size: canvasSize });
20
- particle.position.setTo(newPosition);
21
- particle.velocity.setTo(particle.initialVelocity);
22
- particle.absorberOrbit = undefined;
23
- particle.needsNewPosition = false;
24
- }
25
- if (this.options.orbits) {
26
- if (particle.absorberOrbit === undefined) {
27
- particle.absorberOrbit = Vector.origin;
28
- particle.absorberOrbit.length = getDistance(particle.getPosition(), this.position);
29
- particle.absorberOrbit.angle = getRandom() * maxAngle;
30
- }
31
- if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
32
- const minSize = Math.min(canvasSize.width, canvasSize.height), offset = 1, randomOffset = 0.1, randomFactor = 0.2;
33
- particle.absorberOrbit.length = minSize * (offset + (getRandom() * randomFactor - randomOffset));
34
- }
35
- particle.absorberOrbitDirection ??=
36
- particle.velocity.x >= minVelocity ? RotateDirection.clockwise : RotateDirection.counterClockwise;
37
- const orbitRadius = particle.absorberOrbit.length, orbitAngle = particle.absorberOrbit.angle, orbitDirection = particle.absorberOrbitDirection;
38
- particle.velocity.setTo(Vector.origin);
39
- const updateFunc = {
40
- x: orbitDirection === RotateDirection.clockwise ? Math.cos : Math.sin,
41
- y: orbitDirection === RotateDirection.clockwise ? Math.sin : Math.cos,
42
- };
43
- particle.position.x = this.position.x + orbitRadius * updateFunc.x(orbitAngle);
44
- particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
45
- particle.absorberOrbit.length -= v.length;
46
- particle.absorberOrbit.angle +=
47
- (((particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio) / percentDenominator) *
48
- container.retina.reduceFactor;
49
- }
50
- else {
51
- const addV = Vector.origin;
52
- addV.length = v.length;
53
- addV.angle = v.angle;
54
- particle.velocity.addTo(addV);
55
- }
56
- };
5
+ color;
6
+ limit;
7
+ mass;
8
+ name;
9
+ opacity;
10
+ options;
11
+ position;
12
+ size;
13
+ _container;
14
+ _currentDuration;
15
+ _currentSpawnDelay;
16
+ _duration;
17
+ _engine;
18
+ _firstSpawn;
19
+ _immortal;
20
+ _lifeCount;
21
+ _spawnDelay;
22
+ initialPosition;
23
+ constructor(engine, container, options, position) {
57
24
  this._container = container;
58
25
  this._engine = engine;
26
+ this._currentDuration = 0;
27
+ this._currentSpawnDelay = 0;
59
28
  this.initialPosition = position ? Vector.create(position.x, position.y) : undefined;
60
29
  if (options instanceof Absorber) {
61
30
  this.options = options;
@@ -64,7 +33,6 @@ export class AbsorberInstance {
64
33
  this.options = new Absorber();
65
34
  this.options.load(options);
66
35
  }
67
- this.dragging = false;
68
36
  this.name = this.options.name;
69
37
  this.opacity = this.options.opacity;
70
38
  this.size = getRangeValue(this.options.size.value) * container.retina.pixelRatio;
@@ -80,29 +48,19 @@ export class AbsorberInstance {
80
48
  r: 0,
81
49
  };
82
50
  this.position = this.initialPosition?.copy() ?? this._calcPosition();
51
+ this._firstSpawn = !this.options.life.wait;
52
+ this._lifeCount = this.options.life.count ?? defaultLifeCount;
53
+ this._immortal = this._lifeCount <= minLifeCount;
54
+ this._spawnDelay = container.retina.reduceFactor
55
+ ? (getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds) /
56
+ container.retina.reduceFactor
57
+ : Infinity;
83
58
  }
84
- attract(particle) {
85
- const container = this._container, options = this.options;
86
- if (options.draggable) {
87
- const mouse = container.interactivity.mouse;
88
- if (mouse.clicking && mouse.downPosition) {
89
- const mouseDist = getDistance(this.position, mouse.downPosition);
90
- if (mouseDist <= this.size) {
91
- this.dragging = true;
92
- }
93
- }
94
- else {
95
- this.dragging = false;
96
- }
97
- if (this.dragging && mouse.position) {
98
- this.position.x = mouse.position.x;
99
- this.position.y = mouse.position.y;
100
- }
101
- }
102
- const pos = particle.getPosition(), { dx, dy, distance } = getDistances(this.position, pos), v = Vector.create(dx, dy);
59
+ attract(particle, delta) {
60
+ const container = this._container, options = this.options, pos = particle.getPosition(), { dx, dy, distance } = getDistances(this.position, pos), v = Vector.create(dx, dy);
103
61
  v.length = (this.mass / Math.pow(distance, squareExp)) * container.retina.reduceFactor;
104
62
  if (distance < this.size + particle.getRadius()) {
105
- const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio;
63
+ const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio * delta.factor;
106
64
  if ((this.size > particle.getRadius() && distance < this.size - particle.getRadius()) ||
107
65
  (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength)) {
108
66
  if (options.destroy) {
@@ -145,4 +103,101 @@ export class AbsorberInstance {
145
103
  ? initialPosition
146
104
  : this._calcPosition();
147
105
  }
106
+ update(delta) {
107
+ if (this._firstSpawn) {
108
+ this._firstSpawn = false;
109
+ this._currentSpawnDelay = this._spawnDelay ?? defaultSpawnDelay;
110
+ }
111
+ if (this._duration !== undefined) {
112
+ this._currentDuration += delta.value;
113
+ if (this._currentDuration >= this._duration) {
114
+ if (!this._immortal) {
115
+ this._lifeCount--;
116
+ }
117
+ if (this._lifeCount > minLifeCount || this._immortal) {
118
+ this.position = this._calcPosition();
119
+ this._spawnDelay = this._container.retina.reduceFactor
120
+ ? (getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds) /
121
+ this._container.retina.reduceFactor
122
+ : Infinity;
123
+ }
124
+ this._currentDuration -= this._duration;
125
+ delete this._duration;
126
+ }
127
+ }
128
+ if (this._spawnDelay !== undefined) {
129
+ this._currentSpawnDelay += delta.value;
130
+ if (this._currentSpawnDelay >= this._spawnDelay) {
131
+ this.play();
132
+ this._currentSpawnDelay -= this._spawnDelay;
133
+ delete this._spawnDelay;
134
+ }
135
+ }
136
+ }
137
+ _calcPosition = () => {
138
+ const exactPosition = calcPositionOrRandomFromSizeRanged({
139
+ size: this._container.canvas.size,
140
+ position: this.options.position,
141
+ });
142
+ return Vector.create(exactPosition.x, exactPosition.y);
143
+ };
144
+ _prepareToDie = () => {
145
+ const duration = this.options.life.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined, minDuration = 0;
146
+ if ((this._lifeCount > minLifeCount || this._immortal) && duration !== undefined && duration > minDuration) {
147
+ this._duration = duration * millisecondsToSeconds;
148
+ }
149
+ };
150
+ _updateParticlePosition = (particle, v) => {
151
+ if (particle.destroyed) {
152
+ return;
153
+ }
154
+ const container = this._container, canvasSize = container.canvas.size;
155
+ if (particle.needsNewPosition) {
156
+ const newPosition = calcPositionOrRandomFromSize({ size: canvasSize });
157
+ particle.position.setTo(newPosition);
158
+ particle.velocity.setTo(particle.initialVelocity);
159
+ particle.absorberOrbit = undefined;
160
+ particle.needsNewPosition = false;
161
+ }
162
+ if (this.options.orbits) {
163
+ if (particle.absorberOrbit === undefined) {
164
+ particle.absorberOrbit = Vector.origin;
165
+ particle.absorberOrbit.length = getDistance(particle.getPosition(), this.position);
166
+ particle.absorberOrbit.angle = getRandom() * maxAngle;
167
+ }
168
+ if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
169
+ const minSize = Math.min(canvasSize.width, canvasSize.height), offset = 1, randomOffset = 0.1, randomFactor = 0.2;
170
+ particle.absorberOrbit.length = minSize * (offset + (getRandom() * randomFactor - randomOffset));
171
+ }
172
+ particle.absorberOrbitDirection ??=
173
+ particle.velocity.x >= minVelocity ? RotateDirection.clockwise : RotateDirection.counterClockwise;
174
+ const orbitRadius = particle.absorberOrbit.length, orbitAngle = particle.absorberOrbit.angle, orbitDirection = particle.absorberOrbitDirection;
175
+ particle.velocity.setTo(Vector.origin);
176
+ const updateFunc = {
177
+ x: orbitDirection === RotateDirection.clockwise ? Math.cos : Math.sin,
178
+ y: orbitDirection === RotateDirection.clockwise ? Math.sin : Math.cos,
179
+ };
180
+ particle.position.x = this.position.x + orbitRadius * updateFunc.x(orbitAngle);
181
+ particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
182
+ particle.absorberOrbit.length -= v.length;
183
+ particle.absorberOrbit.angle +=
184
+ (((particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio) / percentDenominator) *
185
+ container.retina.reduceFactor;
186
+ }
187
+ else {
188
+ const addV = Vector.origin;
189
+ addV.length = v.length;
190
+ addV.angle = v.angle;
191
+ particle.velocity.addTo(addV);
192
+ }
193
+ };
194
+ play = () => {
195
+ if (!((this._lifeCount > minLifeCount || this._immortal || !this.options.life.count) &&
196
+ (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? defaultSpawnDelay)))) {
197
+ return;
198
+ }
199
+ if (this._lifeCount > minLifeCount || this._immortal) {
200
+ this._prepareToDie();
201
+ }
202
+ };
148
203
  }
@@ -0,0 +1,49 @@
1
+ import { isNumber } from "@tsparticles/engine";
2
+ const defaultIndex = 0;
3
+ export class AbsorbersInstancesManager {
4
+ _containerArrays;
5
+ _engine;
6
+ constructor(engine) {
7
+ this._containerArrays = new Map();
8
+ this._engine = engine;
9
+ }
10
+ async addAbsorber(container, options, position) {
11
+ const { AbsorberInstance } = await import("./AbsorberInstance.js"), absorber = new AbsorberInstance(this._engine, container, options, position), array = this.getArray(container);
12
+ array.push(absorber);
13
+ return absorber;
14
+ }
15
+ clear(container) {
16
+ this.initContainer(container);
17
+ this._containerArrays.set(container, []);
18
+ }
19
+ getArray(container) {
20
+ this.initContainer(container);
21
+ let array = this._containerArrays.get(container);
22
+ if (!array) {
23
+ array = [];
24
+ this._containerArrays.set(container, array);
25
+ }
26
+ return array;
27
+ }
28
+ initContainer(container) {
29
+ if (this._containerArrays.has(container)) {
30
+ return;
31
+ }
32
+ this._containerArrays.set(container, []);
33
+ container.getAbsorber ??= (idxOrName) => {
34
+ const array = this.getArray(container);
35
+ return idxOrName === undefined || isNumber(idxOrName)
36
+ ? array[idxOrName ?? defaultIndex]
37
+ : array.find(t => t.name === idxOrName);
38
+ };
39
+ container.addAbsorber ??= (options, position) => {
40
+ return this.addAbsorber(container, options, position);
41
+ };
42
+ }
43
+ removeAbsorber(container, absorber) {
44
+ const index = this.getArray(container).indexOf(absorber), deleteCount = 1;
45
+ if (index >= defaultIndex) {
46
+ this.getArray(container).splice(index, deleteCount);
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,93 @@
1
+ import { ExternalInteractorBase, } from "@tsparticles/plugin-interactivity";
2
+ import { getDistance, isArray, isInArray, itemFromArray, } from "@tsparticles/engine";
3
+ import { Absorber } from "./Options/Classes/Absorber.js";
4
+ const absorbersMode = "absorbers";
5
+ export class AbsorbersInteractor extends ExternalInteractorBase {
6
+ handleClickMode;
7
+ _instancesManager;
8
+ dragging = false;
9
+ draggingAbsorber;
10
+ constructor(container, instancesManager) {
11
+ super(container);
12
+ this._instancesManager = instancesManager;
13
+ this._instancesManager.initContainer(container);
14
+ this.handleClickMode = (mode, interactivityData) => {
15
+ const container = this.container, options = container.actualOptions, absorbers = options.interactivity.modes.absorbers;
16
+ if (!absorbers || mode !== absorbersMode) {
17
+ return;
18
+ }
19
+ const { clickPosition } = interactivityData.mouse;
20
+ if (clickPosition) {
21
+ const existingAbsorber = instancesManager
22
+ .getArray(this.container)
23
+ .some(t => getDistance(t.position, clickPosition) < t.size);
24
+ if (existingAbsorber) {
25
+ return;
26
+ }
27
+ }
28
+ const absorbersModeOptions = itemFromArray(absorbers) ?? new Absorber();
29
+ void this._instancesManager.addAbsorber(container, absorbersModeOptions, clickPosition);
30
+ };
31
+ }
32
+ clear() {
33
+ }
34
+ init() {
35
+ }
36
+ interact(interactivityData, delta) {
37
+ for (const particle of this.container.particles.filter(p => this.isEnabled(interactivityData, p))) {
38
+ for (const absorber of this._instancesManager.getArray(this.container)) {
39
+ if (absorber.options.draggable) {
40
+ const mouse = interactivityData.mouse;
41
+ if (mouse.clicking && mouse.downPosition) {
42
+ const mouseDist = getDistance(absorber.position, mouse.downPosition);
43
+ if (mouseDist <= absorber.size) {
44
+ this.dragging = true;
45
+ this.draggingAbsorber = absorber;
46
+ }
47
+ }
48
+ else {
49
+ this.dragging = false;
50
+ this.draggingAbsorber = undefined;
51
+ }
52
+ if (this.dragging && this.draggingAbsorber == absorber && mouse.position) {
53
+ absorber.position.x = mouse.position.x;
54
+ absorber.position.y = mouse.position.y;
55
+ }
56
+ }
57
+ absorber.attract(particle, delta);
58
+ if (particle.destroyed) {
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ }
64
+ isEnabled(interactivityData, particle) {
65
+ const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity).events;
66
+ if (!mouse.clickPosition || !events.onClick.enable) {
67
+ return false;
68
+ }
69
+ return isInArray(absorbersMode, events.onClick.mode);
70
+ }
71
+ loadModeOptions(options, ...sources) {
72
+ options.absorbers ??= [];
73
+ for (const source of sources) {
74
+ if (!source) {
75
+ continue;
76
+ }
77
+ if (isArray(source.absorbers)) {
78
+ for (const absorber of source.absorbers) {
79
+ const tmp = new Absorber();
80
+ tmp.load(absorber);
81
+ options.absorbers.push(tmp);
82
+ }
83
+ }
84
+ else {
85
+ const tmp = new Absorber();
86
+ tmp.load(source.absorbers);
87
+ options.absorbers.push(tmp);
88
+ }
89
+ }
90
+ }
91
+ reset() {
92
+ }
93
+ }
@@ -1,16 +1,16 @@
1
- import { executeOnSingleOrMultiple, isArray, isInArray, } from "@tsparticles/engine";
1
+ import { executeOnSingleOrMultiple, isArray, } from "@tsparticles/engine";
2
2
  import { Absorber } from "./Options/Classes/Absorber.js";
3
- import { AbsorberClickMode } from "./Enums/AbsorberClickMode.js";
4
- import { Absorbers } from "./Absorbers.js";
5
3
  export class AbsorbersPlugin {
6
- constructor(engine) {
7
- this.id = "absorbers";
8
- this._engine = engine;
4
+ id = "absorbers";
5
+ _instancesManager;
6
+ constructor(instancesManager) {
7
+ this._instancesManager = instancesManager;
9
8
  }
10
9
  async getPlugin(container) {
11
- return Promise.resolve(new Absorbers(container, this._engine));
10
+ const { AbsorbersPluginInstance } = await import("./AbsorbersPluginInstance.js");
11
+ return new AbsorbersPluginInstance(container, this._instancesManager);
12
12
  }
13
- loadOptions(options, source) {
13
+ loadOptions(_container, options, source) {
14
14
  if (!this.needsPlugin(options) && !this.needsPlugin(source)) {
15
15
  return;
16
16
  }
@@ -21,11 +21,6 @@ export class AbsorbersPlugin {
21
21
  return tmp;
22
22
  });
23
23
  }
24
- options.interactivity.modes.absorbers = executeOnSingleOrMultiple(source?.interactivity?.modes?.absorbers, absorber => {
25
- const tmp = new Absorber();
26
- tmp.load(absorber);
27
- return tmp;
28
- });
29
24
  }
30
25
  needsPlugin(options) {
31
26
  if (!options) {
@@ -38,10 +33,6 @@ export class AbsorbersPlugin {
38
33
  else if (absorbers) {
39
34
  return true;
40
35
  }
41
- else if (options.interactivity?.events?.onClick?.mode &&
42
- isInArray(AbsorberClickMode.absorber, options.interactivity.events.onClick.mode)) {
43
- return true;
44
- }
45
36
  return false;
46
37
  }
47
38
  }
@@ -0,0 +1,42 @@
1
+ import { executeOnSingleOrMultiple, isArray, } from "@tsparticles/engine";
2
+ export class AbsorbersPluginInstance {
3
+ _container;
4
+ _instancesManager;
5
+ constructor(container, instancesManager) {
6
+ this._container = container;
7
+ this._instancesManager = instancesManager;
8
+ this._instancesManager.initContainer(container);
9
+ }
10
+ draw(context) {
11
+ for (const absorber of this._instancesManager.getArray(this._container)) {
12
+ absorber.draw(context);
13
+ }
14
+ }
15
+ async init() {
16
+ const absorbers = this._container.actualOptions.absorbers, promises = executeOnSingleOrMultiple(absorbers, async (absorber) => {
17
+ await this._instancesManager.addAbsorber(this._container, absorber);
18
+ });
19
+ if (isArray(promises)) {
20
+ await Promise.all(promises);
21
+ }
22
+ else {
23
+ await promises;
24
+ }
25
+ }
26
+ particleUpdate(particle, delta) {
27
+ for (const absorber of this._instancesManager.getArray(this._container)) {
28
+ absorber.attract(particle, delta);
29
+ if (particle.destroyed) {
30
+ break;
31
+ }
32
+ }
33
+ }
34
+ resize() {
35
+ for (const absorber of this._instancesManager.getArray(this._container)) {
36
+ absorber.resize();
37
+ }
38
+ }
39
+ stop() {
40
+ this._instancesManager.clear(this._container);
41
+ }
42
+ }
@@ -1,6 +1,16 @@
1
1
  import { OptionsColor, isNull, setRangeValue, } from "@tsparticles/engine";
2
+ import { AbsorberLife } from "./AbsorberLife.js";
2
3
  import { AbsorberSize } from "./AbsorberSize.js";
3
4
  export class Absorber {
5
+ color;
6
+ destroy;
7
+ draggable;
8
+ life;
9
+ name;
10
+ opacity;
11
+ orbits;
12
+ position;
13
+ size;
4
14
  constructor() {
5
15
  this.color = new OptionsColor();
6
16
  this.color.value = "#000000";
@@ -8,6 +18,7 @@ export class Absorber {
8
18
  this.opacity = 1;
9
19
  this.destroy = true;
10
20
  this.orbits = false;
21
+ this.life = new AbsorberLife();
11
22
  this.size = new AbsorberSize();
12
23
  }
13
24
  load(data) {
@@ -20,6 +31,9 @@ export class Absorber {
20
31
  if (data.draggable !== undefined) {
21
32
  this.draggable = data.draggable;
22
33
  }
34
+ if (data.life !== undefined) {
35
+ this.life.load(data.life);
36
+ }
23
37
  this.name = data.name;
24
38
  if (data.opacity !== undefined) {
25
39
  this.opacity = data.opacity;
@@ -0,0 +1,27 @@
1
+ import { isNull, setRangeValue } from "@tsparticles/engine";
2
+ export class AbsorberLife {
3
+ count;
4
+ delay;
5
+ duration;
6
+ wait;
7
+ constructor() {
8
+ this.wait = false;
9
+ }
10
+ load(data) {
11
+ if (isNull(data)) {
12
+ return;
13
+ }
14
+ if (data.count !== undefined) {
15
+ this.count = data.count;
16
+ }
17
+ if (data.delay !== undefined) {
18
+ this.delay = setRangeValue(data.delay);
19
+ }
20
+ if (data.duration !== undefined) {
21
+ this.duration = setRangeValue(data.duration);
22
+ }
23
+ if (data.wait !== undefined) {
24
+ this.wait = data.wait;
25
+ }
26
+ }
27
+ }
@@ -1,6 +1,8 @@
1
1
  import { ValueWithRandom, isNull, isNumber } from "@tsparticles/engine";
2
2
  import { AbsorberSizeLimit } from "./AbsorberSizeLimit.js";
3
3
  export class AbsorberSize extends ValueWithRandom {
4
+ density;
5
+ limit;
4
6
  constructor() {
5
7
  super();
6
8
  this.density = 5;
@@ -1,5 +1,7 @@
1
1
  import { isNull } from "@tsparticles/engine";
2
2
  export class AbsorberSizeLimit {
3
+ mass;
4
+ radius;
3
5
  constructor() {
4
6
  this.radius = 0;
5
7
  this.mass = 0;
@@ -0,0 +1 @@
1
+ export {};
package/cjs/index.js CHANGED
@@ -1,8 +1,16 @@
1
- export function loadAbsorbersPlugin(engine) {
2
- engine.checkVersion("4.0.0-alpha.2");
3
- engine.register(async (e) => {
4
- const { AbsorbersPlugin } = await import("./AbsorbersPlugin.js");
5
- e.addPlugin(new AbsorbersPlugin(e));
1
+ export async function loadAbsorbersPlugin(engine) {
2
+ engine.checkVersion("4.0.0-alpha.20");
3
+ await engine.register(async (e) => {
4
+ const [{ ensureInteractivityPluginLoaded }, { AbsorbersInstancesManager }, { AbsorbersPlugin },] = await Promise.all([
5
+ import("@tsparticles/plugin-interactivity"),
6
+ import("./AbsorbersInstancesManager.js"),
7
+ import("./AbsorbersPlugin.js"),
8
+ ]), instancesManager = new AbsorbersInstancesManager(e);
9
+ ensureInteractivityPluginLoaded(e);
10
+ e.addPlugin(new AbsorbersPlugin(instancesManager));
11
+ e.addInteractor?.("externalAbsorbers", async (container) => {
12
+ const { AbsorbersInteractor } = await import("./AbsorbersInteractor.js");
13
+ return new AbsorbersInteractor(container, instancesManager);
14
+ });
6
15
  });
7
16
  }
8
- export * from "./Enums/AbsorberClickMode.js";