@tsparticles/plugin-emitters 3.0.0-beta.2 → 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 (80) hide show
  1. package/browser/EmitterInstance.js +133 -80
  2. package/browser/EmitterShapeBase.js +12 -0
  3. package/browser/Emitters.js +7 -6
  4. package/browser/Options/Classes/Emitter.js +3 -4
  5. package/browser/Options/Classes/EmitterShape.js +21 -0
  6. package/browser/Options/Classes/EmitterShapeReplace.js +17 -0
  7. package/browser/Options/Interfaces/IEmitterShape.js +1 -0
  8. package/browser/Options/Interfaces/IEmitterShapeReplace.js +1 -0
  9. package/browser/ShapeManager.js +8 -8
  10. package/browser/index.js +7 -8
  11. package/cjs/EmitterInstance.js +133 -80
  12. package/cjs/EmitterShapeBase.js +16 -0
  13. package/cjs/Emitters.js +7 -6
  14. package/cjs/IRandomPositionData.js +2 -0
  15. package/cjs/Options/Classes/Emitter.js +3 -4
  16. package/cjs/Options/Classes/EmitterShape.js +25 -0
  17. package/cjs/Options/Classes/EmitterShapeReplace.js +21 -0
  18. package/cjs/Options/Interfaces/IEmitterShape.js +2 -0
  19. package/cjs/Options/Interfaces/IEmitterShapeReplace.js +2 -0
  20. package/cjs/ShapeManager.js +8 -8
  21. package/cjs/index.js +7 -8
  22. package/esm/EmitterInstance.js +133 -80
  23. package/esm/EmitterShapeBase.js +12 -0
  24. package/esm/Emitters.js +7 -6
  25. package/esm/IEmitterShapeGenerator.js +1 -0
  26. package/esm/IRandomPositionData.js +1 -0
  27. package/esm/Options/Classes/Emitter.js +3 -4
  28. package/esm/Options/Classes/EmitterShape.js +21 -0
  29. package/esm/Options/Classes/EmitterShapeReplace.js +17 -0
  30. package/esm/Options/Interfaces/IEmitterShape.js +1 -0
  31. package/esm/Options/Interfaces/IEmitterShapeReplace.js +1 -0
  32. package/esm/ShapeManager.js +8 -8
  33. package/esm/index.js +7 -8
  34. package/package.json +3 -3
  35. package/report.html +4 -22
  36. package/tsparticles.plugin.emitters.js +208 -176
  37. package/tsparticles.plugin.emitters.min.js +1 -1
  38. package/tsparticles.plugin.emitters.min.js.LICENSE.txt +1 -1
  39. package/types/EmitterContainer.d.ts +1 -1
  40. package/types/EmitterInstance.d.ts +11 -9
  41. package/types/EmitterShapeBase.d.ts +13 -0
  42. package/types/Emitters.d.ts +2 -2
  43. package/types/EmittersEngine.d.ts +2 -2
  44. package/types/IEmitterShape.d.ts +4 -1
  45. package/types/IEmitterShapeGenerator.d.ts +5 -0
  46. package/types/IRandomPositionData.d.ts +6 -0
  47. package/types/Options/Classes/Emitter.d.ts +2 -2
  48. package/types/Options/Classes/EmitterShape.d.ts +10 -0
  49. package/types/Options/Classes/EmitterShapeReplace.d.ts +8 -0
  50. package/types/Options/Interfaces/IEmitter.d.ts +2 -2
  51. package/types/Options/Interfaces/IEmitterShape.d.ts +6 -0
  52. package/types/Options/Interfaces/IEmitterShapeReplace.d.ts +4 -0
  53. package/types/ShapeManager.d.ts +4 -4
  54. package/types/index.d.ts +4 -1
  55. package/umd/EmitterInstance.js +133 -80
  56. package/umd/EmitterShapeBase.js +26 -0
  57. package/umd/Emitters.js +7 -6
  58. package/umd/IRandomPositionData.js +12 -0
  59. package/umd/Options/Classes/Emitter.js +4 -5
  60. package/umd/Options/Classes/EmitterShape.js +35 -0
  61. package/umd/Options/Classes/EmitterShapeReplace.js +31 -0
  62. package/umd/Options/Interfaces/IEmitterShape.js +12 -0
  63. package/umd/Options/Interfaces/IEmitterShapeReplace.js +12 -0
  64. package/umd/ShapeManager.js +8 -8
  65. package/umd/index.js +8 -9
  66. package/browser/Shapes/Circle/CircleShape.js +0 -24
  67. package/browser/Shapes/Square/SquareShape.js +0 -40
  68. package/cjs/Shapes/Circle/CircleShape.js +0 -28
  69. package/cjs/Shapes/Square/SquareShape.js +0 -44
  70. package/esm/Shapes/Circle/CircleShape.js +0 -24
  71. package/esm/Shapes/Square/SquareShape.js +0 -40
  72. package/types/Enums/EmitterShapeType.d.ts +0 -6
  73. package/types/Shapes/Circle/CircleShape.d.ts +0 -5
  74. package/types/Shapes/Square/SquareShape.d.ts +0 -5
  75. package/umd/Shapes/Circle/CircleShape.js +0 -38
  76. package/umd/Shapes/Square/SquareShape.js +0 -54
  77. /package/browser/{Enums/EmitterShapeType.js → IEmitterShapeGenerator.js} +0 -0
  78. /package/{esm/Enums/EmitterShapeType.js → browser/IRandomPositionData.js} +0 -0
  79. /package/cjs/{Enums/EmitterShapeType.js → IEmitterShapeGenerator.js} +0 -0
  80. /package/umd/{Enums/EmitterShapeType.js → IEmitterShapeGenerator.js} +0 -0
