@tsparticles/interaction-particles-links 3.0.2 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import { Circle, Rectangle } from "@tsparticles/engine";
2
+ const double = 2;
2
3
  export class CircleWarp extends Circle {
3
4
  constructor(x, y, radius, canvasSize) {
4
5
  super(x, y, radius);
@@ -22,11 +23,11 @@ export class CircleWarp extends Circle {
22
23
  y: range.position.y - this.canvasSize.height,
23
24
  };
24
25
  if (circle.radius !== undefined) {
25
- const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * 2);
26
+ const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * double);
26
27
  return super.intersects(biggerCircle);
27
28
  }
28
29
  else if (rect.size !== undefined) {
29
- const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
30
+ const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * double, rect.size.height * double);
30
31
  return super.intersects(rectSW);
31
32
  }
32
33
  return false;
@@ -1,5 +1,6 @@
1
1
  import { getDistance, getLinkColor, getRandom, getRangeValue, rangeColorToRgb, } from "@tsparticles/engine";
2
2
  import { drawLinkLine, drawLinkTriangle, setLinkFrequency } from "./Utils.js";
3
+ const minOpacity = 0, minWidth = 0, minDistance = 0, half = 0.5;
3
4
  export class LinkInstance {
4
5
  constructor(container) {
5
6
  this.container = container;
@@ -29,7 +30,7 @@ export class LinkInstance {
29
30
  if (!colorLine) {
30
31
  return;
31
32
  }
32
- const width = p1.retina.linksWidth ?? 0, maxDistance = p1.retina.linksDistance ?? 0, { backgroundMask } = options;
33
+ const width = p1.retina.linksWidth ?? minWidth, maxDistance = p1.retina.linksDistance ?? minDistance, { backgroundMask } = options;
33
34
  drawLinkLine({
34
35
  context: ctx,
35
36
  width,
@@ -53,12 +54,12 @@ export class LinkInstance {
53
54
  if (!triangleOptions.enable) {
54
55
  return;
55
56
  }
56
- const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) / 2;
57
- if (opacityTriangle <= 0) {
57
+ const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * half;
58
+ if (opacityTriangle <= minOpacity) {
58
59
  return;
59
60
  }
60
61
  container.canvas.draw((ctx) => {
61
- const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? 0;
62
+ const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? minDistance;
62
63
  if (getDistance(pos1, pos2) > linksDistance ||
63
64
  getDistance(pos3, pos2) > linksDistance ||
64
65
  getDistance(pos3, pos1) > linksDistance) {
@@ -91,10 +92,10 @@ export class LinkInstance {
91
92
  return;
92
93
  }
93
94
  const vertices = p2.links?.filter((t) => {
94
- const linkFreq = this._getLinkFrequency(p2, t.destination);
95
+ const linkFreq = this._getLinkFrequency(p2, t.destination), minCount = 0;
95
96
  return (p2.options.links &&
96
97
  linkFreq <= p2.options.links.frequency &&
97
- p1Links.findIndex((l) => l.destination === t.destination) >= 0);
98
+ p1Links.findIndex((l) => l.destination === t.destination) >= minCount);
98
99
  });
99
100
  if (!vertices?.length) {
100
101
  return;
@@ -120,13 +121,13 @@ export class LinkInstance {
120
121
  }
121
122
  drawParticle(context, particle) {
122
123
  const { links, options } = particle;
123
- if (!links || links.length <= 0) {
124
+ if (!links?.length) {
124
125
  return;
125
126
  }
126
127
  const p1Links = links.filter((l) => options.links && this._getLinkFrequency(particle, l.destination) <= options.links.frequency);
127
128
  for (const link of p1Links) {
128
129
  this._drawTriangles(options, particle, link, p1Links);
129
- if (link.opacity > 0 && (particle.retina.linksWidth ?? 0) > 0) {
130
+ if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {
130
131
  this._drawLinkLine(particle, link);
131
132
  }
132
133
  }
@@ -134,6 +135,7 @@ export class LinkInstance {
134
135
  async init() {
135
136
  this._freqs.links = new Map();
136
137
  this._freqs.triangles = new Map();
138
+ await Promise.resolve();
137
139
  }
138
140
  particleCreated(particle) {
139
141
  particle.links = [];
package/browser/Linker.js CHANGED
@@ -1,6 +1,10 @@
1
1
  import { Circle, ParticlesInteractorBase, getDistances, getLinkRandomColor, } from "@tsparticles/engine";
2
2
  import { CircleWarp } from "./CircleWarp.js";
3
3
  import { Links } from "./Options/Classes/Links.js";
4
+ const squarePower = 2, opacityOffset = 1, origin = {
5
+ x: 0,
6
+ y: 0,
7
+ }, minDistance = 0;
4
8
  function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
5
9
  const { dx, dy, distance } = getDistances(pos1, pos2);
6
10
  if (!warp || distance <= optDistance) {
@@ -13,7 +17,7 @@ function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
13
17
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
14
18
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
15
19
  };
16
- return Math.sqrt(warpDistances.x ** 2 + warpDistances.y ** 2);
20
+ return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
17
21
  }
18
22
  export class Linker extends ParticlesInteractorBase {
19
23
  constructor(container) {
@@ -52,10 +56,10 @@ export class Linker extends ParticlesInteractorBase {
52
56
  }
53
57
  p1.links = [];
54
58
  const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;
55
- if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
59
+ if (pos1.x < origin.x || pos1.y < origin.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
56
60
  return;
57
61
  }
58
- const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? 0, warp = linkOpt1.warp, range = warp
62
+ const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp
59
63
  ? new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize)
60
64
  : new Circle(pos1.x, pos1.y, optDistance), query = container.particles.quadTree.query(range);
61
65
  for (const p2 of query) {
@@ -71,20 +75,21 @@ export class Linker extends ParticlesInteractorBase {
71
75
  continue;
72
76
  }
73
77
  const pos2 = p2.getPosition();
74
- if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
78
+ if (pos2.x < origin.x || pos2.y < origin.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
75
79
  continue;
76
80
  }
77
81
  const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
78
82
  if (distance > optDistance) {
79
83
  continue;
80
84
  }
81
- const opacityLine = (1 - distance / optDistance) * optOpacity;
85
+ const opacityLine = (opacityOffset - distance / optDistance) * optOpacity;
82
86
  this._setColor(p1);
83
87
  p1.links.push({
84
88
  destination: p2,
85
89
  opacity: opacityLine,
86
90
  });
87
91
  }
92
+ await Promise.resolve();
88
93
  }
89
94
  isEnabled(particle) {
90
95
  return !!particle.options.links?.enable;
package/cjs/CircleWarp.js CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CircleWarp = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
+ const double = 2;
5
6
  class CircleWarp extends engine_1.Circle {
6
7
  constructor(x, y, radius, canvasSize) {
7
8
  super(x, y, radius);
@@ -25,11 +26,11 @@ class CircleWarp extends engine_1.Circle {
25
26
  y: range.position.y - this.canvasSize.height,
26
27
  };
27
28
  if (circle.radius !== undefined) {
28
- const biggerCircle = new engine_1.Circle(newPos.x, newPos.y, circle.radius * 2);
29
+ const biggerCircle = new engine_1.Circle(newPos.x, newPos.y, circle.radius * double);
29
30
  return super.intersects(biggerCircle);
30
31
  }
31
32
  else if (rect.size !== undefined) {
32
- const rectSW = new engine_1.Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
33
+ const rectSW = new engine_1.Rectangle(newPos.x, newPos.y, rect.size.width * double, rect.size.height * double);
33
34
  return super.intersects(rectSW);
34
35
  }
35
36
  return false;
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.LinkInstance = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
5
  const Utils_js_1 = require("./Utils.js");
6
+ const minOpacity = 0, minWidth = 0, minDistance = 0, half = 0.5;
6
7
  class LinkInstance {
7
8
  constructor(container) {
8
9
  this.container = container;
@@ -32,7 +33,7 @@ class LinkInstance {
32
33
  if (!colorLine) {
33
34
  return;
34
35
  }
35
- const width = p1.retina.linksWidth ?? 0, maxDistance = p1.retina.linksDistance ?? 0, { backgroundMask } = options;
36
+ const width = p1.retina.linksWidth ?? minWidth, maxDistance = p1.retina.linksDistance ?? minDistance, { backgroundMask } = options;
36
37
  (0, Utils_js_1.drawLinkLine)({
37
38
  context: ctx,
38
39
  width,
@@ -56,12 +57,12 @@ class LinkInstance {
56
57
  if (!triangleOptions.enable) {
57
58
  return;
58
59
  }
59
- const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) / 2;
60
- if (opacityTriangle <= 0) {
60
+ const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * half;
61
+ if (opacityTriangle <= minOpacity) {
61
62
  return;
62
63
  }
63
64
  container.canvas.draw((ctx) => {
64
- const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? 0;
65
+ const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? minDistance;
65
66
  if ((0, engine_1.getDistance)(pos1, pos2) > linksDistance ||
66
67
  (0, engine_1.getDistance)(pos3, pos2) > linksDistance ||
67
68
  (0, engine_1.getDistance)(pos3, pos1) > linksDistance) {
@@ -94,10 +95,10 @@ class LinkInstance {
94
95
  return;
95
96
  }
96
97
  const vertices = p2.links?.filter((t) => {
97
- const linkFreq = this._getLinkFrequency(p2, t.destination);
98
+ const linkFreq = this._getLinkFrequency(p2, t.destination), minCount = 0;
98
99
  return (p2.options.links &&
99
100
  linkFreq <= p2.options.links.frequency &&
100
- p1Links.findIndex((l) => l.destination === t.destination) >= 0);
101
+ p1Links.findIndex((l) => l.destination === t.destination) >= minCount);
101
102
  });
102
103
  if (!vertices?.length) {
103
104
  return;
@@ -123,13 +124,13 @@ class LinkInstance {
123
124
  }
124
125
  drawParticle(context, particle) {
125
126
  const { links, options } = particle;
126
- if (!links || links.length <= 0) {
127
+ if (!links?.length) {
127
128
  return;
128
129
  }
129
130
  const p1Links = links.filter((l) => options.links && this._getLinkFrequency(particle, l.destination) <= options.links.frequency);
130
131
  for (const link of p1Links) {
131
132
  this._drawTriangles(options, particle, link, p1Links);
132
- if (link.opacity > 0 && (particle.retina.linksWidth ?? 0) > 0) {
133
+ if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {
133
134
  this._drawLinkLine(particle, link);
134
135
  }
135
136
  }
@@ -137,6 +138,7 @@ class LinkInstance {
137
138
  async init() {
138
139
  this._freqs.links = new Map();
139
140
  this._freqs.triangles = new Map();
141
+ await Promise.resolve();
140
142
  }
141
143
  particleCreated(particle) {
142
144
  particle.links = [];
package/cjs/Linker.js CHANGED
@@ -4,6 +4,10 @@ exports.Linker = void 0;
4
4
  const engine_1 = require("@tsparticles/engine");
5
5
  const CircleWarp_js_1 = require("./CircleWarp.js");
6
6
  const Links_js_1 = require("./Options/Classes/Links.js");
7
+ const squarePower = 2, opacityOffset = 1, origin = {
8
+ x: 0,
9
+ y: 0,
10
+ }, minDistance = 0;
7
11
  function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
8
12
  const { dx, dy, distance } = (0, engine_1.getDistances)(pos1, pos2);
9
13
  if (!warp || distance <= optDistance) {
@@ -16,7 +20,7 @@ function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
16
20
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
17
21
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
18
22
  };
19
- return Math.sqrt(warpDistances.x ** 2 + warpDistances.y ** 2);
23
+ return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
20
24
  }
21
25
  class Linker extends engine_1.ParticlesInteractorBase {
22
26
  constructor(container) {
@@ -55,10 +59,10 @@ class Linker extends engine_1.ParticlesInteractorBase {
55
59
  }
56
60
  p1.links = [];
57
61
  const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;
58
- if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
62
+ if (pos1.x < origin.x || pos1.y < origin.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
59
63
  return;
60
64
  }
61
- const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? 0, warp = linkOpt1.warp, range = warp
65
+ const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp
62
66
  ? new CircleWarp_js_1.CircleWarp(pos1.x, pos1.y, optDistance, canvasSize)
63
67
  : new engine_1.Circle(pos1.x, pos1.y, optDistance), query = container.particles.quadTree.query(range);
64
68
  for (const p2 of query) {
@@ -74,20 +78,21 @@ class Linker extends engine_1.ParticlesInteractorBase {
74
78
  continue;
75
79
  }
76
80
  const pos2 = p2.getPosition();
77
- if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
81
+ if (pos2.x < origin.x || pos2.y < origin.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
78
82
  continue;
79
83
  }
80
84
  const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
81
85
  if (distance > optDistance) {
82
86
  continue;
83
87
  }
84
- const opacityLine = (1 - distance / optDistance) * optOpacity;
88
+ const opacityLine = (opacityOffset - distance / optDistance) * optOpacity;
85
89
  this._setColor(p1);
86
90
  p1.links.push({
87
91
  destination: p2,
88
92
  opacity: opacityLine,
89
93
  });
90
94
  }
95
+ await Promise.resolve();
91
96
  }
92
97
  isEnabled(particle) {
93
98
  return !!particle.options.links?.enable;
package/esm/CircleWarp.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Circle, Rectangle } from "@tsparticles/engine";
2
+ const double = 2;
2
3
  export class CircleWarp extends Circle {
3
4
  constructor(x, y, radius, canvasSize) {
4
5
  super(x, y, radius);
@@ -22,11 +23,11 @@ export class CircleWarp extends Circle {
22
23
  y: range.position.y - this.canvasSize.height,
23
24
  };
24
25
  if (circle.radius !== undefined) {
25
- const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * 2);
26
+ const biggerCircle = new Circle(newPos.x, newPos.y, circle.radius * double);
26
27
  return super.intersects(biggerCircle);
27
28
  }
28
29
  else if (rect.size !== undefined) {
29
- const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
30
+ const rectSW = new Rectangle(newPos.x, newPos.y, rect.size.width * double, rect.size.height * double);
30
31
  return super.intersects(rectSW);
31
32
  }
32
33
  return false;
@@ -1,5 +1,6 @@
1
1
  import { getDistance, getLinkColor, getRandom, getRangeValue, rangeColorToRgb, } from "@tsparticles/engine";
2
2
  import { drawLinkLine, drawLinkTriangle, setLinkFrequency } from "./Utils.js";
3
+ const minOpacity = 0, minWidth = 0, minDistance = 0, half = 0.5;
3
4
  export class LinkInstance {
4
5
  constructor(container) {
5
6
  this.container = container;
@@ -29,7 +30,7 @@ export class LinkInstance {
29
30
  if (!colorLine) {
30
31
  return;
31
32
  }
32
- const width = p1.retina.linksWidth ?? 0, maxDistance = p1.retina.linksDistance ?? 0, { backgroundMask } = options;
33
+ const width = p1.retina.linksWidth ?? minWidth, maxDistance = p1.retina.linksDistance ?? minDistance, { backgroundMask } = options;
33
34
  drawLinkLine({
34
35
  context: ctx,
35
36
  width,
@@ -53,12 +54,12 @@ export class LinkInstance {
53
54
  if (!triangleOptions.enable) {
54
55
  return;
55
56
  }
56
- const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) / 2;
57
- if (opacityTriangle <= 0) {
57
+ const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * half;
58
+ if (opacityTriangle <= minOpacity) {
58
59
  return;
59
60
  }
60
61
  container.canvas.draw((ctx) => {
61
- const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? 0;
62
+ const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? minDistance;
62
63
  if (getDistance(pos1, pos2) > linksDistance ||
63
64
  getDistance(pos3, pos2) > linksDistance ||
64
65
  getDistance(pos3, pos1) > linksDistance) {
@@ -91,10 +92,10 @@ export class LinkInstance {
91
92
  return;
92
93
  }
93
94
  const vertices = p2.links?.filter((t) => {
94
- const linkFreq = this._getLinkFrequency(p2, t.destination);
95
+ const linkFreq = this._getLinkFrequency(p2, t.destination), minCount = 0;
95
96
  return (p2.options.links &&
96
97
  linkFreq <= p2.options.links.frequency &&
97
- p1Links.findIndex((l) => l.destination === t.destination) >= 0);
98
+ p1Links.findIndex((l) => l.destination === t.destination) >= minCount);
98
99
  });
99
100
  if (!vertices?.length) {
100
101
  return;
@@ -120,13 +121,13 @@ export class LinkInstance {
120
121
  }
121
122
  drawParticle(context, particle) {
122
123
  const { links, options } = particle;
123
- if (!links || links.length <= 0) {
124
+ if (!links?.length) {
124
125
  return;
125
126
  }
126
127
  const p1Links = links.filter((l) => options.links && this._getLinkFrequency(particle, l.destination) <= options.links.frequency);
127
128
  for (const link of p1Links) {
128
129
  this._drawTriangles(options, particle, link, p1Links);
129
- if (link.opacity > 0 && (particle.retina.linksWidth ?? 0) > 0) {
130
+ if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {
130
131
  this._drawLinkLine(particle, link);
131
132
  }
132
133
  }
@@ -134,6 +135,7 @@ export class LinkInstance {
134
135
  async init() {
135
136
  this._freqs.links = new Map();
136
137
  this._freqs.triangles = new Map();
138
+ await Promise.resolve();
137
139
  }
138
140
  particleCreated(particle) {
139
141
  particle.links = [];
package/esm/Linker.js CHANGED
@@ -1,6 +1,10 @@
1
1
  import { Circle, ParticlesInteractorBase, getDistances, getLinkRandomColor, } from "@tsparticles/engine";
2
2
  import { CircleWarp } from "./CircleWarp.js";
3
3
  import { Links } from "./Options/Classes/Links.js";
4
+ const squarePower = 2, opacityOffset = 1, origin = {
5
+ x: 0,
6
+ y: 0,
7
+ }, minDistance = 0;
4
8
  function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
5
9
  const { dx, dy, distance } = getDistances(pos1, pos2);
6
10
  if (!warp || distance <= optDistance) {
@@ -13,7 +17,7 @@ function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
13
17
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
14
18
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
15
19
  };
16
- return Math.sqrt(warpDistances.x ** 2 + warpDistances.y ** 2);
20
+ return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
17
21
  }
18
22
  export class Linker extends ParticlesInteractorBase {
19
23
  constructor(container) {
@@ -52,10 +56,10 @@ export class Linker extends ParticlesInteractorBase {
52
56
  }
53
57
  p1.links = [];
54
58
  const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;
55
- if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
59
+ if (pos1.x < origin.x || pos1.y < origin.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
56
60
  return;
57
61
  }
58
- const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? 0, warp = linkOpt1.warp, range = warp
62
+ const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp
59
63
  ? new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize)
60
64
  : new Circle(pos1.x, pos1.y, optDistance), query = container.particles.quadTree.query(range);
61
65
  for (const p2 of query) {
@@ -71,20 +75,21 @@ export class Linker extends ParticlesInteractorBase {
71
75
  continue;
72
76
  }
73
77
  const pos2 = p2.getPosition();
74
- if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
78
+ if (pos2.x < origin.x || pos2.y < origin.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
75
79
  continue;
76
80
  }
77
81
  const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
78
82
  if (distance > optDistance) {
79
83
  continue;
80
84
  }
81
- const opacityLine = (1 - distance / optDistance) * optOpacity;
85
+ const opacityLine = (opacityOffset - distance / optDistance) * optOpacity;
82
86
  this._setColor(p1);
83
87
  p1.links.push({
84
88
  destination: p2,
85
89
  opacity: opacityLine,
86
90
  });
87
91
  }
92
+ await Promise.resolve();
88
93
  }
89
94
  isEnabled(particle) {
90
95
  return !!particle.options.links?.enable;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/interaction-particles-links",
3
- "version": "3.0.2",
3
+ "version": "3.1.0",
4
4
  "description": "tsParticles links particles interaction",
5
5
  "homepage": "https://particles.js.org",
6
6
  "repository": {
@@ -87,7 +87,7 @@
87
87
  "./package.json": "./package.json"
88
88
  },
89
89
  "dependencies": {
90
- "@tsparticles/engine": "^3.0.2"
90
+ "@tsparticles/engine": "^3.1.0"
91
91
  },
92
92
  "publishConfig": {
93
93
  "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/interaction-particles-links [6 Dec 2023 at 17:40]</title>
6
+ <title>@tsparticles/interaction-particles-links [13 Jan 2024 at 23:00]</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.interaction.particles.links.js","isAsset":true,"statSize":17184,"parsedSize":21077,"gzipSize":4965,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":17142,"groups":[{"id":493,"label":"index.js + 9 modules (concatenated)","path":"./dist/browser/index.js + 9 modules (concatenated)","statSize":17142,"parsedSize":21077,"gzipSize":4965,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser","statSize":17142,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/index.js","statSize":576,"parsedSize":708,"gzipSize":166,"inaccurateSizes":true},{"id":null,"label":"interaction.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/interaction.js","statSize":201,"parsedSize":247,"gzipSize":58,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes","statSize":2440,"groups":[{"id":null,"label":"Links.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/Links.js","statSize":1407,"parsedSize":1729,"gzipSize":407,"inaccurateSizes":true},{"id":null,"label":"LinksShadow.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/LinksShadow.js","statSize":478,"parsedSize":587,"gzipSize":138,"inaccurateSizes":true},{"id":null,"label":"LinksTriangle.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/LinksTriangle.js","statSize":555,"parsedSize":682,"gzipSize":160,"inaccurateSizes":true}],"parsedSize":3000,"gzipSize":706,"inaccurateSizes":true},{"id":null,"label":"plugin.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/plugin.js","statSize":388,"parsedSize":477,"gzipSize":112,"inaccurateSizes":true},{"id":null,"label":"Linker.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Linker.js","statSize":3430,"parsedSize":4217,"gzipSize":993,"inaccurateSizes":true},{"id":null,"label":"LinkInstance.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/LinkInstance.js","statSize":5588,"parsedSize":6870,"gzipSize":1618,"inaccurateSizes":true},{"id":null,"label":"CircleWarp.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/CircleWarp.js","statSize":1228,"parsedSize":1509,"gzipSize":355,"inaccurateSizes":true},{"id":null,"label":"Utils.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Utils.js","statSize":3291,"parsedSize":4046,"gzipSize":953,"inaccurateSizes":true}],"parsedSize":21077,"gzipSize":4965,"inaccurateSizes":true}]}],"parsedSize":21077,"gzipSize":4965},{"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.interaction.particles.links":true}}];
34
+ window.chartData = [{"label":"tsparticles.interaction.particles.links.js","isAsset":true,"statSize":17596,"parsedSize":21572,"gzipSize":5099,"groups":[{"label":"dist/browser","path":"./dist/browser","statSize":17554,"groups":[{"id":824,"label":"index.js + 9 modules (concatenated)","path":"./dist/browser/index.js + 9 modules (concatenated)","statSize":17554,"parsedSize":21572,"gzipSize":5099,"concatenated":true,"groups":[{"label":"dist/browser","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser","statSize":17554,"groups":[{"id":null,"label":"index.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/index.js","statSize":576,"parsedSize":707,"gzipSize":167,"inaccurateSizes":true},{"id":null,"label":"interaction.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/interaction.js","statSize":201,"parsedSize":247,"gzipSize":58,"inaccurateSizes":true},{"label":"Options/Classes","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes","statSize":2440,"groups":[{"id":null,"label":"Links.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/Links.js","statSize":1407,"parsedSize":1729,"gzipSize":408,"inaccurateSizes":true},{"id":null,"label":"LinksShadow.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/LinksShadow.js","statSize":478,"parsedSize":587,"gzipSize":138,"inaccurateSizes":true},{"id":null,"label":"LinksTriangle.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Options/Classes/LinksTriangle.js","statSize":555,"parsedSize":682,"gzipSize":161,"inaccurateSizes":true}],"parsedSize":2998,"gzipSize":708,"inaccurateSizes":true},{"id":null,"label":"plugin.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/plugin.js","statSize":388,"parsedSize":476,"gzipSize":112,"inaccurateSizes":true},{"id":null,"label":"Linker.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Linker.js","statSize":3629,"parsedSize":4459,"gzipSize":1054,"inaccurateSizes":true},{"id":null,"label":"LinkInstance.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/LinkInstance.js","statSize":5768,"parsedSize":7088,"gzipSize":1675,"inaccurateSizes":true},{"id":null,"label":"CircleWarp.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/CircleWarp.js","statSize":1261,"parsedSize":1549,"gzipSize":366,"inaccurateSizes":true},{"id":null,"label":"Utils.js","path":"./dist/browser/index.js + 9 modules (concatenated)/dist/browser/Utils.js","statSize":3291,"parsedSize":4044,"gzipSize":955,"inaccurateSizes":true}],"parsedSize":21572,"gzipSize":5099,"inaccurateSizes":true}]}],"parsedSize":21572,"gzipSize":5099},{"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.interaction.particles.links":true}}];
35
35
  window.entrypoints = ["tsparticles.interaction.particles.links","tsparticles.interaction.particles.links.min"];
36
36
  window.defaultSizes = "parsed";
37
37
  </script>
@@ -4,7 +4,7 @@
4
4
  * Demo / Generator : https://particles.js.org/
5
5
  * GitHub : https://www.github.com/matteobruni/tsparticles
6
6
  * How to use? : Check the GitHub README
7
- * v3.0.2
7
+ * v3.1.0
8
8
  */
9
9
  (function webpackUniversalModuleDefinition(root, factory) {
10
10
  if(typeof exports === 'object' && typeof module === 'object')
@@ -101,6 +101,7 @@ __webpack_require__.d(__webpack_exports__, {
101
101
  var engine_root_window_ = __webpack_require__(533);
102
102
  ;// CONCATENATED MODULE: ./dist/browser/CircleWarp.js
103
103
 
104
+ const CircleWarp_double = 2;
104
105
  class CircleWarp extends engine_root_window_.Circle {
105
106
  constructor(x, y, radius, canvasSize) {
106
107
  super(x, y, radius);
@@ -140,10 +141,10 @@ class CircleWarp extends engine_root_window_.Circle {
140
141
  y: range.position.y - this.canvasSize.height
141
142
  };
142
143
  if (circle.radius !== undefined) {
143
- const biggerCircle = new engine_root_window_.Circle(newPos.x, newPos.y, circle.radius * 2);
144
+ const biggerCircle = new engine_root_window_.Circle(newPos.x, newPos.y, circle.radius * CircleWarp_double);
144
145
  return super.intersects(biggerCircle);
145
146
  } else if (rect.size !== undefined) {
146
- const rectSW = new engine_root_window_.Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
147
+ const rectSW = new engine_root_window_.Rectangle(newPos.x, newPos.y, rect.size.width * CircleWarp_double, rect.size.height * CircleWarp_double);
147
148
  return super.intersects(rectSW);
148
149
  }
149
150
  return false;
@@ -255,6 +256,13 @@ class Links {
255
256
 
256
257
 
257
258
 
259
+ const squarePower = 2,
260
+ opacityOffset = 1,
261
+ origin = {
262
+ x: 0,
263
+ y: 0
264
+ },
265
+ minDistance = 0;
258
266
  function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
259
267
  const {
260
268
  dx,
@@ -272,7 +280,7 @@ function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
272
280
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
273
281
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y)
274
282
  };
275
- return Math.sqrt(warpDistances.x ** 2 + warpDistances.y ** 2);
283
+ return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
276
284
  }
277
285
  class Linker extends engine_root_window_.ParticlesInteractorBase {
278
286
  constructor(container) {
@@ -310,12 +318,12 @@ class Linker extends engine_root_window_.ParticlesInteractorBase {
310
318
  const pos1 = p1.getPosition(),
311
319
  container = this.container,
312
320
  canvasSize = container.canvas.size;
313
- if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
321
+ if (pos1.x < origin.x || pos1.y < origin.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
314
322
  return;
315
323
  }
316
324
  const linkOpt1 = p1.options.links,
317
325
  optOpacity = linkOpt1.opacity,
318
- optDistance = p1.retina.linksDistance ?? 0,
326
+ optDistance = p1.retina.linksDistance ?? minDistance,
319
327
  warp = linkOpt1.warp,
320
328
  range = warp ? new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new engine_root_window_.Circle(pos1.x, pos1.y, optDistance),
321
329
  query = container.particles.quadTree.query(range);
@@ -325,20 +333,21 @@ class Linker extends engine_root_window_.ParticlesInteractorBase {
325
333
  continue;
326
334
  }
327
335
  const pos2 = p2.getPosition();
328
- if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
336
+ if (pos2.x < origin.x || pos2.y < origin.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
329
337
  continue;
330
338
  }
331
339
  const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
332
340
  if (distance > optDistance) {
333
341
  continue;
334
342
  }
335
- const opacityLine = (1 - distance / optDistance) * optOpacity;
343
+ const opacityLine = (opacityOffset - distance / optDistance) * optOpacity;
336
344
  this._setColor(p1);
337
345
  p1.links.push({
338
346
  destination: p2,
339
347
  opacity: opacityLine
340
348
  });
341
349
  }
350
+ await Promise.resolve();
342
351
  }
343
352
  isEnabled(particle) {
344
353
  return !!particle.options.links?.enable;
@@ -498,6 +507,10 @@ function setLinkFrequency(particles, dictionary) {
498
507
  ;// CONCATENATED MODULE: ./dist/browser/LinkInstance.js
499
508
 
500
509
 
510
+ const minOpacity = 0,
511
+ minWidth = 0,
512
+ LinkInstance_minDistance = 0,
513
+ half = 0.5;
501
514
  class LinkInstance {
502
515
  constructor(container) {
503
516
  this.container = container;
@@ -531,8 +544,8 @@ class LinkInstance {
531
544
  if (!colorLine) {
532
545
  return;
533
546
  }
534
- const width = p1.retina.linksWidth ?? 0,
535
- maxDistance = p1.retina.linksDistance ?? 0,
547
+ const width = p1.retina.linksWidth ?? minWidth,
548
+ maxDistance = p1.retina.linksDistance ?? LinkInstance_minDistance,
536
549
  {
537
550
  backgroundMask
538
551
  } = options;
@@ -563,15 +576,15 @@ class LinkInstance {
563
576
  options = container.actualOptions,
564
577
  p2 = link1.destination,
565
578
  p3 = link2.destination,
566
- opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) / 2;
567
- if (opacityTriangle <= 0) {
579
+ opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * half;
580
+ if (opacityTriangle <= minOpacity) {
568
581
  return;
569
582
  }
570
583
  container.canvas.draw(ctx => {
571
584
  const pos1 = p1.getPosition(),
572
585
  pos2 = p2.getPosition(),
573
586
  pos3 = p3.getPosition(),
574
- linksDistance = p1.retina.linksDistance ?? 0;
587
+ linksDistance = p1.retina.linksDistance ?? LinkInstance_minDistance;
575
588
  if ((0,engine_root_window_.getDistance)(pos1, pos2) > linksDistance || (0,engine_root_window_.getDistance)(pos3, pos2) > linksDistance || (0,engine_root_window_.getDistance)(pos3, pos1) > linksDistance) {
576
589
  return;
577
590
  }
@@ -600,8 +613,9 @@ class LinkInstance {
600
613
  return;
601
614
  }
602
615
  const vertices = p2.links?.filter(t => {
603
- const linkFreq = this._getLinkFrequency(p2, t.destination);
604
- return p2.options.links && linkFreq <= p2.options.links.frequency && p1Links.findIndex(l => l.destination === t.destination) >= 0;
616
+ const linkFreq = this._getLinkFrequency(p2, t.destination),
617
+ minCount = 0;
618
+ return p2.options.links && linkFreq <= p2.options.links.frequency && p1Links.findIndex(l => l.destination === t.destination) >= minCount;
605
619
  });
606
620
  if (!vertices?.length) {
607
621
  return;
@@ -631,13 +645,13 @@ class LinkInstance {
631
645
  links,
632
646
  options
633
647
  } = particle;
634
- if (!links || links.length <= 0) {
648
+ if (!links?.length) {
635
649
  return;
636
650
  }
637
651
  const p1Links = links.filter(l => options.links && this._getLinkFrequency(particle, l.destination) <= options.links.frequency);
638
652
  for (const link of p1Links) {
639
653
  this._drawTriangles(options, particle, link, p1Links);
640
- if (link.opacity > 0 && (particle.retina.linksWidth ?? 0) > 0) {
654
+ if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {
641
655
  this._drawLinkLine(particle, link);
642
656
  }
643
657
  }
@@ -645,6 +659,7 @@ class LinkInstance {
645
659
  async init() {
646
660
  this._freqs.links = new Map();
647
661
  this._freqs.triangles = new Map();
662
+ await Promise.resolve();
648
663
  }
649
664
  particleCreated(particle) {
650
665
  particle.links = [];
@@ -1,2 +1,2 @@
1
1
  /*! For license information please see tsparticles.interaction.particles.links.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 n="object"==typeof exports?t(require("@tsparticles/engine")):t(i.window);for(var e in n)("object"==typeof exports?exports:i)[e]=n[e]}}(this,(i=>(()=>{"use strict";var t={533:t=>{t.exports=i}},n={};function e(i){var s=n[i];if(void 0!==s)return s.exports;var o=n[i]={exports:{}};return t[i](o,o.exports,e),o.exports}e.d=(i,t)=>{for(var n in t)e.o(t,n)&&!e.o(i,n)&&Object.defineProperty(i,n,{enumerable:!0,get:t[n]})},e.o=(i,t)=>Object.prototype.hasOwnProperty.call(i,t),e.r=i=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(i,"__esModule",{value:!0})};var s={};return(()=>{e.r(s),e.d(s,{Links:()=>r,LinksShadow:()=>n,LinksTriangle:()=>o,loadParticlesLinksInteraction:()=>p});var i=e(533);class t extends i.Circle{constructor(i,t,n,e){super(i,t,n),this.canvasSize=e,this.canvasSize={...e}}contains(i){const{width:t,height:n}=this.canvasSize,{x:e,y:s}=i;return super.contains(i)||super.contains({x:e-t,y:s})||super.contains({x:e-t,y:s-n})||super.contains({x:e,y:s-n})}intersects(t){if(super.intersects(t))return!0;const n=t,e=t,s={x:t.position.x-this.canvasSize.width,y:t.position.y-this.canvasSize.height};if(void 0!==e.radius){const t=new i.Circle(s.x,s.y,2*e.radius);return super.intersects(t)}if(void 0!==n.size){const t=new i.Rectangle(s.x,s.y,2*n.size.width,2*n.size.height);return super.intersects(t)}return!1}}class n{constructor(){this.blur=5,this.color=new i.OptionsColor,this.color.value="#000",this.enable=!1}load(t){t&&(void 0!==t.blur&&(this.blur=t.blur),this.color=i.OptionsColor.create(this.color,t.color),void 0!==t.enable&&(this.enable=t.enable))}}class o{constructor(){this.enable=!1,this.frequency=1}load(t){t&&(void 0!==t.color&&(this.color=i.OptionsColor.create(this.color,t.color)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=t.opacity))}}class r{constructor(){this.blink=!1,this.color=new i.OptionsColor,this.color.value="#fff",this.consent=!1,this.distance=100,this.enable=!1,this.frequency=1,this.opacity=1,this.shadow=new n,this.triangles=new o,this.width=1,this.warp=!1}load(t){t&&(void 0!==t.id&&(this.id=t.id),void 0!==t.blink&&(this.blink=t.blink),this.color=i.OptionsColor.create(this.color,t.color),void 0!==t.consent&&(this.consent=t.consent),void 0!==t.distance&&(this.distance=t.distance),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=t.opacity),this.shadow.load(t.shadow),this.triangles.load(t.triangles),void 0!==t.width&&(this.width=t.width),void 0!==t.warp&&(this.warp=t.warp))}}function a(t,n,e,s,o){const{dx:r,dy:a,distance:c}=(0,i.getDistances)(t,n);if(!o||c<=e)return c;const l={x:Math.abs(r),y:Math.abs(a)},d=Math.min(l.x,s.width-l.x),h=Math.min(l.y,s.height-l.y);return Math.sqrt(d**2+h**2)}class c extends i.ParticlesInteractorBase{constructor(t){super(t),this._setColor=t=>{if(!t.options.links)return;const n=this.linkContainer,e=t.options.links;let s=void 0===e.id?n.particles.linksColor:n.particles.linksColors.get(e.id);if(s)return;const o=e.color;s=(0,i.getLinkRandomColor)(o,e.blink,e.consent),void 0===e.id?n.particles.linksColor=s:n.particles.linksColors.set(e.id,s)},this.linkContainer=t}clear(){}init(){this.linkContainer.particles.linksColor=void 0,this.linkContainer.particles.linksColors=new Map}async interact(n){if(!n.options.links)return;n.links=[];const e=n.getPosition(),s=this.container,o=s.canvas.size;if(e.x<0||e.y<0||e.x>o.width||e.y>o.height)return;const r=n.options.links,c=r.opacity,l=n.retina.linksDistance??0,d=r.warp,h=d?new t(e.x,e.y,l,o):new i.Circle(e.x,e.y,l),p=s.particles.quadTree.query(h);for(const i of p){const t=i.options.links;if(n===i||!t?.enable||r.id!==t.id||i.spawning||i.destroyed||!i.links||n.links.some((t=>t.destination===i))||i.links.some((i=>i.destination===n)))continue;const s=i.getPosition();if(s.x<0||s.y<0||s.x>o.width||s.y>o.height)continue;const h=a(e,s,l,o,d&&t.warp);if(h>l)continue;const p=(1-h/l)*c;this._setColor(n),n.links.push({destination:i,opacity:p})}}isEnabled(i){return!!i.options.links?.enable}loadParticlesOptions(i,...t){i.links||(i.links=new r);for(const n of t)i.links.load(n?.links)}reset(){}}function l(t,n){const e=((s=t.map((i=>i.id))).sort(((i,t)=>i-t)),s.join("_"));var s;let o=n.get(e);return void 0===o&&(o=(0,i.getRandom)(),n.set(e,o)),o}class d{constructor(t){this.container=t,this._drawLinkLine=(t,n)=>{const e=t.options.links;if(!e?.enable)return;const s=this.container,o=s.actualOptions,r=n.destination,a=t.getPosition(),c=r.getPosition();let l=n.opacity;s.canvas.draw((n=>{let d;const h=t.options.twinkle?.lines;if(h?.enable){const t=h.frequency,n=(0,i.rangeColorToRgb)(h.color);(0,i.getRandom)()<t&&n&&(d=n,l=(0,i.getRangeValue)(h.opacity))}if(!d){const n=void 0!==e.id?s.particles.linksColors.get(e.id):s.particles.linksColor;d=(0,i.getLinkColor)(t,r,n)}if(!d)return;const p=t.retina.linksWidth??0,u=t.retina.linksDistance??0,{backgroundMask:y}=o;!function(t){let n=!1;const{begin:e,end:s,maxDistance:o,context:r,canvasSize:a,width:c,backgroundMask:l,colorLine:d,opacity:h,links:p}=t;if((0,i.getDistance)(e,s)<=o)(0,i.drawLine)(r,e,s),n=!0;else if(p.warp){let t,c;const l={x:s.x-a.width,y:s.y},d=(0,i.getDistances)(e,l);if(d.distance<=o){const i=e.y-d.dy/d.dx*e.x;t={x:0,y:i},c={x:a.width,y:i}}else{const n={x:s.x,y:s.y-a.height},r=(0,i.getDistances)(e,n);if(r.distance<=o){const i=-(e.y-r.dy/r.dx*e.x)/(r.dy/r.dx);t={x:i,y:0},c={x:i,y:a.height}}else{const n={x:s.x-a.width,y:s.y-a.height},r=(0,i.getDistances)(e,n);if(r.distance<=o){const i=e.y-r.dy/r.dx*e.x;t={x:-i/(r.dy/r.dx),y:i},c={x:t.x+a.width,y:t.y+a.height}}}}t&&c&&((0,i.drawLine)(r,e,t),(0,i.drawLine)(r,s,c),n=!0)}if(!n)return;r.lineWidth=c,l.enable&&(r.globalCompositeOperation=l.composite),r.strokeStyle=(0,i.getStyleFromRgb)(d,h);const{shadow:u}=p;if(u.enable){const t=(0,i.rangeColorToRgb)(u.color);t&&(r.shadowBlur=u.blur,r.shadowColor=(0,i.getStyleFromRgb)(t))}r.stroke()}({context:n,width:p,begin:a,end:c,maxDistance:u,canvasSize:s.canvas.size,links:e,backgroundMask:y,colorLine:d,opacity:l})}))},this._drawLinkTriangle=(t,n,e)=>{const s=t.options.links;if(!s?.enable)return;const o=s.triangles;if(!o.enable)return;const r=this.container,a=r.actualOptions,c=n.destination,l=e.destination,d=o.opacity??(n.opacity+e.opacity)/2;d<=0||r.canvas.draw((n=>{const e=t.getPosition(),h=c.getPosition(),p=l.getPosition(),u=t.retina.linksDistance??0;if((0,i.getDistance)(e,h)>u||(0,i.getDistance)(p,h)>u||(0,i.getDistance)(p,e)>u)return;let y=(0,i.rangeColorToRgb)(o.color);if(!y){const n=void 0!==s.id?r.particles.linksColors.get(s.id):r.particles.linksColor;y=(0,i.getLinkColor)(t,c,n)}y&&function(t){const{context:n,pos1:e,pos2:s,pos3:o,backgroundMask:r,colorTriangle:a,opacityTriangle:c}=t;!function(i,t,n,e){i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(n.x,n.y),i.lineTo(e.x,e.y),i.closePath()}(n,e,s,o),r.enable&&(n.globalCompositeOperation=r.composite),n.fillStyle=(0,i.getStyleFromRgb)(a,c),n.fill()}({context:n,pos1:e,pos2:h,pos3:p,backgroundMask:a.backgroundMask,colorTriangle:y,opacityTriangle:d})}))},this._drawTriangles=(i,t,n,e)=>{const s=n.destination;if(!i.links?.triangles.enable||!s.options.links?.triangles.enable)return;const o=s.links?.filter((i=>{const t=this._getLinkFrequency(s,i.destination);return s.options.links&&t<=s.options.links.frequency&&e.findIndex((t=>t.destination===i.destination))>=0}));if(o?.length)for(const e of o){const o=e.destination;this._getTriangleFrequency(t,s,o)>i.links.triangles.frequency||this._drawLinkTriangle(t,n,e)}},this._getLinkFrequency=(i,t)=>l([i,t],this._freqs.links),this._getTriangleFrequency=(i,t,n)=>l([i,t,n],this._freqs.triangles),this._freqs={links:new Map,triangles:new Map}}drawParticle(i,t){const{links:n,options:e}=t;if(!n||n.length<=0)return;const s=n.filter((i=>e.links&&this._getLinkFrequency(t,i.destination)<=e.links.frequency));for(const i of s)this._drawTriangles(e,t,i,s),i.opacity>0&&(t.retina.linksWidth??0)>0&&this._drawLinkLine(t,i)}async init(){this._freqs.links=new Map,this._freqs.triangles=new Map}particleCreated(i){if(i.links=[],!i.options.links)return;const t=this.container.retina.pixelRatio,{retina:n}=i,{distance:e,width:s}=i.options.links;n.linksDistance=e*t,n.linksWidth=s*t}particleDestroyed(i){i.links=[]}}class h{constructor(){this.id="links"}getPlugin(i){return new d(i)}loadOptions(){}needsPlugin(){return!0}}async function p(i,t=!0){await async function(i,t=!0){await i.addInteractor("particlesLinks",(i=>new c(i)),t)}(i,t),await async function(i,t=!0){const n=new h;await i.addPlugin(n,t)}(i,t)}})(),s})()));
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 n="object"==typeof exports?t(require("@tsparticles/engine")):t(i.window);for(var e in n)("object"==typeof exports?exports:i)[e]=n[e]}}(this,(i=>(()=>{"use strict";var t={533:t=>{t.exports=i}},n={};function e(i){var s=n[i];if(void 0!==s)return s.exports;var o=n[i]={exports:{}};return t[i](o,o.exports,e),o.exports}e.d=(i,t)=>{for(var n in t)e.o(t,n)&&!e.o(i,n)&&Object.defineProperty(i,n,{enumerable:!0,get:t[n]})},e.o=(i,t)=>Object.prototype.hasOwnProperty.call(i,t),e.r=i=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(i,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(i,"__esModule",{value:!0})};var s={};return(()=>{e.r(s),e.d(s,{Links:()=>r,LinksShadow:()=>n,LinksTriangle:()=>o,loadParticlesLinksInteraction:()=>y});var i=e(533);class t extends i.Circle{constructor(i,t,n,e){super(i,t,n),this.canvasSize=e,this.canvasSize={...e}}contains(i){const{width:t,height:n}=this.canvasSize,{x:e,y:s}=i;return super.contains(i)||super.contains({x:e-t,y:s})||super.contains({x:e-t,y:s-n})||super.contains({x:e,y:s-n})}intersects(t){if(super.intersects(t))return!0;const n=t,e=t,s={x:t.position.x-this.canvasSize.width,y:t.position.y-this.canvasSize.height};if(void 0!==e.radius){const t=new i.Circle(s.x,s.y,2*e.radius);return super.intersects(t)}if(void 0!==n.size){const t=new i.Rectangle(s.x,s.y,2*n.size.width,2*n.size.height);return super.intersects(t)}return!1}}class n{constructor(){this.blur=5,this.color=new i.OptionsColor,this.color.value="#000",this.enable=!1}load(t){t&&(void 0!==t.blur&&(this.blur=t.blur),this.color=i.OptionsColor.create(this.color,t.color),void 0!==t.enable&&(this.enable=t.enable))}}class o{constructor(){this.enable=!1,this.frequency=1}load(t){t&&(void 0!==t.color&&(this.color=i.OptionsColor.create(this.color,t.color)),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=t.opacity))}}class r{constructor(){this.blink=!1,this.color=new i.OptionsColor,this.color.value="#fff",this.consent=!1,this.distance=100,this.enable=!1,this.frequency=1,this.opacity=1,this.shadow=new n,this.triangles=new o,this.width=1,this.warp=!1}load(t){t&&(void 0!==t.id&&(this.id=t.id),void 0!==t.blink&&(this.blink=t.blink),this.color=i.OptionsColor.create(this.color,t.color),void 0!==t.consent&&(this.consent=t.consent),void 0!==t.distance&&(this.distance=t.distance),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.frequency&&(this.frequency=t.frequency),void 0!==t.opacity&&(this.opacity=t.opacity),this.shadow.load(t.shadow),this.triangles.load(t.triangles),void 0!==t.width&&(this.width=t.width),void 0!==t.warp&&(this.warp=t.warp))}}const a=0,l=0;function c(t,n,e,s,o){const{dx:r,dy:a,distance:l}=(0,i.getDistances)(t,n);if(!o||l<=e)return l;const c={x:Math.abs(r),y:Math.abs(a)},d=Math.min(c.x,s.width-c.x),h=Math.min(c.y,s.height-c.y);return Math.sqrt(d**2+h**2)}class d extends i.ParticlesInteractorBase{constructor(t){super(t),this._setColor=t=>{if(!t.options.links)return;const n=this.linkContainer,e=t.options.links;let s=void 0===e.id?n.particles.linksColor:n.particles.linksColors.get(e.id);if(s)return;const o=e.color;s=(0,i.getLinkRandomColor)(o,e.blink,e.consent),void 0===e.id?n.particles.linksColor=s:n.particles.linksColors.set(e.id,s)},this.linkContainer=t}clear(){}init(){this.linkContainer.particles.linksColor=void 0,this.linkContainer.particles.linksColors=new Map}async interact(n){if(!n.options.links)return;n.links=[];const e=n.getPosition(),s=this.container,o=s.canvas.size;if(e.x<a||e.y<l||e.x>o.width||e.y>o.height)return;const r=n.options.links,d=r.opacity,h=n.retina.linksDistance??0,p=r.warp,u=p?new t(e.x,e.y,h,o):new i.Circle(e.x,e.y,h),y=s.particles.quadTree.query(u);for(const i of y){const t=i.options.links;if(n===i||!t?.enable||r.id!==t.id||i.spawning||i.destroyed||!i.links||n.links.some((t=>t.destination===i))||i.links.some((i=>i.destination===n)))continue;const s=i.getPosition();if(s.x<a||s.y<l||s.x>o.width||s.y>o.height)continue;const u=c(e,s,h,o,p&&t.warp);if(u>h)continue;const y=(1-u/h)*d;this._setColor(n),n.links.push({destination:i,opacity:y})}await Promise.resolve()}isEnabled(i){return!!i.options.links?.enable}loadParticlesOptions(i,...t){i.links||(i.links=new r);for(const n of t)i.links.load(n?.links)}reset(){}}function h(t,n){const e=((s=t.map((i=>i.id))).sort(((i,t)=>i-t)),s.join("_"));var s;let o=n.get(e);return void 0===o&&(o=(0,i.getRandom)(),n.set(e,o)),o}class p{constructor(t){this.container=t,this._drawLinkLine=(t,n)=>{const e=t.options.links;if(!e?.enable)return;const s=this.container,o=s.actualOptions,r=n.destination,a=t.getPosition(),l=r.getPosition();let c=n.opacity;s.canvas.draw((n=>{let d;const h=t.options.twinkle?.lines;if(h?.enable){const t=h.frequency,n=(0,i.rangeColorToRgb)(h.color);(0,i.getRandom)()<t&&n&&(d=n,c=(0,i.getRangeValue)(h.opacity))}if(!d){const n=void 0!==e.id?s.particles.linksColors.get(e.id):s.particles.linksColor;d=(0,i.getLinkColor)(t,r,n)}if(!d)return;const p=t.retina.linksWidth??0,u=t.retina.linksDistance??0,{backgroundMask:y}=o;!function(t){let n=!1;const{begin:e,end:s,maxDistance:o,context:r,canvasSize:a,width:l,backgroundMask:c,colorLine:d,opacity:h,links:p}=t;if((0,i.getDistance)(e,s)<=o)(0,i.drawLine)(r,e,s),n=!0;else if(p.warp){let t,l;const c={x:s.x-a.width,y:s.y},d=(0,i.getDistances)(e,c);if(d.distance<=o){const i=e.y-d.dy/d.dx*e.x;t={x:0,y:i},l={x:a.width,y:i}}else{const n={x:s.x,y:s.y-a.height},r=(0,i.getDistances)(e,n);if(r.distance<=o){const i=-(e.y-r.dy/r.dx*e.x)/(r.dy/r.dx);t={x:i,y:0},l={x:i,y:a.height}}else{const n={x:s.x-a.width,y:s.y-a.height},r=(0,i.getDistances)(e,n);if(r.distance<=o){const i=e.y-r.dy/r.dx*e.x;t={x:-i/(r.dy/r.dx),y:i},l={x:t.x+a.width,y:t.y+a.height}}}}t&&l&&((0,i.drawLine)(r,e,t),(0,i.drawLine)(r,s,l),n=!0)}if(!n)return;r.lineWidth=l,c.enable&&(r.globalCompositeOperation=c.composite),r.strokeStyle=(0,i.getStyleFromRgb)(d,h);const{shadow:u}=p;if(u.enable){const t=(0,i.rangeColorToRgb)(u.color);t&&(r.shadowBlur=u.blur,r.shadowColor=(0,i.getStyleFromRgb)(t))}r.stroke()}({context:n,width:p,begin:a,end:l,maxDistance:u,canvasSize:s.canvas.size,links:e,backgroundMask:y,colorLine:d,opacity:c})}))},this._drawLinkTriangle=(t,n,e)=>{const s=t.options.links;if(!s?.enable)return;const o=s.triangles;if(!o.enable)return;const r=this.container,a=r.actualOptions,l=n.destination,c=e.destination,d=o.opacity??.5*(n.opacity+e.opacity);d<=0||r.canvas.draw((n=>{const e=t.getPosition(),h=l.getPosition(),p=c.getPosition(),u=t.retina.linksDistance??0;if((0,i.getDistance)(e,h)>u||(0,i.getDistance)(p,h)>u||(0,i.getDistance)(p,e)>u)return;let y=(0,i.rangeColorToRgb)(o.color);if(!y){const n=void 0!==s.id?r.particles.linksColors.get(s.id):r.particles.linksColor;y=(0,i.getLinkColor)(t,l,n)}y&&function(t){const{context:n,pos1:e,pos2:s,pos3:o,backgroundMask:r,colorTriangle:a,opacityTriangle:l}=t;!function(i,t,n,e){i.beginPath(),i.moveTo(t.x,t.y),i.lineTo(n.x,n.y),i.lineTo(e.x,e.y),i.closePath()}(n,e,s,o),r.enable&&(n.globalCompositeOperation=r.composite),n.fillStyle=(0,i.getStyleFromRgb)(a,l),n.fill()}({context:n,pos1:e,pos2:h,pos3:p,backgroundMask:a.backgroundMask,colorTriangle:y,opacityTriangle:d})}))},this._drawTriangles=(i,t,n,e)=>{const s=n.destination;if(!i.links?.triangles.enable||!s.options.links?.triangles.enable)return;const o=s.links?.filter((i=>{const t=this._getLinkFrequency(s,i.destination);return s.options.links&&t<=s.options.links.frequency&&e.findIndex((t=>t.destination===i.destination))>=0}));if(o?.length)for(const e of o){const o=e.destination;this._getTriangleFrequency(t,s,o)>i.links.triangles.frequency||this._drawLinkTriangle(t,n,e)}},this._getLinkFrequency=(i,t)=>h([i,t],this._freqs.links),this._getTriangleFrequency=(i,t,n)=>h([i,t,n],this._freqs.triangles),this._freqs={links:new Map,triangles:new Map}}drawParticle(i,t){const{links:n,options:e}=t;if(!n?.length)return;const s=n.filter((i=>e.links&&this._getLinkFrequency(t,i.destination)<=e.links.frequency));for(const i of s)this._drawTriangles(e,t,i,s),i.opacity>0&&(t.retina.linksWidth??0)>0&&this._drawLinkLine(t,i)}async init(){this._freqs.links=new Map,this._freqs.triangles=new Map,await Promise.resolve()}particleCreated(i){if(i.links=[],!i.options.links)return;const t=this.container.retina.pixelRatio,{retina:n}=i,{distance:e,width:s}=i.options.links;n.linksDistance=e*t,n.linksWidth=s*t}particleDestroyed(i){i.links=[]}}class u{constructor(){this.id="links"}getPlugin(i){return new p(i)}loadOptions(){}needsPlugin(){return!0}}async function y(i,t=!0){await async function(i,t=!0){await i.addInteractor("particlesLinks",(i=>new d(i)),t)}(i,t),await async function(i,t=!0){const n=new u;await i.addPlugin(n,t)}(i,t)}})(),s})()));
@@ -1 +1 @@
1
- /*! tsParticles Links Particles Interaction v3.0.2 by Matteo Bruni */
1
+ /*! tsParticles Links Particles Interaction v3.1.0 by Matteo Bruni */
package/types/Types.d.ts CHANGED
@@ -16,7 +16,7 @@ export type LinkParticle = Particle & {
16
16
  linksWidth?: number;
17
17
  };
18
18
  };
19
- export type LinkLineDrawParams = {
19
+ export interface LinkLineDrawParams {
20
20
  backgroundMask: BackgroundMask;
21
21
  begin: ICoordinates;
22
22
  canvasSize: IDimension;
@@ -27,8 +27,8 @@ export type LinkLineDrawParams = {
27
27
  maxDistance: number;
28
28
  opacity: number;
29
29
  width: number;
30
- };
31
- export type LinkTriangleDrawParams = {
30
+ }
31
+ export interface LinkTriangleDrawParams {
32
32
  backgroundMask: BackgroundMask;
33
33
  colorTriangle: IRgb;
34
34
  context: CanvasRenderingContext2D;
@@ -36,7 +36,7 @@ export type LinkTriangleDrawParams = {
36
36
  pos1: ICoordinates;
37
37
  pos2: ICoordinates;
38
38
  pos3: ICoordinates;
39
- };
39
+ }
40
40
  export type IParticlesLinkOptions = IParticlesOptions & {
41
41
  links?: ILinks;
42
42
  };
package/umd/CircleWarp.js CHANGED
@@ -11,6 +11,7 @@
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.CircleWarp = void 0;
13
13
  const engine_1 = require("@tsparticles/engine");
14
+ const double = 2;
14
15
  class CircleWarp extends engine_1.Circle {
15
16
  constructor(x, y, radius, canvasSize) {
16
17
  super(x, y, radius);
@@ -34,11 +35,11 @@
34
35
  y: range.position.y - this.canvasSize.height,
35
36
  };
36
37
  if (circle.radius !== undefined) {
37
- const biggerCircle = new engine_1.Circle(newPos.x, newPos.y, circle.radius * 2);
38
+ const biggerCircle = new engine_1.Circle(newPos.x, newPos.y, circle.radius * double);
38
39
  return super.intersects(biggerCircle);
39
40
  }
40
41
  else if (rect.size !== undefined) {
41
- const rectSW = new engine_1.Rectangle(newPos.x, newPos.y, rect.size.width * 2, rect.size.height * 2);
42
+ const rectSW = new engine_1.Rectangle(newPos.x, newPos.y, rect.size.width * double, rect.size.height * double);
42
43
  return super.intersects(rectSW);
43
44
  }
44
45
  return false;
@@ -12,6 +12,7 @@
12
12
  exports.LinkInstance = void 0;
13
13
  const engine_1 = require("@tsparticles/engine");
14
14
  const Utils_js_1 = require("./Utils.js");
15
+ const minOpacity = 0, minWidth = 0, minDistance = 0, half = 0.5;
15
16
  class LinkInstance {
16
17
  constructor(container) {
17
18
  this.container = container;
@@ -41,7 +42,7 @@
41
42
  if (!colorLine) {
42
43
  return;
43
44
  }
44
- const width = p1.retina.linksWidth ?? 0, maxDistance = p1.retina.linksDistance ?? 0, { backgroundMask } = options;
45
+ const width = p1.retina.linksWidth ?? minWidth, maxDistance = p1.retina.linksDistance ?? minDistance, { backgroundMask } = options;
45
46
  (0, Utils_js_1.drawLinkLine)({
46
47
  context: ctx,
47
48
  width,
@@ -65,12 +66,12 @@
65
66
  if (!triangleOptions.enable) {
66
67
  return;
67
68
  }
68
- const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) / 2;
69
- if (opacityTriangle <= 0) {
69
+ const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * half;
70
+ if (opacityTriangle <= minOpacity) {
70
71
  return;
71
72
  }
72
73
  container.canvas.draw((ctx) => {
73
- const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? 0;
74
+ const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? minDistance;
74
75
  if ((0, engine_1.getDistance)(pos1, pos2) > linksDistance ||
75
76
  (0, engine_1.getDistance)(pos3, pos2) > linksDistance ||
76
77
  (0, engine_1.getDistance)(pos3, pos1) > linksDistance) {
@@ -103,10 +104,10 @@
103
104
  return;
104
105
  }
105
106
  const vertices = p2.links?.filter((t) => {
106
- const linkFreq = this._getLinkFrequency(p2, t.destination);
107
+ const linkFreq = this._getLinkFrequency(p2, t.destination), minCount = 0;
107
108
  return (p2.options.links &&
108
109
  linkFreq <= p2.options.links.frequency &&
109
- p1Links.findIndex((l) => l.destination === t.destination) >= 0);
110
+ p1Links.findIndex((l) => l.destination === t.destination) >= minCount);
110
111
  });
111
112
  if (!vertices?.length) {
112
113
  return;
@@ -132,13 +133,13 @@
132
133
  }
133
134
  drawParticle(context, particle) {
134
135
  const { links, options } = particle;
135
- if (!links || links.length <= 0) {
136
+ if (!links?.length) {
136
137
  return;
137
138
  }
138
139
  const p1Links = links.filter((l) => options.links && this._getLinkFrequency(particle, l.destination) <= options.links.frequency);
139
140
  for (const link of p1Links) {
140
141
  this._drawTriangles(options, particle, link, p1Links);
141
- if (link.opacity > 0 && (particle.retina.linksWidth ?? 0) > 0) {
142
+ if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {
142
143
  this._drawLinkLine(particle, link);
143
144
  }
144
145
  }
@@ -146,6 +147,7 @@
146
147
  async init() {
147
148
  this._freqs.links = new Map();
148
149
  this._freqs.triangles = new Map();
150
+ await Promise.resolve();
149
151
  }
150
152
  particleCreated(particle) {
151
153
  particle.links = [];
package/umd/Linker.js CHANGED
@@ -13,6 +13,10 @@
13
13
  const engine_1 = require("@tsparticles/engine");
14
14
  const CircleWarp_js_1 = require("./CircleWarp.js");
15
15
  const Links_js_1 = require("./Options/Classes/Links.js");
16
+ const squarePower = 2, opacityOffset = 1, origin = {
17
+ x: 0,
18
+ y: 0,
19
+ }, minDistance = 0;
16
20
  function getLinkDistance(pos1, pos2, optDistance, canvasSize, warp) {
17
21
  const { dx, dy, distance } = (0, engine_1.getDistances)(pos1, pos2);
18
22
  if (!warp || distance <= optDistance) {
@@ -25,7 +29,7 @@
25
29
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
26
30
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
27
31
  };
28
- return Math.sqrt(warpDistances.x ** 2 + warpDistances.y ** 2);
32
+ return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
29
33
  }
30
34
  class Linker extends engine_1.ParticlesInteractorBase {
31
35
  constructor(container) {
@@ -64,10 +68,10 @@
64
68
  }
65
69
  p1.links = [];
66
70
  const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;
67
- if (pos1.x < 0 || pos1.y < 0 || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
71
+ if (pos1.x < origin.x || pos1.y < origin.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
68
72
  return;
69
73
  }
70
- const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? 0, warp = linkOpt1.warp, range = warp
74
+ const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp
71
75
  ? new CircleWarp_js_1.CircleWarp(pos1.x, pos1.y, optDistance, canvasSize)
72
76
  : new engine_1.Circle(pos1.x, pos1.y, optDistance), query = container.particles.quadTree.query(range);
73
77
  for (const p2 of query) {
@@ -83,20 +87,21 @@
83
87
  continue;
84
88
  }
85
89
  const pos2 = p2.getPosition();
86
- if (pos2.x < 0 || pos2.y < 0 || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
90
+ if (pos2.x < origin.x || pos2.y < origin.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
87
91
  continue;
88
92
  }
89
93
  const distance = getLinkDistance(pos1, pos2, optDistance, canvasSize, warp && linkOpt2.warp);
90
94
  if (distance > optDistance) {
91
95
  continue;
92
96
  }
93
- const opacityLine = (1 - distance / optDistance) * optOpacity;
97
+ const opacityLine = (opacityOffset - distance / optDistance) * optOpacity;
94
98
  this._setColor(p1);
95
99
  p1.links.push({
96
100
  destination: p2,
97
101
  opacity: opacityLine,
98
102
  });
99
103
  }
104
+ await Promise.resolve();
100
105
  }
101
106
  isEnabled(particle) {
102
107
  return !!particle.options.links?.enable;