@tsparticles/interaction-particles-links 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.
- package/browser/CircleWarp.js +3 -2
- package/browser/LinkInstance.js +10 -8
- package/browser/Linker.js +10 -5
- package/cjs/CircleWarp.js +3 -2
- package/cjs/LinkInstance.js +10 -8
- package/cjs/Linker.js +10 -5
- package/esm/CircleWarp.js +3 -2
- package/esm/LinkInstance.js +10 -8
- package/esm/Linker.js +10 -5
- package/package.json +2 -2
- package/report.html +2 -2
- package/tsparticles.interaction.particles.links.js +32 -17
- package/tsparticles.interaction.particles.links.min.js +1 -1
- package/tsparticles.interaction.particles.links.min.js.LICENSE.txt +1 -1
- package/types/Types.d.ts +4 -4
- package/umd/CircleWarp.js +3 -2
- package/umd/LinkInstance.js +10 -8
- package/umd/Linker.js +10 -5
package/browser/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 *
|
|
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 *
|
|
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;
|
package/browser/LinkInstance.js
CHANGED
|
@@ -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 ??
|
|
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)
|
|
57
|
-
if (opacityTriangle <=
|
|
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 ??
|
|
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) >=
|
|
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
|
|
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 >
|
|
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 **
|
|
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 <
|
|
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 ??
|
|
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 <
|
|
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 = (
|
|
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 *
|
|
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 *
|
|
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;
|
package/cjs/LinkInstance.js
CHANGED
|
@@ -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 ??
|
|
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)
|
|
60
|
-
if (opacityTriangle <=
|
|
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 ??
|
|
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) >=
|
|
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
|
|
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 >
|
|
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 **
|
|
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 <
|
|
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 ??
|
|
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 <
|
|
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 = (
|
|
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 *
|
|
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 *
|
|
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;
|
package/esm/LinkInstance.js
CHANGED
|
@@ -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 ??
|
|
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)
|
|
57
|
-
if (opacityTriangle <=
|
|
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 ??
|
|
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) >=
|
|
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
|
|
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 >
|
|
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 **
|
|
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 <
|
|
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 ??
|
|
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 <
|
|
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 = (
|
|
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
|
|
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
|
|
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
|
+
<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":
|
|
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
|
|
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 *
|
|
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 *
|
|
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 **
|
|
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 <
|
|
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 ??
|
|
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 <
|
|
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 = (
|
|
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 ??
|
|
535
|
-
maxDistance = p1.retina.linksDistance ??
|
|
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)
|
|
567
|
-
if (opacityTriangle <=
|
|
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 ??
|
|
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
|
-
|
|
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
|
|
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 >
|
|
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:()=>
|
|
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
|
|
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
|
|
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
|
|
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 *
|
|
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 *
|
|
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;
|
package/umd/LinkInstance.js
CHANGED
|
@@ -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 ??
|
|
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)
|
|
69
|
-
if (opacityTriangle <=
|
|
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 ??
|
|
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) >=
|
|
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
|
|
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 >
|
|
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 **
|
|
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 <
|
|
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 ??
|
|
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 <
|
|
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 = (
|
|
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;
|