@tsparticles/engine 3.0.0-beta.1 → 3.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/README.md +8 -8
  2. package/browser/Core/Container.js +3 -5
  3. package/browser/Core/Engine.js +10 -50
  4. package/browser/Core/Particle.js +13 -13
  5. package/browser/Core/Particles.js +3 -2
  6. package/browser/Utils/CanvasUtils.js +9 -6
  7. package/browser/Utils/Utils.js +6 -0
  8. package/browser/export-types.js +0 -2
  9. package/cjs/Core/Container.js +3 -5
  10. package/cjs/Core/Engine.js +9 -49
  11. package/cjs/Core/Particle.js +13 -13
  12. package/cjs/Core/Particles.js +3 -2
  13. package/cjs/Utils/CanvasUtils.js +9 -6
  14. package/cjs/Utils/Utils.js +8 -1
  15. package/cjs/export-types.js +0 -2
  16. package/esm/Core/Container.js +3 -5
  17. package/esm/Core/Engine.js +10 -50
  18. package/esm/Core/Particle.js +13 -13
  19. package/esm/Core/Particles.js +3 -2
  20. package/esm/Utils/CanvasUtils.js +9 -6
  21. package/esm/Utils/Utils.js +6 -0
  22. package/esm/export-types.js +0 -2
  23. package/package.json +3 -3
  24. package/report.html +23 -5
  25. package/scripts/install.js +8 -8
  26. package/tsparticles.engine.js +83 -72
  27. package/tsparticles.engine.min.js +1 -1
  28. package/tsparticles.engine.min.js.LICENSE.txt +1 -1
  29. package/types/Core/Container.d.ts +2 -2
  30. package/types/Core/Engine.d.ts +3 -4
  31. package/types/Core/Interfaces/IShapeDrawer.d.ts +19 -9
  32. package/types/Core/Particle.d.ts +1 -3
  33. package/types/Enums/Types/EventType.d.ts +1 -0
  34. package/types/Types/CustomEventArgs.d.ts +1 -1
  35. package/types/Utils/CanvasUtils.d.ts +11 -2
  36. package/types/Utils/ColorUtils.d.ts +2 -2
  37. package/types/Utils/Utils.d.ts +4 -3
  38. package/types/export-types.d.ts +0 -2
  39. package/umd/Core/Container.js +4 -6
  40. package/umd/Core/Engine.js +9 -49
  41. package/umd/Core/Particle.js +13 -13
  42. package/umd/Core/Particles.js +3 -2
  43. package/umd/Utils/CanvasUtils.js +9 -6
  44. package/umd/Utils/Utils.js +8 -1
  45. package/umd/export-types.js +1 -3
  46. package/browser/Core/Interfaces/IParticle.js +0 -1
  47. package/browser/Types/ShapeDrawerFunctions.js +0 -1
  48. package/cjs/Core/Interfaces/IParticle.js +0 -2
  49. package/cjs/Types/ShapeDrawerFunctions.js +0 -2
  50. package/esm/Core/Interfaces/IParticle.js +0 -1
  51. package/esm/Types/ShapeDrawerFunctions.js +0 -1
  52. package/types/Core/Interfaces/IParticle.d.ts +0 -48
  53. package/types/Types/ShapeDrawerFunctions.d.ts +0 -10
  54. package/umd/Core/Interfaces/IParticle.js +0 -12
  55. package/umd/Types/ShapeDrawerFunctions.js +0 -12
