@tsparticles/plugin-emitters 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,7 @@
1
- import { Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, isPointInside, itemFromSingleOrMultiple, randomInRange, rangeColorToHsl, } from "@tsparticles/engine";
1
+ import { Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, isPointInside, itemFromSingleOrMultiple, millisecondsToSeconds, randomInRange, rangeColorToHsl, } from "@tsparticles/engine";
2
2
  import { Emitter } from "./Options/Classes/Emitter.js";
3
3
  import { EmitterSize } from "./Options/Classes/EmitterSize.js";
4
+ const half = 0.5, defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1;
4
5
  function setParticlesOptionsColor(particlesOptions, color) {
5
6
  if (particlesOptions.color) {
6
7
  particlesOptions.color.value = color;
@@ -32,12 +33,12 @@ export class EmitterInstance {
32
33
  if (this._paused) {
33
34
  return;
34
35
  }
35
- const duration = this.options.life?.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined;
36
+ const duration = this.options.life?.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
36
37
  if (this.container.retina.reduceFactor &&
37
- (this._lifeCount > 0 || this._immortal) &&
38
+ (this._lifeCount > minLifeCount || this._immortal) &&
38
39
  duration !== undefined &&
39
- duration > 0) {
40
- this._duration = duration * 1000;
40
+ duration > minDuration) {
41
+ this._duration = duration * millisecondsToSeconds;
41
42
  }
42
43
  };
43
44
  this._setColorAnimation = (animation, initValue, maxValue) => {
@@ -45,8 +46,8 @@ export class EmitterInstance {
45
46
  if (!animation.enable) {
46
47
  return initValue;
47
48
  }
48
- const colorOffset = randomInRange(animation.offset), delay = getRangeValue(this.options.rate.delay), emitFactor = (1000 * delay) / container.retina.reduceFactor, colorSpeed = getRangeValue(animation.speed ?? 0);
49
- return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * 3.6) % maxValue;
49
+ const colorOffset = randomInRange(animation.offset), delay = getRangeValue(this.options.rate.delay), emitFactor = (delay * millisecondsToSeconds) / container.retina.reduceFactor, defaultColorSpeed = 0, colorFactor = 3.6, colorSpeed = getRangeValue(animation.speed ?? defaultColorSpeed);
50
+ return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * colorFactor) % maxValue;
50
51
  };
51
52
  this._engine = engine;
52
53
  this._currentDuration = 0;
@@ -60,7 +61,9 @@ export class EmitterInstance {
60
61
  this.options = new Emitter();
61
62
  this.options.load(options);
62
63
  }
63
- this._spawnDelay = (getRangeValue(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
64
+ this._spawnDelay =
65
+ (getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds) /
66
+ this.container.retina.reduceFactor;
64
67
  this.position = this._initialPosition ?? this._calcPosition();
65
68
  this.name = this.options.name;
66
69
  this.fill = this.options.fill;
@@ -77,8 +80,8 @@ export class EmitterInstance {
77
80
  this._particlesOptions = particlesOptions;
78
81
  this._size = this._calcSize();
79
82
  this.size = getSize(this._size, this.container.canvas.size);
80
- this._lifeCount = this.options.life.count ?? -1;
81
- this._immortal = this._lifeCount <= 0;
83
+ this._lifeCount = this.options.life.count ?? defaultLifeCount;
84
+ this._immortal = this._lifeCount <= minLifeCount;
82
85
  if (this.options.domId) {
83
86
  const element = document.getElementById(this.options.domId);
84
87
  if (element) {
@@ -129,15 +132,15 @@ export class EmitterInstance {
129
132
  return;
130
133
  }
131
134
  if (!(this.container.retina.reduceFactor &&
132
- (this._lifeCount > 0 || this._immortal || !this.options.life.count) &&
133
- (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? 0)))) {
135
+ (this._lifeCount > minLifeCount || this._immortal || !this.options.life.count) &&
136
+ (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? defaultSpawnDelay)))) {
134
137
  return;
135
138
  }
136
139
  if (this._emitDelay === undefined) {
137
140
  const delay = getRangeValue(this.options.rate.delay);
138
- this._emitDelay = (1000 * delay) / this.container.retina.reduceFactor;
141
+ this._emitDelay = (delay * millisecondsToSeconds) / this.container.retina.reduceFactor;
139
142
  }
140
- if (this._lifeCount > 0 || this._immortal) {
143
+ if (this._lifeCount > minLifeCount || this._immortal) {
141
144
  this._prepareToDie();
142
145
  }
143
146
  }
@@ -157,8 +160,8 @@ export class EmitterInstance {
157
160
  }
158
161
  if (this._firstSpawn) {
159
162
  this._firstSpawn = false;
160
- this._currentSpawnDelay = this._spawnDelay ?? 0;
161
- this._currentEmitDelay = this._emitDelay ?? 0;
163
+ this._currentSpawnDelay = this._spawnDelay ?? defaultSpawnDelay;
164
+ this._currentEmitDelay = this._emitDelay ?? defaultEmitDelay;
162
165
  }
163
166
  if (!this._startParticlesAdded) {
164
167
  this._startParticlesAdded = true;
@@ -174,11 +177,12 @@ export class EmitterInstance {
174
177
  if (!this._immortal) {
175
178
  this._lifeCount--;
176
179
  }
177
- if (this._lifeCount > 0 || this._immortal) {
180
+ if (this._lifeCount > minLifeCount || this._immortal) {
178
181
  this.position = this._calcPosition();
179
182
  this._shape?.resize(this.position, this.size);
180
183
  this._spawnDelay =
181
- (getRangeValue(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
184
+ (getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds) /
185
+ this.container.retina.reduceFactor;
182
186
  }
183
187
  else {
184
188
  this._destroy();
@@ -201,7 +205,7 @@ export class EmitterInstance {
201
205
  if (this._emitDelay !== undefined) {
202
206
  this._currentEmitDelay += delta.value;
203
207
  if (this._currentEmitDelay >= this._emitDelay) {
204
- this._emit();
208
+ await this._emit();
205
209
  this._currentEmitDelay -= this._emitDelay;
206
210
  }
207
211
  }
@@ -210,10 +214,10 @@ export class EmitterInstance {
210
214
  if (this.options.domId) {
211
215
  const container = this.container, element = document.getElementById(this.options.domId);
212
216
  if (element) {
213
- const elRect = element.getBoundingClientRect();
217
+ const elRect = element.getBoundingClientRect(), pxRatio = container.retina.pixelRatio;
214
218
  return {
215
- x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
216
- y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio,
219
+ x: (elRect.x + elRect.width * half) * pxRatio,
220
+ y: (elRect.y + elRect.height * half) * pxRatio,
217
221
  };
218
222
  }
219
223
  }
@@ -260,9 +264,14 @@ export class EmitterInstance {
260
264
  if (this.spawnColor) {
261
265
  const hslAnimation = this.options.spawnColor?.animation;
262
266
  if (hslAnimation) {
263
- this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
264
- this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
265
- this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
267
+ const maxValues = {
268
+ h: 360,
269
+ s: 100,
270
+ l: 100,
271
+ };
272
+ this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h);
273
+ this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
274
+ this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, maxValues.l);
266
275
  }
267
276
  setParticlesOptionsColor(particlesOptions, this.spawnColor);
268
277
  }
@@ -14,8 +14,9 @@ export class Emitters {
14
14
  },
15
15
  value: [],
16
16
  };
17
+ const defaultIndex = 0;
17
18
  container.getEmitter = (idxOrName) => idxOrName === undefined || isNumber(idxOrName)
18
- ? this.array[idxOrName || 0]
19
+ ? this.array[idxOrName ?? defaultIndex]
19
20
  : this.array.find((t) => t.name === idxOrName);
20
21
  container.addEmitter = async (options, position) => this.addEmitter(options, position);
21
22
  container.removeEmitter = (idxOrName) => {
@@ -52,7 +53,8 @@ export class Emitters {
52
53
  }
53
54
  let emittersModeOptions;
54
55
  if (modeEmitters && isArray(modeEmitters.value)) {
55
- if (modeEmitters.value.length > 0 && modeEmitters.random.enable) {
56
+ const minLength = 0;
57
+ if (modeEmitters.value.length > minLength && modeEmitters.random.enable) {
56
58
  emittersModeOptions = [];
57
59
  const usedIndexes = [];
58
60
  for (let i = 0; i < modeEmitters.random.count; i++) {
@@ -73,8 +75,8 @@ export class Emitters {
73
75
  emittersModeOptions = modeEmitters?.value;
74
76
  }
75
77
  const emittersOptions = emittersModeOptions ?? emitterOptions, ePosition = this.container.interactivity.mouse.clickPosition;
76
- executeOnSingleOrMultiple(emittersOptions, (emitter) => {
77
- this.addEmitter(emitter, ePosition);
78
+ void executeOnSingleOrMultiple(emittersOptions, async (emitter) => {
79
+ await this.addEmitter(emitter, ePosition);
78
80
  });
79
81
  }
80
82
  async init() {
@@ -103,9 +105,9 @@ export class Emitters {
103
105
  }
104
106
  }
105
107
  removeEmitter(emitter) {
106
- const index = this.array.indexOf(emitter);
107
- if (index >= 0) {
108
- this.array.splice(index, 1);
108
+ const index = this.array.indexOf(emitter), minIndex = 0, deleteCount = 1;
109
+ if (index >= minIndex) {
110
+ this.array.splice(index, deleteCount);
109
111
  }
110
112
  }
111
113
  resize() {
package/browser/index.js CHANGED
@@ -39,10 +39,11 @@ class EmittersPlugin {
39
39
  else {
40
40
  const emitterMode = interactivityEmitters;
41
41
  if (emitterMode.value !== undefined) {
42
+ const defaultCount = 1;
42
43
  if (isArray(emitterMode.value)) {
43
44
  options.interactivity.modes.emitters = {
44
45
  random: {
45
- count: emitterMode.random.count ?? 1,
46
+ count: emitterMode.random.count ?? defaultCount,
46
47
  enable: emitterMode.random.enable ?? false,
47
48
  },
48
49
  value: emitterMode.value.map((s) => {
@@ -57,7 +58,7 @@ class EmittersPlugin {
57
58
  tmp.load(emitterMode.value);
58
59
  options.interactivity.modes.emitters = {
59
60
  random: {
60
- count: emitterMode.random.count ?? 1,
61
+ count: emitterMode.random.count ?? defaultCount,
61
62
  enable: emitterMode.random.enable ?? false,
62
63
  },
63
64
  value: tmp,
@@ -4,6 +4,7 @@ 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
+ const half = 0.5, defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1;
7
8
  function setParticlesOptionsColor(particlesOptions, color) {
8
9
  if (particlesOptions.color) {
9
10
  particlesOptions.color.value = color;
@@ -35,12 +36,12 @@ class EmitterInstance {
35
36
  if (this._paused) {
36
37
  return;
37
38
  }
38
- const duration = this.options.life?.duration !== undefined ? (0, engine_1.getRangeValue)(this.options.life.duration) : undefined;
39
+ const duration = this.options.life?.duration !== undefined ? (0, engine_1.getRangeValue)(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
39
40
  if (this.container.retina.reduceFactor &&
40
- (this._lifeCount > 0 || this._immortal) &&
41
+ (this._lifeCount > minLifeCount || this._immortal) &&
41
42
  duration !== undefined &&
42
- duration > 0) {
43
- this._duration = duration * 1000;
43
+ duration > minDuration) {
44
+ this._duration = duration * engine_1.millisecondsToSeconds;
44
45
  }
45
46
  };
46
47
  this._setColorAnimation = (animation, initValue, maxValue) => {
@@ -48,8 +49,8 @@ class EmitterInstance {
48
49
  if (!animation.enable) {
49
50
  return initValue;
50
51
  }
51
- const colorOffset = (0, engine_1.randomInRange)(animation.offset), delay = (0, engine_1.getRangeValue)(this.options.rate.delay), emitFactor = (1000 * delay) / container.retina.reduceFactor, colorSpeed = (0, engine_1.getRangeValue)(animation.speed ?? 0);
52
- return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * 3.6) % maxValue;
52
+ const colorOffset = (0, engine_1.randomInRange)(animation.offset), delay = (0, engine_1.getRangeValue)(this.options.rate.delay), emitFactor = (delay * engine_1.millisecondsToSeconds) / container.retina.reduceFactor, defaultColorSpeed = 0, colorFactor = 3.6, colorSpeed = (0, engine_1.getRangeValue)(animation.speed ?? defaultColorSpeed);
53
+ return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * colorFactor) % maxValue;
53
54
  };
54
55
  this._engine = engine;
55
56
  this._currentDuration = 0;
@@ -63,7 +64,9 @@ class EmitterInstance {
63
64
  this.options = new Emitter_js_1.Emitter();
64
65
  this.options.load(options);
65
66
  }
66
- this._spawnDelay = ((0, engine_1.getRangeValue)(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
67
+ this._spawnDelay =
68
+ ((0, engine_1.getRangeValue)(this.options.life.delay ?? defaultLifeDelay) * engine_1.millisecondsToSeconds) /
69
+ this.container.retina.reduceFactor;
67
70
  this.position = this._initialPosition ?? this._calcPosition();
68
71
  this.name = this.options.name;
69
72
  this.fill = this.options.fill;
@@ -80,8 +83,8 @@ class EmitterInstance {
80
83
  this._particlesOptions = particlesOptions;
81
84
  this._size = this._calcSize();
82
85
  this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size);
83
- this._lifeCount = this.options.life.count ?? -1;
84
- this._immortal = this._lifeCount <= 0;
86
+ this._lifeCount = this.options.life.count ?? defaultLifeCount;
87
+ this._immortal = this._lifeCount <= minLifeCount;
85
88
  if (this.options.domId) {
86
89
  const element = document.getElementById(this.options.domId);
87
90
  if (element) {
@@ -132,15 +135,15 @@ class EmitterInstance {
132
135
  return;
133
136
  }
134
137
  if (!(this.container.retina.reduceFactor &&
135
- (this._lifeCount > 0 || this._immortal || !this.options.life.count) &&
136
- (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? 0)))) {
138
+ (this._lifeCount > minLifeCount || this._immortal || !this.options.life.count) &&
139
+ (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? defaultSpawnDelay)))) {
137
140
  return;
138
141
  }
139
142
  if (this._emitDelay === undefined) {
140
143
  const delay = (0, engine_1.getRangeValue)(this.options.rate.delay);
141
- this._emitDelay = (1000 * delay) / this.container.retina.reduceFactor;
144
+ this._emitDelay = (delay * engine_1.millisecondsToSeconds) / this.container.retina.reduceFactor;
142
145
  }
143
- if (this._lifeCount > 0 || this._immortal) {
146
+ if (this._lifeCount > minLifeCount || this._immortal) {
144
147
  this._prepareToDie();
145
148
  }
146
149
  }
@@ -160,8 +163,8 @@ class EmitterInstance {
160
163
  }
161
164
  if (this._firstSpawn) {
162
165
  this._firstSpawn = false;
163
- this._currentSpawnDelay = this._spawnDelay ?? 0;
164
- this._currentEmitDelay = this._emitDelay ?? 0;
166
+ this._currentSpawnDelay = this._spawnDelay ?? defaultSpawnDelay;
167
+ this._currentEmitDelay = this._emitDelay ?? defaultEmitDelay;
165
168
  }
166
169
  if (!this._startParticlesAdded) {
167
170
  this._startParticlesAdded = true;
@@ -177,11 +180,12 @@ class EmitterInstance {
177
180
  if (!this._immortal) {
178
181
  this._lifeCount--;
179
182
  }
180
- if (this._lifeCount > 0 || this._immortal) {
183
+ if (this._lifeCount > minLifeCount || this._immortal) {
181
184
  this.position = this._calcPosition();
182
185
  this._shape?.resize(this.position, this.size);
183
186
  this._spawnDelay =
184
- ((0, engine_1.getRangeValue)(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
187
+ ((0, engine_1.getRangeValue)(this.options.life.delay ?? defaultLifeDelay) * engine_1.millisecondsToSeconds) /
188
+ this.container.retina.reduceFactor;
185
189
  }
186
190
  else {
187
191
  this._destroy();
@@ -204,7 +208,7 @@ class EmitterInstance {
204
208
  if (this._emitDelay !== undefined) {
205
209
  this._currentEmitDelay += delta.value;
206
210
  if (this._currentEmitDelay >= this._emitDelay) {
207
- this._emit();
211
+ await this._emit();
208
212
  this._currentEmitDelay -= this._emitDelay;
209
213
  }
210
214
  }
@@ -213,10 +217,10 @@ class EmitterInstance {
213
217
  if (this.options.domId) {
214
218
  const container = this.container, element = document.getElementById(this.options.domId);
215
219
  if (element) {
216
- const elRect = element.getBoundingClientRect();
220
+ const elRect = element.getBoundingClientRect(), pxRatio = container.retina.pixelRatio;
217
221
  return {
218
- x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
219
- y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio,
222
+ x: (elRect.x + elRect.width * half) * pxRatio,
223
+ y: (elRect.y + elRect.height * half) * pxRatio,
220
224
  };
221
225
  }
222
226
  }
@@ -263,9 +267,14 @@ class EmitterInstance {
263
267
  if (this.spawnColor) {
264
268
  const hslAnimation = this.options.spawnColor?.animation;
265
269
  if (hslAnimation) {
266
- this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
267
- this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
268
- this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
270
+ const maxValues = {
271
+ h: 360,
272
+ s: 100,
273
+ l: 100,
274
+ };
275
+ this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h);
276
+ this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
277
+ this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, maxValues.l);
269
278
  }
270
279
  setParticlesOptionsColor(particlesOptions, this.spawnColor);
271
280
  }
package/cjs/Emitters.js CHANGED
@@ -17,8 +17,9 @@ class Emitters {
17
17
  },
18
18
  value: [],
19
19
  };
20
+ const defaultIndex = 0;
20
21
  container.getEmitter = (idxOrName) => idxOrName === undefined || (0, engine_1.isNumber)(idxOrName)
21
- ? this.array[idxOrName || 0]
22
+ ? this.array[idxOrName ?? defaultIndex]
22
23
  : this.array.find((t) => t.name === idxOrName);
23
24
  container.addEmitter = async (options, position) => this.addEmitter(options, position);
24
25
  container.removeEmitter = (idxOrName) => {
@@ -55,7 +56,8 @@ class Emitters {
55
56
  }
56
57
  let emittersModeOptions;
57
58
  if (modeEmitters && (0, engine_1.isArray)(modeEmitters.value)) {
58
- if (modeEmitters.value.length > 0 && modeEmitters.random.enable) {
59
+ const minLength = 0;
60
+ if (modeEmitters.value.length > minLength && modeEmitters.random.enable) {
59
61
  emittersModeOptions = [];
60
62
  const usedIndexes = [];
61
63
  for (let i = 0; i < modeEmitters.random.count; i++) {
@@ -76,8 +78,8 @@ class Emitters {
76
78
  emittersModeOptions = modeEmitters?.value;
77
79
  }
78
80
  const emittersOptions = emittersModeOptions ?? emitterOptions, ePosition = this.container.interactivity.mouse.clickPosition;
79
- (0, engine_1.executeOnSingleOrMultiple)(emittersOptions, (emitter) => {
80
- this.addEmitter(emitter, ePosition);
81
+ void (0, engine_1.executeOnSingleOrMultiple)(emittersOptions, async (emitter) => {
82
+ await this.addEmitter(emitter, ePosition);
81
83
  });
82
84
  }
83
85
  async init() {
@@ -106,9 +108,9 @@ class Emitters {
106
108
  }
107
109
  }
108
110
  removeEmitter(emitter) {
109
- const index = this.array.indexOf(emitter);
110
- if (index >= 0) {
111
- this.array.splice(index, 1);
111
+ const index = this.array.indexOf(emitter), minIndex = 0, deleteCount = 1;
112
+ if (index >= minIndex) {
113
+ this.array.splice(index, deleteCount);
112
114
  }
113
115
  }
114
116
  resize() {
package/cjs/index.js CHANGED
@@ -56,10 +56,11 @@ class EmittersPlugin {
56
56
  else {
57
57
  const emitterMode = interactivityEmitters;
58
58
  if (emitterMode.value !== undefined) {
59
+ const defaultCount = 1;
59
60
  if ((0, engine_1.isArray)(emitterMode.value)) {
60
61
  options.interactivity.modes.emitters = {
61
62
  random: {
62
- count: emitterMode.random.count ?? 1,
63
+ count: emitterMode.random.count ?? defaultCount,
63
64
  enable: emitterMode.random.enable ?? false,
64
65
  },
65
66
  value: emitterMode.value.map((s) => {
@@ -74,7 +75,7 @@ class EmittersPlugin {
74
75
  tmp.load(emitterMode.value);
75
76
  options.interactivity.modes.emitters = {
76
77
  random: {
77
- count: emitterMode.random.count ?? 1,
78
+ count: emitterMode.random.count ?? defaultCount,
78
79
  enable: emitterMode.random.enable ?? false,
79
80
  },
80
81
  value: tmp,
@@ -1,6 +1,7 @@
1
- import { Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, isPointInside, itemFromSingleOrMultiple, randomInRange, rangeColorToHsl, } from "@tsparticles/engine";
1
+ import { Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, isPointInside, itemFromSingleOrMultiple, millisecondsToSeconds, randomInRange, rangeColorToHsl, } from "@tsparticles/engine";
2
2
  import { Emitter } from "./Options/Classes/Emitter.js";
3
3
  import { EmitterSize } from "./Options/Classes/EmitterSize.js";
4
+ const half = 0.5, defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1;
4
5
  function setParticlesOptionsColor(particlesOptions, color) {
5
6
  if (particlesOptions.color) {
6
7
  particlesOptions.color.value = color;
@@ -32,12 +33,12 @@ export class EmitterInstance {
32
33
  if (this._paused) {
33
34
  return;
34
35
  }
35
- const duration = this.options.life?.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined;
36
+ const duration = this.options.life?.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
36
37
  if (this.container.retina.reduceFactor &&
37
- (this._lifeCount > 0 || this._immortal) &&
38
+ (this._lifeCount > minLifeCount || this._immortal) &&
38
39
  duration !== undefined &&
39
- duration > 0) {
40
- this._duration = duration * 1000;
40
+ duration > minDuration) {
41
+ this._duration = duration * millisecondsToSeconds;
41
42
  }
42
43
  };
43
44
  this._setColorAnimation = (animation, initValue, maxValue) => {
@@ -45,8 +46,8 @@ export class EmitterInstance {
45
46
  if (!animation.enable) {
46
47
  return initValue;
47
48
  }
48
- const colorOffset = randomInRange(animation.offset), delay = getRangeValue(this.options.rate.delay), emitFactor = (1000 * delay) / container.retina.reduceFactor, colorSpeed = getRangeValue(animation.speed ?? 0);
49
- return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * 3.6) % maxValue;
49
+ const colorOffset = randomInRange(animation.offset), delay = getRangeValue(this.options.rate.delay), emitFactor = (delay * millisecondsToSeconds) / container.retina.reduceFactor, defaultColorSpeed = 0, colorFactor = 3.6, colorSpeed = getRangeValue(animation.speed ?? defaultColorSpeed);
50
+ return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * colorFactor) % maxValue;
50
51
  };
51
52
  this._engine = engine;
52
53
  this._currentDuration = 0;
@@ -60,7 +61,9 @@ export class EmitterInstance {
60
61
  this.options = new Emitter();
61
62
  this.options.load(options);
62
63
  }
63
- this._spawnDelay = (getRangeValue(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
64
+ this._spawnDelay =
65
+ (getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds) /
66
+ this.container.retina.reduceFactor;
64
67
  this.position = this._initialPosition ?? this._calcPosition();
65
68
  this.name = this.options.name;
66
69
  this.fill = this.options.fill;
@@ -77,8 +80,8 @@ export class EmitterInstance {
77
80
  this._particlesOptions = particlesOptions;
78
81
  this._size = this._calcSize();
79
82
  this.size = getSize(this._size, this.container.canvas.size);
80
- this._lifeCount = this.options.life.count ?? -1;
81
- this._immortal = this._lifeCount <= 0;
83
+ this._lifeCount = this.options.life.count ?? defaultLifeCount;
84
+ this._immortal = this._lifeCount <= minLifeCount;
82
85
  if (this.options.domId) {
83
86
  const element = document.getElementById(this.options.domId);
84
87
  if (element) {
@@ -129,15 +132,15 @@ export class EmitterInstance {
129
132
  return;
130
133
  }
131
134
  if (!(this.container.retina.reduceFactor &&
132
- (this._lifeCount > 0 || this._immortal || !this.options.life.count) &&
133
- (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? 0)))) {
135
+ (this._lifeCount > minLifeCount || this._immortal || !this.options.life.count) &&
136
+ (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? defaultSpawnDelay)))) {
134
137
  return;
135
138
  }
136
139
  if (this._emitDelay === undefined) {
137
140
  const delay = getRangeValue(this.options.rate.delay);
138
- this._emitDelay = (1000 * delay) / this.container.retina.reduceFactor;
141
+ this._emitDelay = (delay * millisecondsToSeconds) / this.container.retina.reduceFactor;
139
142
  }
140
- if (this._lifeCount > 0 || this._immortal) {
143
+ if (this._lifeCount > minLifeCount || this._immortal) {
141
144
  this._prepareToDie();
142
145
  }
143
146
  }
@@ -157,8 +160,8 @@ export class EmitterInstance {
157
160
  }
158
161
  if (this._firstSpawn) {
159
162
  this._firstSpawn = false;
160
- this._currentSpawnDelay = this._spawnDelay ?? 0;
161
- this._currentEmitDelay = this._emitDelay ?? 0;
163
+ this._currentSpawnDelay = this._spawnDelay ?? defaultSpawnDelay;
164
+ this._currentEmitDelay = this._emitDelay ?? defaultEmitDelay;
162
165
  }
163
166
  if (!this._startParticlesAdded) {
164
167
  this._startParticlesAdded = true;
@@ -174,11 +177,12 @@ export class EmitterInstance {
174
177
  if (!this._immortal) {
175
178
  this._lifeCount--;
176
179
  }
177
- if (this._lifeCount > 0 || this._immortal) {
180
+ if (this._lifeCount > minLifeCount || this._immortal) {
178
181
  this.position = this._calcPosition();
179
182
  this._shape?.resize(this.position, this.size);
180
183
  this._spawnDelay =
181
- (getRangeValue(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
184
+ (getRangeValue(this.options.life.delay ?? defaultLifeDelay) * millisecondsToSeconds) /
185
+ this.container.retina.reduceFactor;
182
186
  }
183
187
  else {
184
188
  this._destroy();
@@ -201,7 +205,7 @@ export class EmitterInstance {
201
205
  if (this._emitDelay !== undefined) {
202
206
  this._currentEmitDelay += delta.value;
203
207
  if (this._currentEmitDelay >= this._emitDelay) {
204
- this._emit();
208
+ await this._emit();
205
209
  this._currentEmitDelay -= this._emitDelay;
206
210
  }
207
211
  }
@@ -210,10 +214,10 @@ export class EmitterInstance {
210
214
  if (this.options.domId) {
211
215
  const container = this.container, element = document.getElementById(this.options.domId);
212
216
  if (element) {
213
- const elRect = element.getBoundingClientRect();
217
+ const elRect = element.getBoundingClientRect(), pxRatio = container.retina.pixelRatio;
214
218
  return {
215
- x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
216
- y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio,
219
+ x: (elRect.x + elRect.width * half) * pxRatio,
220
+ y: (elRect.y + elRect.height * half) * pxRatio,
217
221
  };
218
222
  }
219
223
  }
@@ -260,9 +264,14 @@ export class EmitterInstance {
260
264
  if (this.spawnColor) {
261
265
  const hslAnimation = this.options.spawnColor?.animation;
262
266
  if (hslAnimation) {
263
- this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
264
- this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
265
- this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
267
+ const maxValues = {
268
+ h: 360,
269
+ s: 100,
270
+ l: 100,
271
+ };
272
+ this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h);
273
+ this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
274
+ this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, maxValues.l);
266
275
  }
267
276
  setParticlesOptionsColor(particlesOptions, this.spawnColor);
268
277
  }
package/esm/Emitters.js CHANGED
@@ -14,8 +14,9 @@ export class Emitters {
14
14
  },
15
15
  value: [],
16
16
  };
17
+ const defaultIndex = 0;
17
18
  container.getEmitter = (idxOrName) => idxOrName === undefined || isNumber(idxOrName)
18
- ? this.array[idxOrName || 0]
19
+ ? this.array[idxOrName ?? defaultIndex]
19
20
  : this.array.find((t) => t.name === idxOrName);
20
21
  container.addEmitter = async (options, position) => this.addEmitter(options, position);
21
22
  container.removeEmitter = (idxOrName) => {
@@ -52,7 +53,8 @@ export class Emitters {
52
53
  }
53
54
  let emittersModeOptions;
54
55
  if (modeEmitters && isArray(modeEmitters.value)) {
55
- if (modeEmitters.value.length > 0 && modeEmitters.random.enable) {
56
+ const minLength = 0;
57
+ if (modeEmitters.value.length > minLength && modeEmitters.random.enable) {
56
58
  emittersModeOptions = [];
57
59
  const usedIndexes = [];
58
60
  for (let i = 0; i < modeEmitters.random.count; i++) {
@@ -73,8 +75,8 @@ export class Emitters {
73
75
  emittersModeOptions = modeEmitters?.value;
74
76
  }
75
77
  const emittersOptions = emittersModeOptions ?? emitterOptions, ePosition = this.container.interactivity.mouse.clickPosition;
76
- executeOnSingleOrMultiple(emittersOptions, (emitter) => {
77
- this.addEmitter(emitter, ePosition);
78
+ void executeOnSingleOrMultiple(emittersOptions, async (emitter) => {
79
+ await this.addEmitter(emitter, ePosition);
78
80
  });
79
81
  }
80
82
  async init() {
@@ -103,9 +105,9 @@ export class Emitters {
103
105
  }
104
106
  }
105
107
  removeEmitter(emitter) {
106
- const index = this.array.indexOf(emitter);
107
- if (index >= 0) {
108
- this.array.splice(index, 1);
108
+ const index = this.array.indexOf(emitter), minIndex = 0, deleteCount = 1;
109
+ if (index >= minIndex) {
110
+ this.array.splice(index, deleteCount);
109
111
  }
110
112
  }
111
113
  resize() {
package/esm/index.js CHANGED
@@ -39,10 +39,11 @@ class EmittersPlugin {
39
39
  else {
40
40
  const emitterMode = interactivityEmitters;
41
41
  if (emitterMode.value !== undefined) {
42
+ const defaultCount = 1;
42
43
  if (isArray(emitterMode.value)) {
43
44
  options.interactivity.modes.emitters = {
44
45
  random: {
45
- count: emitterMode.random.count ?? 1,
46
+ count: emitterMode.random.count ?? defaultCount,
46
47
  enable: emitterMode.random.enable ?? false,
47
48
  },
48
49
  value: emitterMode.value.map((s) => {
@@ -57,7 +58,7 @@ class EmittersPlugin {
57
58
  tmp.load(emitterMode.value);
58
59
  options.interactivity.modes.emitters = {
59
60
  random: {
60
- count: emitterMode.random.count ?? 1,
61
+ count: emitterMode.random.count ?? defaultCount,
61
62
  enable: emitterMode.random.enable ?? false,
62
63
  },
63
64
  value: tmp,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/plugin-emitters",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "tsParticles emitters plugin",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -86,7 +86,7 @@
86
86
  "./package.json": "./package.json"
87
87
  },
88
88
  "dependencies": {
89
- "@tsparticles/engine": "^3.0.2"
89
+ "@tsparticles/engine": "^3.1.0"
90
90
  },
91
91
  "publishConfig": {
92
92
  "access": "public"
package/report.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8"/>
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
6
- <title>@tsparticles/plugin-emitters [6 Dec 2023 at 17:42]</title>
6
+ <title>@tsparticles/plugin-emitters [13 Jan 2024 at 23:04]</title>
7
7
  <link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
8
8
 
9
9
  <script>
@@ -31,7 +31,7 @@
31
31
  <body>
32
32
  <div id="app"></div>
33
33
  <script>
34
- window.chartData = [{"label":"tsparticles.plugin.emitters.js","isAsset":true,"statSize":21910,"parsedSize":25750,"gzipSize":5437,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":21868,"groups":[{"id":211,"label":"index.js + 10 modules (concatenated)","path":"./dist/browser/index.js + 10 modules (concatenated)","statSize":21868,"parsedSize":25750,"gzipSize":5437,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser","statSize":21868,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/index.js","statSize":3436,"parsedSize":4045,"gzipSize":854,"inaccurateSizes":true},{"id":null,"label":"Emitters.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Emitters.js","statSize":3709,"parsedSize":4367,"gzipSize":922,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes","statSize":3971,"groups":[{"id":null,"label":"Emitter.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/Emitter.js","statSize":1813,"parsedSize":2134,"gzipSize":450,"inaccurateSizes":true},{"id":null,"label":"EmitterLife.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterLife.js","statSize":510,"parsedSize":600,"gzipSize":126,"inaccurateSizes":true},{"id":null,"label":"EmitterRate.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterRate.js","statSize":402,"parsedSize":473,"gzipSize":99,"inaccurateSizes":true},{"id":null,"label":"EmitterShape.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterShape.js","statSize":524,"parsedSize":617,"gzipSize":130,"inaccurateSizes":true},{"id":null,"label":"EmitterSize.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterSize.js","statSize":406,"parsedSize":478,"gzipSize":100,"inaccurateSizes":true},{"id":null,"label":"EmitterShapeReplace.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterShapeReplace.js","statSize":316,"parsedSize":372,"gzipSize":78,"inaccurateSizes":true}],"parsedSize":4675,"gzipSize":987,"inaccurateSizes":true},{"id":null,"label":"ShapeManager.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/ShapeManager.js","statSize":400,"parsedSize":471,"gzipSize":99,"inaccurateSizes":true},{"id":null,"label":"EmitterShapeBase.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/EmitterShapeBase.js","statSize":269,"parsedSize":316,"gzipSize":66,"inaccurateSizes":true},{"id":null,"label":"EmitterInstance.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/EmitterInstance.js","statSize":10083,"parsedSize":11872,"gzipSize":2506,"inaccurateSizes":true}],"parsedSize":25750,"gzipSize":5437,"inaccurateSizes":true}]}],"parsedSize":25750,"gzipSize":5437},{"label":"engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":533,"label":"engine\",\"root\":\"window\"}","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles/engine\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"tsparticles.plugin.emitters":true}}];
34
+ window.chartData = [{"label":"tsparticles.plugin.emitters.js","isAsset":true,"statSize":22797,"parsedSize":26714,"gzipSize":5627,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":22755,"groups":[{"id":959,"label":"index.js + 10 modules (concatenated)","path":"./dist/browser/index.js + 10 modules (concatenated)","statSize":22755,"parsedSize":26714,"gzipSize":5627,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser","statSize":22755,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/index.js","statSize":3492,"parsedSize":4099,"gzipSize":863,"inaccurateSizes":true},{"id":null,"label":"Emitters.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Emitters.js","statSize":3860,"parsedSize":4531,"gzipSize":954,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes","statSize":3971,"groups":[{"id":null,"label":"Emitter.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/Emitter.js","statSize":1813,"parsedSize":2128,"gzipSize":448,"inaccurateSizes":true},{"id":null,"label":"EmitterLife.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterLife.js","statSize":510,"parsedSize":598,"gzipSize":126,"inaccurateSizes":true},{"id":null,"label":"EmitterRate.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterRate.js","statSize":402,"parsedSize":471,"gzipSize":99,"inaccurateSizes":true},{"id":null,"label":"EmitterShape.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterShape.js","statSize":524,"parsedSize":615,"gzipSize":129,"inaccurateSizes":true},{"id":null,"label":"EmitterSize.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterSize.js","statSize":406,"parsedSize":476,"gzipSize":100,"inaccurateSizes":true},{"id":null,"label":"EmitterShapeReplace.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/Options/Classes/EmitterShapeReplace.js","statSize":316,"parsedSize":370,"gzipSize":78,"inaccurateSizes":true}],"parsedSize":4661,"gzipSize":981,"inaccurateSizes":true},{"id":null,"label":"ShapeManager.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/ShapeManager.js","statSize":400,"parsedSize":469,"gzipSize":98,"inaccurateSizes":true},{"id":null,"label":"EmitterShapeBase.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/EmitterShapeBase.js","statSize":269,"parsedSize":315,"gzipSize":66,"inaccurateSizes":true},{"id":null,"label":"EmitterInstance.js","path":"./dist/browser/index.js + 10 modules (concatenated)/dist/browser/EmitterInstance.js","statSize":10763,"parsedSize":12635,"gzipSize":2661,"inaccurateSizes":true}],"parsedSize":26714,"gzipSize":5627,"inaccurateSizes":true}]}],"parsedSize":26714,"gzipSize":5627},{"label":"engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":533,"label":"engine\",\"root\":\"window\"}","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles/engine\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"tsparticles.plugin.emitters":true}}];
35
35
  window.entrypoints = ["tsparticles.plugin.emitters","tsparticles.plugin.emitters.min"];
36
36
  window.defaultSizes = "parsed";
37
37
  </script>
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v3.0.2
7
+ * v3.1.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -268,6 +268,12 @@ class Emitter {
268
268
 
269
269
 
270
270
 
271
+ const half = 0.5,
272
+ defaultLifeDelay = 0,
273
+ minLifeCount = 0,
274
+ defaultSpawnDelay = 0,
275
+ defaultEmitDelay = 0,
276
+ defaultLifeCount = -1;
271
277
  function setParticlesOptionsColor(particlesOptions, color) {
272
278
  if (particlesOptions.color) {
273
279
  particlesOptions.color.value = color;
@@ -298,9 +304,11 @@ class EmitterInstance {
298
304
  if (this._paused) {
299
305
  return;
300
306
  }
301
- const duration = this.options.life?.duration !== undefined ? (0,engine_root_window_.getRangeValue)(this.options.life.duration) : undefined;
302
- if (this.container.retina.reduceFactor && (this._lifeCount > 0 || this._immortal) && duration !== undefined && duration > 0) {
303
- this._duration = duration * 1000;
307
+ const duration = this.options.life?.duration !== undefined ? (0,engine_root_window_.getRangeValue)(this.options.life.duration) : undefined,
308
+ minDuration = 0,
309
+ minLifeCount = 0;
310
+ if (this.container.retina.reduceFactor && (this._lifeCount > minLifeCount || this._immortal) && duration !== undefined && duration > minDuration) {
311
+ this._duration = duration * engine_root_window_.millisecondsToSeconds;
304
312
  }
305
313
  };
306
314
  this._setColorAnimation = (animation, initValue, maxValue) => {
@@ -310,9 +318,11 @@ class EmitterInstance {
310
318
  }
311
319
  const colorOffset = (0,engine_root_window_.randomInRange)(animation.offset),
312
320
  delay = (0,engine_root_window_.getRangeValue)(this.options.rate.delay),
313
- emitFactor = 1000 * delay / container.retina.reduceFactor,
314
- colorSpeed = (0,engine_root_window_.getRangeValue)(animation.speed ?? 0);
315
- return (initValue + colorSpeed * container.fpsLimit / emitFactor + colorOffset * 3.6) % maxValue;
321
+ emitFactor = delay * engine_root_window_.millisecondsToSeconds / container.retina.reduceFactor,
322
+ defaultColorSpeed = 0,
323
+ colorFactor = 3.6,
324
+ colorSpeed = (0,engine_root_window_.getRangeValue)(animation.speed ?? defaultColorSpeed);
325
+ return (initValue + colorSpeed * container.fpsLimit / emitFactor + colorOffset * colorFactor) % maxValue;
316
326
  };
317
327
  this._engine = engine;
318
328
  this._currentDuration = 0;
@@ -325,7 +335,7 @@ class EmitterInstance {
325
335
  this.options = new Emitter();
326
336
  this.options.load(options);
327
337
  }
328
- this._spawnDelay = (0,engine_root_window_.getRangeValue)(this.options.life.delay ?? 0) * 1000 / this.container.retina.reduceFactor;
338
+ this._spawnDelay = (0,engine_root_window_.getRangeValue)(this.options.life.delay ?? defaultLifeDelay) * engine_root_window_.millisecondsToSeconds / this.container.retina.reduceFactor;
329
339
  this.position = this._initialPosition ?? this._calcPosition();
330
340
  this.name = this.options.name;
331
341
  this.fill = this.options.fill;
@@ -342,8 +352,8 @@ class EmitterInstance {
342
352
  this._particlesOptions = particlesOptions;
343
353
  this._size = this._calcSize();
344
354
  this.size = (0,engine_root_window_.getSize)(this._size, this.container.canvas.size);
345
- this._lifeCount = this.options.life.count ?? -1;
346
- this._immortal = this._lifeCount <= 0;
355
+ this._lifeCount = this.options.life.count ?? defaultLifeCount;
356
+ this._immortal = this._lifeCount <= minLifeCount;
347
357
  if (this.options.domId) {
348
358
  const element = document.getElementById(this.options.domId);
349
359
  if (element) {
@@ -394,14 +404,14 @@ class EmitterInstance {
394
404
  if (this._paused) {
395
405
  return;
396
406
  }
397
- if (!(this.container.retina.reduceFactor && (this._lifeCount > 0 || this._immortal || !this.options.life.count) && (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? 0)))) {
407
+ if (!(this.container.retina.reduceFactor && (this._lifeCount > minLifeCount || this._immortal || !this.options.life.count) && (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? defaultSpawnDelay)))) {
398
408
  return;
399
409
  }
400
410
  if (this._emitDelay === undefined) {
401
411
  const delay = (0,engine_root_window_.getRangeValue)(this.options.rate.delay);
402
- this._emitDelay = 1000 * delay / this.container.retina.reduceFactor;
412
+ this._emitDelay = delay * engine_root_window_.millisecondsToSeconds / this.container.retina.reduceFactor;
403
413
  }
404
- if (this._lifeCount > 0 || this._immortal) {
414
+ if (this._lifeCount > minLifeCount || this._immortal) {
405
415
  this._prepareToDie();
406
416
  }
407
417
  }
@@ -418,8 +428,8 @@ class EmitterInstance {
418
428
  }
419
429
  if (this._firstSpawn) {
420
430
  this._firstSpawn = false;
421
- this._currentSpawnDelay = this._spawnDelay ?? 0;
422
- this._currentEmitDelay = this._emitDelay ?? 0;
431
+ this._currentSpawnDelay = this._spawnDelay ?? defaultSpawnDelay;
432
+ this._currentEmitDelay = this._emitDelay ?? defaultEmitDelay;
423
433
  }
424
434
  if (!this._startParticlesAdded) {
425
435
  this._startParticlesAdded = true;
@@ -435,10 +445,10 @@ class EmitterInstance {
435
445
  if (!this._immortal) {
436
446
  this._lifeCount--;
437
447
  }
438
- if (this._lifeCount > 0 || this._immortal) {
448
+ if (this._lifeCount > minLifeCount || this._immortal) {
439
449
  this.position = this._calcPosition();
440
450
  this._shape?.resize(this.position, this.size);
441
- this._spawnDelay = (0,engine_root_window_.getRangeValue)(this.options.life.delay ?? 0) * 1000 / this.container.retina.reduceFactor;
451
+ this._spawnDelay = (0,engine_root_window_.getRangeValue)(this.options.life.delay ?? defaultLifeDelay) * engine_root_window_.millisecondsToSeconds / this.container.retina.reduceFactor;
442
452
  } else {
443
453
  this._destroy();
444
454
  }
@@ -460,7 +470,7 @@ class EmitterInstance {
460
470
  if (this._emitDelay !== undefined) {
461
471
  this._currentEmitDelay += delta.value;
462
472
  if (this._currentEmitDelay >= this._emitDelay) {
463
- this._emit();
473
+ await this._emit();
464
474
  this._currentEmitDelay -= this._emitDelay;
465
475
  }
466
476
  }
@@ -470,10 +480,11 @@ class EmitterInstance {
470
480
  const container = this.container,
471
481
  element = document.getElementById(this.options.domId);
472
482
  if (element) {
473
- const elRect = element.getBoundingClientRect();
483
+ const elRect = element.getBoundingClientRect(),
484
+ pxRatio = container.retina.pixelRatio;
474
485
  return {
475
- x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
476
- y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio
486
+ x: (elRect.x + elRect.width * half) * pxRatio,
487
+ y: (elRect.y + elRect.height * half) * pxRatio
477
488
  };
478
489
  }
479
490
  }
@@ -519,9 +530,14 @@ class EmitterInstance {
519
530
  if (this.spawnColor) {
520
531
  const hslAnimation = this.options.spawnColor?.animation;
521
532
  if (hslAnimation) {
522
- this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
523
- this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
524
- this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
533
+ const maxValues = {
534
+ h: 360,
535
+ s: 100,
536
+ l: 100
537
+ };
538
+ this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h);
539
+ this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
540
+ this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, maxValues.l);
525
541
  }
526
542
  setParticlesOptionsColor(particlesOptions, this.spawnColor);
527
543
  }
@@ -571,7 +587,8 @@ class Emitters {
571
587
  },
572
588
  value: []
573
589
  };
574
- container.getEmitter = idxOrName => idxOrName === undefined || (0,engine_root_window_.isNumber)(idxOrName) ? this.array[idxOrName || 0] : this.array.find(t => t.name === idxOrName);
590
+ const defaultIndex = 0;
591
+ container.getEmitter = idxOrName => idxOrName === undefined || (0,engine_root_window_.isNumber)(idxOrName) ? this.array[idxOrName ?? defaultIndex] : this.array.find(t => t.name === idxOrName);
575
592
  container.addEmitter = async (options, position) => this.addEmitter(options, position);
576
593
  container.removeEmitter = idxOrName => {
577
594
  const emitter = container.getEmitter(idxOrName);
@@ -608,7 +625,8 @@ class Emitters {
608
625
  }
609
626
  let emittersModeOptions;
610
627
  if (modeEmitters && (0,engine_root_window_.isArray)(modeEmitters.value)) {
611
- if (modeEmitters.value.length > 0 && modeEmitters.random.enable) {
628
+ const minLength = 0;
629
+ if (modeEmitters.value.length > minLength && modeEmitters.random.enable) {
612
630
  emittersModeOptions = [];
613
631
  const usedIndexes = [];
614
632
  for (let i = 0; i < modeEmitters.random.count; i++) {
@@ -628,8 +646,8 @@ class Emitters {
628
646
  }
629
647
  const emittersOptions = emittersModeOptions ?? emitterOptions,
630
648
  ePosition = this.container.interactivity.mouse.clickPosition;
631
- (0,engine_root_window_.executeOnSingleOrMultiple)(emittersOptions, emitter => {
632
- this.addEmitter(emitter, ePosition);
649
+ void (0,engine_root_window_.executeOnSingleOrMultiple)(emittersOptions, async emitter => {
650
+ await this.addEmitter(emitter, ePosition);
633
651
  });
634
652
  }
635
653
  async init() {
@@ -657,9 +675,11 @@ class Emitters {
657
675
  }
658
676
  }
659
677
  removeEmitter(emitter) {
660
- const index = this.array.indexOf(emitter);
661
- if (index >= 0) {
662
- this.array.splice(index, 1);
678
+ const index = this.array.indexOf(emitter),
679
+ minIndex = 0,
680
+ deleteCount = 1;
681
+ if (index >= minIndex) {
682
+ this.array.splice(index, deleteCount);
663
683
  }
664
684
  }
665
685
  resize() {
@@ -748,10 +768,11 @@ class EmittersPlugin {
748
768
  } else {
749
769
  const emitterMode = interactivityEmitters;
750
770
  if (emitterMode.value !== undefined) {
771
+ const defaultCount = 1;
751
772
  if ((0,engine_root_window_.isArray)(emitterMode.value)) {
752
773
  options.interactivity.modes.emitters = {
753
774
  random: {
754
- count: emitterMode.random.count ?? 1,
775
+ count: emitterMode.random.count ?? defaultCount,
755
776
  enable: emitterMode.random.enable ?? false
756
777
  },
757
778
  value: emitterMode.value.map(s => {
@@ -765,7 +786,7 @@ class EmittersPlugin {
765
786
  tmp.load(emitterMode.value);
766
787
  options.interactivity.modes.emitters = {
767
788
  random: {
768
- count: emitterMode.random.count ?? 1,
789
+ count: emitterMode.random.count ?? defaultCount,
769
790
  enable: emitterMode.random.enable ?? false
770
791
  },
771
792
  value: tmp
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see tsparticles.plugin.emitters.min.js.LICENSE.txt */
2
- !function(t,i){if("object"==typeof exports&&"object"==typeof module)module.exports=i(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],i);else{var e="object"==typeof exports?i(require("@tsparticles/engine")):i(t.window);for(var s in e)("object"==typeof exports?exports:t)[s]=e[s]}}(this,(t=>(()=>{"use strict";var i={533:i=>{i.exports=t}},e={};function s(t){var o=e[t];if(void 0!==o)return o.exports;var n=e[t]={exports:{}};return i[t](n,n.exports,s),n.exports}s.d=(t,i)=>{for(var e in i)s.o(i,e)&&!s.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:i[e]})},s.o=(t,i)=>Object.prototype.hasOwnProperty.call(t,i),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};return(()=>{s.r(o),s.d(o,{EmitterShapeBase:()=>m,loadEmittersPlugin:()=>_});var t=s(533);class i{constructor(){this.wait=!1}load(i){i&&(void 0!==i.count&&(this.count=i.count),void 0!==i.delay&&(this.delay=(0,t.setRangeValue)(i.delay)),void 0!==i.duration&&(this.duration=(0,t.setRangeValue)(i.duration)),void 0!==i.wait&&(this.wait=i.wait))}}class e{constructor(){this.quantity=1,this.delay=.1}load(i){void 0!==i&&(void 0!==i.quantity&&(this.quantity=(0,t.setRangeValue)(i.quantity)),void 0!==i.delay&&(this.delay=(0,t.setRangeValue)(i.delay)))}}class n{constructor(){this.color=!1,this.opacity=!1}load(t){t&&(void 0!==t.color&&(this.color=t.color),void 0!==t.opacity&&(this.opacity=t.opacity))}}class a{constructor(){this.options={},this.replace=new n,this.type="square"}load(i){i&&(void 0!==i.options&&(this.options=(0,t.deepExtend)({},i.options??{})),this.replace.load(i.replace),void 0!==i.type&&(this.type=i.type))}}class r{constructor(){this.mode="percent",this.height=0,this.width=0}load(t){void 0!==t&&(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}class h{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new i,this.rate=new e,this.shape=new a,this.startCount=0}load(i){i&&(void 0!==i.autoPlay&&(this.autoPlay=i.autoPlay),void 0!==i.size&&(this.size||(this.size=new r),this.size.load(i.size)),void 0!==i.direction&&(this.direction=i.direction),this.domId=i.domId,void 0!==i.fill&&(this.fill=i.fill),this.life.load(i.life),this.name=i.name,this.particles=(0,t.executeOnSingleOrMultiple)(i.particles,(i=>(0,t.deepExtend)({},i))),this.rate.load(i.rate),this.shape.load(i.shape),void 0!==i.position&&(this.position={},void 0!==i.position.x&&(this.position.x=(0,t.setRangeValue)(i.position.x)),void 0!==i.position.y&&(this.position.y=(0,t.setRangeValue)(i.position.y))),void 0!==i.spawnColor&&(void 0===this.spawnColor&&(this.spawnColor=new t.AnimatableColor),this.spawnColor.load(i.spawnColor)),void 0!==i.startCount&&(this.startCount=i.startCount))}}function l(t,i){t.color?t.color.value=i:t.color={value:i}}class c{constructor(i,e,s,o,n){this.emitters=e,this.container=s,this._destroy=()=>{this._mutationObserver?.disconnect(),this._mutationObserver=void 0,this._resizeObserver?.disconnect(),this._resizeObserver=void 0,this.emitters.removeEmitter(this),this._engine.dispatchEvent("emitterDestroyed",{container:this.container,data:{emitter:this}})},this._prepareToDie=()=>{if(this._paused)return;const i=void 0!==this.options.life?.duration?(0,t.getRangeValue)(this.options.life.duration):void 0;this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal)&&void 0!==i&&i>0&&(this._duration=1e3*i)},this._setColorAnimation=(i,e,s)=>{const o=this.container;if(!i.enable)return e;const n=(0,t.randomInRange)(i.offset),a=1e3*(0,t.getRangeValue)(this.options.rate.delay)/o.retina.reduceFactor;return(e+(0,t.getRangeValue)(i.speed??0)*o.fpsLimit/a+3.6*n)%s},this._engine=i,this._currentDuration=0,this._currentEmitDelay=0,this._currentSpawnDelay=0,this._initialPosition=n,o instanceof h?this.options=o:(this.options=new h,this.options.load(o)),this._spawnDelay=1e3*(0,t.getRangeValue)(this.options.life.delay??0)/this.container.retina.reduceFactor,this.position=this._initialPosition??this._calcPosition(),this.name=this.options.name,this.fill=this.options.fill,this._firstSpawn=!this.options.life.wait,this._startParticlesAdded=!1;let a=(0,t.deepExtend)({},this.options.particles);if(a??={},a.move??={},a.move.direction??=this.options.direction,this.options.spawnColor&&(this.spawnColor=(0,t.rangeColorToHsl)(this.options.spawnColor)),this._paused=!this.options.autoPlay,this._particlesOptions=a,this._size=this._calcSize(),this.size=(0,t.getSize)(this._size,this.container.canvas.size),this._lifeCount=this.options.life.count??-1,this._immortal=this._lifeCount<=0,this.options.domId){const t=document.getElementById(this.options.domId);t&&(this._mutationObserver=new MutationObserver((()=>{this.resize()})),this._resizeObserver=new ResizeObserver((()=>{this.resize()})),this._mutationObserver.observe(t,{attributes:!0,attributeFilter:["style","width","height"]}),this._resizeObserver.observe(t))}const r=this.options.shape,l=this._engine.emitterShapeManager?.getShapeGenerator(r.type);l&&(this._shape=l.generate(this.position,this.size,this.fill,r.options)),this._engine.dispatchEvent("emitterCreated",{container:s,data:{emitter:this}}),this.play()}externalPause(){this._paused=!0,this.pause()}externalPlay(){this._paused=!1,this.play()}async init(){await(this._shape?.init())}pause(){this._paused||delete this._emitDelay}play(){if(!this._paused&&this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal||!this.options.life.count)&&(this._firstSpawn||this._currentSpawnDelay>=(this._spawnDelay??0))){if(void 0===this._emitDelay){const i=(0,t.getRangeValue)(this.options.rate.delay);this._emitDelay=1e3*i/this.container.retina.reduceFactor}(this._lifeCount>0||this._immortal)&&this._prepareToDie()}}resize(){const i=this._initialPosition;this.position=i&&(0,t.isPointInside)(i,this.container.canvas.size,t.Vector.origin)?i:this._calcPosition(),this._size=this._calcSize(),this.size=(0,t.getSize)(this._size,this.container.canvas.size),this._shape?.resize(this.position,this.size)}async update(i){this._paused||(this._firstSpawn&&(this._firstSpawn=!1,this._currentSpawnDelay=this._spawnDelay??0,this._currentEmitDelay=this._emitDelay??0),this._startParticlesAdded||(this._startParticlesAdded=!0,await this._emitParticles(this.options.startCount)),void 0!==this._duration&&(this._currentDuration+=i.value,this._currentDuration>=this._duration&&(this.pause(),void 0!==this._spawnDelay&&delete this._spawnDelay,this._immortal||this._lifeCount--,this._lifeCount>0||this._immortal?(this.position=this._calcPosition(),this._shape?.resize(this.position,this.size),this._spawnDelay=1e3*(0,t.getRangeValue)(this.options.life.delay??0)/this.container.retina.reduceFactor):this._destroy(),this._currentDuration-=this._duration,delete this._duration)),void 0!==this._spawnDelay&&(this._currentSpawnDelay+=i.value,this._currentSpawnDelay>=this._spawnDelay&&(this._engine.dispatchEvent("emitterPlay",{container:this.container}),this.play(),this._currentSpawnDelay-=this._currentSpawnDelay,delete this._spawnDelay)),void 0!==this._emitDelay&&(this._currentEmitDelay+=i.value,this._currentEmitDelay>=this._emitDelay&&(this._emit(),this._currentEmitDelay-=this._emitDelay)))}_calcPosition(){if(this.options.domId){const t=this.container,i=document.getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect();return{x:(e.x+e.width/2)*t.retina.pixelRatio,y:(e.y+e.height/2)*t.retina.pixelRatio}}}return(0,t.calcPositionOrRandomFromSizeRanged)({size:this.container.canvas.size,position:this.options.position})}_calcSize(){const t=this.container;if(this.options.domId){const i=document.getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect();return{width:e.width*t.retina.pixelRatio,height:e.height*t.retina.pixelRatio,mode:"precise"}}}return this.options.size??(()=>{const t=new r;return t.load({height:0,mode:"percent",width:0}),t})()}async _emit(){if(this._paused)return;const i=(0,t.getRangeValue)(this.options.rate.quantity);await this._emitParticles(i)}async _emitParticles(i){const e=(0,t.itemFromSingleOrMultiple)(this._particlesOptions);for(let s=0;s<i;s++){const i=(0,t.deepExtend)({},e);if(this.spawnColor){const t=this.options.spawnColor?.animation;t&&(this.spawnColor.h=this._setColorAnimation(t.h,this.spawnColor.h,360),this.spawnColor.s=this._setColorAnimation(t.s,this.spawnColor.s,100),this.spawnColor.l=this._setColorAnimation(t.l,this.spawnColor.l,100)),l(i,this.spawnColor)}const s=this.options.shape;let o=this.position;if(this._shape){const t=await this._shape.randomPosition();if(t){o=t.position;const e=s.replace;e.color&&t.color&&l(i,t.color),e.opacity&&(i.opacity?i.opacity.value=t.opacity:i.opacity={value:t.opacity})}else o=null}o&&this.container.particles.addParticle(o,i)}}}class d{constructor(i,e){this.container=e,this._engine=i,this.array=[],this.emitters=[],this.interactivityEmitters={random:{count:1,enable:!1},value:[]},e.getEmitter=i=>void 0===i||(0,t.isNumber)(i)?this.array[i||0]:this.array.find((t=>t.name===i)),e.addEmitter=async(t,i)=>this.addEmitter(t,i),e.removeEmitter=t=>{const i=e.getEmitter(t);i&&this.removeEmitter(i)},e.playEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPlay()},e.pauseEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPause()}}async addEmitter(t,i){const e=new h;e.load(t);const s=new c(this._engine,this,this.container,e,i);return await s.init(),this.array.push(s),s}handleClickMode(i){const e=this.emitters,s=this.interactivityEmitters;if("emitter"!==i)return;let o;if(s&&(0,t.isArray)(s.value))if(s.value.length>0&&s.random.enable){o=[];const i=[];for(let e=0;e<s.random.count;e++){const n=(0,t.arrayRandomIndex)(s.value);i.includes(n)&&i.length<s.value.length?e--:(i.push(n),o.push((0,t.itemFromArray)(s.value,n)))}}else o=s.value;else o=s?.value;const n=o??e,a=this.container.interactivity.mouse.clickPosition;(0,t.executeOnSingleOrMultiple)(n,(t=>{this.addEmitter(t,a)}))}async init(){if(this.emitters=this.container.actualOptions.emitters,this.interactivityEmitters=this.container.actualOptions.interactivity.modes.emitters,this.emitters)if((0,t.isArray)(this.emitters))for(const t of this.emitters)await this.addEmitter(t);else await this.addEmitter(this.emitters)}pause(){for(const t of this.array)t.pause()}play(){for(const t of this.array)t.play()}removeEmitter(t){const i=this.array.indexOf(t);i>=0&&this.array.splice(i,1)}resize(){for(const t of this.array)t.resize()}stop(){this.array=[]}async update(t){for(const i of this.array)await i.update(t)}}const p=new Map;class u{constructor(t){this._engine=t}addShapeGenerator(t,i){this.getShapeGenerator(t)||p.set(t,i)}getShapeGenerator(t){return p.get(t)}getSupportedShapeGenerators(){return p.keys()}}class m{constructor(t,i,e,s){this.position=t,this.size=i,this.fill=e,this.options=s}resize(t,i){this.position=t,this.size=i}}class y{constructor(t){this._engine=t,this.id="emitters"}getPlugin(t){return new d(this._engine,t)}loadOptions(i,e){if(!this.needsPlugin(i)&&!this.needsPlugin(e))return;e?.emitters&&(i.emitters=(0,t.executeOnSingleOrMultiple)(e.emitters,(t=>{const i=new h;return i.load(t),i})));const s=e?.interactivity?.modes?.emitters;if(s)if((0,t.isArray)(s))i.interactivity.modes.emitters={random:{count:1,enable:!0},value:s.map((t=>{const i=new h;return i.load(t),i}))};else{const e=s;if(void 0!==e.value)if((0,t.isArray)(e.value))i.interactivity.modes.emitters={random:{count:e.random.count??1,enable:e.random.enable??!1},value:e.value.map((t=>{const i=new h;return i.load(t),i}))};else{const t=new h;t.load(e.value),i.interactivity.modes.emitters={random:{count:e.random.count??1,enable:e.random.enable??!1},value:t}}else{(i.interactivity.modes.emitters={random:{count:1,enable:!1},value:new h}).value.load(s)}}}needsPlugin(i){if(!i)return!1;const e=i.emitters;return(0,t.isArray)(e)&&!!e.length||void 0!==e||!!i.interactivity?.events?.onClick?.mode&&(0,t.isInArray)("emitter",i.interactivity.events.onClick.mode)}}async function _(t,i=!0){t.emitterShapeManager||(t.emitterShapeManager=new u(t)),t.addEmitterShapeGenerator||(t.addEmitterShapeGenerator=(i,e)=>{t.emitterShapeManager?.addShapeGenerator(i,e)});const e=new y(t);await t.addPlugin(e,i)}})(),o})()));
2
+ !function(t,i){if("object"==typeof exports&&"object"==typeof module)module.exports=i(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],i);else{var e="object"==typeof exports?i(require("@tsparticles/engine")):i(t.window);for(var s in e)("object"==typeof exports?exports:t)[s]=e[s]}}(this,(t=>(()=>{"use strict";var i={533:i=>{i.exports=t}},e={};function s(t){var o=e[t];if(void 0!==o)return o.exports;var n=e[t]={exports:{}};return i[t](n,n.exports,s),n.exports}s.d=(t,i)=>{for(var e in i)s.o(i,e)&&!s.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:i[e]})},s.o=(t,i)=>Object.prototype.hasOwnProperty.call(t,i),s.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})};var o={};return(()=>{s.r(o),s.d(o,{EmitterShapeBase:()=>m,loadEmittersPlugin:()=>_});var t=s(533);class i{constructor(){this.wait=!1}load(i){i&&(void 0!==i.count&&(this.count=i.count),void 0!==i.delay&&(this.delay=(0,t.setRangeValue)(i.delay)),void 0!==i.duration&&(this.duration=(0,t.setRangeValue)(i.duration)),void 0!==i.wait&&(this.wait=i.wait))}}class e{constructor(){this.quantity=1,this.delay=.1}load(i){void 0!==i&&(void 0!==i.quantity&&(this.quantity=(0,t.setRangeValue)(i.quantity)),void 0!==i.delay&&(this.delay=(0,t.setRangeValue)(i.delay)))}}class n{constructor(){this.color=!1,this.opacity=!1}load(t){t&&(void 0!==t.color&&(this.color=t.color),void 0!==t.opacity&&(this.opacity=t.opacity))}}class a{constructor(){this.options={},this.replace=new n,this.type="square"}load(i){i&&(void 0!==i.options&&(this.options=(0,t.deepExtend)({},i.options??{})),this.replace.load(i.replace),void 0!==i.type&&(this.type=i.type))}}class r{constructor(){this.mode="percent",this.height=0,this.width=0}load(t){void 0!==t&&(void 0!==t.mode&&(this.mode=t.mode),void 0!==t.height&&(this.height=t.height),void 0!==t.width&&(this.width=t.width))}}class h{constructor(){this.autoPlay=!0,this.fill=!0,this.life=new i,this.rate=new e,this.shape=new a,this.startCount=0}load(i){i&&(void 0!==i.autoPlay&&(this.autoPlay=i.autoPlay),void 0!==i.size&&(this.size||(this.size=new r),this.size.load(i.size)),void 0!==i.direction&&(this.direction=i.direction),this.domId=i.domId,void 0!==i.fill&&(this.fill=i.fill),this.life.load(i.life),this.name=i.name,this.particles=(0,t.executeOnSingleOrMultiple)(i.particles,(i=>(0,t.deepExtend)({},i))),this.rate.load(i.rate),this.shape.load(i.shape),void 0!==i.position&&(this.position={},void 0!==i.position.x&&(this.position.x=(0,t.setRangeValue)(i.position.x)),void 0!==i.position.y&&(this.position.y=(0,t.setRangeValue)(i.position.y))),void 0!==i.spawnColor&&(void 0===this.spawnColor&&(this.spawnColor=new t.AnimatableColor),this.spawnColor.load(i.spawnColor)),void 0!==i.startCount&&(this.startCount=i.startCount))}}function l(t,i){t.color?t.color.value=i:t.color={value:i}}class c{constructor(i,e,s,o,n){this.emitters=e,this.container=s,this._destroy=()=>{this._mutationObserver?.disconnect(),this._mutationObserver=void 0,this._resizeObserver?.disconnect(),this._resizeObserver=void 0,this.emitters.removeEmitter(this),this._engine.dispatchEvent("emitterDestroyed",{container:this.container,data:{emitter:this}})},this._prepareToDie=()=>{if(this._paused)return;const i=void 0!==this.options.life?.duration?(0,t.getRangeValue)(this.options.life.duration):void 0;this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal)&&void 0!==i&&i>0&&(this._duration=i*t.millisecondsToSeconds)},this._setColorAnimation=(i,e,s)=>{const o=this.container;if(!i.enable)return e;const n=(0,t.randomInRange)(i.offset),a=(0,t.getRangeValue)(this.options.rate.delay)*t.millisecondsToSeconds/o.retina.reduceFactor;return(e+(0,t.getRangeValue)(i.speed??0)*o.fpsLimit/a+3.6*n)%s},this._engine=i,this._currentDuration=0,this._currentEmitDelay=0,this._currentSpawnDelay=0,this._initialPosition=n,o instanceof h?this.options=o:(this.options=new h,this.options.load(o)),this._spawnDelay=(0,t.getRangeValue)(this.options.life.delay??0)*t.millisecondsToSeconds/this.container.retina.reduceFactor,this.position=this._initialPosition??this._calcPosition(),this.name=this.options.name,this.fill=this.options.fill,this._firstSpawn=!this.options.life.wait,this._startParticlesAdded=!1;let a=(0,t.deepExtend)({},this.options.particles);if(a??={},a.move??={},a.move.direction??=this.options.direction,this.options.spawnColor&&(this.spawnColor=(0,t.rangeColorToHsl)(this.options.spawnColor)),this._paused=!this.options.autoPlay,this._particlesOptions=a,this._size=this._calcSize(),this.size=(0,t.getSize)(this._size,this.container.canvas.size),this._lifeCount=this.options.life.count??-1,this._immortal=this._lifeCount<=0,this.options.domId){const t=document.getElementById(this.options.domId);t&&(this._mutationObserver=new MutationObserver((()=>{this.resize()})),this._resizeObserver=new ResizeObserver((()=>{this.resize()})),this._mutationObserver.observe(t,{attributes:!0,attributeFilter:["style","width","height"]}),this._resizeObserver.observe(t))}const r=this.options.shape,l=this._engine.emitterShapeManager?.getShapeGenerator(r.type);l&&(this._shape=l.generate(this.position,this.size,this.fill,r.options)),this._engine.dispatchEvent("emitterCreated",{container:s,data:{emitter:this}}),this.play()}externalPause(){this._paused=!0,this.pause()}externalPlay(){this._paused=!1,this.play()}async init(){await(this._shape?.init())}pause(){this._paused||delete this._emitDelay}play(){if(!this._paused&&this.container.retina.reduceFactor&&(this._lifeCount>0||this._immortal||!this.options.life.count)&&(this._firstSpawn||this._currentSpawnDelay>=(this._spawnDelay??0))){if(void 0===this._emitDelay){const i=(0,t.getRangeValue)(this.options.rate.delay);this._emitDelay=i*t.millisecondsToSeconds/this.container.retina.reduceFactor}(this._lifeCount>0||this._immortal)&&this._prepareToDie()}}resize(){const i=this._initialPosition;this.position=i&&(0,t.isPointInside)(i,this.container.canvas.size,t.Vector.origin)?i:this._calcPosition(),this._size=this._calcSize(),this.size=(0,t.getSize)(this._size,this.container.canvas.size),this._shape?.resize(this.position,this.size)}async update(i){this._paused||(this._firstSpawn&&(this._firstSpawn=!1,this._currentSpawnDelay=this._spawnDelay??0,this._currentEmitDelay=this._emitDelay??0),this._startParticlesAdded||(this._startParticlesAdded=!0,await this._emitParticles(this.options.startCount)),void 0!==this._duration&&(this._currentDuration+=i.value,this._currentDuration>=this._duration&&(this.pause(),void 0!==this._spawnDelay&&delete this._spawnDelay,this._immortal||this._lifeCount--,this._lifeCount>0||this._immortal?(this.position=this._calcPosition(),this._shape?.resize(this.position,this.size),this._spawnDelay=(0,t.getRangeValue)(this.options.life.delay??0)*t.millisecondsToSeconds/this.container.retina.reduceFactor):this._destroy(),this._currentDuration-=this._duration,delete this._duration)),void 0!==this._spawnDelay&&(this._currentSpawnDelay+=i.value,this._currentSpawnDelay>=this._spawnDelay&&(this._engine.dispatchEvent("emitterPlay",{container:this.container}),this.play(),this._currentSpawnDelay-=this._currentSpawnDelay,delete this._spawnDelay)),void 0!==this._emitDelay&&(this._currentEmitDelay+=i.value,this._currentEmitDelay>=this._emitDelay&&(await this._emit(),this._currentEmitDelay-=this._emitDelay)))}_calcPosition(){if(this.options.domId){const t=this.container,i=document.getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect(),s=t.retina.pixelRatio;return{x:(e.x+.5*e.width)*s,y:(e.y+.5*e.height)*s}}}return(0,t.calcPositionOrRandomFromSizeRanged)({size:this.container.canvas.size,position:this.options.position})}_calcSize(){const t=this.container;if(this.options.domId){const i=document.getElementById(this.options.domId);if(i){const e=i.getBoundingClientRect();return{width:e.width*t.retina.pixelRatio,height:e.height*t.retina.pixelRatio,mode:"precise"}}}return this.options.size??(()=>{const t=new r;return t.load({height:0,mode:"percent",width:0}),t})()}async _emit(){if(this._paused)return;const i=(0,t.getRangeValue)(this.options.rate.quantity);await this._emitParticles(i)}async _emitParticles(i){const e=(0,t.itemFromSingleOrMultiple)(this._particlesOptions);for(let s=0;s<i;s++){const i=(0,t.deepExtend)({},e);if(this.spawnColor){const t=this.options.spawnColor?.animation;if(t){const i={h:360,s:100,l:100};this.spawnColor.h=this._setColorAnimation(t.h,this.spawnColor.h,i.h),this.spawnColor.s=this._setColorAnimation(t.s,this.spawnColor.s,i.s),this.spawnColor.l=this._setColorAnimation(t.l,this.spawnColor.l,i.l)}l(i,this.spawnColor)}const s=this.options.shape;let o=this.position;if(this._shape){const t=await this._shape.randomPosition();if(t){o=t.position;const e=s.replace;e.color&&t.color&&l(i,t.color),e.opacity&&(i.opacity?i.opacity.value=t.opacity:i.opacity={value:t.opacity})}else o=null}o&&this.container.particles.addParticle(o,i)}}}class d{constructor(i,e){this.container=e,this._engine=i,this.array=[],this.emitters=[],this.interactivityEmitters={random:{count:1,enable:!1},value:[]};e.getEmitter=i=>void 0===i||(0,t.isNumber)(i)?this.array[i??0]:this.array.find((t=>t.name===i)),e.addEmitter=async(t,i)=>this.addEmitter(t,i),e.removeEmitter=t=>{const i=e.getEmitter(t);i&&this.removeEmitter(i)},e.playEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPlay()},e.pauseEmitter=t=>{const i=e.getEmitter(t);i&&i.externalPause()}}async addEmitter(t,i){const e=new h;e.load(t);const s=new c(this._engine,this,this.container,e,i);return await s.init(),this.array.push(s),s}handleClickMode(i){const e=this.emitters,s=this.interactivityEmitters;if("emitter"!==i)return;let o;if(s&&(0,t.isArray)(s.value)){const i=0;if(s.value.length>i&&s.random.enable){o=[];const i=[];for(let e=0;e<s.random.count;e++){const n=(0,t.arrayRandomIndex)(s.value);i.includes(n)&&i.length<s.value.length?e--:(i.push(n),o.push((0,t.itemFromArray)(s.value,n)))}}else o=s.value}else o=s?.value;const n=o??e,a=this.container.interactivity.mouse.clickPosition;(0,t.executeOnSingleOrMultiple)(n,(async t=>{await this.addEmitter(t,a)}))}async init(){if(this.emitters=this.container.actualOptions.emitters,this.interactivityEmitters=this.container.actualOptions.interactivity.modes.emitters,this.emitters)if((0,t.isArray)(this.emitters))for(const t of this.emitters)await this.addEmitter(t);else await this.addEmitter(this.emitters)}pause(){for(const t of this.array)t.pause()}play(){for(const t of this.array)t.play()}removeEmitter(t){const i=this.array.indexOf(t);i>=0&&this.array.splice(i,1)}resize(){for(const t of this.array)t.resize()}stop(){this.array=[]}async update(t){for(const i of this.array)await i.update(t)}}const p=new Map;class u{constructor(t){this._engine=t}addShapeGenerator(t,i){this.getShapeGenerator(t)||p.set(t,i)}getShapeGenerator(t){return p.get(t)}getSupportedShapeGenerators(){return p.keys()}}class m{constructor(t,i,e,s){this.position=t,this.size=i,this.fill=e,this.options=s}resize(t,i){this.position=t,this.size=i}}class y{constructor(t){this._engine=t,this.id="emitters"}getPlugin(t){return new d(this._engine,t)}loadOptions(i,e){if(!this.needsPlugin(i)&&!this.needsPlugin(e))return;e?.emitters&&(i.emitters=(0,t.executeOnSingleOrMultiple)(e.emitters,(t=>{const i=new h;return i.load(t),i})));const s=e?.interactivity?.modes?.emitters;if(s)if((0,t.isArray)(s))i.interactivity.modes.emitters={random:{count:1,enable:!0},value:s.map((t=>{const i=new h;return i.load(t),i}))};else{const e=s;if(void 0!==e.value){const s=1;if((0,t.isArray)(e.value))i.interactivity.modes.emitters={random:{count:e.random.count??s,enable:e.random.enable??!1},value:e.value.map((t=>{const i=new h;return i.load(t),i}))};else{const t=new h;t.load(e.value),i.interactivity.modes.emitters={random:{count:e.random.count??s,enable:e.random.enable??!1},value:t}}}else{(i.interactivity.modes.emitters={random:{count:1,enable:!1},value:new h}).value.load(s)}}}needsPlugin(i){if(!i)return!1;const e=i.emitters;return(0,t.isArray)(e)&&!!e.length||void 0!==e||!!i.interactivity?.events?.onClick?.mode&&(0,t.isInArray)("emitter",i.interactivity.events.onClick.mode)}}async function _(t,i=!0){t.emitterShapeManager||(t.emitterShapeManager=new u(t)),t.addEmitterShapeGenerator||(t.addEmitterShapeGenerator=(i,e)=>{t.emitterShapeManager?.addShapeGenerator(i,e)});const e=new y(t);await t.addPlugin(e,i)}})(),o})()));
@@ -1 +1 @@
1
- /*! tsParticles Emitters Plugin v3.0.2 by Matteo Bruni */
1
+ /*! tsParticles Emitters Plugin v3.1.0 by Matteo Bruni */
@@ -13,6 +13,7 @@
13
13
  const engine_1 = require("@tsparticles/engine");
14
14
  const Emitter_js_1 = require("./Options/Classes/Emitter.js");
15
15
  const EmitterSize_js_1 = require("./Options/Classes/EmitterSize.js");
16
+ const half = 0.5, defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1;
16
17
  function setParticlesOptionsColor(particlesOptions, color) {
17
18
  if (particlesOptions.color) {
18
19
  particlesOptions.color.value = color;
@@ -44,12 +45,12 @@
44
45
  if (this._paused) {
45
46
  return;
46
47
  }
47
- const duration = this.options.life?.duration !== undefined ? (0, engine_1.getRangeValue)(this.options.life.duration) : undefined;
48
+ const duration = this.options.life?.duration !== undefined ? (0, engine_1.getRangeValue)(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
48
49
  if (this.container.retina.reduceFactor &&
49
- (this._lifeCount > 0 || this._immortal) &&
50
+ (this._lifeCount > minLifeCount || this._immortal) &&
50
51
  duration !== undefined &&
51
- duration > 0) {
52
- this._duration = duration * 1000;
52
+ duration > minDuration) {
53
+ this._duration = duration * engine_1.millisecondsToSeconds;
53
54
  }
54
55
  };
55
56
  this._setColorAnimation = (animation, initValue, maxValue) => {
@@ -57,8 +58,8 @@
57
58
  if (!animation.enable) {
58
59
  return initValue;
59
60
  }
60
- const colorOffset = (0, engine_1.randomInRange)(animation.offset), delay = (0, engine_1.getRangeValue)(this.options.rate.delay), emitFactor = (1000 * delay) / container.retina.reduceFactor, colorSpeed = (0, engine_1.getRangeValue)(animation.speed ?? 0);
61
- return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * 3.6) % maxValue;
61
+ const colorOffset = (0, engine_1.randomInRange)(animation.offset), delay = (0, engine_1.getRangeValue)(this.options.rate.delay), emitFactor = (delay * engine_1.millisecondsToSeconds) / container.retina.reduceFactor, defaultColorSpeed = 0, colorFactor = 3.6, colorSpeed = (0, engine_1.getRangeValue)(animation.speed ?? defaultColorSpeed);
62
+ return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * colorFactor) % maxValue;
62
63
  };
63
64
  this._engine = engine;
64
65
  this._currentDuration = 0;
@@ -72,7 +73,9 @@
72
73
  this.options = new Emitter_js_1.Emitter();
73
74
  this.options.load(options);
74
75
  }
75
- this._spawnDelay = ((0, engine_1.getRangeValue)(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
76
+ this._spawnDelay =
77
+ ((0, engine_1.getRangeValue)(this.options.life.delay ?? defaultLifeDelay) * engine_1.millisecondsToSeconds) /
78
+ this.container.retina.reduceFactor;
76
79
  this.position = this._initialPosition ?? this._calcPosition();
77
80
  this.name = this.options.name;
78
81
  this.fill = this.options.fill;
@@ -89,8 +92,8 @@
89
92
  this._particlesOptions = particlesOptions;
90
93
  this._size = this._calcSize();
91
94
  this.size = (0, engine_1.getSize)(this._size, this.container.canvas.size);
92
- this._lifeCount = this.options.life.count ?? -1;
93
- this._immortal = this._lifeCount <= 0;
95
+ this._lifeCount = this.options.life.count ?? defaultLifeCount;
96
+ this._immortal = this._lifeCount <= minLifeCount;
94
97
  if (this.options.domId) {
95
98
  const element = document.getElementById(this.options.domId);
96
99
  if (element) {
@@ -141,15 +144,15 @@
141
144
  return;
142
145
  }
143
146
  if (!(this.container.retina.reduceFactor &&
144
- (this._lifeCount > 0 || this._immortal || !this.options.life.count) &&
145
- (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? 0)))) {
147
+ (this._lifeCount > minLifeCount || this._immortal || !this.options.life.count) &&
148
+ (this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? defaultSpawnDelay)))) {
146
149
  return;
147
150
  }
148
151
  if (this._emitDelay === undefined) {
149
152
  const delay = (0, engine_1.getRangeValue)(this.options.rate.delay);
150
- this._emitDelay = (1000 * delay) / this.container.retina.reduceFactor;
153
+ this._emitDelay = (delay * engine_1.millisecondsToSeconds) / this.container.retina.reduceFactor;
151
154
  }
152
- if (this._lifeCount > 0 || this._immortal) {
155
+ if (this._lifeCount > minLifeCount || this._immortal) {
153
156
  this._prepareToDie();
154
157
  }
155
158
  }
@@ -169,8 +172,8 @@
169
172
  }
170
173
  if (this._firstSpawn) {
171
174
  this._firstSpawn = false;
172
- this._currentSpawnDelay = this._spawnDelay ?? 0;
173
- this._currentEmitDelay = this._emitDelay ?? 0;
175
+ this._currentSpawnDelay = this._spawnDelay ?? defaultSpawnDelay;
176
+ this._currentEmitDelay = this._emitDelay ?? defaultEmitDelay;
174
177
  }
175
178
  if (!this._startParticlesAdded) {
176
179
  this._startParticlesAdded = true;
@@ -186,11 +189,12 @@
186
189
  if (!this._immortal) {
187
190
  this._lifeCount--;
188
191
  }
189
- if (this._lifeCount > 0 || this._immortal) {
192
+ if (this._lifeCount > minLifeCount || this._immortal) {
190
193
  this.position = this._calcPosition();
191
194
  this._shape?.resize(this.position, this.size);
192
195
  this._spawnDelay =
193
- ((0, engine_1.getRangeValue)(this.options.life.delay ?? 0) * 1000) / this.container.retina.reduceFactor;
196
+ ((0, engine_1.getRangeValue)(this.options.life.delay ?? defaultLifeDelay) * engine_1.millisecondsToSeconds) /
197
+ this.container.retina.reduceFactor;
194
198
  }
195
199
  else {
196
200
  this._destroy();
@@ -213,7 +217,7 @@
213
217
  if (this._emitDelay !== undefined) {
214
218
  this._currentEmitDelay += delta.value;
215
219
  if (this._currentEmitDelay >= this._emitDelay) {
216
- this._emit();
220
+ await this._emit();
217
221
  this._currentEmitDelay -= this._emitDelay;
218
222
  }
219
223
  }
@@ -222,10 +226,10 @@
222
226
  if (this.options.domId) {
223
227
  const container = this.container, element = document.getElementById(this.options.domId);
224
228
  if (element) {
225
- const elRect = element.getBoundingClientRect();
229
+ const elRect = element.getBoundingClientRect(), pxRatio = container.retina.pixelRatio;
226
230
  return {
227
- x: (elRect.x + elRect.width / 2) * container.retina.pixelRatio,
228
- y: (elRect.y + elRect.height / 2) * container.retina.pixelRatio,
231
+ x: (elRect.x + elRect.width * half) * pxRatio,
232
+ y: (elRect.y + elRect.height * half) * pxRatio,
229
233
  };
230
234
  }
231
235
  }
@@ -272,9 +276,14 @@
272
276
  if (this.spawnColor) {
273
277
  const hslAnimation = this.options.spawnColor?.animation;
274
278
  if (hslAnimation) {
275
- this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, 360);
276
- this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, 100);
277
- this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, 100);
279
+ const maxValues = {
280
+ h: 360,
281
+ s: 100,
282
+ l: 100,
283
+ };
284
+ this.spawnColor.h = this._setColorAnimation(hslAnimation.h, this.spawnColor.h, maxValues.h);
285
+ this.spawnColor.s = this._setColorAnimation(hslAnimation.s, this.spawnColor.s, maxValues.s);
286
+ this.spawnColor.l = this._setColorAnimation(hslAnimation.l, this.spawnColor.l, maxValues.l);
278
287
  }
279
288
  setParticlesOptionsColor(particlesOptions, this.spawnColor);
280
289
  }
package/umd/Emitters.js CHANGED
@@ -26,8 +26,9 @@
26
26
  },
27
27
  value: [],
28
28
  };
29
+ const defaultIndex = 0;
29
30
  container.getEmitter = (idxOrName) => idxOrName === undefined || (0, engine_1.isNumber)(idxOrName)
30
- ? this.array[idxOrName || 0]
31
+ ? this.array[idxOrName ?? defaultIndex]
31
32
  : this.array.find((t) => t.name === idxOrName);
32
33
  container.addEmitter = async (options, position) => this.addEmitter(options, position);
33
34
  container.removeEmitter = (idxOrName) => {
@@ -64,7 +65,8 @@
64
65
  }
65
66
  let emittersModeOptions;
66
67
  if (modeEmitters && (0, engine_1.isArray)(modeEmitters.value)) {
67
- if (modeEmitters.value.length > 0 && modeEmitters.random.enable) {
68
+ const minLength = 0;
69
+ if (modeEmitters.value.length > minLength && modeEmitters.random.enable) {
68
70
  emittersModeOptions = [];
69
71
  const usedIndexes = [];
70
72
  for (let i = 0; i < modeEmitters.random.count; i++) {
@@ -85,8 +87,8 @@
85
87
  emittersModeOptions = modeEmitters?.value;
86
88
  }
87
89
  const emittersOptions = emittersModeOptions ?? emitterOptions, ePosition = this.container.interactivity.mouse.clickPosition;
88
- (0, engine_1.executeOnSingleOrMultiple)(emittersOptions, (emitter) => {
89
- this.addEmitter(emitter, ePosition);
90
+ void (0, engine_1.executeOnSingleOrMultiple)(emittersOptions, async (emitter) => {
91
+ await this.addEmitter(emitter, ePosition);
90
92
  });
91
93
  }
92
94
  async init() {
@@ -115,9 +117,9 @@
115
117
  }
116
118
  }
117
119
  removeEmitter(emitter) {
118
- const index = this.array.indexOf(emitter);
119
- if (index >= 0) {
120
- this.array.splice(index, 1);
120
+ const index = this.array.indexOf(emitter), minIndex = 0, deleteCount = 1;
121
+ if (index >= minIndex) {
122
+ this.array.splice(index, deleteCount);
121
123
  }
122
124
  }
123
125
  resize() {
package/umd/index.js CHANGED
@@ -65,10 +65,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
65
65
  else {
66
66
  const emitterMode = interactivityEmitters;
67
67
  if (emitterMode.value !== undefined) {
68
+ const defaultCount = 1;
68
69
  if ((0, engine_1.isArray)(emitterMode.value)) {
69
70
  options.interactivity.modes.emitters = {
70
71
  random: {
71
- count: emitterMode.random.count ?? 1,
72
+ count: emitterMode.random.count ?? defaultCount,
72
73
  enable: emitterMode.random.enable ?? false,
73
74
  },
74
75
  value: emitterMode.value.map((s) => {
@@ -83,7 +84,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
83
84
  tmp.load(emitterMode.value);
84
85
  options.interactivity.modes.emitters = {
85
86
  random: {
86
- count: emitterMode.random.count ?? 1,
87
+ count: emitterMode.random.count ?? defaultCount,
87
88
  enable: emitterMode.random.enable ?? false,
88
89
  },
89
90
  value: tmp,