@@ -4,17 +4,25 @@ exports.EmitterInstance = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
5
  const Emitter_js_1 = require("./Options/Classes/Emitter.js");
6
6
  const EmitterSize_js_1 = require("./Options/Classes/EmitterSize.js");
7
+ function setParticlesOptionsColor(particlesOptions, color) {
8
+ if (particlesOptions.color) {
9
+ particlesOptions.color.value = color;
10
+ }
11
+ else {
12
+ particlesOptions.color = {
13
+ value: color,
14
+ };
15
+ }
16
+ }
7
17
  class EmitterInstance {
8
18
  constructor(engine, emitters, container, options, position) {
9
19
  this.emitters = emitters;
10
20
  this.container = container;
11
- this._calcPosition = () => {
12
- return (0, engine_1.calcPositionOrRandomFromSizeRanged)({
13
- size: this.container.canvas.size,
14
- position: this.options.position,
15
- });
16
- };
17
21
  this._destroy = () => {
22
+ this._mutationObserver?.disconnect();
23
+ this._mutationObserver = undefined;
24
+ this._resizeObserver?.disconnect();
25
+ this._resizeObserver = undefined;
18
26
  this.emitters.removeEmitter(this);
19
27
  this._engine.dispatchEvent("emitterDestroyed", {
20
28
  container: this.container,
@@ -23,40 +31,6 @@ class EmitterInstance {
23
31
  },
24
32
  });
25
33
  };
26
- this._emit = () => {
27
- if (this._paused) {
28
- return;
29
- }
30
- const quantity = (0, engine_1.getRangeValue)(this.options.rate.quantity);
31
- this._emitParticles(quantity);
32
- };
33
- this._emitParticles = (quantity) => {
34
- const position = this.getPosition(), size = this.getSize(), singleParticlesOptions = (0, engine_1.itemFromSingleOrMultiple)(this._particlesOptions);
35
- for (let i = 0; i < quantity; i++) {
36
- const particlesOptions = (0, engine_1.deepExtend)({}, singleParticlesOptions);
37
- if (this.spawnColor) {
38
- const hslAnimation = this.options.spawnColor?.animation;
39
- if (hslAnimation) {
40
- this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
41
- this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
42
- this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
43
- }
44
- if (!particlesOptions.color) {
45
- particlesOptions.color = {
46
- value: this.spawnColor,
47
- };
48
- }
49
- else {
50
- particlesOptions.color.value = this.spawnColor;
51
- }
52
- }
53
- if (!position) {
54
- return;
55
- }
56
- const pPosition = this._shape?.randomPosition(position, size, this.fill) ?? position;
57
- this.container.particles.addParticle(pPosition, particlesOptions);
58
- }
59
- };
60
34
  this._prepareToDie = () => {
61
35
  if (this._paused) {
62
36
  return;
@@ -92,7 +66,6 @@ class EmitterInstance {
92
66
  this._spawnDelay = ((0, engine_1.getRangeValue)(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
93
67
  this.position = this._initialPosition ?? this._calcPosition();
94
68
  this.name = this.options.name;
95
- this._shape = this._engine.emitterShapeManager?.getShape(this.options.shape);
96
69
  this.fill = this.options.fill;
97
70
  this._firstSpawn = !this.options.life.wait;
98
71
  this._startParticlesAdded = false;
@@ -105,19 +78,30 @@ class EmitterInstance {
105
78
  }
106
79
  this._paused = !this.options.autoPlay;
107
80
  this._particlesOptions = particlesOptions;
108
- this.size =
109
- this.options.size ??
110
- (() => {
111
- const size = new EmitterSize_js_1.EmitterSize();
112
- size.load({
113
- height: 0,
114
- mode: "percent",
115
- width: 0,
116
- });
117
- return size;
118
- })();
81
+ this._size = this._calcSize();
82
+ this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size);
119
83
  this._lifeCount = this.options.life.count ?? -1;
120
84
  this._immortal = this._lifeCount <= 0;
85
+ if (this.options.domId) {
86
+ const element = document.getElementById(this.options.domId);
87
+ if (element) {
88
+ this._mutationObserver = new MutationObserver(() => {
89
+ this.resize();
90
+ });
91
+ this._resizeObserver = new ResizeObserver(() => {
92
+ this.resize();
93
+ });
94
+ this._mutationObserver.observe(element, {
95
+ attributes: true,
96
+ attributeFilter: ["style", "width", "height"],
97
+ });
98
+ this._resizeObserver.observe(element);
99
+ }
100
+ }
101
+ const shapeOptions = this.options.shape, shapeGenerator = this._engine.emitterShapeManager?.getShapeGenerator(shapeOptions.type);
102
+ if (shapeGenerator) {
103
+ this._shape = shapeGenerator.generate(this.position, this.size, this.fill, shapeOptions.options);
104
+ }
121
105
  this._engine.dispatchEvent("emitterCreated", {
122
106
  container,
123
107
  data: {
@@ -134,32 +118,8 @@ class EmitterInstance {
134
118
  this._paused = false;
135
119
  this.play();
136
120
  }
137
- getPosition() {
138
- if (this.options.domId) {
139
- const container = this.container, element = document.getElementById(this.options.domId);
140
- if (element) {
141
- const elRect = element.getBoundingClientRect();
142
- return {
143
- x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
144
- y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio,
145
- };
146
- }
147
- }
148
- return this.position;
149
- }
150
- getSize() {
151
- const container = this.container;
152
- if (this.options.domId) {
153
- const element = document.getElementById(this.options.domId);
154
- if (element) {
155
- const elRect = element.getBoundingClientRect();
156
- return {
157
- width: elRect.width * container.retina.pixelRatio,
158
- height: elRect.height * container.retina.pixelRatio,
159
- };
160
- }
161
- }
162
- return (0, engine_1.getSize)(this.size, container.canvas.size);
121
+ async init() {
122
+ await this._shape?.init();
163
123
  }
164
124
  pause() {
165
125
  if (this._paused) {
@@ -190,8 +150,11 @@ class EmitterInstance {
190
150
  initialPosition && (0, engine_1.isPointInside)(initialPosition, this.container.canvas.size, engine_1.Vector.origin)
191
151
  ? initialPosition
192
152
  : this._calcPosition();
153
+ this._size = this._calcSize();
154
+ this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size);
155
+ this._shape?.resize(this.position, this.size);
193
156
  }
194
- update(delta) {
157
+ async update(delta) {
195
158
  if (this._paused) {
196
159
  return;
197
160
  }
@@ -202,7 +165,7 @@ class EmitterInstance {
202
165
  }
203
166
  if (!this._startParticlesAdded) {
204
167
  this._startParticlesAdded = true;
205
- this._emitParticles(this.options.startCount);
168
+ await this._emitParticles(this.options.startCount);
206
169
  }
207
170
  if (this._duration !== undefined) {
208
171
  this._currentDuration += delta.value;
@@ -245,5 +208,95 @@ class EmitterInstance {
245
208
  }
246
209
  }
247
210
  }
211
+ _calcPosition() {
212
+ if (this.options.domId) {
213
+ const container = this.container, element = document.getElementById(this.options.domId);
214
+ if (element) {
215
+ const elRect = element.getBoundingClientRect();
216
+ return {
217
+ x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
218
+ y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio,
219
+ };
220
+ }
221
+ }
222
+ return (0, engine_1.calcPositionOrRandomFromSizeRanged)({
223
+ size: this.container.canvas.size,
224
+ position: this.options.position,
225
+ });
226
+ }
227
+ _calcSize() {
228
+ const container = this.container;
229
+ if (this.options.domId) {
230
+ const element = document.getElementById(this.options.domId);
231
+ if (element) {
232
+ const elRect = element.getBoundingClientRect();
233
+ return {
234
+ width: elRect.width * container.retina.pixelRatio,
235
+ height: elRect.height * container.retina.pixelRatio,
236
+ mode: "precise",
237
+ };
238
+ }
239
+ }
240
+ return (this.options.size ??
241
+ (() => {
242
+ const size = new EmitterSize_js_1.EmitterSize();
243
+ size.load({
244
+ height: 0,
245
+ mode: "percent",
246
+ width: 0,
247
+ });
248
+ return size;
249
+ })());
250
+ }
251
+ async _emit() {
252
+ if (this._paused) {
253
+ return;
254
+ }
255
+ const quantity = (0, engine_1.getRangeValue)(this.options.rate.quantity);
256
+ await this._emitParticles(quantity);
257
+ }
258
+ async _emitParticles(quantity) {
259
+ const singleParticlesOptions = (0, engine_1.itemFromSingleOrMultiple)(this._particlesOptions);
260
+ for (let i = 0; i < quantity; i++) {
261
+ const particlesOptions = (0, engine_1.deepExtend)({}, singleParticlesOptions);
262
+ if (this.spawnColor) {
263
+ const hslAnimation = this.options.spawnColor?.animation;
264
+ if (hslAnimation) {
265
+ this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
266
+ this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
267
+ this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
268
+ }
269
+ setParticlesOptionsColor(particlesOptions, this.spawnColor);
270
+ }
271
+ const shapeOptions = this.options.shape;
272
+ let position = this.position;
273
+ if (this._shape) {
274
+ const shapePosData = await this._shape.randomPosition();
275
+ if (shapePosData) {
276
+ position = shapePosData.position;
277
+ const replaceData = shapeOptions.replace;
278
+ if (replaceData.color && shapePosData.color) {
279
+ setParticlesOptionsColor(particlesOptions, shapePosData.color);
280
+ }
281
+ if (replaceData.opacity) {
282
+ if (particlesOptions.opacity) {
283
+ particlesOptions.opacity.value = shapePosData.opacity;
284
+ }
285
+ else {
286
+ particlesOptions.opacity = {
287
+ value: shapePosData.opacity,
288
+ };
289
+ }
290
+ }
291
+ }
292
+ else {
293
+ position = null;
294
+ }
295
+ }
296
+ if (position) {
297
+ this.container.particles.addParticle(position, particlesOptions);
298
+ }
299
+ }
300
+ }
248
301
  }
249
302
  exports.EmitterInstance = EmitterInstance;
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmitterShapeBase = void 0;
4
+ class EmitterShapeBase {
5
+ constructor(position, size, fill, options) {
6
+ this.position = position;
7
+ this.size = size;
8
+ this.fill = fill;
9
+ this.options = options;
10
+ }
11
+ resize(position, size) {
12
+ this.position = position;
13
+ this.size = size;
14
+ }
15
+ }
16
+ exports.EmitterShapeBase = EmitterShapeBase;
package/cjs/Emitters.js CHANGED
@@ -20,7 +20,7 @@ class Emitters {
20
20
  container.getEmitter = (idxOrName) => idxOrName === undefined || (0, engine_1.isNumber)(idxOrName)
21
21
  ? this.array[idxOrName || 0]
22
22
  : this.array.find((t) => t.name === idxOrName);
23
- container.addEmitter = (options, position) => this.addEmitter(options, position);
23
+ container.addEmitter = async (options, position) => this.addEmitter(options, position);
24
24
  container.removeEmitter = (idxOrName) => {
25
25
  const emitter = container.getEmitter(idxOrName);
26
26
  if (emitter) {
@@ -40,10 +40,11 @@ class Emitters {
40
40
  }
41
41
  };
42
42
  }
43
- addEmitter(options, position) {
43
+ async addEmitter(options, position) {
44
44
  const emitterOptions = new Emitter_js_1.Emitter();
45
45
  emitterOptions.load(options);
46
46
  const emitter = new EmitterInstance_js_1.EmitterInstance(this._engine, this, this.container, emitterOptions, position);
47
+ await emitter.init();
47
48
  this.array.push(emitter);
48
49
  return emitter;
49
50
  }
@@ -87,11 +88,11 @@ class Emitters {
87
88
  }
88
89
  if ((0, engine_1.isArray)(this.emitters)) {
89
90
  for (const emitterOptions of this.emitters) {
90
- this.addEmitter(emitterOptions);
91
+ await this.addEmitter(emitterOptions);
91
92
  }
92
93
  }
93
94
  else {
94
- this.addEmitter(this.emitters);
95
+ await this.addEmitter(this.emitters);
95
96
  }
96
97
  }
97
98
  pause() {
@@ -118,9 +119,9 @@ class Emitters {
118
119
  stop() {
119
120
  this.array = [];
120
121
  }
121
- update(delta) {
122
+ async update(delta) {
122
123
  for (const emitter of this.array) {
123
- emitter.update(delta);
124
+ await emitter.update(delta);
124
125
  }
125
126
  }
126
127
  }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -4,6 +4,7 @@ exports.Emitter = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
5
  const EmitterLife_js_1 = require("./EmitterLife.js");
6
6
  const EmitterRate_js_1 = require("./EmitterRate.js");
7
+ const EmitterShape_js_1 = require("./EmitterShape.js");
7
8
  const EmitterSize_js_1 = require("./EmitterSize.js");
8
9
  class Emitter {
9
10
  constructor() {
@@ -11,7 +12,7 @@ class Emitter {
11
12
  this.fill = true;
12
13
  this.life = new EmitterLife_js_1.EmitterLife();
13
14
  this.rate = new EmitterRate_js_1.EmitterRate();
14
- this.shape = "square";
15
+ this.shape = new EmitterShape_js_1.EmitterShape();
15
16
  this.startCount = 0;
16
17
  }
17
18
  load(data) {
@@ -40,9 +41,7 @@ class Emitter {
40
41
  return (0, engine_1.deepExtend)({}, particles);
41
42
  });
42
43
  this.rate.load(data.rate);
43
- if (data.shape !== undefined) {
44
- this.shape = data.shape;
45
- }
44
+ this.shape.load(data.shape);
46
45
  if (data.position !== undefined) {
47
46
  this.position = {};
48
47
  if (data.position.x !== undefined) {
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmitterShape = void 0;
4
+ const engine_1 = require("@tsparticles/engine");
5
+ const EmitterShapeReplace_js_1 = require("./EmitterShapeReplace.js");
6
+ class EmitterShape {
7
+ constructor() {
8
+ this.options = {};
9
+ this.replace = new EmitterShapeReplace_js_1.EmitterShapeReplace();
10
+ this.type = "square";
11
+ }
12
+ load(data) {
13
+ if (!data) {
14
+ return;
15
+ }
16
+ if (data.options !== undefined) {
17
+ this.options = (0, engine_1.deepExtend)({}, data.options ?? {});
18
+ }
19
+ this.replace.load(data.replace);
20
+ if (data.type !== undefined) {
21
+ this.type = data.type;
22
+ }
23
+ }
24
+ }
25
+ exports.EmitterShape = EmitterShape;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EmitterShapeReplace = void 0;
4
+ class EmitterShapeReplace {
5
+ constructor() {
6
+ this.color = false;
7
+ this.opacity = false;
8
+ }
9
+ load(data) {
10
+ if (!data) {
11
+ return;
12
+ }
13
+ if (data.color !== undefined) {
14
+ this.color = data.color;
15
+ }
16
+ if (data.opacity !== undefined) {
17
+ this.opacity = data.opacity;
18
+ }
19
+ }
20
+ }
21
+ exports.EmitterShapeReplace = EmitterShapeReplace;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,21 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ShapeManager = void 0;
4
- const shapes = new Map();
4
+ const shapeGeneratorss = new Map();
5
5
  class ShapeManager {
6
6
  constructor(engine) {
7
7
  this._engine = engine;
8
8
  }
9
- addShape(name, drawer) {
10
- if (!this.getShape(name)) {
11
- shapes.set(name, drawer);
9
+ addShapeGenerator(name, generator) {
10
+ if (!this.getShapeGenerator(name)) {
11
+ shapeGeneratorss.set(name, generator);
12
12
  }
13
13
  }
14
- getShape(name) {
15
- return shapes.get(name);
14
+ getShapeGenerator(name) {
15
+ return shapeGeneratorss.get(name);
16
16
  }
17
- getSupportedShapes() {
18
- return shapes.keys();
17
+ getSupportedShapeGenerators() {
18
+ return shapeGeneratorss.keys();
19
19
  }
20
20
  }
21
21
  exports.ShapeManager = ShapeManager;
package/cjs/index.js CHANGED
@@ -16,11 +16,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.loadEmittersPlugin = void 0;
18
18
  const engine_1 = require("@tsparticles/engine");
19
- const CircleShape_js_1 = require("./Shapes/Circle/CircleShape.js");
20
19
  const Emitter_js_1 = require("./Options/Classes/Emitter.js");
21
20
  const Emitters_js_1 = require("./Emitters.js");
22
21
  const ShapeManager_js_1 = require("./ShapeManager.js");
23
- const SquareShape_js_1 = require("./Shapes/Square/SquareShape.js");
24
22
  class EmittersPlugin {
25
23
  constructor(engine) {
26
24
  this._engine = engine;
@@ -111,18 +109,19 @@ async function loadEmittersPlugin(engine, refresh = true) {
111
109
  if (!engine.emitterShapeManager) {
112
110
  engine.emitterShapeManager = new ShapeManager_js_1.ShapeManager(engine);
113
111
  }
114
- if (!engine.addEmitterShape) {
115
- engine.addEmitterShape = (name, shape) => {
116
- engine.emitterShapeManager?.addShape(name, shape);
112
+ if (!engine.addEmitterShapeGenerator) {
113
+ engine.addEmitterShapeGenerator = (name, generator) => {
114
+ engine.emitterShapeManager?.addShapeGenerator(name, generator);
117
115
  };
118
116
  }
119
117
  const plugin = new EmittersPlugin(engine);
120
118
  await engine.addPlugin(plugin, refresh);
121
- engine.addEmitterShape("circle", new CircleShape_js_1.CircleShape());
122
- engine.addEmitterShape("square", new SquareShape_js_1.SquareShape());
123
119
  }
124
120
  exports.loadEmittersPlugin = loadEmittersPlugin;
125
121
  __exportStar(require("./EmitterContainer.js"), exports);
122
+ __exportStar(require("./EmitterShapeBase.js"), exports);
126
123
  __exportStar(require("./EmittersEngine.js"), exports);
124
+ __exportStar(require("./IEmitterShape.js"), exports);
125
+ __exportStar(require("./IEmitterShapeGenerator.js"), exports);
127
126
  __exportStar(require("./Enums/EmitterClickMode.js"), exports);
128
- __exportStar(require("./Enums/EmitterShapeType.js"), exports);
127
+ __exportStar(require("./IRandomPositionData.js"), exports);