package/README.md CHANGED
@@ -11,11 +11,11 @@ React.js, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Inferno, Riot.j
11
11
  [![npm](https://img.shields.io/npm/v/@tsparticles/engine?style=for-the-badge)](https://www.npmjs.com/package/tsparticles)
12
12
  [![npm](https://img.shields.io/npm/dm/tsparticles?style=for-the-badge)](https://www.npmjs.com/package/tsparticles)
13
13
  [![lerna](https://img.shields.io/badge/maintained%20with-lerna-cc00ff?style=for-the-badge)](https://lerna.js.org/)
14
- [![CodeFactor](https://www.codefactor.io/repository/github/matteobruni/tsparticles/badge)](https://www.codefactor.io/repository/github/matteobruni/tsparticles)
15
- [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b983aaf3461a4c48b1e2eecce1ff1d74)](https://www.codacy.com/manual/ar3s/tsparticles?utm_source=github.com&utm_medium=referral&utm_content=matteobruni/tsparticles&utm_campaign=Badge_Grade)
14
+ [![CodeFactor](https://www.codefactor.io/repository/github/tsparticles/tsparticles/badge)](https://www.codefactor.io/repository/github/tsparticles/tsparticles)
15
+ [![Codacy Badge](https://api.codacy.com/project/badge/Grade/b983aaf3461a4c48b1e2eecce1ff1d74)](https://www.codacy.com/manual/ar3s/tsparticles?utm_source=github.com&utm_medium=referral&utm_content=tsparticles/tsparticles&utm_campaign=Badge_Grade)
16
16
  [![Rate this package](https://badges.openbase.com/js/rating/tsparticles.svg?style=openbase&token=A9jHQ1nkb6fnCndKM7O2w4hx3OD8PVCuqHtSpw8mMOg=)](https://openbase.com/js/tsparticles?utm_source=embedded&utm_medium=badge&utm_campaign=rating-badge&utm_term=js/tsparticles)
17
- [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/matteobruni/tsparticles)
18
- [![Run on Repl.it](https://repl.it/badge/github/matteobruni/tsparticles)](https://repl.it/github/matteobruni/tsparticles)
17
+ [![Gitpod Ready-to-Code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](https://gitpod.io/#https://github.com/tsparticles/tsparticles)
18
+ [![Run on Repl.it](https://repl.it/badge/github/tsparticles/tsparticles)](https://repl.it/github/tsparticles/tsparticles)
19
19
 
20
20
  [![Discord](https://img.shields.io/discord/872061157379301416?label=discord&logo=discord&logoColor=white&style=for-the-badge)](https://discord.gg/hACwv45Hme)
21
21
  [![Slack](https://particles.js.org/images/slack.png)](https://join.slack.com/t/tsparticles/shared_invite/enQtOTcxNTQxNjQ4NzkxLWE2MTZhZWExMWRmOWI5MTMxNjczOGE1Yjk0MjViYjdkYTUzODM3OTc5MGQ5MjFlODc4MzE0N2Q1OWQxZDc1YzI)
@@ -114,7 +114,7 @@ particles.js
114
114
  it's even easier**.
115
115
 
116
116
  You'll find the
117
- instructions [below](https://github.com/matteobruni/tsparticles/blob/main/README.md#library-installation), with all the
117
+ instructions [below](https://github.com/tsparticles/tsparticles/blob/main/README.md#library-installation), with all the
118
118
  links you need, and _don't be scared by **TypeScript**, it's just the source language_.
119
119
 
120
120
  **The output files are just JavaScript**. 🤩
@@ -124,7 +124,7 @@ all
124
124
  files splitted for `import` syntax.
125
125
 
126
126
  **If you are interested** there are some _simple instructions_
127
- just [below](https://github.com/matteobruni/tsparticles/blob/main/README.md#library-installation) to guide you to
127
+ just [below](https://github.com/tsparticles/tsparticles/blob/main/README.md#library-installation) to guide you to
128
128
  migrate from the old particles.js library.
129
129
 
130
130
  ## **_Library installation_**
@@ -839,10 +839,10 @@ e --> u
839
839
 
840
840
  <p>
841
841
  <a href="https://www.jetbrains.com/?from=tsParticles">
842
- <img src="https://raw.githubusercontent.com/matteobruni/tsparticles/gh-pages/images/jetbrains-logos/jetbrains-variant-4.png" height="150" alt="JetBrains" />
842
+ <img src="https://raw.githubusercontent.com/tsparticles/tsparticles/gh-pages/images/jetbrains-logos/jetbrains-variant-4.png" height="150" alt="JetBrains" />
843
843
  </a>
844
844
  <a href="https://www.jetbrains.com/webstorm/?from=tsParticles">
845
- <img src="https://raw.githubusercontent.com/matteobruni/tsparticles/gh-pages/images/jetbrains-logos/logo.png" height="150" alt="JetBrains" />
845
+ <img src="https://raw.githubusercontent.com/tsparticles/tsparticles/gh-pages/images/jetbrains-logos/logo.png" height="150" alt="JetBrains" />
846
846
  </a>
847
847
  </p>
848
848
 
@@ -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;
@@ -65,6 +64,7 @@ export class Container {
65
64
  }
66
65
  };
67
66
  this._engine = engine;
67
+ this.id = Symbol(id);
68
68
  this.fpsLimit = 120;
69
69
  this.smooth = false;
70
70
  this._delay = 0;
@@ -94,9 +94,7 @@ export class Container {
94
94
  this._options = loadContainerOptions(this._engine, this);
95
95
  this.actualOptions = loadContainerOptions(this._engine, this);
96
96
  this._eventListeners = new EventListeners(this);
97
- if (typeof IntersectionObserver !== "undefined" && IntersectionObserver) {
98
- this._intersectionObserver = new IntersectionObserver((entries) => this._intersectionManager(entries));
99
- }
97
+ this._intersectionObserver = safeIntersectionObserver((entries) => this._intersectionManager(entries));
100
98
  this._engine.dispatchEvent("containerBuilt", { container: this });
101
99
  }
102
100
  get options() {
@@ -1,5 +1,5 @@
1
1
  import { errorPrefix, generatedAttribute } from "./Utils/Constants.js";
2
- import { executeOnSingleOrMultiple, getLogger, isBoolean, isFunction, isString, itemFromSingleOrMultiple, } from "../Utils/Utils.js";
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";
@@ -50,18 +50,12 @@ export class Engine {
50
50
  return res;
51
51
  }
52
52
  get version() {
53
- return "3.0.0-beta.1";
53
+ return "3.0.0-beta.3";
54
54
  }
55
- addConfig(nameOrConfig, config) {
56
- if (isString(nameOrConfig)) {
57
- if (config) {
58
- config.name = nameOrConfig;
59
- this._configs.set(nameOrConfig, config);
60
- }
61
- }
62
- else {
63
- this._configs.set(nameOrConfig.name ?? "default", nameOrConfig);
64
- }
55
+ addConfig(config) {
56
+ const name = config.name ?? "default";
57
+ this._configs.set(name, config);
58
+ this._eventDispatcher.dispatchEvent("configAdded", { data: { name, config } });
65
59
  }
66
60
  addEventListener(type, listener) {
67
61
  this._eventDispatcher.addEventListener(type, listener);
@@ -90,45 +84,11 @@ export class Engine {
90
84
  (override || !this.getPreset(preset)) && this.presets.set(preset, options);
91
85
  await this.refresh(refresh);
92
86
  }
93
- async addShape(shape, drawer, initOrRefresh, afterEffectOrRefresh, destroyOrRefresh, refresh = true) {
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
- }
87
+ async addShape(shape, drawer, refresh = true) {
128
88
  executeOnSingleOrMultiple(shape, (type) => {
129
- !this.getShapeDrawer(type) && this.drawers.set(type, customDrawer);
89
+ !this.getShapeDrawer(type) && this.drawers.set(type, drawer);
130
90
  });
131
- await this.refresh(realRefresh);
91
+ await this.refresh(refresh);
132
92
  }
133
93
  clearPlugins(container) {
134
94
  this.updaters.delete(container);
@@ -194,7 +154,7 @@ export class Engine {
194
154
  domContainer.id = id;
195
155
  document.body.append(domContainer);
196
156
  }
197
- const currentOptions = itemFromSingleOrMultiple(options, index), dom = this.dom(), oldIndex = dom.findIndex((v) => v.id === id);
157
+ const currentOptions = itemFromSingleOrMultiple(options, index), dom = this.dom(), oldIndex = dom.findIndex((v) => v.id.description === id);
198
158
  if (oldIndex >= 0) {
199
159
  const old = this.domItem(oldIndex);
200
160
  if (old && !old.destroyed) {
@@ -7,7 +7,17 @@ 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
- const fixOutMode = (data) => {
10
+ function loadShapeData(shape, shapeOptions, id, reduceDuplicates) {
11
+ const shapeData = shapeOptions.options[shape];
12
+ if (!shapeData) {
13
+ return;
14
+ }
15
+ return deepExtend({
16
+ close: shapeOptions.close,
17
+ fill: shapeOptions.fill,
18
+ }, itemFromSingleOrMultiple(shapeData, id, reduceDuplicates));
19
+ }
20
+ function fixOutMode(data) {
11
21
  if (!isInArray(data.outMode, data.checkModes)) {
12
22
  return;
13
23
  }
@@ -18,7 +28,7 @@ const fixOutMode = (data) => {
18
28
  else if (data.coord < diameter) {
19
29
  data.setCb(data.radius);
20
30
  }
21
- };
31
+ }
22
32
  export class Particle {
23
33
  constructor(engine, id, container, position, overrideOptions, group) {
24
34
  this.container = container;
@@ -129,16 +139,6 @@ export class Particle {
129
139
  }
130
140
  this.offset = Vector.origin;
131
141
  };
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
142
  this._engine = engine;
143
143
  this.init(id, position, overrideOptions, group);
144
144
  }
@@ -217,7 +217,7 @@ export class Particle {
217
217
  shapeOptions.load(overrideOptions.shape);
218
218
  }
219
219
  }
220
- this.shapeData = this._loadShapeData(shapeOptions, reduceDuplicates);
220
+ this.shapeData = loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates);
221
221
  particlesOptions.load(overrideOptions);
222
222
  const shapeData = this.shapeData;
223
223
  if (shapeData) {
@@ -70,8 +70,9 @@ export class Particles {
70
70
  return false;
71
71
  }
72
72
  particle.destroy(override);
73
+ const zIdx = this._zArray.indexOf(particle);
73
74
  this._array.splice(index, 1);
74
- this._zArray = this._zArray.splice(this._zArray.indexOf(particle), 1);
75
+ this._zArray.splice(zIdx, 1);
75
76
  this.pool.push(particle);
76
77
  this._engine.dispatchEvent("particleRemoved", {
77
78
  container: this._container,
@@ -172,7 +173,7 @@ export class Particles {
172
173
  }
173
174
  this.addManualParticles();
174
175
  if (!handled) {
175
- const particlesOptions = options.particles, groups = options.particles.groups;
176
+ const particlesOptions = options.particles, groups = particlesOptions.groups;
176
177
  for (const group in groups) {
177
178
  const groupOptions = groups[group];
178
179
  for (let i = this.count, j = 0; j < groupOptions.number?.value && i < particlesOptions.number.value; i++, j++) {
@@ -58,7 +58,8 @@ export function drawParticle(data) {
58
58
  if (colorStyles.stroke) {
59
59
  context.strokeStyle = colorStyles.stroke;
60
60
  }
61
- drawShape(container, context, particle, radius, opacity, delta);
61
+ const drawData = { container, context, particle, radius, opacity, delta };
62
+ drawShape(drawData);
62
63
  if (strokeWidth > 0) {
63
64
  context.stroke();
64
65
  }
@@ -68,11 +69,12 @@ export function drawParticle(data) {
68
69
  if (particle.fill) {
69
70
  context.fill();
70
71
  }
71
- drawShapeAfterEffect(container, context, particle, radius, opacity, delta);
72
+ drawShapeAfterEffect(drawData);
72
73
  context.globalCompositeOperation = "source-over";
73
74
  context.setTransform(1, 0, 0, 1, 0, 0);
74
75
  }
75
- export function drawShape(container, context, particle, radius, opacity, delta) {
76
+ export function drawShape(data) {
77
+ const { container, context, particle, radius, opacity, delta } = data;
76
78
  if (!particle.shape) {
77
79
  return;
78
80
  }
@@ -80,9 +82,10 @@ export function drawShape(container, context, particle, radius, opacity, delta)
80
82
  if (!drawer) {
81
83
  return;
82
84
  }
83
- drawer.draw(context, particle, radius, opacity, delta, container.retina.pixelRatio);
85
+ drawer.draw({ context, particle, radius, opacity, delta, pixelRatio: container.retina.pixelRatio });
84
86
  }
85
- export function drawShapeAfterEffect(container, context, particle, radius, opacity, delta) {
87
+ export function drawShapeAfterEffect(data) {
88
+ const { container, context, particle, radius, opacity, delta } = data;
86
89
  if (!particle.shape) {
87
90
  return;
88
91
  }
@@ -90,7 +93,7 @@ export function drawShapeAfterEffect(container, context, particle, radius, opaci
90
93
  if (!drawer || !drawer.afterEffect) {
91
94
  return;
92
95
  }
93
- drawer.afterEffect(context, particle, radius, opacity, delta, container.retina.pixelRatio);
96
+ drawer.afterEffect({ context, particle, radius, opacity, delta, pixelRatio: container.retina.pixelRatio });
94
97
  }
95
98
  export function drawPlugin(context, plugin, delta) {
96
99
  if (!plugin.draw) {
@@ -52,6 +52,12 @@ export function safeMatchMedia(query) {
52
52
  }
53
53
  return matchMedia(query);
54
54
  }
55
+ export function safeIntersectionObserver(callback) {
56
+ if (isSsr() || typeof IntersectionObserver === "undefined") {
57
+ return;
58
+ }
59
+ return new IntersectionObserver(callback);
60
+ }
55
61
  export function safeMutationObserver(callback) {
56
62
  if (isSsr() || typeof MutationObserver === "undefined") {
57
63
  return;
@@ -15,7 +15,6 @@ export * from "./Core/Interfaces/IInteractor.js";
15
15
  export * from "./Core/Interfaces/ILoadParams.js";
16
16
  export * from "./Core/Interfaces/IMouseData.js";
17
17
  export * from "./Core/Interfaces/IMovePathGenerator.js";
18
- export * from "./Core/Interfaces/IParticle.js";
19
18
  export * from "./Core/Interfaces/IParticleColorStyle.js";
20
19
  export * from "./Core/Interfaces/IParticleHslAnimation.js";
21
20
  export * from "./Core/Interfaces/IParticleLife.js";
@@ -93,5 +92,4 @@ export * from "./Types/PathOptions.js";
93
92
  export * from "./Types/RangeValue.js";
94
93
  export * from "./Types/RecursivePartial.js";
95
94
  export * from "./Types/ShapeData.js";
96
- export * from "./Types/ShapeDrawerFunctions.js";
97
95
  export * from "./Types/SingleOrMultiple.js";
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Container = void 0;
4
+ const Utils_js_1 = require("../Utils/Utils.js");
4
5
  const Canvas_js_1 = require("./Canvas.js");
5
6
  const EventListeners_js_1 = require("./Utils/EventListeners.js");
6
7
  const Options_js_1 = require("../Options/Classes/Options.js");
7
8
  const Particles_js_1 = require("./Particles.js");
8
9
  const Retina_js_1 = require("./Retina.js");
9
10
  const Constants_js_1 = require("./Utils/Constants.js");
10
- const Utils_js_1 = require("../Utils/Utils.js");
11
11
  const NumberUtils_js_1 = require("../Utils/NumberUtils.js");
12
12
  const OptionsUtils_js_1 = require("../Utils/OptionsUtils.js");
13
13
  function guardCheck(container) {
@@ -26,7 +26,6 @@ function loadContainerOptions(engine, container, ...sourceOptionsArr) {
26
26
  }
27
27
  class Container {
28
28
  constructor(engine, id, sourceOptions) {
29
- this.id = id;
30
29
  this._intersectionManager = (entries) => {
31
30
  if (!guardCheck(this) || !this.actualOptions.pauseOnOutsideViewport) {
32
31
  return;
@@ -68,6 +67,7 @@ class Container {
68
67
  }
69
68
  };
70
69
  this._engine = engine;
70
+ this.id = Symbol(id);
71
71
  this.fpsLimit = 120;
72
72
  this.smooth = false;
73
73
  this._delay = 0;
@@ -97,9 +97,7 @@ class Container {
97
97
  this._options = loadContainerOptions(this._engine, this);
98
98
  this.actualOptions = loadContainerOptions(this._engine, this);
99
99
  this._eventListeners = new EventListeners_js_1.EventListeners(this);
100
- if (typeof IntersectionObserver !== "undefined" && IntersectionObserver) {
101
- this._intersectionObserver = new IntersectionObserver((entries) => this._intersectionManager(entries));
102
- }
100
+ this._intersectionObserver = (0, Utils_js_1.safeIntersectionObserver)((entries) => this._intersectionManager(entries));
103
101
  this._engine.dispatchEvent("containerBuilt", { container: this });
104
102
  }
105
103
  get options() {
@@ -53,18 +53,12 @@ class Engine {
53
53
  return res;
54
54
  }
55
55
  get version() {
56
- return "3.0.0-beta.1";
56
+ return "3.0.0-beta.3";
57
57
  }
58
- addConfig(nameOrConfig, config) {
59
- if ((0, Utils_js_1.isString)(nameOrConfig)) {
60
- if (config) {
61
- config.name = nameOrConfig;
62
- this._configs.set(nameOrConfig, config);
63
- }
64
- }
65
- else {
66
- this._configs.set(nameOrConfig.name ?? "default", nameOrConfig);
67
- }
58
+ addConfig(config) {
59
+ const name = config.name ?? "default";
60
+ this._configs.set(name, config);
61
+ this._eventDispatcher.dispatchEvent("configAdded", { data: { name, config } });
68
62
  }
69
63
  addEventListener(type, listener) {
70
64
  this._eventDispatcher.addEventListener(type, listener);
@@ -93,45 +87,11 @@ class Engine {
93
87
  (override || !this.getPreset(preset)) && this.presets.set(preset, options);
94
88
  await this.refresh(refresh);
95
89
  }
96
- async addShape(shape, drawer, initOrRefresh, afterEffectOrRefresh, destroyOrRefresh, refresh = true) {
97
- let customDrawer;
98
- let realRefresh = refresh, realInit, realAfterEffect, realDestroy;
99
- if ((0, Utils_js_1.isBoolean)(initOrRefresh)) {
100
- realRefresh = initOrRefresh;
101
- realInit = undefined;
102
- }
103
- else {
104
- realInit = initOrRefresh;
105
- }
106
- if ((0, Utils_js_1.isBoolean)(afterEffectOrRefresh)) {
107
- realRefresh = afterEffectOrRefresh;
108
- realAfterEffect = undefined;
109
- }
110
- else {
111
- realAfterEffect = afterEffectOrRefresh;
112
- }
113
- if ((0, Utils_js_1.isBoolean)(destroyOrRefresh)) {
114
- realRefresh = destroyOrRefresh;
115
- realDestroy = undefined;
116
- }
117
- else {
118
- realDestroy = destroyOrRefresh;
119
- }
120
- if ((0, Utils_js_1.isFunction)(drawer)) {
121
- customDrawer = {
122
- afterEffect: realAfterEffect,
123
- destroy: realDestroy,
124
- draw: drawer,
125
- init: realInit,
126
- };
127
- }
128
- else {
129
- customDrawer = drawer;
130
- }
90
+ async addShape(shape, drawer, refresh = true) {
131
91
  (0, Utils_js_1.executeOnSingleOrMultiple)(shape, (type) => {
132
- !this.getShapeDrawer(type) && this.drawers.set(type, customDrawer);
92
+ !this.getShapeDrawer(type) && this.drawers.set(type, drawer);
133
93
  });
134
- await this.refresh(realRefresh);
94
+ await this.refresh(refresh);
135
95
  }
136
96
  clearPlugins(container) {
137
97
  this.updaters.delete(container);
@@ -197,7 +157,7 @@ class Engine {
197
157
  domContainer.id = id;
198
158
  document.body.append(domContainer);
199
159
  }
200
- const currentOptions = (0, Utils_js_1.itemFromSingleOrMultiple)(options, index), dom = this.dom(), oldIndex = dom.findIndex((v) => v.id === id);
160
+ const currentOptions = (0, Utils_js_1.itemFromSingleOrMultiple)(options, index), dom = this.dom(), oldIndex = dom.findIndex((v) => v.id.description === id);
201
161
  if (oldIndex >= 0) {
202
162
  const old = this.domItem(oldIndex);
203
163
  if (old && !old.destroyed) {
@@ -10,7 +10,17 @@ const Vector3d_js_1 = require("./Utils/Vector3d.js");
10
10
  const CanvasUtils_js_1 = require("../Utils/CanvasUtils.js");
11
11
  const Constants_js_1 = require("./Utils/Constants.js");
12
12
  const OptionsUtils_js_1 = require("../Utils/OptionsUtils.js");
13
- const fixOutMode = (data) => {
13
+ function loadShapeData(shape, shapeOptions, id, reduceDuplicates) {
14
+ const shapeData = shapeOptions.options[shape];
15
+ if (!shapeData) {
16
+ return;
17
+ }
18
+ return (0, Utils_js_1.deepExtend)({
19
+ close: shapeOptions.close,
20
+ fill: shapeOptions.fill,
21
+ }, (0, Utils_js_1.itemFromSingleOrMultiple)(shapeData, id, reduceDuplicates));
22
+ }
23
+ function fixOutMode(data) {
14
24
  if (!(0, Utils_js_1.isInArray)(data.outMode, data.checkModes)) {
15
25
  return;
16
26
  }
@@ -21,7 +31,7 @@ const fixOutMode = (data) => {
21
31
  else if (data.coord < diameter) {
22
32
  data.setCb(data.radius);
23
33
  }
24
- };
34
+ }
25
35
  class Particle {
26
36
  constructor(engine, id, container, position, overrideOptions, group) {
27
37
  this.container = container;
@@ -132,16 +142,6 @@ class Particle {
132
142
  }
133
143
  this.offset = Vector_js_1.Vector.origin;
134
144
  };
135
- this._loadShapeData = (shapeOptions, reduceDuplicates) => {
136
- const shapeData = shapeOptions.options[this.shape];
137
- if (!shapeData) {
138
- return;
139
- }
140
- return (0, Utils_js_1.deepExtend)({
141
- close: shapeOptions.close,
142
- fill: shapeOptions.fill,
143
- }, (0, Utils_js_1.itemFromSingleOrMultiple)(shapeData, this.id, reduceDuplicates));
144
- };
145
145
  this._engine = engine;
146
146
  this.init(id, position, overrideOptions, group);
147
147
  }
@@ -220,7 +220,7 @@ class Particle {
220
220
  shapeOptions.load(overrideOptions.shape);
221
221
  }
222
222
  }
223
- this.shapeData = this._loadShapeData(shapeOptions, reduceDuplicates);
223
+ this.shapeData = loadShapeData(this.shape, shapeOptions, this.id, reduceDuplicates);
224
224
  particlesOptions.load(overrideOptions);
225
225
  const shapeData = this.shapeData;
226
226
  if (shapeData) {
@@ -73,8 +73,9 @@ class Particles {
73
73
  return false;
74
74
  }
75
75
  particle.destroy(override);
76
+ const zIdx = this._zArray.indexOf(particle);
76
77
  this._array.splice(index, 1);
77
- this._zArray = this._zArray.splice(this._zArray.indexOf(particle), 1);
78
+ this._zArray.splice(zIdx, 1);
78
79
  this.pool.push(particle);
79
80
  this._engine.dispatchEvent("particleRemoved", {
80
81
  container: this._container,
@@ -175,7 +176,7 @@ class Particles {
175
176
  }
176
177
  this.addManualParticles();
177
178
  if (!handled) {
178
- const particlesOptions = options.particles, groups = options.particles.groups;
179
+ const particlesOptions = options.particles, groups = particlesOptions.groups;
179
180
  for (const group in groups) {
180
181
  const groupOptions = groups[group];
181
182
  for (let i = this.count, j = 0; j < groupOptions.number?.value && i < particlesOptions.number.value; i++, j++) {
@@ -66,7 +66,8 @@ function drawParticle(data) {
66
66
  if (colorStyles.stroke) {
67
67
  context.strokeStyle = colorStyles.stroke;
68
68
  }
69
- drawShape(container, context, particle, radius, opacity, delta);
69
+ const drawData = { container, context, particle, radius, opacity, delta };
70
+ drawShape(drawData);
70
71
  if (strokeWidth > 0) {
71
72
  context.stroke();
72
73
  }
@@ -76,12 +77,13 @@ function drawParticle(data) {
76
77
  if (particle.fill) {
77
78
  context.fill();
78
79
  }
79
- drawShapeAfterEffect(container, context, particle, radius, opacity, delta);
80
+ drawShapeAfterEffect(drawData);
80
81
  context.globalCompositeOperation = "source-over";
81
82
  context.setTransform(1, 0, 0, 1, 0, 0);
82
83
  }
83
84
  exports.drawParticle = drawParticle;
84
- function drawShape(container, context, particle, radius, opacity, delta) {
85
+ function drawShape(data) {
86
+ const { container, context, particle, radius, opacity, delta } = data;
85
87
  if (!particle.shape) {
86
88
  return;
87
89
  }
@@ -89,10 +91,11 @@ function drawShape(container, context, particle, radius, opacity, delta) {
89
91
  if (!drawer) {
90
92
  return;
91
93
  }
92
- drawer.draw(context, particle, radius, opacity, delta, container.retina.pixelRatio);
94
+ drawer.draw({ context, particle, radius, opacity, delta, pixelRatio: container.retina.pixelRatio });
93
95
  }
94
96
  exports.drawShape = drawShape;
95
- function drawShapeAfterEffect(container, context, particle, radius, opacity, delta) {
97
+ function drawShapeAfterEffect(data) {
98
+ const { container, context, particle, radius, opacity, delta } = data;
96
99
  if (!particle.shape) {
97
100
  return;
98
101
  }
@@ -100,7 +103,7 @@ function drawShapeAfterEffect(container, context, particle, radius, opacity, del
100
103
  if (!drawer || !drawer.afterEffect) {
101
104
  return;
102
105
  }
103
- drawer.afterEffect(context, particle, radius, opacity, delta, container.retina.pixelRatio);
106
+ drawer.afterEffect({ context, particle, radius, opacity, delta, pixelRatio: container.retina.pixelRatio });
104
107
  }
105
108
  exports.drawShapeAfterEffect = drawShapeAfterEffect;
106
109
  function drawPlugin(context, plugin, delta) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isArray = exports.isObject = exports.isFunction = exports.isNumber = exports.isString = exports.isBoolean = exports.getSize = exports.getPosition = exports.initParticleNumericAnimationValue = exports.findItemFromSingleOrMultiple = exports.itemFromSingleOrMultiple = exports.executeOnSingleOrMultiple = exports.rectBounce = exports.circleBounce = exports.circleBounceDataFromParticle = exports.divMode = exports.singleDivModeExecute = exports.divModeExecute = exports.isDivModeEnabled = exports.deepExtend = exports.calculateBounds = exports.areBoundsInside = exports.isPointInside = exports.itemFromArray = exports.arrayRandomIndex = exports.loadFont = exports.isInArray = exports.safeMutationObserver = exports.safeMatchMedia = exports.hasMatchMedia = exports.isSsr = exports.getLogger = exports.setLogger = void 0;
3
+ exports.isArray = exports.isObject = exports.isFunction = exports.isNumber = exports.isString = exports.isBoolean = exports.getSize = exports.getPosition = exports.initParticleNumericAnimationValue = exports.findItemFromSingleOrMultiple = exports.itemFromSingleOrMultiple = exports.executeOnSingleOrMultiple = exports.rectBounce = exports.circleBounce = exports.circleBounceDataFromParticle = exports.divMode = exports.singleDivModeExecute = exports.divModeExecute = exports.isDivModeEnabled = exports.deepExtend = exports.calculateBounds = exports.areBoundsInside = exports.isPointInside = exports.itemFromArray = exports.arrayRandomIndex = exports.loadFont = exports.isInArray = exports.safeMutationObserver = exports.safeIntersectionObserver = exports.safeMatchMedia = exports.hasMatchMedia = exports.isSsr = exports.getLogger = exports.setLogger = void 0;
4
4
  const NumberUtils_js_1 = require("./NumberUtils.js");
5
5
  const Vector_js_1 = require("../Core/Utils/Vector.js");
6
6
  const _logger = {
@@ -60,6 +60,13 @@ function safeMatchMedia(query) {
60
60
  return matchMedia(query);
61
61
  }
62
62
  exports.safeMatchMedia = safeMatchMedia;
63
+ function safeIntersectionObserver(callback) {
64
+ if (isSsr() || typeof IntersectionObserver === "undefined") {
65
+ return;
66
+ }
67
+ return new IntersectionObserver(callback);
68
+ }
69
+ exports.safeIntersectionObserver = safeIntersectionObserver;
63
70
  function safeMutationObserver(callback) {
64
71
  if (isSsr() || typeof MutationObserver === "undefined") {
65
72
  return;
@@ -31,7 +31,6 @@ __exportStar(require("./Core/Interfaces/IInteractor.js"), exports);
31
31
  __exportStar(require("./Core/Interfaces/ILoadParams.js"), exports);
32
32
  __exportStar(require("./Core/Interfaces/IMouseData.js"), exports);
33
33
  __exportStar(require("./Core/Interfaces/IMovePathGenerator.js"), exports);
34
- __exportStar(require("./Core/Interfaces/IParticle.js"), exports);
35
34
  __exportStar(require("./Core/Interfaces/IParticleColorStyle.js"), exports);
36
35
  __exportStar(require("./Core/Interfaces/IParticleHslAnimation.js"), exports);
37
36
  __exportStar(require("./Core/Interfaces/IParticleLife.js"), exports);
@@ -109,5 +108,4 @@ __exportStar(require("./Types/PathOptions.js"), exports);
109
108
  __exportStar(require("./Types/RangeValue.js"), exports);
110
109
  __exportStar(require("./Types/RecursivePartial.js"), exports);
111
110
  __exportStar(require("./Types/ShapeData.js"), exports);
112
- __exportStar(require("./Types/ShapeDrawerFunctions.js"), exports);
113
111
  __exportStar(require("./Types/SingleOrMultiple.js"), exports);
@@ -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;
@@ -65,6 +64,7 @@ export class Container {
65
64
  }
66
65
  };
67
66
  this._engine = engine;
67
+ this.id = Symbol(id);
68
68
  this.fpsLimit = 120;
69
69
  this.smooth = false;
70
70
  this._delay = 0;
@@ -94,9 +94,7 @@ export class Container {
94
94
  this._options = loadContainerOptions(this._engine, this);
95
95
  this.actualOptions = loadContainerOptions(this._engine, this);
96
96
  this._eventListeners = new EventListeners(this);
97
- if (typeof IntersectionObserver !== "undefined" && IntersectionObserver) {
98
- this._intersectionObserver = new IntersectionObserver((entries) => this._intersectionManager(entries));
99
- }
97
+ this._intersectionObserver = safeIntersectionObserver((entries) => this._intersectionManager(entries));
100
98
  this._engine.dispatchEvent("containerBuilt", { container: this });
101
99
  }
102
100
  get options() {