@tsparticles/engine 3.0.0-alpha.0 → 3.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +62 -83
  2. package/browser/Core/Particle.js +4 -1
  3. package/browser/Core/Particles.js +28 -19
  4. package/browser/Core/Utils/EventListeners.js +83 -68
  5. package/browser/Enums/Modes/AnimationMode.js +1 -0
  6. package/browser/Options/Classes/AnimationOptions.js +4 -0
  7. package/browser/Options/Classes/ManualParticle.js +2 -1
  8. package/browser/Options/Classes/Particles/Shape/Shape.js +8 -0
  9. package/browser/Utils/Utils.js +24 -4
  10. package/browser/bundle.js +1 -0
  11. package/browser/index.js +1 -0
  12. package/cjs/Core/Particle.js +4 -1
  13. package/cjs/Core/Particles.js +28 -19
  14. package/cjs/Core/Utils/EventListeners.js +83 -68
  15. package/cjs/Enums/Modes/AnimationMode.js +2 -0
  16. package/cjs/Options/Classes/AnimationOptions.js +4 -0
  17. package/cjs/Options/Classes/ManualParticle.js +2 -1
  18. package/cjs/Options/Classes/Particles/Shape/Shape.js +8 -0
  19. package/cjs/Utils/Utils.js +24 -4
  20. package/cjs/bundle.js +1 -0
  21. package/cjs/index.js +1 -0
  22. package/esm/Core/Particle.js +4 -1
  23. package/esm/Core/Particles.js +28 -19
  24. package/esm/Core/Utils/EventListeners.js +83 -68
  25. package/esm/Enums/Modes/AnimationMode.js +1 -0
  26. package/esm/Options/Classes/AnimationOptions.js +4 -0
  27. package/esm/Options/Classes/ManualParticle.js +2 -1
  28. package/esm/Options/Classes/Particles/Shape/Shape.js +8 -0
  29. package/esm/Utils/Utils.js +24 -4
  30. package/esm/bundle.js +1 -0
  31. package/esm/index.js +1 -0
  32. package/package.json +1 -1
  33. package/report.html +2 -2
  34. package/tsparticles.engine.js +152 -90
  35. package/tsparticles.engine.min.js +1 -1
  36. package/tsparticles.engine.min.js.LICENSE.txt +1 -1
  37. package/types/Core/Interfaces/ICoordinates.d.ts +3 -1
  38. package/types/Core/Interfaces/IDimension.d.ts +4 -0
  39. package/types/Core/Particles.d.ts +1 -0
  40. package/types/Core/Utils/EventListeners.d.ts +14 -10
  41. package/types/Enums/Modes/AnimationMode.d.ts +6 -0
  42. package/types/Options/Classes/AnimationOptions.d.ts +2 -0
  43. package/types/Options/Classes/ManualParticle.d.ts +2 -2
  44. package/types/Options/Classes/Particles/Move/Spin.d.ts +2 -2
  45. package/types/Options/Classes/Particles/Shape/Shape.d.ts +2 -0
  46. package/types/Options/Interfaces/IAnimation.d.ts +2 -0
  47. package/types/Options/Interfaces/IManualParticle.d.ts +2 -2
  48. package/types/Options/Interfaces/Particles/Move/ISpin.d.ts +2 -2
  49. package/types/Options/Interfaces/Particles/Shape/IShape.d.ts +2 -0
  50. package/types/bundle.d.ts +1 -0
  51. package/types/index.d.ts +1 -0
  52. package/umd/Core/Particle.js +4 -1
  53. package/umd/Core/Particles.js +28 -19
  54. package/umd/Core/Utils/EventListeners.js +83 -68
  55. package/umd/Enums/Modes/AnimationMode.js +12 -0
  56. package/umd/Options/Classes/AnimationOptions.js +4 -0
  57. package/umd/Options/Classes/ManualParticle.js +2 -1
  58. package/umd/Options/Classes/Particles/Shape/Shape.js +8 -0
  59. package/umd/Utils/Utils.js +24 -4
  60. package/umd/bundle.js +2 -1
  61. package/umd/index.js +2 -1
