@tsparticles/plugin-emitters 4.0.0-alpha.8 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/392.min.js +1 -0
- package/399.min.js +1 -0
- package/414.min.js +1 -0
- package/592.min.js +1 -0
- package/764.min.js +1 -0
- package/815.min.js +1 -0
- package/README.md +5 -0
- package/browser/EmitterInstance.js +121 -85
- package/browser/EmitterShapeBase.js +4 -0
- package/browser/EmittersInstancesManager.js +5 -3
- package/browser/EmittersInteractor.js +5 -1
- package/browser/EmittersPlugin.js +2 -1
- package/browser/EmittersPluginInstance.js +2 -0
- package/browser/Options/Classes/Emitter.js +25 -3
- package/browser/Options/Classes/EmitterLife.js +4 -0
- package/browser/Options/Classes/EmitterRate.js +2 -0
- package/browser/Options/Classes/EmitterShape.js +3 -0
- package/browser/Options/Classes/EmitterShapeReplace.js +2 -0
- package/browser/Options/Classes/EmitterSize.js +3 -0
- package/browser/Options/Classes/EmitterSpawn.js +18 -0
- package/browser/Options/Interfaces/IEmitterSpawn.js +1 -0
- package/browser/index.js +19 -9
- package/cjs/EmitterInstance.js +121 -85
- package/cjs/EmitterShapeBase.js +4 -0
- package/cjs/EmittersInstancesManager.js +5 -3
- package/cjs/EmittersInteractor.js +5 -1
- package/cjs/EmittersPlugin.js +2 -1
- package/cjs/EmittersPluginInstance.js +2 -0
- package/cjs/Options/Classes/Emitter.js +25 -3
- package/cjs/Options/Classes/EmitterLife.js +4 -0
- package/cjs/Options/Classes/EmitterRate.js +2 -0
- package/cjs/Options/Classes/EmitterShape.js +3 -0
- package/cjs/Options/Classes/EmitterShapeReplace.js +2 -0
- package/cjs/Options/Classes/EmitterSize.js +3 -0
- package/cjs/Options/Classes/EmitterSpawn.js +18 -0
- package/cjs/Options/Interfaces/IEmitterSpawn.js +1 -0
- package/cjs/index.js +19 -9
- package/dist_browser_EmitterInstance_js.js +2 -2
- package/dist_browser_EmittersInstancesManager_js.js +18 -8
- package/dist_browser_EmittersInteractor_js.js +19 -9
- package/dist_browser_EmittersPluginInstance_js.js +2 -2
- package/dist_browser_EmittersPlugin_js.js +18 -8
- package/dist_browser_ShapeManager_js.js +2 -2
- package/esm/EmitterInstance.js +121 -85
- package/esm/EmitterShapeBase.js +4 -0
- package/esm/EmittersInstancesManager.js +5 -3
- package/esm/EmittersInteractor.js +5 -1
- package/esm/EmittersPlugin.js +2 -1
- package/esm/EmittersPluginInstance.js +2 -0
- package/esm/Options/Classes/Emitter.js +25 -3
- package/esm/Options/Classes/EmitterLife.js +4 -0
- package/esm/Options/Classes/EmitterRate.js +2 -0
- package/esm/Options/Classes/EmitterShape.js +3 -0
- package/esm/Options/Classes/EmitterShapeReplace.js +2 -0
- package/esm/Options/Classes/EmitterSize.js +3 -0
- package/esm/Options/Classes/EmitterSpawn.js +18 -0
- package/esm/Options/Interfaces/IEmitterSpawn.js +1 -0
- package/esm/index.js +19 -9
- package/package.json +3 -3
- package/report.html +84 -29
- package/tsparticles.plugin.emitters.js +44 -32
- package/tsparticles.plugin.emitters.min.js +2 -2
- package/types/EmitterInstance.d.ts +11 -6
- package/types/EmittersEngine.d.ts +5 -2
- package/types/EmittersInstancesManager.d.ts +3 -3
- package/types/EmittersInteractor.d.ts +1 -0
- package/types/EmittersPlugin.d.ts +1 -1
- package/types/IEmitterShapeGenerator.d.ts +2 -2
- package/types/Options/Classes/Emitter.d.ts +4 -1
- package/types/Options/Classes/EmitterSpawn.d.ts +7 -0
- package/types/Options/Interfaces/IEmitter.d.ts +4 -1
- package/types/Options/Interfaces/IEmitterSpawn.d.ts +5 -0
- package/types/index.d.ts +1 -0
- package/umd/EmitterInstance.js +120 -84
- package/umd/EmitterShapeBase.js +4 -0
- package/umd/EmittersInstancesManager.js +5 -3
- package/umd/EmittersInteractor.js +5 -1
- package/umd/EmittersPlugin.js +2 -1
- package/umd/EmittersPluginInstance.js +2 -0
- package/umd/Options/Classes/Emitter.js +26 -4
- package/umd/Options/Classes/EmitterLife.js +4 -0
- package/umd/Options/Classes/EmitterRate.js +2 -0
- package/umd/Options/Classes/EmitterShape.js +3 -0
- package/umd/Options/Classes/EmitterShapeReplace.js +2 -0
- package/umd/Options/Classes/EmitterSize.js +3 -0
- package/umd/Options/Classes/EmitterSpawn.js +32 -0
- package/umd/Options/Interfaces/IEmitterSpawn.js +12 -0
- package/umd/index.js +20 -9
- package/129.min.js +0 -2
- package/129.min.js.LICENSE.txt +0 -1
- package/246.min.js +0 -2
- package/246.min.js.LICENSE.txt +0 -1
- package/330.min.js +0 -2
- package/330.min.js.LICENSE.txt +0 -1
- package/490.min.js +0 -2
- package/490.min.js.LICENSE.txt +0 -1
- package/849.min.js +0 -2
- package/849.min.js.LICENSE.txt +0 -1
- package/940.min.js +0 -2
- package/940.min.js.LICENSE.txt +0 -1
- package/tsparticles.plugin.emitters.min.js.LICENSE.txt +0 -1
package/browser/index.js
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
export async function loadEmittersPlugin(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-
|
|
3
|
-
await engine.register(async (e) => {
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
engine.checkVersion("4.0.0-beta.1");
|
|
3
|
+
await engine.pluginManager.register(async (e) => {
|
|
4
|
+
const [{ ensureInteractivityPluginLoaded }, { ShapeManager }, { EmittersInstancesManager }, { EmittersPlugin },] = await Promise.all([
|
|
5
|
+
import("@tsparticles/plugin-interactivity"),
|
|
6
|
+
import("./ShapeManager.js"),
|
|
7
|
+
import("./EmittersInstancesManager.js"),
|
|
8
|
+
import("./EmittersPlugin.js"),
|
|
9
|
+
]), pluginManager = e.pluginManager, instancesManager = new EmittersInstancesManager(pluginManager);
|
|
10
|
+
ensureInteractivityPluginLoaded(e);
|
|
11
|
+
pluginManager.emitterShapeManager ??= new ShapeManager();
|
|
12
|
+
pluginManager.addEmitterShapeGenerator ??= (name, generator) => {
|
|
13
|
+
pluginManager.emitterShapeManager?.addShapeGenerator(name, generator);
|
|
9
14
|
};
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
pluginManager.addPlugin(new EmittersPlugin(instancesManager));
|
|
16
|
+
pluginManager.addInteractor?.("externalEmitters", async (container) => {
|
|
12
17
|
const { EmittersInteractor } = await import("./EmittersInteractor.js");
|
|
13
18
|
return new EmittersInteractor(instancesManager, container);
|
|
14
19
|
});
|
|
15
20
|
});
|
|
16
21
|
}
|
|
22
|
+
export function ensureEmittersPluginLoaded(e) {
|
|
23
|
+
if (!e.pluginManager.addEmitterShapeGenerator) {
|
|
24
|
+
throw new Error("tsParticles Emitters Plugin is not loaded");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
17
27
|
export * from "./EmitterShapeBase.js";
|
|
18
28
|
export * from "./Enums/EmitterClickMode.js";
|
package/cjs/EmitterInstance.js
CHANGED
|
@@ -1,54 +1,55 @@
|
|
|
1
|
-
import { PixelMode, Vector, calcPositionOrRandomFromSizeRanged, deepExtend, getRangeValue, getSize, hMax, half, isPointInside, itemFromSingleOrMultiple, lMax, millisecondsToSeconds, randomInRangeValue, rangeColorToHsl, sMax, safeDocument, } from "@tsparticles/engine";
|
|
1
|
+
import { AnimatableColor, Fill, PixelMode, Stroke, Vector, calcPositionOrRandomFromSizeRanged, deepExtend, defaultOpacity, getRangeValue, getSize, hMax, half, isPointInside, itemFromSingleOrMultiple, lMax, millisecondsToSeconds, randomInRangeValue, rangeColorToHsl, sMax, safeDocument, } from "@tsparticles/engine";
|
|
2
2
|
import { Emitter } from "./Options/Classes/Emitter.js";
|
|
3
3
|
import { EmitterSize } from "./Options/Classes/EmitterSize.js";
|
|
4
|
-
const defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1, defaultColorAnimationFactor = 1, colorFactor = 3.6;
|
|
5
|
-
function
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
}
|
|
4
|
+
const defaultLifeDelay = 0, minLifeCount = 0, defaultSpawnDelay = 0, defaultEmitDelay = 0, defaultLifeCount = -1, defaultColorAnimationFactor = 1, colorFactor = 3.6, defaultStrokeWidth = 1;
|
|
5
|
+
function setParticlesOptionsFillColor(particlesOptions, color, opacity, enable) {
|
|
6
|
+
particlesOptions.fill = new Fill();
|
|
7
|
+
particlesOptions.fill.color = AnimatableColor.create(undefined, { value: color });
|
|
8
|
+
particlesOptions.fill.enable = enable;
|
|
9
|
+
particlesOptions.fill.opacity = opacity;
|
|
10
|
+
}
|
|
11
|
+
function setParticlesOptionsStrokeColor(particlesOptions, color, opacity, width) {
|
|
12
|
+
particlesOptions.stroke = new Stroke();
|
|
13
|
+
particlesOptions.stroke.color = AnimatableColor.create(undefined, { value: color });
|
|
14
|
+
particlesOptions.stroke.opacity = opacity;
|
|
15
|
+
particlesOptions.stroke.width = width;
|
|
14
16
|
}
|
|
15
17
|
export class EmitterInstance {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
this._engine = engine;
|
|
18
|
+
fill;
|
|
19
|
+
name;
|
|
20
|
+
options;
|
|
21
|
+
position;
|
|
22
|
+
size;
|
|
23
|
+
spawnFillColor;
|
|
24
|
+
spawnFillEnabled;
|
|
25
|
+
spawnFillOpacity;
|
|
26
|
+
spawnStrokeColor;
|
|
27
|
+
spawnStrokeOpacity;
|
|
28
|
+
spawnStrokeWidth;
|
|
29
|
+
_container;
|
|
30
|
+
_currentDuration;
|
|
31
|
+
_currentEmitDelay;
|
|
32
|
+
_currentSpawnDelay;
|
|
33
|
+
_duration;
|
|
34
|
+
_emitDelay;
|
|
35
|
+
_firstSpawn;
|
|
36
|
+
_immortal;
|
|
37
|
+
_initialPosition;
|
|
38
|
+
_lifeCount;
|
|
39
|
+
_mutationObserver;
|
|
40
|
+
_particlesOptions;
|
|
41
|
+
_paused;
|
|
42
|
+
_pluginManager;
|
|
43
|
+
_removeCallback;
|
|
44
|
+
_resizeObserver;
|
|
45
|
+
_shape;
|
|
46
|
+
_size;
|
|
47
|
+
_spawnDelay;
|
|
48
|
+
_startParticlesAdded;
|
|
49
|
+
constructor(pluginManager, container, removeCallback, options, position) {
|
|
50
|
+
this._pluginManager = pluginManager;
|
|
51
|
+
this._container = container;
|
|
52
|
+
this._removeCallback = removeCallback;
|
|
52
53
|
this._currentDuration = 0;
|
|
53
54
|
this._currentEmitDelay = 0;
|
|
54
55
|
this._currentSpawnDelay = 0;
|
|
@@ -72,13 +73,16 @@ export class EmitterInstance {
|
|
|
72
73
|
const particlesOptions = deepExtend({}, this.options.particles);
|
|
73
74
|
particlesOptions.move ??= {};
|
|
74
75
|
particlesOptions.move.direction ??= this.options.direction;
|
|
75
|
-
if (this.options.
|
|
76
|
-
this.
|
|
76
|
+
if (this.options.spawn.fill?.color) {
|
|
77
|
+
this.spawnFillColor = rangeColorToHsl(this._pluginManager, this.options.spawn.fill.color);
|
|
78
|
+
}
|
|
79
|
+
if (this.options.spawn.stroke?.color) {
|
|
80
|
+
this.spawnStrokeColor = rangeColorToHsl(this._pluginManager, this.options.spawn.stroke.color);
|
|
77
81
|
}
|
|
78
82
|
this._paused = !this.options.autoPlay;
|
|
79
83
|
this._particlesOptions = particlesOptions;
|
|
80
84
|
this._size = this._calcSize();
|
|
81
|
-
this.size = getSize(this._size, this.
|
|
85
|
+
this.size = getSize(this._size, this._container.canvas.size);
|
|
82
86
|
this._lifeCount = this.options.life.count ?? defaultLifeCount;
|
|
83
87
|
this._immortal = this._lifeCount <= minLifeCount;
|
|
84
88
|
if (this.options.domId) {
|
|
@@ -97,15 +101,12 @@ export class EmitterInstance {
|
|
|
97
101
|
this._resizeObserver.observe(element);
|
|
98
102
|
}
|
|
99
103
|
}
|
|
100
|
-
const shapeOptions = this.options.shape, shapeGenerator = this.
|
|
104
|
+
const shapeOptions = this.options.shape, shapeGenerator = this._pluginManager.emitterShapeManager?.getShapeGenerator(shapeOptions.type);
|
|
101
105
|
if (shapeGenerator) {
|
|
102
|
-
this._shape = shapeGenerator.generate(this.position, this.size, this.fill, shapeOptions.options);
|
|
106
|
+
this._shape = shapeGenerator.generate(this._container, this.position, this.size, this.fill, shapeOptions.options);
|
|
103
107
|
}
|
|
104
|
-
this.
|
|
105
|
-
|
|
106
|
-
data: {
|
|
107
|
-
emitter: this,
|
|
108
|
-
},
|
|
108
|
+
this._container.dispatchEvent("emitterCreated", {
|
|
109
|
+
emitter: this,
|
|
109
110
|
});
|
|
110
111
|
this.play();
|
|
111
112
|
}
|
|
@@ -134,7 +135,7 @@ export class EmitterInstance {
|
|
|
134
135
|
(this._firstSpawn || this._currentSpawnDelay >= (this._spawnDelay ?? defaultSpawnDelay)))) {
|
|
135
136
|
return;
|
|
136
137
|
}
|
|
137
|
-
const container = this.
|
|
138
|
+
const container = this._container;
|
|
138
139
|
if (this._emitDelay === undefined) {
|
|
139
140
|
const delay = getRangeValue(this.options.rate.delay);
|
|
140
141
|
this._emitDelay = container.retina.reduceFactor
|
|
@@ -146,7 +147,7 @@ export class EmitterInstance {
|
|
|
146
147
|
}
|
|
147
148
|
}
|
|
148
149
|
resize() {
|
|
149
|
-
const initialPosition = this._initialPosition, container = this.
|
|
150
|
+
const initialPosition = this._initialPosition, container = this._container;
|
|
150
151
|
this.position =
|
|
151
152
|
initialPosition && isPointInside(initialPosition, container.canvas.size, Vector.origin)
|
|
152
153
|
? initialPosition
|
|
@@ -159,7 +160,7 @@ export class EmitterInstance {
|
|
|
159
160
|
if (this._paused) {
|
|
160
161
|
return;
|
|
161
162
|
}
|
|
162
|
-
const container = this.
|
|
163
|
+
const container = this._container;
|
|
163
164
|
if (this._firstSpawn) {
|
|
164
165
|
this._firstSpawn = false;
|
|
165
166
|
this._currentSpawnDelay = this._spawnDelay ?? defaultSpawnDelay;
|
|
@@ -197,11 +198,9 @@ export class EmitterInstance {
|
|
|
197
198
|
if (this._spawnDelay !== undefined) {
|
|
198
199
|
this._currentSpawnDelay += delta.value;
|
|
199
200
|
if (this._currentSpawnDelay >= this._spawnDelay) {
|
|
200
|
-
this.
|
|
201
|
-
container: this.container,
|
|
202
|
-
});
|
|
201
|
+
this._container.dispatchEvent("emitterPlay");
|
|
203
202
|
this.play();
|
|
204
|
-
this._currentSpawnDelay -= this.
|
|
203
|
+
this._currentSpawnDelay -= this._spawnDelay;
|
|
205
204
|
delete this._spawnDelay;
|
|
206
205
|
}
|
|
207
206
|
}
|
|
@@ -214,7 +213,7 @@ export class EmitterInstance {
|
|
|
214
213
|
}
|
|
215
214
|
}
|
|
216
215
|
_calcPosition() {
|
|
217
|
-
const container = this.
|
|
216
|
+
const container = this._container;
|
|
218
217
|
if (this.options.domId) {
|
|
219
218
|
const element = safeDocument().getElementById(this.options.domId);
|
|
220
219
|
if (element) {
|
|
@@ -231,7 +230,7 @@ export class EmitterInstance {
|
|
|
231
230
|
});
|
|
232
231
|
}
|
|
233
232
|
_calcSize() {
|
|
234
|
-
const container = this.
|
|
233
|
+
const container = this._container;
|
|
235
234
|
if (this.options.domId) {
|
|
236
235
|
const element = safeDocument().getElementById(this.options.domId);
|
|
237
236
|
if (element) {
|
|
@@ -254,6 +253,16 @@ export class EmitterInstance {
|
|
|
254
253
|
return size;
|
|
255
254
|
})());
|
|
256
255
|
}
|
|
256
|
+
_destroy = () => {
|
|
257
|
+
this._mutationObserver?.disconnect();
|
|
258
|
+
this._mutationObserver = undefined;
|
|
259
|
+
this._resizeObserver?.disconnect();
|
|
260
|
+
this._resizeObserver = undefined;
|
|
261
|
+
this._removeCallback(this);
|
|
262
|
+
this._container.dispatchEvent("emitterDestroyed", {
|
|
263
|
+
emitter: this,
|
|
264
|
+
});
|
|
265
|
+
};
|
|
257
266
|
_emit() {
|
|
258
267
|
if (this._paused) {
|
|
259
268
|
return;
|
|
@@ -263,18 +272,36 @@ export class EmitterInstance {
|
|
|
263
272
|
}
|
|
264
273
|
_emitParticles(quantity) {
|
|
265
274
|
const singleParticlesOptions = (itemFromSingleOrMultiple(this._particlesOptions) ??
|
|
266
|
-
{}),
|
|
275
|
+
{}), fillHslAnimation = this.options.spawn.fill?.color.animation, fillEnabled = this.options.spawn.fill?.enable ?? !!this.options.spawn.fill?.color, fillOpacity = this.options.spawn.fill?.opacity === undefined
|
|
276
|
+
? defaultOpacity
|
|
277
|
+
: getRangeValue(this.options.spawn.fill.opacity), strokeHslAnimation = this.options.spawn.stroke?.color?.animation, strokeOpacity = this.options.spawn.stroke?.opacity === undefined
|
|
278
|
+
? defaultOpacity
|
|
279
|
+
: getRangeValue(this.options.spawn.stroke.opacity), strokeWidth = this.options.spawn.stroke?.width === undefined
|
|
280
|
+
? defaultStrokeWidth
|
|
281
|
+
: getRangeValue(this.options.spawn.stroke.width), reduceFactor = this._container.retina.reduceFactor, needsFillColorAnimation = !!fillHslAnimation, needsStrokeColorAnimation = !!strokeHslAnimation, needsShapeData = !!this._shape, needsColorAnimation = needsFillColorAnimation || needsStrokeColorAnimation, needsCopy = needsColorAnimation || needsShapeData, maxValues = needsColorAnimation ? { h: hMax, s: sMax, l: lMax } : null, shapeOptions = this.options.shape;
|
|
267
282
|
for (let i = 0; i < quantity * reduceFactor; i++) {
|
|
268
283
|
const particlesOptions = needsCopy
|
|
269
284
|
? deepExtend({}, singleParticlesOptions)
|
|
270
285
|
: singleParticlesOptions;
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
286
|
+
this.spawnFillOpacity = fillOpacity;
|
|
287
|
+
this.spawnFillEnabled = fillEnabled;
|
|
288
|
+
this.spawnStrokeOpacity = strokeOpacity;
|
|
289
|
+
this.spawnStrokeWidth = strokeWidth;
|
|
290
|
+
if (this.spawnFillColor) {
|
|
291
|
+
if (fillHslAnimation && maxValues) {
|
|
292
|
+
this.spawnFillColor.h = this._setColorAnimation(fillHslAnimation.h, this.spawnFillColor.h, maxValues.h, colorFactor);
|
|
293
|
+
this.spawnFillColor.s = this._setColorAnimation(fillHslAnimation.s, this.spawnFillColor.s, maxValues.s);
|
|
294
|
+
this.spawnFillColor.l = this._setColorAnimation(fillHslAnimation.l, this.spawnFillColor.l, maxValues.l);
|
|
295
|
+
}
|
|
296
|
+
setParticlesOptionsFillColor(particlesOptions, this.spawnFillColor, this.spawnFillOpacity, this.spawnFillEnabled);
|
|
297
|
+
}
|
|
298
|
+
if (this.spawnStrokeColor) {
|
|
299
|
+
if (strokeHslAnimation && maxValues) {
|
|
300
|
+
this.spawnStrokeColor.h = this._setColorAnimation(strokeHslAnimation.h, this.spawnStrokeColor.h, maxValues.h, colorFactor);
|
|
301
|
+
this.spawnStrokeColor.s = this._setColorAnimation(strokeHslAnimation.s, this.spawnStrokeColor.s, maxValues.s);
|
|
302
|
+
this.spawnStrokeColor.l = this._setColorAnimation(strokeHslAnimation.l, this.spawnStrokeColor.l, maxValues.l);
|
|
276
303
|
}
|
|
277
|
-
|
|
304
|
+
setParticlesOptionsStrokeColor(particlesOptions, this.spawnStrokeColor, this.spawnStrokeOpacity, this.spawnStrokeWidth);
|
|
278
305
|
}
|
|
279
306
|
let position = this.position;
|
|
280
307
|
if (this._shape) {
|
|
@@ -283,17 +310,7 @@ export class EmitterInstance {
|
|
|
283
310
|
position = shapePosData.position;
|
|
284
311
|
const replaceData = shapeOptions.replace;
|
|
285
312
|
if (replaceData.color && shapePosData.color) {
|
|
286
|
-
|
|
287
|
-
}
|
|
288
|
-
if (replaceData.opacity) {
|
|
289
|
-
if (particlesOptions.opacity) {
|
|
290
|
-
particlesOptions.opacity.value = shapePosData.opacity;
|
|
291
|
-
}
|
|
292
|
-
else {
|
|
293
|
-
particlesOptions.opacity = {
|
|
294
|
-
value: shapePosData.opacity,
|
|
295
|
-
};
|
|
296
|
-
}
|
|
313
|
+
setParticlesOptionsFillColor(particlesOptions, shapePosData.color, replaceData.opacity ? (shapePosData.opacity ?? defaultOpacity) : defaultOpacity, true);
|
|
297
314
|
}
|
|
298
315
|
}
|
|
299
316
|
else {
|
|
@@ -301,8 +318,27 @@ export class EmitterInstance {
|
|
|
301
318
|
}
|
|
302
319
|
}
|
|
303
320
|
if (position) {
|
|
304
|
-
this.
|
|
321
|
+
this._container.particles.addParticle(position, particlesOptions);
|
|
305
322
|
}
|
|
306
323
|
}
|
|
307
324
|
}
|
|
325
|
+
_prepareToDie = () => {
|
|
326
|
+
if (this._paused) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const duration = this.options.life.duration !== undefined ? getRangeValue(this.options.life.duration) : undefined, minDuration = 0, minLifeCount = 0;
|
|
330
|
+
if ((this._lifeCount > minLifeCount || this._immortal) && duration !== undefined && duration > minDuration) {
|
|
331
|
+
this._duration = duration * millisecondsToSeconds;
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
_setColorAnimation = (animation, initValue, maxValue, factor = defaultColorAnimationFactor) => {
|
|
335
|
+
const container = this._container;
|
|
336
|
+
if (!animation.enable) {
|
|
337
|
+
return initValue;
|
|
338
|
+
}
|
|
339
|
+
const colorOffset = randomInRangeValue(animation.offset), delay = getRangeValue(this.options.rate.delay), emitFactor = container.retina.reduceFactor
|
|
340
|
+
? (delay * millisecondsToSeconds) / container.retina.reduceFactor
|
|
341
|
+
: Infinity, colorSpeed = getRangeValue(animation.speed);
|
|
342
|
+
return (initValue + (colorSpeed * container.fpsLimit) / emitFactor + colorOffset * factor) % maxValue;
|
|
343
|
+
};
|
|
308
344
|
}
|
package/cjs/EmitterShapeBase.js
CHANGED
|
@@ -2,14 +2,16 @@ import { isNumber } from "@tsparticles/engine";
|
|
|
2
2
|
import { Emitter } from "./Options/Classes/Emitter.js";
|
|
3
3
|
const defaultIndex = 0;
|
|
4
4
|
export class EmittersInstancesManager {
|
|
5
|
-
|
|
5
|
+
_containerArrays;
|
|
6
|
+
_pluginManager;
|
|
7
|
+
constructor(pluginManager) {
|
|
6
8
|
this._containerArrays = new Map();
|
|
7
|
-
this.
|
|
9
|
+
this._pluginManager = pluginManager;
|
|
8
10
|
}
|
|
9
11
|
async addEmitter(container, options, position) {
|
|
10
12
|
const emitterOptions = new Emitter();
|
|
11
13
|
emitterOptions.load(options);
|
|
12
|
-
const { EmitterInstance } = await import("./EmitterInstance.js"), emitter = new EmitterInstance(this.
|
|
14
|
+
const { EmitterInstance } = await import("./EmitterInstance.js"), emitter = new EmitterInstance(this._pluginManager, container, (emitter) => {
|
|
13
15
|
this.removeEmitter(container, emitter);
|
|
14
16
|
}, emitterOptions, position);
|
|
15
17
|
await emitter.init();
|
|
@@ -4,9 +4,13 @@ import { Emitter } from "./Options/Classes/Emitter.js";
|
|
|
4
4
|
import { defaultRandomOptions } from "./constants.js";
|
|
5
5
|
const emittersMode = "emitters";
|
|
6
6
|
export class EmittersInteractor extends ExternalInteractorBase {
|
|
7
|
+
handleClickMode;
|
|
8
|
+
maxDistance;
|
|
9
|
+
_instancesManager;
|
|
7
10
|
constructor(instancesManager, container) {
|
|
8
11
|
super(container);
|
|
9
12
|
this._instancesManager = instancesManager;
|
|
13
|
+
this.maxDistance = 0;
|
|
10
14
|
this.handleClickMode = (mode, interactivityData) => {
|
|
11
15
|
const container = this.container, options = container.actualOptions, modeEmitters = options.interactivity.modes.emitters;
|
|
12
16
|
if (!modeEmitters || mode !== emittersMode) {
|
|
@@ -77,7 +81,7 @@ export class EmittersInteractor extends ExternalInteractorBase {
|
|
|
77
81
|
options.emitters.value.push(tmp);
|
|
78
82
|
}
|
|
79
83
|
}
|
|
80
|
-
else if (
|
|
84
|
+
else if ("value" in source.emitters) {
|
|
81
85
|
const emitterModeOptions = source.emitters;
|
|
82
86
|
options.emitters.random.enable = emitterModeOptions.random?.enable ?? options.emitters.random.enable;
|
|
83
87
|
options.emitters.random.count = emitterModeOptions.random?.count ?? options.emitters.random.count;
|
package/cjs/EmittersPlugin.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { executeOnSingleOrMultiple, isArray, } from "@tsparticles/engine";
|
|
2
2
|
import { Emitter } from "./Options/Classes/Emitter.js";
|
|
3
3
|
export class EmittersPlugin {
|
|
4
|
+
id = "emitters";
|
|
5
|
+
_instancesManager;
|
|
4
6
|
constructor(instancesManager) {
|
|
5
7
|
this._instancesManager = instancesManager;
|
|
6
|
-
this.id = "emitters";
|
|
7
8
|
}
|
|
8
9
|
async getPlugin(container) {
|
|
9
10
|
const { EmittersPluginInstance } = await import("./EmittersPluginInstance.js");
|
|
@@ -3,13 +3,30 @@ import { EmitterLife } from "./EmitterLife.js";
|
|
|
3
3
|
import { EmitterRate } from "./EmitterRate.js";
|
|
4
4
|
import { EmitterShape } from "./EmitterShape.js";
|
|
5
5
|
import { EmitterSize } from "./EmitterSize.js";
|
|
6
|
+
import { EmitterSpawn } from "./EmitterSpawn.js";
|
|
6
7
|
export class Emitter {
|
|
8
|
+
autoPlay;
|
|
9
|
+
direction;
|
|
10
|
+
domId;
|
|
11
|
+
fill;
|
|
12
|
+
life;
|
|
13
|
+
name;
|
|
14
|
+
particles;
|
|
15
|
+
position;
|
|
16
|
+
rate;
|
|
17
|
+
shape;
|
|
18
|
+
size;
|
|
19
|
+
spawn;
|
|
20
|
+
spawnFillColor;
|
|
21
|
+
spawnStrokeColor;
|
|
22
|
+
startCount;
|
|
7
23
|
constructor() {
|
|
8
24
|
this.autoPlay = true;
|
|
9
25
|
this.fill = true;
|
|
10
26
|
this.life = new EmitterLife();
|
|
11
27
|
this.rate = new EmitterRate();
|
|
12
28
|
this.shape = new EmitterShape();
|
|
29
|
+
this.spawn = new EmitterSpawn();
|
|
13
30
|
this.startCount = 0;
|
|
14
31
|
}
|
|
15
32
|
load(data) {
|
|
@@ -37,6 +54,7 @@ export class Emitter {
|
|
|
37
54
|
});
|
|
38
55
|
this.rate.load(data.rate);
|
|
39
56
|
this.shape.load(data.shape);
|
|
57
|
+
this.spawn.load(data.spawn);
|
|
40
58
|
if (data.position !== undefined) {
|
|
41
59
|
this.position = {};
|
|
42
60
|
if (data.position.x !== undefined) {
|
|
@@ -46,9 +64,13 @@ export class Emitter {
|
|
|
46
64
|
this.position.y = setRangeValue(data.position.y);
|
|
47
65
|
}
|
|
48
66
|
}
|
|
49
|
-
if (data.
|
|
50
|
-
this.
|
|
51
|
-
this.
|
|
67
|
+
if (data.spawnFillColor !== undefined) {
|
|
68
|
+
this.spawnFillColor ??= new AnimatableColor();
|
|
69
|
+
this.spawnFillColor.load(data.spawnFillColor);
|
|
70
|
+
}
|
|
71
|
+
if (data.spawnStrokeColor !== undefined) {
|
|
72
|
+
this.spawnStrokeColor ??= new AnimatableColor();
|
|
73
|
+
this.spawnStrokeColor.load(data.spawnStrokeColor);
|
|
52
74
|
}
|
|
53
75
|
if (data.startCount !== undefined) {
|
|
54
76
|
this.startCount = data.startCount;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { deepExtend, isNull } from "@tsparticles/engine";
|
|
2
2
|
import { EmitterShapeReplace } from "./EmitterShapeReplace.js";
|
|
3
3
|
export class EmitterShape {
|
|
4
|
+
options;
|
|
5
|
+
replace;
|
|
6
|
+
type;
|
|
4
7
|
constructor() {
|
|
5
8
|
this.options = {};
|
|
6
9
|
this.replace = new EmitterShapeReplace();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Fill, Stroke, isNull } from "@tsparticles/engine";
|
|
2
|
+
export class EmitterSpawn {
|
|
3
|
+
fill;
|
|
4
|
+
stroke;
|
|
5
|
+
load(data) {
|
|
6
|
+
if (isNull(data)) {
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (data.fill) {
|
|
10
|
+
this.fill ??= new Fill();
|
|
11
|
+
this.fill.load(data.fill);
|
|
12
|
+
}
|
|
13
|
+
if (data.stroke) {
|
|
14
|
+
this.stroke ??= new Stroke();
|
|
15
|
+
this.stroke.load(data.stroke);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/cjs/index.js
CHANGED
|
@@ -1,18 +1,28 @@
|
|
|
1
1
|
export async function loadEmittersPlugin(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-
|
|
3
|
-
await engine.register(async (e) => {
|
|
4
|
-
const {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
engine.checkVersion("4.0.0-beta.1");
|
|
3
|
+
await engine.pluginManager.register(async (e) => {
|
|
4
|
+
const [{ ensureInteractivityPluginLoaded }, { ShapeManager }, { EmittersInstancesManager }, { EmittersPlugin },] = await Promise.all([
|
|
5
|
+
import("@tsparticles/plugin-interactivity"),
|
|
6
|
+
import("./ShapeManager.js"),
|
|
7
|
+
import("./EmittersInstancesManager.js"),
|
|
8
|
+
import("./EmittersPlugin.js"),
|
|
9
|
+
]), pluginManager = e.pluginManager, instancesManager = new EmittersInstancesManager(pluginManager);
|
|
10
|
+
ensureInteractivityPluginLoaded(e);
|
|
11
|
+
pluginManager.emitterShapeManager ??= new ShapeManager();
|
|
12
|
+
pluginManager.addEmitterShapeGenerator ??= (name, generator) => {
|
|
13
|
+
pluginManager.emitterShapeManager?.addShapeGenerator(name, generator);
|
|
9
14
|
};
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
pluginManager.addPlugin(new EmittersPlugin(instancesManager));
|
|
16
|
+
pluginManager.addInteractor?.("externalEmitters", async (container) => {
|
|
12
17
|
const { EmittersInteractor } = await import("./EmittersInteractor.js");
|
|
13
18
|
return new EmittersInteractor(instancesManager, container);
|
|
14
19
|
});
|
|
15
20
|
});
|
|
16
21
|
}
|
|
22
|
+
export function ensureEmittersPluginLoaded(e) {
|
|
23
|
+
if (!e.pluginManager.addEmitterShapeGenerator) {
|
|
24
|
+
throw new Error("tsParticles Emitters Plugin is not loaded");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
17
27
|
export * from "./EmitterShapeBase.js";
|
|
18
28
|
export * from "./Enums/EmitterClickMode.js";
|