@tsparticles/engine 3.0.0-beta.2 → 3.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/browser/Core/Canvas.js +2 -2
- package/browser/Core/Container.js +39 -24
- package/browser/Core/Engine.js +26 -53
- package/browser/Core/Particle.js +88 -53
- package/browser/Core/Particles.js +51 -26
- package/browser/Core/Retina.js +0 -2
- package/browser/Core/Utils/QuadTree.js +1 -1
- package/browser/Options/Classes/BackgroundMask/BackgroundMask.js +1 -2
- package/browser/Options/Classes/ColorAnimation.js +4 -24
- package/browser/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js +0 -1
- package/browser/Options/Classes/Particles/Effect/Effect.js +32 -0
- package/browser/Options/Classes/Particles/Number/ParticlesNumber.js +3 -5
- package/browser/Options/Classes/Particles/Number/ParticlesNumberLimit.js +17 -0
- package/browser/Options/Classes/Particles/Opacity/Opacity.js +2 -3
- package/browser/Options/Classes/Particles/ParticlesOptions.js +3 -0
- package/browser/Options/Classes/Particles/Size/Size.js +2 -3
- package/browser/Options/Classes/ValueWithRandom.js +1 -10
- package/browser/Utils/CanvasUtils.js +29 -21
- package/browser/Utils/ColorUtils.js +24 -38
- package/browser/Utils/NumberUtils.js +7 -16
- package/browser/Utils/Utils.js +13 -7
- package/browser/export-types.js +4 -2
- package/browser/exports.js +2 -3
- package/cjs/Core/Canvas.js +2 -2
- package/cjs/Core/Container.js +39 -24
- package/cjs/Core/Engine.js +25 -52
- package/cjs/Core/Particle.js +87 -52
- package/cjs/Core/Particles.js +51 -26
- package/cjs/Core/Retina.js +0 -2
- package/cjs/Core/Utils/QuadTree.js +1 -1
- package/cjs/Options/Classes/BackgroundMask/BackgroundMask.js +1 -2
- package/cjs/Options/Classes/ColorAnimation.js +4 -24
- package/cjs/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js +0 -1
- package/cjs/Options/Classes/Particles/Effect/Effect.js +36 -0
- package/cjs/Options/Classes/Particles/Number/ParticlesNumber.js +3 -5
- package/cjs/Options/Classes/Particles/Number/ParticlesNumberLimit.js +21 -0
- package/cjs/Options/Classes/Particles/Opacity/Opacity.js +1 -2
- package/cjs/Options/Classes/Particles/ParticlesOptions.js +3 -0
- package/cjs/Options/Classes/Particles/Size/Size.js +2 -3
- package/cjs/Options/Classes/ValueWithRandom.js +1 -10
- package/cjs/Utils/CanvasUtils.js +32 -24
- package/cjs/Utils/ColorUtils.js +24 -38
- package/cjs/Utils/NumberUtils.js +8 -18
- package/cjs/Utils/Utils.js +14 -7
- package/cjs/export-types.js +4 -2
- package/cjs/exports.js +2 -3
- package/esm/Core/Canvas.js +2 -2
- package/esm/Core/Container.js +39 -24
- package/esm/Core/Engine.js +26 -53
- package/esm/Core/Particle.js +88 -53
- package/esm/Core/Particles.js +51 -26
- package/esm/Core/Retina.js +0 -2
- package/esm/Core/Utils/QuadTree.js +1 -1
- package/esm/Options/Classes/BackgroundMask/BackgroundMask.js +1 -2
- package/esm/Options/Classes/ColorAnimation.js +4 -24
- package/esm/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js +0 -1
- package/esm/Options/Classes/Particles/Effect/Effect.js +32 -0
- package/esm/Options/Classes/Particles/Number/ParticlesNumber.js +3 -5
- package/esm/Options/Classes/Particles/Number/ParticlesNumberLimit.js +17 -0
- package/esm/Options/Classes/Particles/Opacity/Opacity.js +2 -3
- package/esm/Options/Classes/Particles/ParticlesOptions.js +3 -0
- package/esm/Options/Classes/Particles/Size/Size.js +2 -3
- package/esm/Options/Classes/ValueWithRandom.js +1 -10
- package/esm/Utils/CanvasUtils.js +29 -21
- package/esm/Utils/ColorUtils.js +24 -38
- package/esm/Utils/NumberUtils.js +7 -16
- package/esm/Utils/Utils.js +13 -7
- package/esm/export-types.js +4 -2
- package/esm/exports.js +2 -3
- package/package.json +1 -1
- package/report.html +4 -22
- package/tsparticles.engine.js +461 -347
- package/tsparticles.engine.min.js +1 -1
- package/tsparticles.engine.min.js.LICENSE.txt +1 -1
- package/types/Core/Canvas.d.ts +0 -1
- package/types/Core/Container.d.ts +9 -8
- package/types/Core/Engine.d.ts +9 -5
- package/types/Core/Interfaces/IContainerPlugin.d.ts +2 -3
- package/types/Core/Interfaces/IEffectDrawer.d.ts +10 -0
- package/types/Core/Interfaces/IExternalInteractor.d.ts +3 -4
- package/types/Core/Interfaces/IInteractor.d.ts +3 -3
- package/types/Core/Interfaces/IParticleRetinaProps.d.ts +0 -1
- package/types/Core/Interfaces/IParticlesInteractor.d.ts +3 -3
- package/types/Core/Interfaces/IShapeDrawData.d.ts +10 -0
- package/types/Core/Interfaces/IShapeDrawer.d.ts +11 -9
- package/types/Core/Particle.d.ts +7 -5
- package/types/Core/Particles.d.ts +10 -7
- package/types/Core/Retina.d.ts +0 -1
- package/types/Core/Utils/ExternalInteractorBase.d.ts +4 -4
- package/types/Core/Utils/InteractionManager.d.ts +1 -2
- package/types/Core/Utils/ParticlesInteractorBase.d.ts +5 -5
- package/types/Enums/Modes/LimitMode.d.ts +4 -0
- package/types/Enums/Types/EasingType.d.ts +3 -0
- package/types/Enums/Types/EventType.d.ts +1 -0
- package/types/Options/Classes/BackgroundMask/BackgroundMask.d.ts +1 -1
- package/types/Options/Classes/ColorAnimation.d.ts +2 -7
- package/types/Options/Classes/Interactivity/Events/ClickEvent.d.ts +1 -2
- package/types/Options/Classes/Interactivity/Events/DivEvent.d.ts +1 -2
- package/types/Options/Classes/Interactivity/Events/Events.d.ts +3 -3
- package/types/Options/Classes/Interactivity/Events/HoverEvent.d.ts +2 -3
- package/types/Options/Classes/Interactivity/Interactivity.d.ts +2 -2
- package/types/Options/Classes/Options.d.ts +6 -6
- package/types/Options/Classes/Particles/Bounce/ParticlesBounce.d.ts +2 -2
- package/types/Options/Classes/Particles/Collisions/Collisions.d.ts +3 -3
- package/types/Options/Classes/Particles/Effect/Effect.d.ts +13 -0
- package/types/Options/Classes/Particles/Move/Move.d.ts +8 -8
- package/types/Options/Classes/Particles/Move/MoveTrail.d.ts +1 -1
- package/types/Options/Classes/Particles/Number/ParticlesNumber.d.ts +3 -2
- package/types/Options/Classes/Particles/Number/ParticlesNumberLimit.d.ts +10 -0
- package/types/Options/Classes/Particles/Opacity/Opacity.d.ts +3 -3
- package/types/Options/Classes/Particles/ParticlesOptions.d.ts +12 -10
- package/types/Options/Classes/Particles/Size/Size.d.ts +3 -3
- package/types/Options/Classes/Theme/Theme.d.ts +1 -1
- package/types/Options/Classes/ValueWithRandom.d.ts +2 -4
- package/types/Options/Interfaces/IValueWithRandom.d.ts +0 -2
- package/types/Options/Interfaces/Interactivity/Events/IClickEvent.d.ts +1 -2
- package/types/Options/Interfaces/Interactivity/Events/IDivEvent.d.ts +1 -2
- package/types/Options/Interfaces/Interactivity/Events/IHoverEvent.d.ts +1 -2
- package/types/Options/Interfaces/Particles/Effect/IEffect.d.ts +8 -0
- package/types/Options/Interfaces/Particles/IParticlesOptions.d.ts +2 -0
- package/types/Options/Interfaces/Particles/Number/IParticlesNumber.d.ts +2 -1
- package/types/Options/Interfaces/Particles/Number/IParticlesNumberLimit.d.ts +5 -0
- package/types/Types/CustomEventArgs.d.ts +1 -1
- package/types/Utils/CanvasUtils.d.ts +12 -3
- package/types/Utils/ColorUtils.d.ts +2 -2
- package/types/Utils/NumberUtils.d.ts +0 -2
- package/types/Utils/Utils.d.ts +6 -6
- package/types/export-types.d.ts +5 -2
- package/types/exports.d.ts +2 -3
- package/umd/Core/Canvas.js +2 -2
- package/umd/Core/Container.js +40 -25
- package/umd/Core/Engine.js +25 -52
- package/umd/Core/Particle.js +87 -52
- package/umd/Core/Particles.js +51 -26
- package/umd/Core/Retina.js +0 -2
- package/umd/Core/Utils/QuadTree.js +1 -1
- package/umd/Options/Classes/BackgroundMask/BackgroundMask.js +1 -2
- package/umd/Options/Classes/ColorAnimation.js +5 -25
- package/umd/Options/Classes/Particles/Bounce/ParticlesBounceFactor.js +0 -1
- package/umd/Options/Classes/Particles/Effect/Effect.js +46 -0
- package/umd/Options/Classes/Particles/Number/ParticlesNumber.js +4 -6
- package/umd/Options/Classes/{Random.js → Particles/Number/ParticlesNumberLimit.js} +9 -9
- package/umd/Options/Classes/Particles/Opacity/Opacity.js +1 -2
- package/umd/Options/Classes/Particles/ParticlesOptions.js +4 -1
- package/umd/Options/Classes/Particles/Size/Size.js +3 -4
- package/umd/Options/Classes/ValueWithRandom.js +2 -11
- package/umd/Utils/CanvasUtils.js +32 -24
- package/umd/Utils/ColorUtils.js +24 -38
- package/umd/Utils/NumberUtils.js +9 -19
- package/umd/Utils/Utils.js +14 -7
- package/umd/export-types.js +5 -3
- package/umd/exports.js +3 -4
- package/browser/Options/Classes/Random.js +0 -17
- package/cjs/Options/Classes/Random.js +0 -21
- package/cjs/Types/ShapeDrawerFunctions.js +0 -2
- package/esm/Options/Classes/Random.js +0 -17
- package/esm/Options/Interfaces/IRandom.js +0 -1
- package/esm/Types/ShapeDrawerFunctions.js +0 -1
- package/types/Core/Interfaces/IParticle.d.ts +0 -48
- package/types/Enums/Modes/ClickMode.d.ts +0 -9
- package/types/Enums/Modes/DivMode.d.ts +0 -5
- package/types/Enums/Modes/HoverMode.d.ts +0 -11
- package/types/Options/Classes/Random.d.ts +0 -9
- package/types/Options/Interfaces/IRandom.d.ts +0 -4
- package/types/Types/ShapeDrawerFunctions.d.ts +0 -10
- package/umd/Types/ShapeDrawerFunctions.js +0 -12
- /package/browser/Core/Interfaces/{IParticle.js → IEffectDrawer.js} +0 -0
- /package/browser/{Enums/Modes/ClickMode.js → Core/Interfaces/IShapeDrawData.js} +0 -0
- /package/browser/Enums/Modes/{DivMode.js → LimitMode.js} +0 -0
- /package/browser/{Enums/Modes/HoverMode.js → Options/Interfaces/Particles/Effect/IEffect.js} +0 -0
- /package/browser/Options/Interfaces/{IRandom.js → Particles/Number/IParticlesNumberLimit.js} +0 -0
- /package/cjs/Core/Interfaces/{IParticle.js → IEffectDrawer.js} +0 -0
- /package/cjs/{Enums/Modes/ClickMode.js → Core/Interfaces/IShapeDrawData.js} +0 -0
- /package/cjs/Enums/Modes/{DivMode.js → LimitMode.js} +0 -0
- /package/cjs/{Enums/Modes/HoverMode.js → Options/Interfaces/Particles/Effect/IEffect.js} +0 -0
- /package/cjs/Options/Interfaces/{IRandom.js → Particles/Number/IParticlesNumberLimit.js} +0 -0
- /package/{browser/Types/ShapeDrawerFunctions.js → esm/Core/Interfaces/IEffectDrawer.js} +0 -0
- /package/esm/Core/Interfaces/{IParticle.js → IShapeDrawData.js} +0 -0
- /package/esm/Enums/Modes/{ClickMode.js → LimitMode.js} +0 -0
- /package/esm/{Enums/Modes/DivMode.js → Options/Interfaces/Particles/Effect/IEffect.js} +0 -0
- /package/esm/{Enums/Modes/HoverMode.js → Options/Interfaces/Particles/Number/IParticlesNumberLimit.js} +0 -0
- /package/umd/Core/Interfaces/{IParticle.js → IEffectDrawer.js} +0 -0
- /package/umd/{Enums/Modes/ClickMode.js → Core/Interfaces/IShapeDrawData.js} +0 -0
- /package/umd/Enums/Modes/{DivMode.js → LimitMode.js} +0 -0
- /package/umd/{Enums/Modes/HoverMode.js → Options/Interfaces/Particles/Effect/IEffect.js} +0 -0
- /package/umd/Options/Interfaces/{IRandom.js → Particles/Number/IParticlesNumberLimit.js} +0 -0
package/browser/Core/Canvas.js
CHANGED
|
@@ -402,10 +402,10 @@ export class Canvas {
|
|
|
402
402
|
this.element.width = size.width = this.element.offsetWidth * pxRatio;
|
|
403
403
|
this.element.height = size.height = this.element.offsetHeight * pxRatio;
|
|
404
404
|
if (this.container.started) {
|
|
405
|
-
|
|
405
|
+
container.particles.setResizeFactor({
|
|
406
406
|
width: size.width / oldSize.width,
|
|
407
407
|
height: size.height / oldSize.height,
|
|
408
|
-
};
|
|
408
|
+
});
|
|
409
409
|
}
|
|
410
410
|
return true;
|
|
411
411
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { getLogger, safeIntersectionObserver } from "../Utils/Utils.js";
|
|
1
2
|
import { Canvas } from "./Canvas.js";
|
|
2
3
|
import { EventListeners } from "./Utils/EventListeners.js";
|
|
3
4
|
import { Options } from "../Options/Classes/Options.js";
|
|
4
5
|
import { Particles } from "./Particles.js";
|
|
5
6
|
import { Retina } from "./Retina.js";
|
|
6
7
|
import { errorPrefix } from "./Utils/Constants.js";
|
|
7
|
-
import { getLogger } from "../Utils/Utils.js";
|
|
8
8
|
import { getRangeValue } from "../Utils/NumberUtils.js";
|
|
9
9
|
import { loadOptions } from "../Utils/OptionsUtils.js";
|
|
10
10
|
function guardCheck(container) {
|
|
@@ -23,7 +23,6 @@ function loadContainerOptions(engine, container, ...sourceOptionsArr) {
|
|
|
23
23
|
}
|
|
24
24
|
export class Container {
|
|
25
25
|
constructor(engine, id, sourceOptions) {
|
|
26
|
-
this.id = id;
|
|
27
26
|
this._intersectionManager = (entries) => {
|
|
28
27
|
if (!guardCheck(this) || !this.actualOptions.pauseOnOutsideViewport) {
|
|
29
28
|
return;
|
|
@@ -37,16 +36,16 @@ export class Container {
|
|
|
37
36
|
};
|
|
38
37
|
this._nextFrame = async (timestamp) => {
|
|
39
38
|
try {
|
|
40
|
-
if (!this.
|
|
41
|
-
this.
|
|
42
|
-
timestamp < this.
|
|
39
|
+
if (!this._smooth &&
|
|
40
|
+
this._lastFrameTime !== undefined &&
|
|
41
|
+
timestamp < this._lastFrameTime + 1000 / this.fpsLimit) {
|
|
43
42
|
this.draw(false);
|
|
44
43
|
return;
|
|
45
44
|
}
|
|
46
|
-
this.
|
|
47
|
-
const delta = initDelta(timestamp - this.
|
|
45
|
+
this._lastFrameTime ??= timestamp;
|
|
46
|
+
const delta = initDelta(timestamp - this._lastFrameTime, this.fpsLimit, this._smooth);
|
|
48
47
|
this.addLifeTime(delta.value);
|
|
49
|
-
this.
|
|
48
|
+
this._lastFrameTime = timestamp;
|
|
50
49
|
if (delta.value > 1000) {
|
|
51
50
|
this.draw(false);
|
|
52
51
|
return;
|
|
@@ -65,8 +64,9 @@ export class Container {
|
|
|
65
64
|
}
|
|
66
65
|
};
|
|
67
66
|
this._engine = engine;
|
|
67
|
+
this.id = Symbol(id);
|
|
68
68
|
this.fpsLimit = 120;
|
|
69
|
-
this.
|
|
69
|
+
this._smooth = false;
|
|
70
70
|
this._delay = 0;
|
|
71
71
|
this._duration = 0;
|
|
72
72
|
this._lifeTime = 0;
|
|
@@ -74,7 +74,7 @@ export class Container {
|
|
|
74
74
|
this.started = false;
|
|
75
75
|
this.destroyed = false;
|
|
76
76
|
this._paused = true;
|
|
77
|
-
this.
|
|
77
|
+
this._lastFrameTime = 0;
|
|
78
78
|
this.zLayers = 100;
|
|
79
79
|
this.pageHidden = false;
|
|
80
80
|
this._sourceOptions = sourceOptions;
|
|
@@ -90,13 +90,12 @@ export class Container {
|
|
|
90
90
|
},
|
|
91
91
|
};
|
|
92
92
|
this.plugins = new Map();
|
|
93
|
-
this.
|
|
93
|
+
this.effectDrawers = new Map();
|
|
94
|
+
this.shapeDrawers = new Map();
|
|
94
95
|
this._options = loadContainerOptions(this._engine, this);
|
|
95
96
|
this.actualOptions = loadContainerOptions(this._engine, this);
|
|
96
97
|
this._eventListeners = new EventListeners(this);
|
|
97
|
-
|
|
98
|
-
this._intersectionObserver = new IntersectionObserver((entries) => this._intersectionManager(entries));
|
|
99
|
-
}
|
|
98
|
+
this._intersectionObserver = safeIntersectionObserver((entries) => this._intersectionManager(entries));
|
|
100
99
|
this._engine.dispatchEvent("containerBuilt", { container: this });
|
|
101
100
|
}
|
|
102
101
|
get options() {
|
|
@@ -202,11 +201,17 @@ export class Container {
|
|
|
202
201
|
this.stop();
|
|
203
202
|
this.particles.destroy();
|
|
204
203
|
this.canvas.destroy();
|
|
205
|
-
for (const [,
|
|
206
|
-
|
|
204
|
+
for (const [, effectDrawer] of this.effectDrawers) {
|
|
205
|
+
effectDrawer.destroy && effectDrawer.destroy(this);
|
|
206
|
+
}
|
|
207
|
+
for (const [, shapeDrawer] of this.shapeDrawers) {
|
|
208
|
+
shapeDrawer.destroy && shapeDrawer.destroy(this);
|
|
207
209
|
}
|
|
208
|
-
for (const key of this.
|
|
209
|
-
this.
|
|
210
|
+
for (const key of this.effectDrawers.keys()) {
|
|
211
|
+
this.effectDrawers.delete(key);
|
|
212
|
+
}
|
|
213
|
+
for (const key of this.shapeDrawers.keys()) {
|
|
214
|
+
this.shapeDrawers.delete(key);
|
|
210
215
|
}
|
|
211
216
|
this._engine.clearPlugins(this);
|
|
212
217
|
this.destroyed = true;
|
|
@@ -223,7 +228,7 @@ export class Container {
|
|
|
223
228
|
let refreshTime = force;
|
|
224
229
|
this._drawAnimationFrame = requestAnimationFrame(async (timestamp) => {
|
|
225
230
|
if (refreshTime) {
|
|
226
|
-
this.
|
|
231
|
+
this._lastFrameTime = undefined;
|
|
227
232
|
refreshTime = false;
|
|
228
233
|
}
|
|
229
234
|
await this._nextFrame(timestamp);
|
|
@@ -258,11 +263,18 @@ export class Container {
|
|
|
258
263
|
if (!guardCheck(this)) {
|
|
259
264
|
return;
|
|
260
265
|
}
|
|
266
|
+
const effects = this._engine.getSupportedEffects();
|
|
267
|
+
for (const type of effects) {
|
|
268
|
+
const drawer = this._engine.getEffectDrawer(type);
|
|
269
|
+
if (drawer) {
|
|
270
|
+
this.effectDrawers.set(type, drawer);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
261
273
|
const shapes = this._engine.getSupportedShapes();
|
|
262
274
|
for (const type of shapes) {
|
|
263
275
|
const drawer = this._engine.getShapeDrawer(type);
|
|
264
276
|
if (drawer) {
|
|
265
|
-
this.
|
|
277
|
+
this.shapeDrawers.set(type, drawer);
|
|
266
278
|
}
|
|
267
279
|
}
|
|
268
280
|
this._options = loadContainerOptions(this._engine, this, this._initialSourceOptions, this.sourceOptions);
|
|
@@ -281,8 +293,11 @@ export class Container {
|
|
|
281
293
|
this._delay = getRangeValue(this.actualOptions.delay) * 1000;
|
|
282
294
|
this._lifeTime = 0;
|
|
283
295
|
this.fpsLimit = this.actualOptions.fpsLimit > 0 ? this.actualOptions.fpsLimit : 120;
|
|
284
|
-
this.
|
|
285
|
-
for (const [, drawer] of this.
|
|
296
|
+
this._smooth = this.actualOptions.smooth;
|
|
297
|
+
for (const [, drawer] of this.effectDrawers) {
|
|
298
|
+
drawer.init && (await drawer.init(this));
|
|
299
|
+
}
|
|
300
|
+
for (const [, drawer] of this.shapeDrawers) {
|
|
286
301
|
drawer.init && (await drawer.init(this));
|
|
287
302
|
}
|
|
288
303
|
for (const [, plugin] of this.plugins) {
|
|
@@ -411,10 +426,10 @@ export class Container {
|
|
|
411
426
|
this.actualOptions.responsive = [];
|
|
412
427
|
const newMaxWidth = this.actualOptions.setResponsive(this.canvas.size.width, this.retina.pixelRatio, this._options);
|
|
413
428
|
this.actualOptions.setTheme(this._currentTheme);
|
|
414
|
-
if (this.
|
|
429
|
+
if (this._responsiveMaxWidth === newMaxWidth) {
|
|
415
430
|
return false;
|
|
416
431
|
}
|
|
417
|
-
this.
|
|
432
|
+
this._responsiveMaxWidth = newMaxWidth;
|
|
418
433
|
return true;
|
|
419
434
|
}
|
|
420
435
|
}
|
package/browser/Core/Engine.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { errorPrefix, generatedAttribute } from "./Utils/Constants.js";
|
|
2
|
-
import { executeOnSingleOrMultiple, getLogger,
|
|
2
|
+
import { executeOnSingleOrMultiple, getLogger, itemFromSingleOrMultiple } from "../Utils/Utils.js";
|
|
3
3
|
import { Container } from "./Container.js";
|
|
4
4
|
import { EventDispatcher } from "../Utils/EventDispatcher.js";
|
|
5
5
|
import { getRandom } from "../Utils/NumberUtils.js";
|
|
@@ -39,7 +39,8 @@ export class Engine {
|
|
|
39
39
|
this.movers = new Map();
|
|
40
40
|
this.updaters = new Map();
|
|
41
41
|
this.presets = new Map();
|
|
42
|
-
this.
|
|
42
|
+
this.effectDrawers = new Map();
|
|
43
|
+
this.shapeDrawers = new Map();
|
|
43
44
|
this.pathGenerators = new Map();
|
|
44
45
|
}
|
|
45
46
|
get configs() {
|
|
@@ -50,18 +51,18 @@ export class Engine {
|
|
|
50
51
|
return res;
|
|
51
52
|
}
|
|
52
53
|
get version() {
|
|
53
|
-
return "3.0.0-beta.
|
|
54
|
+
return "3.0.0-beta.4";
|
|
54
55
|
}
|
|
55
|
-
addConfig(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
addConfig(config) {
|
|
57
|
+
const name = config.name ?? "default";
|
|
58
|
+
this._configs.set(name, config);
|
|
59
|
+
this._eventDispatcher.dispatchEvent("configAdded", { data: { name, config } });
|
|
60
|
+
}
|
|
61
|
+
async addEffect(effect, drawer, refresh = true) {
|
|
62
|
+
executeOnSingleOrMultiple(effect, (type) => {
|
|
63
|
+
!this.getEffectDrawer(type) && this.effectDrawers.set(type, drawer);
|
|
64
|
+
});
|
|
65
|
+
await this.refresh(refresh);
|
|
65
66
|
}
|
|
66
67
|
addEventListener(type, listener) {
|
|
67
68
|
this._eventDispatcher.addEventListener(type, listener);
|
|
@@ -90,45 +91,11 @@ export class Engine {
|
|
|
90
91
|
(override || !this.getPreset(preset)) && this.presets.set(preset, options);
|
|
91
92
|
await this.refresh(refresh);
|
|
92
93
|
}
|
|
93
|
-
async addShape(shape, drawer,
|
|
94
|
-
let customDrawer;
|
|
95
|
-
let realRefresh = refresh, realInit, realAfterEffect, realDestroy;
|
|
96
|
-
if (isBoolean(initOrRefresh)) {
|
|
97
|
-
realRefresh = initOrRefresh;
|
|
98
|
-
realInit = undefined;
|
|
99
|
-
}
|
|
100
|
-
else {
|
|
101
|
-
realInit = initOrRefresh;
|
|
102
|
-
}
|
|
103
|
-
if (isBoolean(afterEffectOrRefresh)) {
|
|
104
|
-
realRefresh = afterEffectOrRefresh;
|
|
105
|
-
realAfterEffect = undefined;
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
realAfterEffect = afterEffectOrRefresh;
|
|
109
|
-
}
|
|
110
|
-
if (isBoolean(destroyOrRefresh)) {
|
|
111
|
-
realRefresh = destroyOrRefresh;
|
|
112
|
-
realDestroy = undefined;
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
realDestroy = destroyOrRefresh;
|
|
116
|
-
}
|
|
117
|
-
if (isFunction(drawer)) {
|
|
118
|
-
customDrawer = {
|
|
119
|
-
afterEffect: realAfterEffect,
|
|
120
|
-
destroy: realDestroy,
|
|
121
|
-
draw: drawer,
|
|
122
|
-
init: realInit,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
customDrawer = drawer;
|
|
127
|
-
}
|
|
94
|
+
async addShape(shape, drawer, refresh = true) {
|
|
128
95
|
executeOnSingleOrMultiple(shape, (type) => {
|
|
129
|
-
!this.getShapeDrawer(type) && this.
|
|
96
|
+
!this.getShapeDrawer(type) && this.shapeDrawers.set(type, drawer);
|
|
130
97
|
});
|
|
131
|
-
await this.refresh(
|
|
98
|
+
await this.refresh(refresh);
|
|
132
99
|
}
|
|
133
100
|
clearPlugins(container) {
|
|
134
101
|
this.updaters.delete(container);
|
|
@@ -156,6 +123,9 @@ export class Engine {
|
|
|
156
123
|
}
|
|
157
124
|
return res;
|
|
158
125
|
}
|
|
126
|
+
getEffectDrawer(type) {
|
|
127
|
+
return this.effectDrawers.get(type);
|
|
128
|
+
}
|
|
159
129
|
getInteractors(container, force = false) {
|
|
160
130
|
return getItemsFromInitializer(container, this.interactors, this._initializers.interactors, force);
|
|
161
131
|
}
|
|
@@ -172,10 +142,13 @@ export class Engine {
|
|
|
172
142
|
return this.presets.get(preset);
|
|
173
143
|
}
|
|
174
144
|
getShapeDrawer(type) {
|
|
175
|
-
return this.
|
|
145
|
+
return this.shapeDrawers.get(type);
|
|
146
|
+
}
|
|
147
|
+
getSupportedEffects() {
|
|
148
|
+
return this.effectDrawers.keys();
|
|
176
149
|
}
|
|
177
150
|
getSupportedShapes() {
|
|
178
|
-
return this.
|
|
151
|
+
return this.shapeDrawers.keys();
|
|
179
152
|
}
|
|
180
153
|
getUpdaters(container, force = false) {
|
|
181
154
|
return getItemsFromInitializer(container, this.updaters, this._initializers.updaters, force);
|
|
@@ -194,7 +167,7 @@ export class Engine {
|
|
|
194
167
|
domContainer.id = id;
|
|
195
168
|
document.body.append(domContainer);
|
|
196
169
|
}
|
|
197
|
-
const currentOptions = itemFromSingleOrMultiple(options, index), dom = this.dom(), oldIndex = dom.findIndex((v) => v.id === id);
|
|
170
|
+
const currentOptions = itemFromSingleOrMultiple(options, index), dom = this.dom(), oldIndex = dom.findIndex((v) => v.id.description === id);
|
|
198
171
|
if (oldIndex >= 0) {
|
|
199
172
|
const old = this.domItem(oldIndex);
|
|
200
173
|
if (old && !old.destroyed) {
|
package/browser/Core/Particle.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { calcExactPositionOrRandomFromSize, clamp, getDistance, getParticleBaseVelocity, getParticleDirectionAngle, getRandom, getRangeValue,
|
|
1
|
+
import { calcExactPositionOrRandomFromSize, clamp, getDistance, getParticleBaseVelocity, getParticleDirectionAngle, getRandom, getRangeValue, randomInRange, setRangeValue, } from "../Utils/NumberUtils.js";
|
|
2
2
|
import { deepExtend, getPosition, initParticleNumericAnimationValue, isInArray, itemFromSingleOrMultiple, } from "../Utils/Utils.js";
|
|
3
3
|
import { getHslFromAnimation, rangeColorToRgb } from "../Utils/ColorUtils.js";
|
|
4
4
|
import { Interactivity } from "../Options/Classes/Interactivity/Interactivity.js";
|
|
@@ -7,7 +7,27 @@ import { Vector3d } from "./Utils/Vector3d.js";
|
|
|
7
7
|
import { alterHsl } from "../Utils/CanvasUtils.js";
|
|
8
8
|
import { errorPrefix } from "./Utils/Constants.js";
|
|
9
9
|
import { loadParticlesOptions } from "../Utils/OptionsUtils.js";
|
|
10
|
-
|
|
10
|
+
function loadEffectData(effect, effectOptions, id, reduceDuplicates) {
|
|
11
|
+
const effectData = effectOptions.options[effect];
|
|
12
|
+
if (!effectData) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
return deepExtend({
|
|
16
|
+
close: effectOptions.close,
|
|
17
|
+
fill: effectOptions.fill,
|
|
18
|
+
}, itemFromSingleOrMultiple(effectData, id, reduceDuplicates));
|
|
19
|
+
}
|
|
20
|
+
function loadShapeData(shape, shapeOptions, id, reduceDuplicates) {
|
|
21
|
+
const shapeData = shapeOptions.options[shape];
|
|
22
|
+
if (!shapeData) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
return deepExtend({
|
|
26
|
+
close: shapeOptions.close,
|
|
27
|
+
fill: shapeOptions.fill,
|
|
28
|
+
}, itemFromSingleOrMultiple(shapeData, id, reduceDuplicates));
|
|
29
|
+
}
|
|
30
|
+
function fixOutMode(data) {
|
|
11
31
|
if (!isInArray(data.outMode, data.checkModes)) {
|
|
12
32
|
return;
|
|
13
33
|
}
|
|
@@ -18,7 +38,7 @@ const fixOutMode = (data) => {
|
|
|
18
38
|
else if (data.coord < diameter) {
|
|
19
39
|
data.setCb(data.radius);
|
|
20
40
|
}
|
|
21
|
-
}
|
|
41
|
+
}
|
|
22
42
|
export class Particle {
|
|
23
43
|
constructor(engine, id, container, position, overrideOptions, group) {
|
|
24
44
|
this.container = container;
|
|
@@ -66,8 +86,8 @@ export class Particle {
|
|
|
66
86
|
return res;
|
|
67
87
|
}
|
|
68
88
|
const rad = (Math.PI / 180) * getRangeValue(moveOptions.angle.value), radOffset = (Math.PI / 180) * getRangeValue(moveOptions.angle.offset), range = {
|
|
69
|
-
left: radOffset - rad
|
|
70
|
-
right: radOffset + rad
|
|
89
|
+
left: radOffset - rad * 0.5,
|
|
90
|
+
right: radOffset + rad * 0.5,
|
|
71
91
|
};
|
|
72
92
|
if (!moveOptions.straight) {
|
|
73
93
|
res.angle += randomInRange(setRangeValue(range.left, range.right));
|
|
@@ -96,7 +116,7 @@ export class Particle {
|
|
|
96
116
|
if (!color || !this.roll || (!this.backColor && !this.roll.alter)) {
|
|
97
117
|
return color;
|
|
98
118
|
}
|
|
99
|
-
const backFactor = this.roll.horizontal && this.roll.vertical ? 2 : 1, backSum = this.roll.horizontal ? Math.PI
|
|
119
|
+
const backFactor = this.roll.horizontal && this.roll.vertical ? 2 : 1, backSum = this.roll.horizontal ? Math.PI * 0.5 : 0, rolled = Math.floor(((this.roll.angle ?? 0) + backSum) / (Math.PI / backFactor)) % 2;
|
|
100
120
|
if (!rolled) {
|
|
101
121
|
return color;
|
|
102
122
|
}
|
|
@@ -129,16 +149,6 @@ export class Particle {
|
|
|
129
149
|
}
|
|
130
150
|
this.offset = Vector.origin;
|
|
131
151
|
};
|
|
132
|
-
this._loadShapeData = (shapeOptions, reduceDuplicates) => {
|
|
133
|
-
const shapeData = shapeOptions.options[this.shape];
|
|
134
|
-
if (!shapeData) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
return deepExtend({
|
|
138
|
-
close: shapeOptions.close,
|
|
139
|
-
fill: shapeOptions.fill,
|
|
140
|
-
}, itemFromSingleOrMultiple(shapeData, this.id, reduceDuplicates));
|
|
141
|
-
};
|
|
142
152
|
this._engine = engine;
|
|
143
153
|
this.init(id, position, overrideOptions, group);
|
|
144
154
|
}
|
|
@@ -151,18 +161,12 @@ export class Particle {
|
|
|
151
161
|
this.slow.inRange = false;
|
|
152
162
|
const container = this.container, pathGenerator = this.pathGenerator;
|
|
153
163
|
for (const [, plugin] of container.plugins) {
|
|
154
|
-
|
|
155
|
-
plugin.particleDestroyed(this, override);
|
|
156
|
-
}
|
|
164
|
+
plugin.particleDestroyed && plugin.particleDestroyed(this, override);
|
|
157
165
|
}
|
|
158
166
|
for (const updater of container.particles.updaters) {
|
|
159
|
-
|
|
160
|
-
updater.particleDestroyed(this, override);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
if (pathGenerator) {
|
|
164
|
-
pathGenerator.reset(this);
|
|
167
|
+
updater.particleDestroyed && updater.particleDestroyed(this, override);
|
|
165
168
|
}
|
|
169
|
+
pathGenerator && pathGenerator.reset(this);
|
|
166
170
|
}
|
|
167
171
|
draw(delta) {
|
|
168
172
|
const container = this.container, canvas = container.canvas;
|
|
@@ -175,7 +179,7 @@ export class Particle {
|
|
|
175
179
|
return this._getRollColor(this.bubble.color ?? getHslFromAnimation(this.color));
|
|
176
180
|
}
|
|
177
181
|
getMass() {
|
|
178
|
-
return
|
|
182
|
+
return this.getRadius() ** 2 * Math.PI * 0.5;
|
|
179
183
|
}
|
|
180
184
|
getPosition() {
|
|
181
185
|
return {
|
|
@@ -194,9 +198,11 @@ export class Particle {
|
|
|
194
198
|
const container = this.container, engine = this._engine;
|
|
195
199
|
this.id = id;
|
|
196
200
|
this.group = group;
|
|
197
|
-
this.
|
|
201
|
+
this.effectClose = true;
|
|
202
|
+
this.effectFill = true;
|
|
203
|
+
this.shapeClose = true;
|
|
204
|
+
this.shapeFill = true;
|
|
198
205
|
this.pathRotation = false;
|
|
199
|
-
this.close = true;
|
|
200
206
|
this.lastPathTime = 0;
|
|
201
207
|
this.destroyed = false;
|
|
202
208
|
this.unbreakable = false;
|
|
@@ -207,18 +213,33 @@ export class Particle {
|
|
|
207
213
|
};
|
|
208
214
|
this.outType = "normal";
|
|
209
215
|
this.ignoresResizeRatio = true;
|
|
210
|
-
const pxRatio = container.retina.pixelRatio, mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this._engine, container, mainOptions.particles), shapeType = particlesOptions.shape.type, { reduceDuplicates } = particlesOptions;
|
|
216
|
+
const pxRatio = container.retina.pixelRatio, mainOptions = container.actualOptions, particlesOptions = loadParticlesOptions(this._engine, container, mainOptions.particles), effectType = particlesOptions.effect.type, shapeType = particlesOptions.shape.type, { reduceDuplicates } = particlesOptions;
|
|
217
|
+
this.effect = itemFromSingleOrMultiple(effectType, this.id, reduceDuplicates);
|
|
211
218
|
this.shape = itemFromSingleOrMultiple(shapeType, this.id, reduceDuplicates);
|
|
212
|
-
const shapeOptions = particlesOptions.shape;
|
|
213
|
-
if (overrideOptions
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
219
|
+
const effectOptions = particlesOptions.effect, shapeOptions = particlesOptions.shape;
|
|
220
|
+
if (overrideOptions) {
|
|
221
|
+
if (overrideOptions.effect && overrideOptions.effect.type) {
|
|
222
|
+
const overrideEffectType = overrideOptions.effect.type, effect = itemFromSingleOrMultiple(overrideEffectType, this.id, reduceDuplicates);
|
|
223
|
+
if (effect) {
|
|
224
|
+
this.effect = effect;
|
|
225
|
+
effectOptions.load(overrideOptions.effect);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (overrideOptions.shape && overrideOptions.shape.type) {
|
|
229
|
+
const overrideShapeType = overrideOptions.shape.type, shape = itemFromSingleOrMultiple(overrideShapeType, this.id, reduceDuplicates);
|
|
230
|
+
if (shape) {
|
|
231
|
+
this.shape = shape;
|
|
232
|
+
shapeOptions.load(overrideOptions.shape);
|
|
233
|
+
}
|
|
218
234
|
}
|
|
219
235
|
}
|
|
220
|
-
this.
|
|
236
|
+
this.effectData = loadEffectData(this.effect, effectOptions, this.id, reduceDuplicates);
|
|
237
|
+
this.shapeData = loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates);
|
|
221
238
|
particlesOptions.load(overrideOptions);
|
|
239
|
+
const effectData = this.effectData;
|
|
240
|
+
if (effectData) {
|
|
241
|
+
particlesOptions.load(effectData.particles);
|
|
242
|
+
}
|
|
222
243
|
const shapeData = this.shapeData;
|
|
223
244
|
if (shapeData) {
|
|
224
245
|
particlesOptions.load(shapeData.particles);
|
|
@@ -227,11 +248,13 @@ export class Particle {
|
|
|
227
248
|
interactivity.load(container.actualOptions.interactivity);
|
|
228
249
|
interactivity.load(particlesOptions.interactivity);
|
|
229
250
|
this.interactivity = interactivity;
|
|
230
|
-
this.
|
|
231
|
-
this.
|
|
251
|
+
this.effectFill = effectData?.fill ?? particlesOptions.effect.fill;
|
|
252
|
+
this.effectClose = effectData?.close ?? particlesOptions.effect.close;
|
|
253
|
+
this.shapeFill = shapeData?.fill ?? particlesOptions.shape.fill;
|
|
254
|
+
this.shapeClose = shapeData?.close ?? particlesOptions.shape.close;
|
|
232
255
|
this.options = particlesOptions;
|
|
233
256
|
const pathOptions = this.options.move.path;
|
|
234
|
-
this.pathDelay =
|
|
257
|
+
this.pathDelay = getRangeValue(pathOptions.delay.value) * 1000;
|
|
235
258
|
if (pathOptions.generator) {
|
|
236
259
|
this.pathGenerator = this._engine.getPathGenerator(pathOptions.generator);
|
|
237
260
|
if (this.pathGenerator && container.addPath(pathOptions.generator, this.pathGenerator)) {
|
|
@@ -252,34 +275,46 @@ export class Particle {
|
|
|
252
275
|
this.velocity = this.initialVelocity.copy();
|
|
253
276
|
this.moveDecay = 1 - getRangeValue(this.options.move.decay);
|
|
254
277
|
const particles = container.particles;
|
|
255
|
-
particles.
|
|
256
|
-
particles.lastZIndex = this.position.z;
|
|
278
|
+
particles.setLastZIndex(this.position.z);
|
|
257
279
|
this.zIndexFactor = this.position.z / container.zLayers;
|
|
258
280
|
this.sides = 24;
|
|
259
|
-
let
|
|
260
|
-
if (!
|
|
261
|
-
|
|
262
|
-
if (
|
|
263
|
-
container.
|
|
281
|
+
let effectDrawer = container.effectDrawers.get(this.effect);
|
|
282
|
+
if (!effectDrawer) {
|
|
283
|
+
effectDrawer = this._engine.getEffectDrawer(this.effect);
|
|
284
|
+
if (effectDrawer) {
|
|
285
|
+
container.effectDrawers.set(this.effect, effectDrawer);
|
|
264
286
|
}
|
|
265
287
|
}
|
|
266
|
-
if (
|
|
267
|
-
|
|
288
|
+
if (effectDrawer && effectDrawer.loadEffect) {
|
|
289
|
+
effectDrawer.loadEffect(this);
|
|
268
290
|
}
|
|
269
|
-
|
|
291
|
+
let shapeDrawer = container.shapeDrawers.get(this.shape);
|
|
292
|
+
if (!shapeDrawer) {
|
|
293
|
+
shapeDrawer = this._engine.getShapeDrawer(this.shape);
|
|
294
|
+
if (shapeDrawer) {
|
|
295
|
+
container.shapeDrawers.set(this.shape, shapeDrawer);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (shapeDrawer && shapeDrawer.loadShape) {
|
|
299
|
+
shapeDrawer.loadShape(this);
|
|
300
|
+
}
|
|
301
|
+
const sideCountFunc = shapeDrawer?.getSidesCount;
|
|
270
302
|
if (sideCountFunc) {
|
|
271
303
|
this.sides = sideCountFunc(this);
|
|
272
304
|
}
|
|
273
305
|
this.spawning = false;
|
|
274
306
|
this.shadowColor = rangeColorToRgb(this.options.shadow.color);
|
|
275
|
-
for (const updater of
|
|
307
|
+
for (const updater of particles.updaters) {
|
|
276
308
|
updater.init(this);
|
|
277
309
|
}
|
|
278
|
-
for (const mover of
|
|
310
|
+
for (const mover of particles.movers) {
|
|
279
311
|
mover.init && mover.init(this);
|
|
280
312
|
}
|
|
281
|
-
if (
|
|
282
|
-
|
|
313
|
+
if (effectDrawer && effectDrawer.particleInit) {
|
|
314
|
+
effectDrawer.particleInit(container, this);
|
|
315
|
+
}
|
|
316
|
+
if (shapeDrawer && shapeDrawer.particleInit) {
|
|
317
|
+
shapeDrawer.particleInit(container, this);
|
|
283
318
|
}
|
|
284
319
|
for (const [, plugin] of container.plugins) {
|
|
285
320
|
plugin.particleCreated && plugin.particleCreated(this);
|