@@ -30,10 +30,14 @@ class Particles {
30
30
  addManualParticles() {
31
31
  const container = this.container, options = container.actualOptions;
32
32
  for (const particle of options.manualParticles) {
33
- this.addParticle((0, NumberUtils_1.calcPositionFromSize)({
34
- size: container.canvas.size,
35
- position: particle.position,
36
- }), particle.options);
33
+ this.addParticle(particle.position
34
+ ? particle.position.mode === "precise"
35
+ ? particle.position
36
+ : (0, NumberUtils_1.calcPositionFromSize)({
37
+ size: container.canvas.size,
38
+ position: particle.position,
39
+ })
40
+ : undefined, particle.options);
37
41
  }
38
42
  }
39
43
  addParticle(position, overrideOptions, group, initializer) {
@@ -130,22 +134,9 @@ class Particles {
130
134
  }
131
135
  let deleted = 0;
132
136
  for (let i = index; deleted < quantity && i < this.count; i++) {
133
- const particle = this.array[i];
134
- if (!particle || particle.group !== group) {
135
- continue;
137
+ if (this._removeParticle(i--, group, override)) {
138
+ deleted++;
136
139
  }
137
- particle.destroy(override);
138
- this.array.splice(i--, 1);
139
- const idx = this.zArray.indexOf(particle);
140
- this.zArray.splice(idx, 1);
141
- this.pool.push(particle);
142
- deleted++;
143
- this._engine.dispatchEvent("particleRemoved", {
144
- container: this.container,
145
- data: {
146
- particle,
147
- },
148
- });
149
140
  }
150
141
  }
151
142
  removeQuantity(quantity, group) {
@@ -262,5 +253,23 @@ class Particles {
262
253
  return;
263
254
  }
264
255
  }
256
+ _removeParticle(index, group, override) {
257
+ const particle = this.array[index];
258
+ if (!particle || particle.group !== group) {
259
+ return false;
260
+ }
261
+ particle.destroy(override);
262
+ this.array.splice(index, 1);
263
+ const zIdx = this.zArray.indexOf(particle);
264
+ this.zArray.splice(zIdx, 1);
265
+ this.pool.push(particle);
266
+ this._engine.dispatchEvent("particleRemoved", {
267
+ container: this.container,
268
+ data: {
269
+ particle,
270
+ },
271
+ });
272
+ return true;
273
+ }
265
274
  }
266
275
  exports.Particles = Particles;
@@ -24,28 +24,28 @@ class EventListeners {
24
24
  this.container = container;
25
25
  this.canPush = true;
26
26
  this.handlers = {
27
- mouseMove: (e) => this.mouseTouchMove(e),
28
- touchStart: (e) => this.mouseTouchMove(e),
29
- touchMove: (e) => this.mouseTouchMove(e),
30
- touchEnd: () => this.mouseTouchFinish(),
31
- mouseLeave: () => this.mouseTouchFinish(),
32
- touchCancel: () => this.mouseTouchFinish(),
33
- touchEndClick: (e) => this.mouseTouchClick(e),
34
- mouseUp: (e) => this.mouseTouchClick(e),
35
- mouseDown: () => this.mouseDown(),
36
- visibilityChange: () => this.handleVisibilityChange(),
37
- themeChange: (e) => this.handleThemeChange(e),
38
- oldThemeChange: (e) => this.handleThemeChange(e),
39
- resize: () => this.handleWindowResize(),
27
+ mouseMove: (e) => this._mouseTouchMove(e),
28
+ touchStart: (e) => this._mouseTouchMove(e),
29
+ touchMove: (e) => this._mouseTouchMove(e),
30
+ touchEnd: () => this._mouseTouchFinish(),
31
+ mouseLeave: () => this._mouseTouchFinish(),
32
+ touchCancel: () => this._mouseTouchFinish(),
33
+ touchEndClick: (e) => this._mouseTouchClick(e),
34
+ mouseUp: (e) => this._mouseTouchClick(e),
35
+ mouseDown: () => this._mouseDown(),
36
+ visibilityChange: () => this._handleVisibilityChange(),
37
+ themeChange: (e) => this._handleThemeChange(e),
38
+ oldThemeChange: (e) => this._handleThemeChange(e),
39
+ resize: () => this._handleWindowResize(),
40
40
  };
41
41
  }
42
42
  addListeners() {
43
- this.manageListeners(true);
43
+ this._manageListeners(true);
44
44
  }
45
45
  removeListeners() {
46
- this.manageListeners(false);
46
+ this._manageListeners(false);
47
47
  }
48
- doMouseTouchClick(e) {
48
+ _doMouseTouchClick(e) {
49
49
  const container = this.container, options = container.actualOptions;
50
50
  if (this.canPush) {
51
51
  const mouseInteractivity = container.interactivity.mouse, mousePos = mouseInteractivity.position;
@@ -55,33 +55,32 @@ class EventListeners {
55
55
  mouseInteractivity.clickPosition = Object.assign({}, mousePos);
56
56
  mouseInteractivity.clickTime = new Date().getTime();
57
57
  const onClick = options.interactivity.events.onClick;
58
- (0, Utils_1.executeOnSingleOrMultiple)(onClick.mode, (mode) => this.handleClickMode(mode));
58
+ (0, Utils_1.executeOnSingleOrMultiple)(onClick.mode, (mode) => this._handleClickMode(mode));
59
59
  }
60
60
  if (e.type === "touchend") {
61
- setTimeout(() => this.mouseTouchFinish(), 500);
61
+ setTimeout(() => this._mouseTouchFinish(), 500);
62
62
  }
63
63
  }
64
- handleClickMode(mode) {
64
+ _handleClickMode(mode) {
65
65
  this.container.handleClickMode(mode);
66
66
  }
67
- handleThemeChange(e) {
67
+ _handleThemeChange(e) {
68
68
  const mediaEvent = e, container = this.container, options = container.options, defaultThemes = options.defaultThemes, themeName = mediaEvent.matches ? defaultThemes.dark : defaultThemes.light, theme = options.themes.find((theme) => theme.name === themeName);
69
69
  if (theme && theme.default.auto) {
70
70
  container.loadTheme(themeName);
71
71
  }
72
72
  }
73
- handleVisibilityChange() {
73
+ _handleVisibilityChange() {
74
74
  const container = this.container, options = container.actualOptions;
75
- this.mouseTouchFinish();
75
+ this._mouseTouchFinish();
76
76
  if (!options.pauseOnBlur) {
77
77
  return;
78
78
  }
79
- if (document === null || document === void 0 ? void 0 : document.hidden) {
80
- container.pageHidden = true;
79
+ container.pageHidden = (document === null || document === void 0 ? void 0 : document.hidden) || false;
80
+ if (container.pageHidden) {
81
81
  container.pause();
82
82
  }
83
83
  else {
84
- container.pageHidden = false;
85
84
  if (container.getAnimationStatus()) {
86
85
  container.play(true);
87
86
  }
@@ -90,14 +89,14 @@ class EventListeners {
90
89
  }
91
90
  }
92
91
  }
93
- handleWindowResize() {
92
+ _handleWindowResize() {
94
93
  if (this.resizeTimeout) {
95
94
  clearTimeout(this.resizeTimeout);
96
95
  delete this.resizeTimeout;
97
96
  }
98
97
  this.resizeTimeout = setTimeout(async () => { var _a; return (_a = this.container.canvas) === null || _a === void 0 ? void 0 : _a.windowResize(); }, this.container.actualOptions.interactivity.events.resize.delay * 1000);
99
98
  }
100
- manageListeners(add) {
99
+ _manageInteractivityEvents(add) {
101
100
  var _a;
102
101
  const handlers = this.handlers, container = this.container, options = container.actualOptions, detectType = options.interactivity.detectsOn;
103
102
  let mouseLeaveTmpEvent = Constants_1.mouseLeaveEvent;
@@ -112,20 +111,6 @@ class EventListeners {
112
111
  else {
113
112
  container.interactivity.element = container.canvas.element;
114
113
  }
115
- const mediaMatch = (0, Utils_1.safeMatchMedia)("(prefers-color-scheme: dark)");
116
- if (mediaMatch) {
117
- if (mediaMatch.addEventListener !== undefined) {
118
- manageListener(mediaMatch, "change", handlers.themeChange, add);
119
- }
120
- else if (mediaMatch.addListener !== undefined) {
121
- if (add) {
122
- mediaMatch.addListener(handlers.oldThemeChange);
123
- }
124
- else {
125
- mediaMatch.removeListener(handlers.oldThemeChange);
126
- }
127
- }
128
- }
129
114
  const interactivityEl = container.interactivity.element;
130
115
  if (!interactivityEl) {
131
116
  return;
@@ -149,35 +134,65 @@ class EventListeners {
149
134
  if (container.canvas.element) {
150
135
  container.canvas.element.style.pointerEvents = html === container.canvas.element ? "initial" : "none";
151
136
  }
152
- if (options.interactivity.events.resize) {
153
- if (typeof ResizeObserver !== "undefined") {
154
- if (this.resizeObserver && !add) {
155
- if (container.canvas.element) {
156
- this.resizeObserver.unobserve(container.canvas.element);
157
- }
158
- this.resizeObserver.disconnect();
159
- delete this.resizeObserver;
160
- }
161
- else if (!this.resizeObserver && add && container.canvas.element) {
162
- this.resizeObserver = new ResizeObserver((entries) => {
163
- const entry = entries.find((e) => e.target === container.canvas.element);
164
- if (!entry) {
165
- return;
166
- }
167
- this.handleWindowResize();
168
- });
169
- this.resizeObserver.observe(container.canvas.element);
170
- }
137
+ }
138
+ _manageListeners(add) {
139
+ this._manageMediaEvents(add);
140
+ this._manageInteractivityEvents(add);
141
+ this._manageResizeEvent(add);
142
+ this._manageVisibilityEvent(add);
143
+ }
144
+ _manageMediaEvents(add) {
145
+ const handlers = this.handlers, mediaMatch = (0, Utils_1.safeMatchMedia)("(prefers-color-scheme: dark)");
146
+ if (!mediaMatch) {
147
+ return;
148
+ }
149
+ if (mediaMatch.addEventListener !== undefined) {
150
+ manageListener(mediaMatch, "change", handlers.themeChange, add);
151
+ return;
152
+ }
153
+ if (mediaMatch.addListener !== undefined) {
154
+ if (add) {
155
+ mediaMatch.addListener(handlers.oldThemeChange);
171
156
  }
172
157
  else {
173
- manageListener(window, Constants_1.resizeEvent, handlers.resize, add);
158
+ mediaMatch.removeListener(handlers.oldThemeChange);
159
+ }
160
+ }
161
+ }
162
+ _manageResizeEvent(add) {
163
+ const handlers = this.handlers, container = this.container, options = container.actualOptions;
164
+ if (!options.interactivity.events.resize) {
165
+ return;
166
+ }
167
+ if (typeof ResizeObserver === "undefined") {
168
+ manageListener(window, Constants_1.resizeEvent, handlers.resize, add);
169
+ return;
170
+ }
171
+ if (this.resizeObserver && !add) {
172
+ if (container.canvas.element) {
173
+ this.resizeObserver.unobserve(container.canvas.element);
174
174
  }
175
+ this.resizeObserver.disconnect();
176
+ delete this.resizeObserver;
177
+ }
178
+ else if (!this.resizeObserver && add && container.canvas.element) {
179
+ this.resizeObserver = new ResizeObserver((entries) => {
180
+ const entry = entries.find((e) => e.target === container.canvas.element);
181
+ if (!entry) {
182
+ return;
183
+ }
184
+ this._handleWindowResize();
185
+ });
186
+ this.resizeObserver.observe(container.canvas.element);
175
187
  }
176
- if (document) {
177
- manageListener(document, Constants_1.visibilityChangeEvent, handlers.visibilityChange, add, false);
188
+ }
189
+ _manageVisibilityEvent(add) {
190
+ if (!document) {
191
+ return;
178
192
  }
193
+ manageListener(document, Constants_1.visibilityChangeEvent, this.handlers.visibilityChange, add);
179
194
  }
180
- mouseDown() {
195
+ _mouseDown() {
181
196
  const interactivity = this.container.interactivity;
182
197
  if (interactivity) {
183
198
  const mouse = interactivity.mouse;
@@ -185,7 +200,7 @@ class EventListeners {
185
200
  mouse.downPosition = mouse.position;
186
201
  }
187
202
  }
188
- mouseTouchClick(e) {
203
+ _mouseTouchClick(e) {
189
204
  const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse;
190
205
  mouse.inside = true;
191
206
  let handled = false;
@@ -203,11 +218,11 @@ class EventListeners {
203
218
  }
204
219
  }
205
220
  if (!handled) {
206
- this.doMouseTouchClick(e);
221
+ this._doMouseTouchClick(e);
207
222
  }
208
223
  mouse.clicking = false;
209
224
  }
210
- mouseTouchFinish() {
225
+ _mouseTouchFinish() {
211
226
  const interactivity = this.container.interactivity;
212
227
  if (!interactivity) {
213
228
  return;
@@ -220,7 +235,7 @@ class EventListeners {
220
235
  mouse.inside = false;
221
236
  mouse.clicking = false;
222
237
  }
223
- mouseTouchMove(e) {
238
+ _mouseTouchMove(e) {
224
239
  var _a, _b, _c, _d, _e, _f, _g;
225
240
  const container = this.container, options = container.actualOptions;
226
241
  if (!((_a = container.interactivity) === null || _a === void 0 ? void 0 : _a.element)) {
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -35,6 +35,7 @@ exports.AnimationOptions = AnimationOptions;
35
35
  class RangedAnimationOptions extends AnimationOptions {
36
36
  constructor() {
37
37
  super();
38
+ this.mode = "auto";
38
39
  this.startValue = "random";
39
40
  }
40
41
  load(data) {
@@ -45,6 +46,9 @@ class RangedAnimationOptions extends AnimationOptions {
45
46
  if (data.minimumValue !== undefined) {
46
47
  this.minimumValue = data.minimumValue;
47
48
  }
49
+ if (data.mode !== undefined) {
50
+ this.mode = data.mode;
51
+ }
48
52
  if (data.startValue !== undefined) {
49
53
  this.startValue = data.startValue;
50
54
  }
@@ -4,7 +4,7 @@ exports.ManualParticle = void 0;
4
4
  const Utils_1 = require("../../Utils/Utils");
5
5
  class ManualParticle {
6
6
  load(data) {
7
- var _a, _b;
7
+ var _a, _b, _c;
8
8
  if (!data) {
9
9
  return;
10
10
  }
@@ -12,6 +12,7 @@ class ManualParticle {
12
12
  this.position = {
13
13
  x: (_a = data.position.x) !== null && _a !== void 0 ? _a : 50,
14
14
  y: (_b = data.position.y) !== null && _b !== void 0 ? _b : 50,
15
+ mode: (_c = data.position.mode) !== null && _c !== void 0 ? _c : "percent",
15
16
  };
16
17
  }
17
18
  if (data.options !== undefined) {
@@ -6,12 +6,20 @@ class Shape {
6
6
  constructor() {
7
7
  this.options = {};
8
8
  this.type = "circle";
9
+ this.close = true;
10
+ this.fill = true;
9
11
  }
10
12
  load(data) {
11
13
  var _a;
12
14
  if (!data) {
13
15
  return;
14
16
  }
17
+ if (data.close !== undefined) {
18
+ this.close = data.close;
19
+ }
20
+ if (data.fill !== undefined) {
21
+ this.fill = data.fill;
22
+ }
15
23
  const options = data.options;
16
24
  if (options !== undefined) {
17
25
  for (const shape in options) {
@@ -250,21 +250,41 @@ function initParticleNumericAnimationValue(options, pxRatio) {
250
250
  maxLoops: (0, NumberUtils_1.getRangeValue)(options.animation.count),
251
251
  };
252
252
  if (animationOptions.enable) {
253
- res.status = "increasing";
254
253
  res.decay = 1 - (0, NumberUtils_1.getRangeValue)(animationOptions.decay);
254
+ let autoStatus = false;
255
+ switch (animationOptions.mode) {
256
+ case "increase":
257
+ res.status = "increasing";
258
+ break;
259
+ case "decrease":
260
+ res.status = "decreasing";
261
+ break;
262
+ case "random":
263
+ res.status = (0, NumberUtils_1.getRandom)() >= 0.5 ? "increasing" : "decreasing";
264
+ break;
265
+ case "auto":
266
+ autoStatus = true;
267
+ break;
268
+ }
255
269
  switch (animationOptions.startValue) {
256
270
  case "min":
257
271
  res.value = res.min;
258
- res.status = "increasing";
272
+ if (autoStatus) {
273
+ res.status = "increasing";
274
+ }
259
275
  break;
260
276
  case "random":
261
277
  res.value = (0, NumberUtils_1.randomInRange)(res);
262
- res.status = (0, NumberUtils_1.getRandom)() >= 0.5 ? "increasing" : "decreasing";
278
+ if (autoStatus) {
279
+ res.status = (0, NumberUtils_1.getRandom)() >= 0.5 ? "increasing" : "decreasing";
280
+ }
263
281
  break;
264
282
  case "max":
265
283
  default:
266
284
  res.value = res.max;
267
- res.status = "decreasing";
285
+ if (autoStatus) {
286
+ res.status = "decreasing";
287
+ }
268
288
  break;
269
289
  }
270
290
  }
package/cjs/bundle.js CHANGED
@@ -36,6 +36,7 @@ __exportStar(require("./Core/Utils/Vector3d"), exports);
36
36
  __exportStar(require("./Enums/Directions/MoveDirection"), exports);
37
37
  __exportStar(require("./Enums/Directions/RotateDirection"), exports);
38
38
  __exportStar(require("./Enums/Directions/OutModeDirection"), exports);
39
+ __exportStar(require("./Enums/Modes/AnimationMode"), exports);
39
40
  __exportStar(require("./Enums/Modes/ClickMode"), exports);
40
41
  __exportStar(require("./Enums/Modes/DivMode"), exports);
41
42
  __exportStar(require("./Enums/Modes/HoverMode"), exports);
package/cjs/index.js CHANGED
@@ -71,6 +71,7 @@ __exportStar(require("./Core/Utils/Vector3d"), exports);
71
71
  __exportStar(require("./Enums/Directions/MoveDirection"), exports);
72
72
  __exportStar(require("./Enums/Directions/RotateDirection"), exports);
73
73
  __exportStar(require("./Enums/Directions/OutModeDirection"), exports);
74
+ __exportStar(require("./Enums/Modes/AnimationMode"), exports);
74
75
  __exportStar(require("./Enums/Modes/ClickMode"), exports);
75
76
  __exportStar(require("./Enums/Modes/DivMode"), exports);
76
77
  __exportStar(require("./Enums/Modes/HoverMode"), exports);
@@ -301,7 +301,10 @@ export class Particle {
301
301
  _loadShapeData(shapeOptions, reduceDuplicates) {
302
302
  const shapeData = shapeOptions.options[this.shape];
303
303
  if (shapeData) {
304
- return deepExtend({}, itemFromSingleOrMultiple(shapeData, this.id, reduceDuplicates));
304
+ return deepExtend({
305
+ close: shapeOptions.close,
306
+ fill: shapeOptions.fill,
307
+ }, itemFromSingleOrMultiple(shapeData, this.id, reduceDuplicates));
305
308
  }
306
309
  }
307
310
  }
@@ -27,10 +27,14 @@ export class Particles {
27
27
  addManualParticles() {
28
28
  const container = this.container, options = container.actualOptions;
29
29
  for (const particle of options.manualParticles) {
30
- this.addParticle(calcPositionFromSize({
31
- size: container.canvas.size,
32
- position: particle.position,
33
- }), particle.options);
30
+ this.addParticle(particle.position
31
+ ? particle.position.mode === "precise"
32
+ ? particle.position
33
+ : calcPositionFromSize({
34
+ size: container.canvas.size,
35
+ position: particle.position,
36
+ })
37
+ : undefined, particle.options);
34
38
  }
35
39
  }
36
40
  addParticle(position, overrideOptions, group, initializer) {
@@ -127,22 +131,9 @@ export class Particles {
127
131
  }
128
132
  let deleted = 0;
129
133
  for (let i = index; deleted < quantity && i < this.count; i++) {
130
- const particle = this.array[i];
131
- if (!particle || particle.group !== group) {
132
- continue;
134
+ if (this._removeParticle(i--, group, override)) {
135
+ deleted++;
133
136
  }
134
- particle.destroy(override);
135
- this.array.splice(i--, 1);
136
- const idx = this.zArray.indexOf(particle);
137
- this.zArray.splice(idx, 1);
138
- this.pool.push(particle);
139
- deleted++;
140
- this._engine.dispatchEvent("particleRemoved", {
141
- container: this.container,
142
- data: {
143
- particle,
144
- },
145
- });
146
137
  }
147
138
  }
148
139
  removeQuantity(quantity, group) {
@@ -259,4 +250,22 @@ export class Particles {
259
250
  return;
260
251
  }
261
252
  }
253
+ _removeParticle(index, group, override) {
254
+ const particle = this.array[index];
255
+ if (!particle || particle.group !== group) {
256
+ return false;
257
+ }
258
+ particle.destroy(override);
259
+ this.array.splice(index, 1);
260
+ const zIdx = this.zArray.indexOf(particle);
261
+ this.zArray.splice(zIdx, 1);
262
+ this.pool.push(particle);
263
+ this._engine.dispatchEvent("particleRemoved", {
264
+ container: this.container,
265
+ data: {
266
+ particle,
267
+ },
268
+ });
269
+ return true;
270
+ }
262
271
  }