@tsparticles/plugin-absorbers 3.0.3 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,9 @@
1
- import { Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, rangeColorToRgb, } from "@tsparticles/engine";
1
+ import { Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, percentDenominator, rangeColorToRgb, } from "@tsparticles/engine";
2
2
  import { Absorber } from "./Options/Classes/Absorber.js";
3
+ const squareExp = 2, absorbFactor = 0.033, minOrbitLength = 0, minRadius = 0, minMass = 0, origin = {
4
+ x: 0,
5
+ y: 0,
6
+ }, minAngle = 0, double = 2, maxAngle = Math.PI * double, minVelocity = 0;
3
7
  export class AbsorberInstance {
4
8
  constructor(absorbers, container, options, position) {
5
9
  this.absorbers = absorbers;
@@ -25,17 +29,17 @@ export class AbsorberInstance {
25
29
  }
26
30
  if (this.options.orbits) {
27
31
  if (particle.absorberOrbit === undefined) {
28
- particle.absorberOrbit = Vector.create(0, 0);
32
+ particle.absorberOrbit = Vector.origin;
29
33
  particle.absorberOrbit.length = getDistance(particle.getPosition(), this.position);
30
- particle.absorberOrbit.angle = getRandom() * Math.PI * 2;
34
+ particle.absorberOrbit.angle = getRandom() * maxAngle;
31
35
  }
32
36
  if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
33
- const minSize = Math.min(canvasSize.width, canvasSize.height);
34
- particle.absorberOrbit.length = minSize * (1 + (getRandom() * 0.2 - 0.1));
37
+ const minSize = Math.min(canvasSize.width, canvasSize.height), offset = 1, randomOffset = 0.1, randomFactor = 0.2;
38
+ particle.absorberOrbit.length = minSize * (offset + (getRandom() * randomFactor - randomOffset));
35
39
  }
36
40
  if (particle.absorberOrbitDirection === undefined) {
37
41
  particle.absorberOrbitDirection =
38
- particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise";
42
+ particle.velocity.x >= minVelocity ? "clockwise" : "counter-clockwise";
39
43
  }
40
44
  const orbitRadius = particle.absorberOrbit.length, orbitAngle = particle.absorberOrbit.angle, orbitDirection = particle.absorberOrbitDirection;
41
45
  particle.velocity.setTo(Vector.origin);
@@ -47,7 +51,7 @@ export class AbsorberInstance {
47
51
  particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
48
52
  particle.absorberOrbit.length -= v.length;
49
53
  particle.absorberOrbit.angle +=
50
- (((particle.retina.moveSpeed ?? 0) * container.retina.pixelRatio) / 100) *
54
+ (((particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio) / percentDenominator) *
51
55
  container.retina.reduceFactor;
52
56
  }
53
57
  else {
@@ -101,11 +105,11 @@ export class AbsorberInstance {
101
105
  }
102
106
  }
103
107
  const pos = particle.getPosition(), { dx, dy, distance } = getDistances(this.position, pos), v = Vector.create(dx, dy);
104
- v.length = (this.mass / Math.pow(distance, 2)) * container.retina.reduceFactor;
108
+ v.length = (this.mass / Math.pow(distance, squareExp)) * container.retina.reduceFactor;
105
109
  if (distance < this.size + particle.getRadius()) {
106
- const sizeFactor = particle.getRadius() * 0.033 * container.retina.pixelRatio;
110
+ const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio;
107
111
  if ((this.size > particle.getRadius() && distance < this.size - particle.getRadius()) ||
108
- (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < 0)) {
112
+ (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength)) {
109
113
  if (options.destroy) {
110
114
  particle.destroy();
111
115
  }
@@ -120,10 +124,10 @@ export class AbsorberInstance {
120
124
  }
121
125
  this._updateParticlePosition(particle, v);
122
126
  }
123
- if (this.limit.radius <= 0 || this.size < this.limit.radius) {
127
+ if (this.limit.radius <= minRadius || this.size < this.limit.radius) {
124
128
  this.size += sizeFactor;
125
129
  }
126
- if (this.limit.mass <= 0 || this.mass < this.limit.mass) {
130
+ if (this.limit.mass <= minMass || this.mass < this.limit.mass) {
127
131
  this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;
128
132
  }
129
133
  }
@@ -134,7 +138,7 @@ export class AbsorberInstance {
134
138
  draw(context) {
135
139
  context.translate(this.position.x, this.position.y);
136
140
  context.beginPath();
137
- context.arc(0, 0, this.size, 0, Math.PI * 2, false);
141
+ context.arc(origin.x, origin.y, this.size, minAngle, maxAngle, false);
138
142
  context.closePath();
139
143
  context.fillStyle = getStyleFromRgb(this.color, this.opacity);
140
144
  context.fill();
@@ -1,5 +1,6 @@
1
1
  import { executeOnSingleOrMultiple, isNumber, itemFromSingleOrMultiple, } from "@tsparticles/engine";
2
2
  import { AbsorberInstance } from "./AbsorberInstance.js";
3
+ const defaultIndex = 0;
3
4
  export class Absorbers {
4
5
  constructor(container) {
5
6
  this.container = container;
@@ -7,7 +8,7 @@ export class Absorbers {
7
8
  this.absorbers = [];
8
9
  this.interactivityAbsorbers = [];
9
10
  container.getAbsorber = (idxOrName) => idxOrName === undefined || isNumber(idxOrName)
10
- ? this.array[idxOrName || 0]
11
+ ? this.array[idxOrName ?? defaultIndex]
11
12
  : this.array.find((t) => t.name === idxOrName);
12
13
  container.addAbsorber = (options, position) => this.addAbsorber(options, position);
13
14
  }
@@ -34,6 +35,7 @@ export class Absorbers {
34
35
  executeOnSingleOrMultiple(this.absorbers, (absorber) => {
35
36
  this.addAbsorber(absorber);
36
37
  });
38
+ await Promise.resolve();
37
39
  }
38
40
  particleUpdate(particle) {
39
41
  for (const absorber of this.array) {
@@ -44,9 +46,9 @@ export class Absorbers {
44
46
  }
45
47
  }
46
48
  removeAbsorber(absorber) {
47
- const index = this.array.indexOf(absorber);
48
- if (index >= 0) {
49
- this.array.splice(index, 1);
49
+ const index = this.array.indexOf(absorber), deleteCount = 1;
50
+ if (index >= defaultIndex) {
51
+ this.array.splice(index, deleteCount);
50
52
  }
51
53
  }
52
54
  resize() {
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.AbsorberInstance = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
5
  const Absorber_js_1 = require("./Options/Classes/Absorber.js");
6
+ const squareExp = 2, absorbFactor = 0.033, minOrbitLength = 0, minRadius = 0, minMass = 0, origin = {
7
+ x: 0,
8
+ y: 0,
9
+ }, minAngle = 0, double = 2, maxAngle = Math.PI * double, minVelocity = 0;
6
10
  class AbsorberInstance {
7
11
  constructor(absorbers, container, options, position) {
8
12
  this.absorbers = absorbers;
@@ -28,17 +32,17 @@ class AbsorberInstance {
28
32
  }
29
33
  if (this.options.orbits) {
30
34
  if (particle.absorberOrbit === undefined) {
31
- particle.absorberOrbit = engine_1.Vector.create(0, 0);
35
+ particle.absorberOrbit = engine_1.Vector.origin;
32
36
  particle.absorberOrbit.length = (0, engine_1.getDistance)(particle.getPosition(), this.position);
33
- particle.absorberOrbit.angle = (0, engine_1.getRandom)() * Math.PI * 2;
37
+ particle.absorberOrbit.angle = (0, engine_1.getRandom)() * maxAngle;
34
38
  }
35
39
  if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
36
- const minSize = Math.min(canvasSize.width, canvasSize.height);
37
- particle.absorberOrbit.length = minSize * (1 + ((0, engine_1.getRandom)() * 0.2 - 0.1));
40
+ const minSize = Math.min(canvasSize.width, canvasSize.height), offset = 1, randomOffset = 0.1, randomFactor = 0.2;
41
+ particle.absorberOrbit.length = minSize * (offset + ((0, engine_1.getRandom)() * randomFactor - randomOffset));
38
42
  }
39
43
  if (particle.absorberOrbitDirection === undefined) {
40
44
  particle.absorberOrbitDirection =
41
- particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise";
45
+ particle.velocity.x >= minVelocity ? "clockwise" : "counter-clockwise";
42
46
  }
43
47
  const orbitRadius = particle.absorberOrbit.length, orbitAngle = particle.absorberOrbit.angle, orbitDirection = particle.absorberOrbitDirection;
44
48
  particle.velocity.setTo(engine_1.Vector.origin);
@@ -50,7 +54,7 @@ class AbsorberInstance {
50
54
  particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
51
55
  particle.absorberOrbit.length -= v.length;
52
56
  particle.absorberOrbit.angle +=
53
- (((particle.retina.moveSpeed ?? 0) * container.retina.pixelRatio) / 100) *
57
+ (((particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio) / engine_1.percentDenominator) *
54
58
  container.retina.reduceFactor;
55
59
  }
56
60
  else {
@@ -104,11 +108,11 @@ class AbsorberInstance {
104
108
  }
105
109
  }
106
110
  const pos = particle.getPosition(), { dx, dy, distance } = (0, engine_1.getDistances)(this.position, pos), v = engine_1.Vector.create(dx, dy);
107
- v.length = (this.mass / Math.pow(distance, 2)) * container.retina.reduceFactor;
111
+ v.length = (this.mass / Math.pow(distance, squareExp)) * container.retina.reduceFactor;
108
112
  if (distance < this.size + particle.getRadius()) {
109
- const sizeFactor = particle.getRadius() * 0.033 * container.retina.pixelRatio;
113
+ const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio;
110
114
  if ((this.size > particle.getRadius() && distance < this.size - particle.getRadius()) ||
111
- (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < 0)) {
115
+ (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength)) {
112
116
  if (options.destroy) {
113
117
  particle.destroy();
114
118
  }
@@ -123,10 +127,10 @@ class AbsorberInstance {
123
127
  }
124
128
  this._updateParticlePosition(particle, v);
125
129
  }
126
- if (this.limit.radius <= 0 || this.size < this.limit.radius) {
130
+ if (this.limit.radius <= minRadius || this.size < this.limit.radius) {
127
131
  this.size += sizeFactor;
128
132
  }
129
- if (this.limit.mass <= 0 || this.mass < this.limit.mass) {
133
+ if (this.limit.mass <= minMass || this.mass < this.limit.mass) {
130
134
  this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;
131
135
  }
132
136
  }
@@ -137,7 +141,7 @@ class AbsorberInstance {
137
141
  draw(context) {
138
142
  context.translate(this.position.x, this.position.y);
139
143
  context.beginPath();
140
- context.arc(0, 0, this.size, 0, Math.PI * 2, false);
144
+ context.arc(origin.x, origin.y, this.size, minAngle, maxAngle, false);
141
145
  context.closePath();
142
146
  context.fillStyle = (0, engine_1.getStyleFromRgb)(this.color, this.opacity);
143
147
  context.fill();
package/cjs/Absorbers.js CHANGED
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Absorbers = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
5
  const AbsorberInstance_js_1 = require("./AbsorberInstance.js");
6
+ const defaultIndex = 0;
6
7
  class Absorbers {
7
8
  constructor(container) {
8
9
  this.container = container;
@@ -10,7 +11,7 @@ class Absorbers {
10
11
  this.absorbers = [];
11
12
  this.interactivityAbsorbers = [];
12
13
  container.getAbsorber = (idxOrName) => idxOrName === undefined || (0, engine_1.isNumber)(idxOrName)
13
- ? this.array[idxOrName || 0]
14
+ ? this.array[idxOrName ?? defaultIndex]
14
15
  : this.array.find((t) => t.name === idxOrName);
15
16
  container.addAbsorber = (options, position) => this.addAbsorber(options, position);
16
17
  }
@@ -37,6 +38,7 @@ class Absorbers {
37
38
  (0, engine_1.executeOnSingleOrMultiple)(this.absorbers, (absorber) => {
38
39
  this.addAbsorber(absorber);
39
40
  });
41
+ await Promise.resolve();
40
42
  }
41
43
  particleUpdate(particle) {
42
44
  for (const absorber of this.array) {
@@ -47,9 +49,9 @@ class Absorbers {
47
49
  }
48
50
  }
49
51
  removeAbsorber(absorber) {
50
- const index = this.array.indexOf(absorber);
51
- if (index >= 0) {
52
- this.array.splice(index, 1);
52
+ const index = this.array.indexOf(absorber), deleteCount = 1;
53
+ if (index >= defaultIndex) {
54
+ this.array.splice(index, deleteCount);
53
55
  }
54
56
  }
55
57
  resize() {
@@ -1,5 +1,9 @@
1
- import { Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, rangeColorToRgb, } from "@tsparticles/engine";
1
+ import { Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, percentDenominator, rangeColorToRgb, } from "@tsparticles/engine";
2
2
  import { Absorber } from "./Options/Classes/Absorber.js";
3
+ const squareExp = 2, absorbFactor = 0.033, minOrbitLength = 0, minRadius = 0, minMass = 0, origin = {
4
+ x: 0,
5
+ y: 0,
6
+ }, minAngle = 0, double = 2, maxAngle = Math.PI * double, minVelocity = 0;
3
7
  export class AbsorberInstance {
4
8
  constructor(absorbers, container, options, position) {
5
9
  this.absorbers = absorbers;
@@ -25,17 +29,17 @@ export class AbsorberInstance {
25
29
  }
26
30
  if (this.options.orbits) {
27
31
  if (particle.absorberOrbit === undefined) {
28
- particle.absorberOrbit = Vector.create(0, 0);
32
+ particle.absorberOrbit = Vector.origin;
29
33
  particle.absorberOrbit.length = getDistance(particle.getPosition(), this.position);
30
- particle.absorberOrbit.angle = getRandom() * Math.PI * 2;
34
+ particle.absorberOrbit.angle = getRandom() * maxAngle;
31
35
  }
32
36
  if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
33
- const minSize = Math.min(canvasSize.width, canvasSize.height);
34
- particle.absorberOrbit.length = minSize * (1 + (getRandom() * 0.2 - 0.1));
37
+ const minSize = Math.min(canvasSize.width, canvasSize.height), offset = 1, randomOffset = 0.1, randomFactor = 0.2;
38
+ particle.absorberOrbit.length = minSize * (offset + (getRandom() * randomFactor - randomOffset));
35
39
  }
36
40
  if (particle.absorberOrbitDirection === undefined) {
37
41
  particle.absorberOrbitDirection =
38
- particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise";
42
+ particle.velocity.x >= minVelocity ? "clockwise" : "counter-clockwise";
39
43
  }
40
44
  const orbitRadius = particle.absorberOrbit.length, orbitAngle = particle.absorberOrbit.angle, orbitDirection = particle.absorberOrbitDirection;
41
45
  particle.velocity.setTo(Vector.origin);
@@ -47,7 +51,7 @@ export class AbsorberInstance {
47
51
  particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
48
52
  particle.absorberOrbit.length -= v.length;
49
53
  particle.absorberOrbit.angle +=
50
- (((particle.retina.moveSpeed ?? 0) * container.retina.pixelRatio) / 100) *
54
+ (((particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio) / percentDenominator) *
51
55
  container.retina.reduceFactor;
52
56
  }
53
57
  else {
@@ -101,11 +105,11 @@ export class AbsorberInstance {
101
105
  }
102
106
  }
103
107
  const pos = particle.getPosition(), { dx, dy, distance } = getDistances(this.position, pos), v = Vector.create(dx, dy);
104
- v.length = (this.mass / Math.pow(distance, 2)) * container.retina.reduceFactor;
108
+ v.length = (this.mass / Math.pow(distance, squareExp)) * container.retina.reduceFactor;
105
109
  if (distance < this.size + particle.getRadius()) {
106
- const sizeFactor = particle.getRadius() * 0.033 * container.retina.pixelRatio;
110
+ const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio;
107
111
  if ((this.size > particle.getRadius() && distance < this.size - particle.getRadius()) ||
108
- (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < 0)) {
112
+ (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength)) {
109
113
  if (options.destroy) {
110
114
  particle.destroy();
111
115
  }
@@ -120,10 +124,10 @@ export class AbsorberInstance {
120
124
  }
121
125
  this._updateParticlePosition(particle, v);
122
126
  }
123
- if (this.limit.radius <= 0 || this.size < this.limit.radius) {
127
+ if (this.limit.radius <= minRadius || this.size < this.limit.radius) {
124
128
  this.size += sizeFactor;
125
129
  }
126
- if (this.limit.mass <= 0 || this.mass < this.limit.mass) {
130
+ if (this.limit.mass <= minMass || this.mass < this.limit.mass) {
127
131
  this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;
128
132
  }
129
133
  }
@@ -134,7 +138,7 @@ export class AbsorberInstance {
134
138
  draw(context) {
135
139
  context.translate(this.position.x, this.position.y);
136
140
  context.beginPath();
137
- context.arc(0, 0, this.size, 0, Math.PI * 2, false);
141
+ context.arc(origin.x, origin.y, this.size, minAngle, maxAngle, false);
138
142
  context.closePath();
139
143
  context.fillStyle = getStyleFromRgb(this.color, this.opacity);
140
144
  context.fill();
package/esm/Absorbers.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { executeOnSingleOrMultiple, isNumber, itemFromSingleOrMultiple, } from "@tsparticles/engine";
2
2
  import { AbsorberInstance } from "./AbsorberInstance.js";
3
+ const defaultIndex = 0;
3
4
  export class Absorbers {
4
5
  constructor(container) {
5
6
  this.container = container;
@@ -7,7 +8,7 @@ export class Absorbers {
7
8
  this.absorbers = [];
8
9
  this.interactivityAbsorbers = [];
9
10
  container.getAbsorber = (idxOrName) => idxOrName === undefined || isNumber(idxOrName)
10
- ? this.array[idxOrName || 0]
11
+ ? this.array[idxOrName ?? defaultIndex]
11
12
  : this.array.find((t) => t.name === idxOrName);
12
13
  container.addAbsorber = (options, position) => this.addAbsorber(options, position);
13
14
  }
@@ -34,6 +35,7 @@ export class Absorbers {
34
35
  executeOnSingleOrMultiple(this.absorbers, (absorber) => {
35
36
  this.addAbsorber(absorber);
36
37
  });
38
+ await Promise.resolve();
37
39
  }
38
40
  particleUpdate(particle) {
39
41
  for (const absorber of this.array) {
@@ -44,9 +46,9 @@ export class Absorbers {
44
46
  }
45
47
  }
46
48
  removeAbsorber(absorber) {
47
- const index = this.array.indexOf(absorber);
48
- if (index >= 0) {
49
- this.array.splice(index, 1);
49
+ const index = this.array.indexOf(absorber), deleteCount = 1;
50
+ if (index >= defaultIndex) {
51
+ this.array.splice(index, deleteCount);
50
52
  }
51
53
  }
52
54
  resize() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/plugin-absorbers",
3
- "version": "3.0.3",
3
+ "version": "3.1.0",
4
4
  "description": "tsParticles absorbers plugin",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -86,7 +86,7 @@
86
86
  "./package.json": "./package.json"
87
87
  },
88
88
  "dependencies": {
89
- "@tsparticles/engine": "^3.0.3"
89
+ "@tsparticles/engine": "^3.1.0"
90
90
  },
91
91
  "publishConfig": {
92
92
  "access": "public"
package/report.html CHANGED
@@ -3,7 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8"/>
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1"/>
6
- <title>@tsparticles/plugin-absorbers [26 Dec 2023 at 19:27]</title>
6
+ <title>@tsparticles/plugin-absorbers [13 Jan 2024 at 23:02]</title>
7
7
  <link rel="shortcut icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAMAAACdt4HsAAABrVBMVEUAAAD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////+O1foceMD///+J0/qK1Pr7/v8Xdr/9///W8P4UdL7L7P0Scr2r4Pyj3vwad8D5/f/2/f+55f3E6f34+/2H0/ojfMKpzOd0rNgQcb3F3O/j9f7c8v6g3Pz0/P/w+v/q+P7n9v6T1/uQ1vuE0vqLut/y+v+Z2fvt+f+15Pzv9fuc2/vR7v2V2Pvd6/bg9P7I6/285/2y4/yp3/zp8vk8i8kqgMT7/P31+fyv4vxGkcz6/P6/6P3j7vfS5PNnpNUxhcbO7f7F6v3O4vHK3/DA2u631Ouy0eqXweKJud5wqthfoNMMbLvY8f73+v2dxeR8sNtTmdDx9/zX6PSjyeaCtd1YnNGX2PuQveCGt95Nls42h8dLlM3F4vBtAAAAM3RSTlMAAyOx0/sKBvik8opWGBMOAe3l1snDm2E9LSb06eHcu5JpHbarfHZCN9CBb08zzkdNS0kYaptYAAAFV0lEQVRYw92X51/aYBDHHS2O2qqttVbrqNq9m+TJIAYIShBkWwqIiCgoWvfeq7Z2/s29hyQNyUcR7LveGwVyXy6XH8/9rqxglLfUPLxVduUor3h0rfp2TYvpivk37929TkG037hffoX0+peVtZQc1589rigVUdXS/ABSAyEmGIO/1XfvldSK8vs3OqB6u3m0nxmIrvgB0dj7rr7Y9IbuF68hnfFaiHA/sxqm0wciIG43P60qKv9WXWc1RXGh/mFESFABTSBi0sNAKzqet17eCtOb3kZIDwxEEU0oAIJGYxNBDhBND29e0rtXXbcpuPmED9IhEAAQ/AXEaF8EPmnrrKsv0LvWR3fg5sWDNAFZOgAgaKvZDogHNU9MFwnnYROkc56RD5CjAbQX9Ow4g7upCsvYu55aSI/Nj0H1akgKQEUM94dwK65hYRmFU9MIcH/fqJYOZYcnuJSU/waKDgTOEVaVKhwrTRP5XzgSpAITYzom7UvkhFX5VutmxeNnWDjjswTKTyfgluNDGbUpWissXhF3s7mlSml+czWkg3D0l1nNjGNjz3myOQOa1KM/jOS6ebdbAVTCi4gljHSFrviza7tOgRWcS0MOUX9zdNgag5w7rRqA44Lzw0hr1WqES36dFliSJFlh2rXIae3FFcDDgKdxrUIDePr8jGcSClV1u7A9xeN0ModY/pHMxmR1EzRh8TJiwqsHmKW0l4FCEZI+jHio+JdPPE9qwQtTRxku2D8sIeRL2LnxWSllANCQGOIiqVHAz2ye2JR0DcH+HoxDkaADLjgxjKQ+AwCX/g0+DNgdG0ukYCONAe+dbc2IAc6fwt1ARoDSezNHxV2Cmzwv3O6lDMV55edBGwGK9n1+x2F8EDfAGCxug8MhpsMEcTEAWf3rx2vZhe/LAmtIn/6apE6PN0ULKgywD9mmdxbmFl3OvD5AS5fW5zLbv/YHmcsBTjf/afDz3MaZTVCfAP9z6/Bw6ycv8EUBWJIn9zYcoAWWlW9+OzO3vkTy8H+RANLmdrpOuYWdZYEXpo+TlCJrW5EARb7fF+bWdqf3hhyZI1nWJQHgznErZhbjoEsWqi8dQNoE294aldzFurwSABL2XXMf9+H1VQGke9exw5P/AnA5Pv5ngMul7LOvO922iwACu8WkCwLCafvM4CeWPxfA8lNHcWZSoi8EwMAIciKX2Z4SWCMAa3snCZ/G4EA8D6CMLNFsGQhkkz/gQNEBbPCbWsxGUpYVu3z8IyNAknwJkfPMEhLyrdi5RTyUVACkw4GSFRNWJNEW+fgPGwHD8/JxnRuLabN4CGNRkAE23na2+VmEAUmrYymSGjMAYqH84YUIyzgzs3XC7gNgH36Vcc4zKY9o9fgPBXUAiHHwVboBHGLiX6Zcjp1f2wu4tvzZKo0ecPnDtQYDQvJXaBeNzce45Fp28ZQLrEZVuFqgBwOalArKXnW1UzlnSusQKJqKYNuz4tOnI6sZG4zanpemv+7ySU2jbA9h6uhcgpfy6G2PahirDZ6zvq6zDduMVFTKvzw8wgyEdelwY9in3XkEPs3osJuwRQ4qTkfzifndg9Gfc4pdsu82+tTnHZTBa2EAMrqr2t43pguc8tNm7JQVQ2S0ukj2d22dhXYP0/veWtwKrCkNoNimAN5+Xr/oLrxswKbVJjteWrX7eR63o4j9q0GxnaBdWgGA5VStpanIjQmEhV0/nVt5VOFUvix6awJhPcAaTEShgrG+iGyvb5a0Ndb1YGHFPEwoqAinoaykaID1o1pdPNu7XsnCKQ3R+hwWIIhGvORcJUBYXe3Xa3vq/mF/N9V13ugufMkfXn+KHsRD0B8AAAAASUVORK5CYII=" type="image/x-icon" />
8
8
 
9
9
  <script>
@@ -31,7 +31,7 @@
31
31
  <body>
32
32
  <div id="app"></div>
33
33
  <script>
34
- window.chartData = [{"label":"tsparticles.plugin.absorbers.js","isAsset":true,"statSize":11782,"parsedSize":15709,"gzipSize":3839,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":11740,"groups":[{"id":164,"label":"index.js + 5 modules (concatenated)","path":"./dist/browser/index.js + 5 modules (concatenated)","statSize":11740,"parsedSize":15709,"gzipSize":3839,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser","statSize":11740,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/index.js","statSize":1489,"parsedSize":1992,"gzipSize":486,"inaccurateSizes":true},{"id":null,"label":"Absorbers.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Absorbers.js","statSize":2028,"parsedSize":2713,"gzipSize":663,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Options/Classes","statSize":2132,"groups":[{"id":null,"label":"Absorber.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Options/Classes/Absorber.js","statSize":1255,"parsedSize":1679,"gzipSize":410,"inaccurateSizes":true},{"id":null,"label":"AbsorberSize.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Options/Classes/AbsorberSize.js","statSize":579,"parsedSize":774,"gzipSize":189,"inaccurateSizes":true},{"id":null,"label":"AbsorberSizeLimit.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Options/Classes/AbsorberSizeLimit.js","statSize":298,"parsedSize":398,"gzipSize":97,"inaccurateSizes":true}],"parsedSize":2852,"gzipSize":697,"inaccurateSizes":true},{"id":null,"label":"AbsorberInstance.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/AbsorberInstance.js","statSize":6091,"parsedSize":8150,"gzipSize":1991,"inaccurateSizes":true}],"parsedSize":15709,"gzipSize":3839,"inaccurateSizes":true}]}],"parsedSize":15709,"gzipSize":3839},{"label":"engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":533,"label":"engine\",\"root\":\"window\"}","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles/engine\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"tsparticles.plugin.absorbers":true}}];
34
+ window.chartData = [{"label":"tsparticles.plugin.absorbers.js","isAsset":true,"statSize":12323,"parsedSize":16284,"gzipSize":4021,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":12281,"groups":[{"id":205,"label":"index.js + 5 modules (concatenated)","path":"./dist/browser/index.js + 5 modules (concatenated)","statSize":12281,"parsedSize":16284,"gzipSize":4021,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser","statSize":12281,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/index.js","statSize":1489,"parsedSize":1974,"gzipSize":487,"inaccurateSizes":true},{"id":null,"label":"Absorbers.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Absorbers.js","statSize":2136,"parsedSize":2832,"gzipSize":699,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Options/Classes","statSize":2132,"groups":[{"id":null,"label":"Absorber.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Options/Classes/Absorber.js","statSize":1255,"parsedSize":1664,"gzipSize":410,"inaccurateSizes":true},{"id":null,"label":"AbsorberSize.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Options/Classes/AbsorberSize.js","statSize":579,"parsedSize":767,"gzipSize":189,"inaccurateSizes":true},{"id":null,"label":"AbsorberSizeLimit.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/Options/Classes/AbsorberSizeLimit.js","statSize":298,"parsedSize":395,"gzipSize":97,"inaccurateSizes":true}],"parsedSize":2826,"gzipSize":698,"inaccurateSizes":true},{"id":null,"label":"AbsorberInstance.js","path":"./dist/browser/index.js + 5 modules (concatenated)/dist/browser/AbsorberInstance.js","statSize":6524,"parsedSize":8650,"gzipSize":2136,"inaccurateSizes":true}],"parsedSize":16284,"gzipSize":4021,"inaccurateSizes":true}]}],"parsedSize":16284,"gzipSize":4021},{"label":"engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles","statSize":42,"groups":[{"id":533,"label":"engine\",\"root\":\"window\"}","path":"./engine\",\"commonjs2\":\"@tsparticles/engine\",\"amd\":\"@tsparticles/engine\",\"root\":\"window\"}","statSize":42}],"parsedSize":0,"gzipSize":0}],"isInitialByEntrypoint":{"tsparticles.plugin.absorbers":true}}];
35
35
  window.entrypoints = ["tsparticles.plugin.absorbers","tsparticles.plugin.absorbers.min"];
36
36
  window.defaultSizes = "parsed";
37
37
  </script>
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v3.0.3
7
+ * v3.1.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -189,6 +189,19 @@ class Absorber {
189
189
  ;// CONCATENATED MODULE: ./dist/browser/AbsorberInstance.js
190
190
 
191
191
 
192
+ const squareExp = 2,
193
+ absorbFactor = 0.033,
194
+ minOrbitLength = 0,
195
+ minRadius = 0,
196
+ minMass = 0,
197
+ origin = {
198
+ x: 0,
199
+ y: 0
200
+ },
201
+ minAngle = 0,
202
+ AbsorberInstance_double = 2,
203
+ maxAngle = Math.PI * AbsorberInstance_double,
204
+ minVelocity = 0;
192
205
  class AbsorberInstance {
193
206
  constructor(absorbers, container, options, position) {
194
207
  this.absorbers = absorbers;
@@ -217,16 +230,19 @@ class AbsorberInstance {
217
230
  }
218
231
  if (this.options.orbits) {
219
232
  if (particle.absorberOrbit === undefined) {
220
- particle.absorberOrbit = engine_root_window_.Vector.create(0, 0);
233
+ particle.absorberOrbit = engine_root_window_.Vector.origin;
221
234
  particle.absorberOrbit.length = (0,engine_root_window_.getDistance)(particle.getPosition(), this.position);
222
- particle.absorberOrbit.angle = (0,engine_root_window_.getRandom)() * Math.PI * 2;
235
+ particle.absorberOrbit.angle = (0,engine_root_window_.getRandom)() * maxAngle;
223
236
  }
224
237
  if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
225
- const minSize = Math.min(canvasSize.width, canvasSize.height);
226
- particle.absorberOrbit.length = minSize * (1 + ((0,engine_root_window_.getRandom)() * 0.2 - 0.1));
238
+ const minSize = Math.min(canvasSize.width, canvasSize.height),
239
+ offset = 1,
240
+ randomOffset = 0.1,
241
+ randomFactor = 0.2;
242
+ particle.absorberOrbit.length = minSize * (offset + ((0,engine_root_window_.getRandom)() * randomFactor - randomOffset));
227
243
  }
228
244
  if (particle.absorberOrbitDirection === undefined) {
229
- particle.absorberOrbitDirection = particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise";
245
+ particle.absorberOrbitDirection = particle.velocity.x >= minVelocity ? "clockwise" : "counter-clockwise";
230
246
  }
231
247
  const orbitRadius = particle.absorberOrbit.length,
232
248
  orbitAngle = particle.absorberOrbit.angle,
@@ -239,7 +255,7 @@ class AbsorberInstance {
239
255
  particle.position.x = this.position.x + orbitRadius * updateFunc.x(orbitAngle);
240
256
  particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
241
257
  particle.absorberOrbit.length -= v.length;
242
- particle.absorberOrbit.angle += (particle.retina.moveSpeed ?? 0) * container.retina.pixelRatio / 100 * container.retina.reduceFactor;
258
+ particle.absorberOrbit.angle += (particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio / engine_root_window_.percentDenominator * container.retina.reduceFactor;
243
259
  } else {
244
260
  const addV = engine_root_window_.Vector.origin;
245
261
  addV.length = v.length;
@@ -296,10 +312,10 @@ class AbsorberInstance {
296
312
  distance
297
313
  } = (0,engine_root_window_.getDistances)(this.position, pos),
298
314
  v = engine_root_window_.Vector.create(dx, dy);
299
- v.length = this.mass / Math.pow(distance, 2) * container.retina.reduceFactor;
315
+ v.length = this.mass / Math.pow(distance, squareExp) * container.retina.reduceFactor;
300
316
  if (distance < this.size + particle.getRadius()) {
301
- const sizeFactor = particle.getRadius() * 0.033 * container.retina.pixelRatio;
302
- if (this.size > particle.getRadius() && distance < this.size - particle.getRadius() || particle.absorberOrbit !== undefined && particle.absorberOrbit.length < 0) {
317
+ const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio;
318
+ if (this.size > particle.getRadius() && distance < this.size - particle.getRadius() || particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength) {
303
319
  if (options.destroy) {
304
320
  particle.destroy();
305
321
  } else {
@@ -312,10 +328,10 @@ class AbsorberInstance {
312
328
  }
313
329
  this._updateParticlePosition(particle, v);
314
330
  }
315
- if (this.limit.radius <= 0 || this.size < this.limit.radius) {
331
+ if (this.limit.radius <= minRadius || this.size < this.limit.radius) {
316
332
  this.size += sizeFactor;
317
333
  }
318
- if (this.limit.mass <= 0 || this.mass < this.limit.mass) {
334
+ if (this.limit.mass <= minMass || this.mass < this.limit.mass) {
319
335
  this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;
320
336
  }
321
337
  } else {
@@ -325,7 +341,7 @@ class AbsorberInstance {
325
341
  draw(context) {
326
342
  context.translate(this.position.x, this.position.y);
327
343
  context.beginPath();
328
- context.arc(0, 0, this.size, 0, Math.PI * 2, false);
344
+ context.arc(origin.x, origin.y, this.size, minAngle, maxAngle, false);
329
345
  context.closePath();
330
346
  context.fillStyle = (0,engine_root_window_.getStyleFromRgb)(this.color, this.opacity);
331
347
  context.fill();
@@ -338,13 +354,14 @@ class AbsorberInstance {
338
354
  ;// CONCATENATED MODULE: ./dist/browser/Absorbers.js
339
355
 
340
356
 
357
+ const defaultIndex = 0;
341
358
  class Absorbers {
342
359
  constructor(container) {
343
360
  this.container = container;
344
361
  this.array = [];
345
362
  this.absorbers = [];
346
363
  this.interactivityAbsorbers = [];
347
- container.getAbsorber = idxOrName => idxOrName === undefined || (0,engine_root_window_.isNumber)(idxOrName) ? this.array[idxOrName || 0] : this.array.find(t => t.name === idxOrName);
364
+ container.getAbsorber = idxOrName => idxOrName === undefined || (0,engine_root_window_.isNumber)(idxOrName) ? this.array[idxOrName ?? defaultIndex] : this.array.find(t => t.name === idxOrName);
348
365
  container.addAbsorber = (options, position) => this.addAbsorber(options, position);
349
366
  }
350
367
  addAbsorber(options, position) {
@@ -373,6 +390,7 @@ class Absorbers {
373
390
  (0,engine_root_window_.executeOnSingleOrMultiple)(this.absorbers, absorber => {
374
391
  this.addAbsorber(absorber);
375
392
  });
393
+ await Promise.resolve();
376
394
  }
377
395
  particleUpdate(particle) {
378
396
  for (const absorber of this.array) {
@@ -383,9 +401,10 @@ class Absorbers {
383
401
  }
384
402
  }
385
403
  removeAbsorber(absorber) {
386
- const index = this.array.indexOf(absorber);
387
- if (index >= 0) {
388
- this.array.splice(index, 1);
404
+ const index = this.array.indexOf(absorber),
405
+ deleteCount = 1;
406
+ if (index >= defaultIndex) {
407
+ this.array.splice(index, deleteCount);
389
408
  }
390
409
  }
391
410
  resize() {
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see tsparticles.plugin.absorbers.min.js.LICENSE.txt */
2
- !function(i,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],t);else{var s="object"==typeof exports?t(require("@tsparticles/engine")):t(i.window);for(var o in s)("object"==typeof exports?exports:i)[o]=s[o]}}(this,(i=>(()=>{"use strict";var t={533:t=>{t.exports=i}},s={};function o(i){var e=s[i];if(void 0!==e)return e.exports;var r=s[i]={exports:{}};return t[i](r,r.exports,o),r.exports}o.d=(i,t)=>{for(var s in t)o.o(t,s)&&!o.o(i,s)&&Object.defineProperty(i,s,{enumerable:!0,get:t[s]})},o.o=(i,t)=>Object.prototype.hasOwnProperty.call(i,t),o.r=i=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(i,"__esModule",{value:!0})};var e={};return(()=>{o.r(e),o.d(e,{loadAbsorbersPlugin:()=>h});var i=o(533);class t{constructor(){this.radius=0,this.mass=0}load(i){i&&(void 0!==i.mass&&(this.mass=i.mass),void 0!==i.radius&&(this.radius=i.radius))}}class s extends i.ValueWithRandom{constructor(){super(),this.density=5,this.value=50,this.limit=new t}load(t){t&&(super.load(t),void 0!==t.density&&(this.density=t.density),(0,i.isNumber)(t.limit)?this.limit.radius=t.limit:this.limit.load(t.limit))}}class r{constructor(){this.color=new i.OptionsColor,this.color.value="#000000",this.draggable=!1,this.opacity=1,this.destroy=!0,this.orbits=!1,this.size=new s}load(t){void 0!==t&&(void 0!==t.color&&(this.color=i.OptionsColor.create(this.color,t.color)),void 0!==t.draggable&&(this.draggable=t.draggable),this.name=t.name,void 0!==t.opacity&&(this.opacity=t.opacity),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=(0,i.setRangeValue)(t.position.x)),void 0!==t.position.y&&(this.position.y=(0,i.setRangeValue)(t.position.y))),void 0!==t.size&&this.size.load(t.size),void 0!==t.destroy&&(this.destroy=t.destroy),void 0!==t.orbits&&(this.orbits=t.orbits))}}class n{constructor(t,s,o,e){this.absorbers=t,this.container=s,this._calcPosition=()=>{const t=(0,i.calcPositionOrRandomFromSizeRanged)({size:this.container.canvas.size,position:this.options.position});return i.Vector.create(t.x,t.y)},this._updateParticlePosition=(t,s)=>{if(t.destroyed)return;const o=this.container,e=o.canvas.size;if(t.needsNewPosition){const s=(0,i.calcPositionOrRandomFromSize)({size:e});t.position.setTo(s),t.velocity.setTo(t.initialVelocity),t.absorberOrbit=void 0,t.needsNewPosition=!1}if(this.options.orbits){if(void 0===t.absorberOrbit&&(t.absorberOrbit=i.Vector.create(0,0),t.absorberOrbit.length=(0,i.getDistance)(t.getPosition(),this.position),t.absorberOrbit.angle=(0,i.getRandom)()*Math.PI*2),t.absorberOrbit.length<=this.size&&!this.options.destroy){const s=Math.min(e.width,e.height);t.absorberOrbit.length=s*(.2*(0,i.getRandom)()-.1+1)}void 0===t.absorberOrbitDirection&&(t.absorberOrbitDirection=t.velocity.x>=0?"clockwise":"counter-clockwise");const r=t.absorberOrbit.length,n=t.absorberOrbit.angle,a=t.absorberOrbitDirection;t.velocity.setTo(i.Vector.origin);const c={x:"clockwise"===a?Math.cos:Math.sin,y:"clockwise"===a?Math.sin:Math.cos};t.position.x=this.position.x+r*c.x(n),t.position.y=this.position.y+r*c.y(n),t.absorberOrbit.length-=s.length,t.absorberOrbit.angle+=(t.retina.moveSpeed??0)*o.retina.pixelRatio/100*o.retina.reduceFactor}else{const o=i.Vector.origin;o.length=s.length,o.angle=s.angle,t.velocity.addTo(o)}},this.initialPosition=e?i.Vector.create(e.x,e.y):void 0,o instanceof r?this.options=o:(this.options=new r,this.options.load(o)),this.dragging=!1,this.name=this.options.name,this.opacity=this.options.opacity,this.size=(0,i.getRangeValue)(this.options.size.value)*s.retina.pixelRatio,this.mass=this.size*this.options.size.density*s.retina.reduceFactor;const n=this.options.size.limit;this.limit={radius:n.radius*s.retina.pixelRatio*s.retina.reduceFactor,mass:n.mass},this.color=(0,i.rangeColorToRgb)(this.options.color)??{b:0,g:0,r:0},this.position=this.initialPosition?.copy()??this._calcPosition()}attract(t){const s=this.container,o=this.options;if(o.draggable){const t=s.interactivity.mouse;if(t.clicking&&t.downPosition){(0,i.getDistance)(this.position,t.downPosition)<=this.size&&(this.dragging=!0)}else this.dragging=!1;this.dragging&&t.position&&(this.position.x=t.position.x,this.position.y=t.position.y)}const e=t.getPosition(),{dx:r,dy:n,distance:a}=(0,i.getDistances)(this.position,e),c=i.Vector.create(r,n);if(c.length=this.mass/Math.pow(a,2)*s.retina.reduceFactor,a<this.size+t.getRadius()){const i=.033*t.getRadius()*s.retina.pixelRatio;this.size>t.getRadius()&&a<this.size-t.getRadius()||void 0!==t.absorberOrbit&&t.absorberOrbit.length<0?o.destroy?t.destroy():(t.needsNewPosition=!0,this._updateParticlePosition(t,c)):(o.destroy&&(t.size.value-=i),this._updateParticlePosition(t,c)),(this.limit.radius<=0||this.size<this.limit.radius)&&(this.size+=i),(this.limit.mass<=0||this.mass<this.limit.mass)&&(this.mass+=i*this.options.size.density*s.retina.reduceFactor)}else this._updateParticlePosition(t,c)}draw(t){t.translate(this.position.x,this.position.y),t.beginPath(),t.arc(0,0,this.size,0,2*Math.PI,!1),t.closePath(),t.fillStyle=(0,i.getStyleFromRgb)(this.color,this.opacity),t.fill()}resize(){const t=this.initialPosition;this.position=t&&(0,i.isPointInside)(t,this.container.canvas.size,i.Vector.origin)?t:this._calcPosition()}}class a{constructor(t){this.container=t,this.array=[],this.absorbers=[],this.interactivityAbsorbers=[],t.getAbsorber=t=>void 0===t||(0,i.isNumber)(t)?this.array[t||0]:this.array.find((i=>i.name===t)),t.addAbsorber=(i,t)=>this.addAbsorber(i,t)}addAbsorber(i,t){const s=new n(this,this.container,i,t);return this.array.push(s),s}draw(i){for(const t of this.array)t.draw(i)}handleClickMode(t){const s=this.absorbers,o=this.interactivityAbsorbers;if("absorber"===t){const t=(0,i.itemFromSingleOrMultiple)(o)??(0,i.itemFromSingleOrMultiple)(s),e=this.container.interactivity.mouse.clickPosition;this.addAbsorber(t,e)}}async init(){this.absorbers=this.container.actualOptions.absorbers,this.interactivityAbsorbers=this.container.actualOptions.interactivity.modes.absorbers,(0,i.executeOnSingleOrMultiple)(this.absorbers,(i=>{this.addAbsorber(i)}))}particleUpdate(i){for(const t of this.array)if(t.attract(i),i.destroyed)break}removeAbsorber(i){const t=this.array.indexOf(i);t>=0&&this.array.splice(t,1)}resize(){for(const i of this.array)i.resize()}stop(){this.array=[]}}class c{constructor(){this.id="absorbers"}getPlugin(i){return new a(i)}loadOptions(t,s){(this.needsPlugin(t)||this.needsPlugin(s))&&(s?.absorbers&&(t.absorbers=(0,i.executeOnSingleOrMultiple)(s.absorbers,(i=>{const t=new r;return t.load(i),t}))),t.interactivity.modes.absorbers=(0,i.executeOnSingleOrMultiple)(s?.interactivity?.modes?.absorbers,(i=>{const t=new r;return t.load(i),t})))}needsPlugin(t){if(!t)return!1;const s=t.absorbers;return(0,i.isArray)(s)?!!s.length:!!s||!(!t.interactivity?.events?.onClick?.mode||!(0,i.isInArray)("absorber",t.interactivity.events.onClick.mode))}}async function h(i,t=!0){await i.addPlugin(new c,t)}})(),e})()));
2
+ !function(i,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine"],t);else{var s="object"==typeof exports?t(require("@tsparticles/engine")):t(i.window);for(var o in s)("object"==typeof exports?exports:i)[o]=s[o]}}(this,(i=>(()=>{"use strict";var t={533:t=>{t.exports=i}},s={};function o(i){var e=s[i];if(void 0!==e)return e.exports;var r=s[i]={exports:{}};return t[i](r,r.exports,o),r.exports}o.d=(i,t)=>{for(var s in t)o.o(t,s)&&!o.o(i,s)&&Object.defineProperty(i,s,{enumerable:!0,get:t[s]})},o.o=(i,t)=>Object.prototype.hasOwnProperty.call(i,t),o.r=i=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(i,"__esModule",{value:!0})};var e={};return(()=>{o.r(e),o.d(e,{loadAbsorbersPlugin:()=>b});var i=o(533);class t{constructor(){this.radius=0,this.mass=0}load(i){i&&(void 0!==i.mass&&(this.mass=i.mass),void 0!==i.radius&&(this.radius=i.radius))}}class s extends i.ValueWithRandom{constructor(){super(),this.density=5,this.value=50,this.limit=new t}load(t){t&&(super.load(t),void 0!==t.density&&(this.density=t.density),(0,i.isNumber)(t.limit)?this.limit.radius=t.limit:this.limit.load(t.limit))}}class r{constructor(){this.color=new i.OptionsColor,this.color.value="#000000",this.draggable=!1,this.opacity=1,this.destroy=!0,this.orbits=!1,this.size=new s}load(t){void 0!==t&&(void 0!==t.color&&(this.color=i.OptionsColor.create(this.color,t.color)),void 0!==t.draggable&&(this.draggable=t.draggable),this.name=t.name,void 0!==t.opacity&&(this.opacity=t.opacity),void 0!==t.position&&(this.position={},void 0!==t.position.x&&(this.position.x=(0,i.setRangeValue)(t.position.x)),void 0!==t.position.y&&(this.position.y=(0,i.setRangeValue)(t.position.y))),void 0!==t.size&&this.size.load(t.size),void 0!==t.destroy&&(this.destroy=t.destroy),void 0!==t.orbits&&(this.orbits=t.orbits))}}const n=0,a=0,c=2*Math.PI;class l{constructor(t,s,o,e){this.absorbers=t,this.container=s,this._calcPosition=()=>{const t=(0,i.calcPositionOrRandomFromSizeRanged)({size:this.container.canvas.size,position:this.options.position});return i.Vector.create(t.x,t.y)},this._updateParticlePosition=(t,s)=>{if(t.destroyed)return;const o=this.container,e=o.canvas.size;if(t.needsNewPosition){const s=(0,i.calcPositionOrRandomFromSize)({size:e});t.position.setTo(s),t.velocity.setTo(t.initialVelocity),t.absorberOrbit=void 0,t.needsNewPosition=!1}if(this.options.orbits){if(void 0===t.absorberOrbit&&(t.absorberOrbit=i.Vector.origin,t.absorberOrbit.length=(0,i.getDistance)(t.getPosition(),this.position),t.absorberOrbit.angle=(0,i.getRandom)()*c),t.absorberOrbit.length<=this.size&&!this.options.destroy){const s=Math.min(e.width,e.height),o=1,r=.1,n=.2;t.absorberOrbit.length=s*(o+((0,i.getRandom)()*n-r))}void 0===t.absorberOrbitDirection&&(t.absorberOrbitDirection=t.velocity.x>=0?"clockwise":"counter-clockwise");const r=t.absorberOrbit.length,n=t.absorberOrbit.angle,a=t.absorberOrbitDirection;t.velocity.setTo(i.Vector.origin);const l={x:"clockwise"===a?Math.cos:Math.sin,y:"clockwise"===a?Math.sin:Math.cos};t.position.x=this.position.x+r*l.x(n),t.position.y=this.position.y+r*l.y(n),t.absorberOrbit.length-=s.length,t.absorberOrbit.angle+=(t.retina.moveSpeed??0)*o.retina.pixelRatio/i.percentDenominator*o.retina.reduceFactor}else{const o=i.Vector.origin;o.length=s.length,o.angle=s.angle,t.velocity.addTo(o)}},this.initialPosition=e?i.Vector.create(e.x,e.y):void 0,o instanceof r?this.options=o:(this.options=new r,this.options.load(o)),this.dragging=!1,this.name=this.options.name,this.opacity=this.options.opacity,this.size=(0,i.getRangeValue)(this.options.size.value)*s.retina.pixelRatio,this.mass=this.size*this.options.size.density*s.retina.reduceFactor;const n=this.options.size.limit;this.limit={radius:n.radius*s.retina.pixelRatio*s.retina.reduceFactor,mass:n.mass},this.color=(0,i.rangeColorToRgb)(this.options.color)??{b:0,g:0,r:0},this.position=this.initialPosition?.copy()??this._calcPosition()}attract(t){const s=this.container,o=this.options;if(o.draggable){const t=s.interactivity.mouse;if(t.clicking&&t.downPosition){(0,i.getDistance)(this.position,t.downPosition)<=this.size&&(this.dragging=!0)}else this.dragging=!1;this.dragging&&t.position&&(this.position.x=t.position.x,this.position.y=t.position.y)}const e=t.getPosition(),{dx:r,dy:n,distance:a}=(0,i.getDistances)(this.position,e),c=i.Vector.create(r,n);if(c.length=this.mass/Math.pow(a,2)*s.retina.reduceFactor,a<this.size+t.getRadius()){const i=.033*t.getRadius()*s.retina.pixelRatio;this.size>t.getRadius()&&a<this.size-t.getRadius()||void 0!==t.absorberOrbit&&t.absorberOrbit.length<0?o.destroy?t.destroy():(t.needsNewPosition=!0,this._updateParticlePosition(t,c)):(o.destroy&&(t.size.value-=i),this._updateParticlePosition(t,c)),(this.limit.radius<=0||this.size<this.limit.radius)&&(this.size+=i),(this.limit.mass<=0||this.mass<this.limit.mass)&&(this.mass+=i*this.options.size.density*s.retina.reduceFactor)}else this._updateParticlePosition(t,c)}draw(t){t.translate(this.position.x,this.position.y),t.beginPath(),t.arc(n,a,this.size,0,c,!1),t.closePath(),t.fillStyle=(0,i.getStyleFromRgb)(this.color,this.opacity),t.fill()}resize(){const t=this.initialPosition;this.position=t&&(0,i.isPointInside)(t,this.container.canvas.size,i.Vector.origin)?t:this._calcPosition()}}class h{constructor(t){this.container=t,this.array=[],this.absorbers=[],this.interactivityAbsorbers=[],t.getAbsorber=t=>void 0===t||(0,i.isNumber)(t)?this.array[t??0]:this.array.find((i=>i.name===t)),t.addAbsorber=(i,t)=>this.addAbsorber(i,t)}addAbsorber(i,t){const s=new l(this,this.container,i,t);return this.array.push(s),s}draw(i){for(const t of this.array)t.draw(i)}handleClickMode(t){const s=this.absorbers,o=this.interactivityAbsorbers;if("absorber"===t){const t=(0,i.itemFromSingleOrMultiple)(o)??(0,i.itemFromSingleOrMultiple)(s),e=this.container.interactivity.mouse.clickPosition;this.addAbsorber(t,e)}}async init(){this.absorbers=this.container.actualOptions.absorbers,this.interactivityAbsorbers=this.container.actualOptions.interactivity.modes.absorbers,(0,i.executeOnSingleOrMultiple)(this.absorbers,(i=>{this.addAbsorber(i)})),await Promise.resolve()}particleUpdate(i){for(const t of this.array)if(t.attract(i),i.destroyed)break}removeAbsorber(i){const t=this.array.indexOf(i);t>=0&&this.array.splice(t,1)}resize(){for(const i of this.array)i.resize()}stop(){this.array=[]}}class d{constructor(){this.id="absorbers"}getPlugin(i){return new h(i)}loadOptions(t,s){(this.needsPlugin(t)||this.needsPlugin(s))&&(s?.absorbers&&(t.absorbers=(0,i.executeOnSingleOrMultiple)(s.absorbers,(i=>{const t=new r;return t.load(i),t}))),t.interactivity.modes.absorbers=(0,i.executeOnSingleOrMultiple)(s?.interactivity?.modes?.absorbers,(i=>{const t=new r;return t.load(i),t})))}needsPlugin(t){if(!t)return!1;const s=t.absorbers;return(0,i.isArray)(s)?!!s.length:!!s||!(!t.interactivity?.events?.onClick?.mode||!(0,i.isInArray)("absorber",t.interactivity.events.onClick.mode))}}async function b(i,t=!0){await i.addPlugin(new d,t)}})(),e})()));
@@ -1 +1 @@
1
- /*! tsParticles Absorbers Plugin v3.0.3 by Matteo Bruni */
1
+ /*! tsParticles Absorbers Plugin v3.1.0 by Matteo Bruni */
@@ -12,6 +12,10 @@
12
12
  exports.AbsorberInstance = void 0;
13
13
  const engine_1 = require("@tsparticles/engine");
14
14
  const Absorber_js_1 = require("./Options/Classes/Absorber.js");
15
+ const squareExp = 2, absorbFactor = 0.033, minOrbitLength = 0, minRadius = 0, minMass = 0, origin = {
16
+ x: 0,
17
+ y: 0,
18
+ }, minAngle = 0, double = 2, maxAngle = Math.PI * double, minVelocity = 0;
15
19
  class AbsorberInstance {
16
20
  constructor(absorbers, container, options, position) {
17
21
  this.absorbers = absorbers;
@@ -37,17 +41,17 @@
37
41
  }
38
42
  if (this.options.orbits) {
39
43
  if (particle.absorberOrbit === undefined) {
40
- particle.absorberOrbit = engine_1.Vector.create(0, 0);
44
+ particle.absorberOrbit = engine_1.Vector.origin;
41
45
  particle.absorberOrbit.length = (0, engine_1.getDistance)(particle.getPosition(), this.position);
42
- particle.absorberOrbit.angle = (0, engine_1.getRandom)() * Math.PI * 2;
46
+ particle.absorberOrbit.angle = (0, engine_1.getRandom)() * maxAngle;
43
47
  }
44
48
  if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
45
- const minSize = Math.min(canvasSize.width, canvasSize.height);
46
- particle.absorberOrbit.length = minSize * (1 + ((0, engine_1.getRandom)() * 0.2 - 0.1));
49
+ const minSize = Math.min(canvasSize.width, canvasSize.height), offset = 1, randomOffset = 0.1, randomFactor = 0.2;
50
+ particle.absorberOrbit.length = minSize * (offset + ((0, engine_1.getRandom)() * randomFactor - randomOffset));
47
51
  }
48
52
  if (particle.absorberOrbitDirection === undefined) {
49
53
  particle.absorberOrbitDirection =
50
- particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise";
54
+ particle.velocity.x >= minVelocity ? "clockwise" : "counter-clockwise";
51
55
  }
52
56
  const orbitRadius = particle.absorberOrbit.length, orbitAngle = particle.absorberOrbit.angle, orbitDirection = particle.absorberOrbitDirection;
53
57
  particle.velocity.setTo(engine_1.Vector.origin);
@@ -59,7 +63,7 @@
59
63
  particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
60
64
  particle.absorberOrbit.length -= v.length;
61
65
  particle.absorberOrbit.angle +=
62
- (((particle.retina.moveSpeed ?? 0) * container.retina.pixelRatio) / 100) *
66
+ (((particle.retina.moveSpeed ?? minVelocity) * container.retina.pixelRatio) / engine_1.percentDenominator) *
63
67
  container.retina.reduceFactor;
64
68
  }
65
69
  else {
@@ -113,11 +117,11 @@
113
117
  }
114
118
  }
115
119
  const pos = particle.getPosition(), { dx, dy, distance } = (0, engine_1.getDistances)(this.position, pos), v = engine_1.Vector.create(dx, dy);
116
- v.length = (this.mass / Math.pow(distance, 2)) * container.retina.reduceFactor;
120
+ v.length = (this.mass / Math.pow(distance, squareExp)) * container.retina.reduceFactor;
117
121
  if (distance < this.size + particle.getRadius()) {
118
- const sizeFactor = particle.getRadius() * 0.033 * container.retina.pixelRatio;
122
+ const sizeFactor = particle.getRadius() * absorbFactor * container.retina.pixelRatio;
119
123
  if ((this.size > particle.getRadius() && distance < this.size - particle.getRadius()) ||
120
- (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < 0)) {
124
+ (particle.absorberOrbit !== undefined && particle.absorberOrbit.length < minOrbitLength)) {
121
125
  if (options.destroy) {
122
126
  particle.destroy();
123
127
  }
@@ -132,10 +136,10 @@
132
136
  }
133
137
  this._updateParticlePosition(particle, v);
134
138
  }
135
- if (this.limit.radius <= 0 || this.size < this.limit.radius) {
139
+ if (this.limit.radius <= minRadius || this.size < this.limit.radius) {
136
140
  this.size += sizeFactor;
137
141
  }
138
- if (this.limit.mass <= 0 || this.mass < this.limit.mass) {
142
+ if (this.limit.mass <= minMass || this.mass < this.limit.mass) {
139
143
  this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;
140
144
  }
141
145
  }
@@ -146,7 +150,7 @@
146
150
  draw(context) {
147
151
  context.translate(this.position.x, this.position.y);
148
152
  context.beginPath();
149
- context.arc(0, 0, this.size, 0, Math.PI * 2, false);
153
+ context.arc(origin.x, origin.y, this.size, minAngle, maxAngle, false);
150
154
  context.closePath();
151
155
  context.fillStyle = (0, engine_1.getStyleFromRgb)(this.color, this.opacity);
152
156
  context.fill();
package/umd/Absorbers.js CHANGED
@@ -12,6 +12,7 @@
12
12
  exports.Absorbers = void 0;
13
13
  const engine_1 = require("@tsparticles/engine");
14
14
  const AbsorberInstance_js_1 = require("./AbsorberInstance.js");
15
+ const defaultIndex = 0;
15
16
  class Absorbers {
16
17
  constructor(container) {
17
18
  this.container = container;
@@ -19,7 +20,7 @@
19
20
  this.absorbers = [];
20
21
  this.interactivityAbsorbers = [];
21
22
  container.getAbsorber = (idxOrName) => idxOrName === undefined || (0, engine_1.isNumber)(idxOrName)
22
- ? this.array[idxOrName || 0]
23
+ ? this.array[idxOrName ?? defaultIndex]
23
24
  : this.array.find((t) => t.name === idxOrName);
24
25
  container.addAbsorber = (options, position) => this.addAbsorber(options, position);
25
26
  }
@@ -46,6 +47,7 @@
46
47
  (0, engine_1.executeOnSingleOrMultiple)(this.absorbers, (absorber) => {
47
48
  this.addAbsorber(absorber);
48
49
  });
50
+ await Promise.resolve();
49
51
  }
50
52
  particleUpdate(particle) {
51
53
  for (const absorber of this.array) {
@@ -56,9 +58,9 @@
56
58
  }
57
59
  }
58
60
  removeAbsorber(absorber) {
59
- const index = this.array.indexOf(absorber);
60
- if (index >= 0) {
61
- this.array.splice(index, 1);
61
+ const index = this.array.indexOf(absorber), deleteCount = 1;
62
+ if (index >= defaultIndex) {
63
+ this.array.splice(index, deleteCount);
62
64
  }
63
65
  }
64
66
  resize() {