@tsparticles/interaction-particles-links 4.0.0-alpha.21 → 4.0.0-alpha.23
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/919.min.js +1 -1
- package/973.min.js +1 -1
- package/browser/CircleWarp.js +33 -18
- package/browser/LinkInstance.js +126 -115
- package/browser/Linker.js +20 -24
- package/browser/Utils.js +1 -76
- package/browser/index.js +2 -2
- package/cjs/CircleWarp.js +33 -18
- package/cjs/LinkInstance.js +126 -115
- package/cjs/Linker.js +20 -24
- package/cjs/Utils.js +1 -76
- package/cjs/index.js +2 -2
- package/dist_browser_LinkInstance_js.js +3 -3
- package/dist_browser_Linker_js.js +3 -3
- package/dist_browser_LinksPlugin_js.js +1 -1
- package/esm/CircleWarp.js +33 -18
- package/esm/LinkInstance.js +126 -115
- package/esm/Linker.js +20 -24
- package/esm/Utils.js +1 -76
- package/esm/index.js +2 -2
- package/package.json +4 -4
- package/report.html +1 -1
- package/tsparticles.interaction.particles.links.js +6 -16
- package/tsparticles.interaction.particles.links.min.js +2 -2
- package/types/CircleWarp.d.ts +2 -2
- package/types/Interfaces.d.ts +3 -1
- package/types/LinkInstance.d.ts +8 -5
- package/types/Linker.d.ts +2 -1
- package/types/Types.d.ts +9 -20
- package/types/Utils.d.ts +1 -5
- package/umd/CircleWarp.js +32 -17
- package/umd/LinkInstance.js +124 -113
- package/umd/Linker.js +19 -23
- package/umd/Utils.js +1 -79
- package/umd/index.js +2 -2
package/cjs/CircleWarp.js
CHANGED
|
@@ -1,33 +1,48 @@
|
|
|
1
|
-
import { Circle, Rectangle
|
|
1
|
+
import { Circle, Rectangle } from "@tsparticles/engine";
|
|
2
2
|
export class CircleWarp extends Circle {
|
|
3
3
|
canvasSize;
|
|
4
4
|
constructor(x, y, radius, canvasSize) {
|
|
5
5
|
super(x, y, radius);
|
|
6
6
|
this.canvasSize = canvasSize;
|
|
7
|
-
this.canvasSize = { ...canvasSize };
|
|
8
7
|
}
|
|
9
8
|
contains(point) {
|
|
9
|
+
if (super.contains(point))
|
|
10
|
+
return true;
|
|
10
11
|
const { width, height } = this.canvasSize, { x, y } = point;
|
|
11
|
-
return (super.contains(
|
|
12
|
-
super.contains({ x: x
|
|
12
|
+
return (super.contains({ x: x - width, y }) ||
|
|
13
|
+
super.contains({ x: x + width, y }) ||
|
|
14
|
+
super.contains({ x, y: y - height }) ||
|
|
15
|
+
super.contains({ x, y: y + height }) ||
|
|
13
16
|
super.contains({ x: x - width, y: y - height }) ||
|
|
14
|
-
super.contains({ x, y: y
|
|
17
|
+
super.contains({ x: x + width, y: y + height }) ||
|
|
18
|
+
super.contains({ x: x - width, y: y + height }) ||
|
|
19
|
+
super.contains({ x: x + width, y: y - height }));
|
|
15
20
|
}
|
|
16
21
|
intersects(range) {
|
|
17
|
-
if (super.intersects(range))
|
|
22
|
+
if (super.intersects(range))
|
|
18
23
|
return true;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
x:
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
const { width, height } = this.canvasSize, pos = range.position, shifts = [
|
|
25
|
+
{ x: -width, y: 0 },
|
|
26
|
+
{ x: width, y: 0 },
|
|
27
|
+
{ x: 0, y: -height },
|
|
28
|
+
{ x: 0, y: height },
|
|
29
|
+
{ x: -width, y: -height },
|
|
30
|
+
{ x: width, y: height },
|
|
31
|
+
{ x: -width, y: height },
|
|
32
|
+
{ x: width, y: -height },
|
|
33
|
+
];
|
|
34
|
+
for (const shift of shifts) {
|
|
35
|
+
const shiftedPos = { x: pos.x + shift.x, y: pos.y + shift.y };
|
|
36
|
+
let shiftedRange;
|
|
37
|
+
if (range instanceof Circle) {
|
|
38
|
+
shiftedRange = new Circle(shiftedPos.x, shiftedPos.y, range.radius);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const rect = range;
|
|
42
|
+
shiftedRange = new Rectangle(shiftedPos.x, shiftedPos.y, rect.size.width, rect.size.height);
|
|
43
|
+
}
|
|
44
|
+
if (super.intersects(shiftedRange))
|
|
45
|
+
return true;
|
|
31
46
|
}
|
|
32
47
|
return false;
|
|
33
48
|
}
|
package/cjs/LinkInstance.js
CHANGED
|
@@ -1,36 +1,110 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
const minOpacity = 0,
|
|
1
|
+
import { getLinkColor as engineGetLinkColor, getRandom, getRangeValue, getStyleFromRgb, half, originPoint, rangeColorToRgb, } from "@tsparticles/engine";
|
|
2
|
+
import { setLinkFrequency } from "./Utils.js";
|
|
3
|
+
const minOpacity = 0, minDistance = 0, minWidth = 0, maxFrequency = 1, defaultFrequency = 0, opacitySteps = 10, defaultWidth = 0, triangleCoordsCount = 6, lineCoordsCount = 4, x1Offset = 0, y1Offset = 1, x2Offset = 2, y2Offset = 3, x3Offset = 4, y3Offset = 5;
|
|
4
4
|
export class LinkInstance {
|
|
5
|
+
_colorCache = new Map();
|
|
5
6
|
_container;
|
|
6
7
|
_engine;
|
|
7
8
|
_freqs;
|
|
9
|
+
_lineBatches = new Map();
|
|
10
|
+
_triangleBatches = new Map();
|
|
8
11
|
constructor(container, engine) {
|
|
9
12
|
this._container = container;
|
|
10
13
|
this._engine = engine;
|
|
11
|
-
this._freqs = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
this._freqs = { links: new Map(), triangles: new Map() };
|
|
15
|
+
}
|
|
16
|
+
draw(context) {
|
|
17
|
+
for (const [, batch] of this._triangleBatches) {
|
|
18
|
+
context.save();
|
|
19
|
+
context.fillStyle = batch.colorStyle;
|
|
20
|
+
context.globalAlpha = batch.opacity;
|
|
21
|
+
context.beginPath();
|
|
22
|
+
for (let i = 0; i < batch.coords.length; i += triangleCoordsCount) {
|
|
23
|
+
const x1 = batch.coords[i + x1Offset] ?? originPoint.x, y1 = batch.coords[i + y1Offset] ?? originPoint.y, x2 = batch.coords[i + x2Offset] ?? originPoint.x, y2 = batch.coords[i + y2Offset] ?? originPoint.y, x3 = batch.coords[i + x3Offset] ?? originPoint.x, y3 = batch.coords[i + y3Offset] ?? originPoint.y;
|
|
24
|
+
context.moveTo(x1, y1);
|
|
25
|
+
context.lineTo(x2, y2);
|
|
26
|
+
context.lineTo(x3, y3);
|
|
27
|
+
}
|
|
28
|
+
context.fill();
|
|
29
|
+
context.restore();
|
|
30
|
+
}
|
|
31
|
+
for (const [, batch] of this._lineBatches) {
|
|
32
|
+
context.save();
|
|
33
|
+
context.strokeStyle = batch.colorStyle;
|
|
34
|
+
context.lineWidth = batch.width;
|
|
35
|
+
context.globalAlpha = batch.opacity;
|
|
36
|
+
context.beginPath();
|
|
37
|
+
for (let i = 0; i < batch.coords.length; i += lineCoordsCount) {
|
|
38
|
+
const x1 = batch.coords[i + x1Offset] ?? originPoint.x, y1 = batch.coords[i + y1Offset] ?? originPoint.y, x2 = batch.coords[i + x2Offset] ?? originPoint.x, y2 = batch.coords[i + y2Offset] ?? originPoint.y;
|
|
39
|
+
context.moveTo(x1, y1);
|
|
40
|
+
context.lineTo(x2, y2);
|
|
41
|
+
}
|
|
42
|
+
context.stroke();
|
|
43
|
+
context.restore();
|
|
44
|
+
}
|
|
45
|
+
this._lineBatches.clear();
|
|
46
|
+
this._triangleBatches.clear();
|
|
15
47
|
}
|
|
16
48
|
drawParticle(_context, particle) {
|
|
17
49
|
const { links, options } = particle;
|
|
18
|
-
if (!links?.length) {
|
|
50
|
+
if (!links?.length || !options.links) {
|
|
19
51
|
return;
|
|
20
52
|
}
|
|
21
|
-
const p1Links = links.filter(l => options.links &&
|
|
53
|
+
const canvasSize = this._container.canvas.size, p1Links = links.filter(l => options.links &&
|
|
22
54
|
(options.links.frequency >= maxFrequency ||
|
|
23
|
-
this._getLinkFrequency(particle, l.destination) <= options.links.frequency));
|
|
55
|
+
this._getLinkFrequency(particle, l.destination) <= options.links.frequency)), pos1 = particle.getPosition();
|
|
24
56
|
for (const link of p1Links) {
|
|
25
|
-
|
|
57
|
+
if (!link.isWarped) {
|
|
58
|
+
this._collectTriangles(options, particle, link, p1Links);
|
|
59
|
+
}
|
|
26
60
|
if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {
|
|
27
|
-
|
|
61
|
+
let opacity = link.opacity, colorLine = link.color;
|
|
62
|
+
const twinkle = particle.options["twinkle"]?.lines;
|
|
63
|
+
if (twinkle?.enable && getRandom() < twinkle.frequency) {
|
|
64
|
+
const twinkleRgb = rangeColorToRgb(this._engine, twinkle.color);
|
|
65
|
+
if (twinkleRgb) {
|
|
66
|
+
colorLine = twinkleRgb;
|
|
67
|
+
opacity = getRangeValue(twinkle.opacity);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!colorLine) {
|
|
71
|
+
const linkColor = options.links.id !== undefined
|
|
72
|
+
? this._container.particles.linksColors.get(options.links.id)
|
|
73
|
+
: this._container.particles.linksColor;
|
|
74
|
+
colorLine = engineGetLinkColor(particle, link.destination, linkColor);
|
|
75
|
+
}
|
|
76
|
+
if (colorLine) {
|
|
77
|
+
const qOpacity = Math.ceil(opacity * opacitySteps) / opacitySteps, colorStyle = this._getCachedStyle(colorLine), width = particle.retina.linksWidth ?? defaultWidth, key = `${colorStyle}_${qOpacity}_${width}`;
|
|
78
|
+
let batch = this._lineBatches.get(key);
|
|
79
|
+
if (!batch) {
|
|
80
|
+
batch = { colorStyle, opacity: qOpacity, width, coords: [] };
|
|
81
|
+
this._lineBatches.set(key, batch);
|
|
82
|
+
}
|
|
83
|
+
const pos2 = link.destination.getPosition();
|
|
84
|
+
if (link.isWarped) {
|
|
85
|
+
const dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
86
|
+
let sx = originPoint.x, sy = originPoint.y;
|
|
87
|
+
if (Math.abs(dx) > canvasSize.width * half) {
|
|
88
|
+
sx = dx > minDistance ? -canvasSize.width : canvasSize.width;
|
|
89
|
+
}
|
|
90
|
+
if (Math.abs(dy) > canvasSize.height * half) {
|
|
91
|
+
sy = dy > minDistance ? -canvasSize.height : canvasSize.height;
|
|
92
|
+
}
|
|
93
|
+
const v2 = { x: pos2.x + sx, y: pos2.y + sy }, v1 = { x: pos1.x - sx, y: pos1.y - sy };
|
|
94
|
+
batch.coords.push(pos1.x, pos1.y, v2.x, v2.y);
|
|
95
|
+
batch.coords.push(v1.x, v1.y, pos2.x, pos2.y);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
batch.coords.push(pos1.x, pos1.y, pos2.x, pos2.y);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
28
101
|
}
|
|
29
102
|
}
|
|
30
103
|
}
|
|
31
104
|
async init() {
|
|
32
|
-
this._freqs.links
|
|
33
|
-
this._freqs.triangles
|
|
105
|
+
this._freqs.links.clear();
|
|
106
|
+
this._freqs.triangles.clear();
|
|
107
|
+
this._colorCache.clear();
|
|
34
108
|
await Promise.resolve();
|
|
35
109
|
}
|
|
36
110
|
particleCreated(particle) {
|
|
@@ -38,122 +112,59 @@ export class LinkInstance {
|
|
|
38
112
|
if (!particle.options.links) {
|
|
39
113
|
return;
|
|
40
114
|
}
|
|
41
|
-
const ratio = this._container.retina.pixelRatio
|
|
42
|
-
retina.linksDistance = distance * ratio;
|
|
43
|
-
retina.linksWidth = width * ratio;
|
|
115
|
+
const ratio = this._container.retina.pixelRatio;
|
|
116
|
+
particle.retina.linksDistance = particle.options.links.distance * ratio;
|
|
117
|
+
particle.retina.linksWidth = particle.options.links.width * ratio;
|
|
44
118
|
}
|
|
45
119
|
particleDestroyed(particle) {
|
|
46
120
|
particle.links = [];
|
|
47
121
|
}
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
if (!
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
const container = this._container, p2 = link.destination, pos1 = p1.getPosition(), pos2 = p2.getPosition();
|
|
54
|
-
let opacity = link.opacity;
|
|
55
|
-
container.canvas.draw(ctx => {
|
|
56
|
-
let colorLine;
|
|
57
|
-
const twinkle = p1.options["twinkle"]?.lines;
|
|
58
|
-
if (twinkle?.enable) {
|
|
59
|
-
const twinkleFreq = twinkle.frequency, twinkleRgb = rangeColorToRgb(this._engine, twinkle.color), twinkling = getRandom() < twinkleFreq;
|
|
60
|
-
if (twinkling && twinkleRgb) {
|
|
61
|
-
colorLine = twinkleRgb;
|
|
62
|
-
opacity = getRangeValue(twinkle.opacity);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (!colorLine) {
|
|
66
|
-
const linkColor = p1LinksOptions.id !== undefined
|
|
67
|
-
? container.particles.linksColors.get(p1LinksOptions.id)
|
|
68
|
-
: container.particles.linksColor;
|
|
69
|
-
colorLine = getLinkColor(p1, p2, linkColor);
|
|
70
|
-
}
|
|
71
|
-
if (!colorLine) {
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
const width = p1.retina.linksWidth ?? minWidth, maxDistance = p1.retina.linksDistance ?? minDistance;
|
|
75
|
-
drawLinkLine({
|
|
76
|
-
context: ctx,
|
|
77
|
-
width,
|
|
78
|
-
begin: pos1,
|
|
79
|
-
end: pos2,
|
|
80
|
-
engine: this._engine,
|
|
81
|
-
maxDistance,
|
|
82
|
-
canvasSize: container.canvas.size,
|
|
83
|
-
links: p1LinksOptions,
|
|
84
|
-
colorLine,
|
|
85
|
-
opacity,
|
|
86
|
-
hdr: container.hdr,
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
};
|
|
90
|
-
_drawLinkTriangle = (p1, link1, link2) => {
|
|
91
|
-
const linksOptions = p1.options.links;
|
|
92
|
-
if (!linksOptions?.enable) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
const triangleOptions = linksOptions.triangles;
|
|
96
|
-
if (!triangleOptions.enable) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
const container = this._container, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * half;
|
|
100
|
-
if (opacityTriangle <= minOpacity) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
container.canvas.draw(ctx => {
|
|
104
|
-
const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? minDistance;
|
|
105
|
-
if (getDistance(pos1, pos2) > linksDistance ||
|
|
106
|
-
getDistance(pos3, pos2) > linksDistance ||
|
|
107
|
-
getDistance(pos3, pos1) > linksDistance) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
let colorTriangle = rangeColorToRgb(this._engine, triangleOptions.color);
|
|
111
|
-
if (!colorTriangle) {
|
|
112
|
-
const linkColor = linksOptions.id !== undefined
|
|
113
|
-
? container.particles.linksColors.get(linksOptions.id)
|
|
114
|
-
: container.particles.linksColor;
|
|
115
|
-
colorTriangle = getLinkColor(p1, p2, linkColor);
|
|
116
|
-
}
|
|
117
|
-
if (!colorTriangle) {
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
drawLinkTriangle({
|
|
121
|
-
context: ctx,
|
|
122
|
-
pos1,
|
|
123
|
-
pos2,
|
|
124
|
-
pos3,
|
|
125
|
-
colorTriangle,
|
|
126
|
-
opacityTriangle,
|
|
127
|
-
hdr: container.hdr,
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
};
|
|
131
|
-
_drawTriangles = (options, p1, link, p1Links) => {
|
|
132
|
-
const p2 = link.destination;
|
|
133
|
-
if (!(options.links?.triangles.enable && p2.options.links?.triangles.enable)) {
|
|
122
|
+
_collectTriangles(options, p1, link, p1Links) {
|
|
123
|
+
const p2 = link.destination, triangleOptions = options.links?.triangles;
|
|
124
|
+
if (!triangleOptions?.enable || !p2.options.links?.triangles.enable) {
|
|
134
125
|
return;
|
|
135
126
|
}
|
|
136
127
|
const vertices = p2.links?.filter(t => {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
p1Links.
|
|
128
|
+
return (!t.isWarped &&
|
|
129
|
+
p2.options.links &&
|
|
130
|
+
this._getLinkFrequency(p2, t.destination) <= p2.options.links.frequency &&
|
|
131
|
+
p1Links.some(l => l.destination === t.destination));
|
|
141
132
|
});
|
|
142
133
|
if (!vertices?.length) {
|
|
143
134
|
return;
|
|
144
135
|
}
|
|
145
136
|
for (const vertex of vertices) {
|
|
146
|
-
const p3 = vertex.destination
|
|
147
|
-
if (
|
|
137
|
+
const p3 = vertex.destination;
|
|
138
|
+
if (this._getTriangleFrequency(p1, p2, p3) > (options.links?.triangles.frequency ?? defaultFrequency)) {
|
|
148
139
|
continue;
|
|
149
140
|
}
|
|
150
|
-
|
|
141
|
+
const opacityTriangle = Math.ceil((link.opacity + vertex.opacity) * half * opacitySteps) / opacitySteps, colorTriangle = rangeColorToRgb(this._engine, triangleOptions.color) ?? link.color;
|
|
142
|
+
if (!colorTriangle) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
const colorStyle = this._getCachedStyle(colorTriangle), key = `${colorStyle}_${opacityTriangle}`;
|
|
146
|
+
let batch = this._triangleBatches.get(key);
|
|
147
|
+
if (!batch) {
|
|
148
|
+
batch = { colorStyle, opacity: opacityTriangle, coords: [] };
|
|
149
|
+
this._triangleBatches.set(key, batch);
|
|
150
|
+
}
|
|
151
|
+
const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition();
|
|
152
|
+
batch.coords.push(pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y);
|
|
151
153
|
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
+
}
|
|
155
|
+
_getCachedStyle(rgb) {
|
|
156
|
+
const key = `${rgb.r},${rgb.g},${rgb.b}`;
|
|
157
|
+
let style = this._colorCache.get(key);
|
|
158
|
+
if (!style) {
|
|
159
|
+
style = getStyleFromRgb(rgb, this._container.hdr);
|
|
160
|
+
this._colorCache.set(key, style);
|
|
161
|
+
}
|
|
162
|
+
return style;
|
|
163
|
+
}
|
|
164
|
+
_getLinkFrequency(p1, p2) {
|
|
154
165
|
return setLinkFrequency([p1, p2], this._freqs.links);
|
|
155
|
-
}
|
|
156
|
-
_getTriangleFrequency
|
|
166
|
+
}
|
|
167
|
+
_getTriangleFrequency(p1, p2, p3) {
|
|
157
168
|
return setLinkFrequency([p1, p2, p3], this._freqs.triangles);
|
|
158
|
-
}
|
|
169
|
+
}
|
|
159
170
|
}
|
package/cjs/Linker.js
CHANGED
|
@@ -1,17 +1,10 @@
|
|
|
1
|
-
import { Circle, getDistances, getLinkRandomColor, originPoint, } from "@tsparticles/engine";
|
|
1
|
+
import { Circle, getDistances, getLinkColor, getLinkRandomColor, originPoint, } from "@tsparticles/engine";
|
|
2
2
|
import { CircleWarp } from "./CircleWarp.js";
|
|
3
3
|
import { Links } from "./Options/Classes/Links.js";
|
|
4
4
|
import { ParticlesInteractorBase } from "@tsparticles/plugin-interactivity";
|
|
5
5
|
const squarePower = 2, opacityOffset = 1, minDistance = 0;
|
|
6
|
-
function
|
|
7
|
-
const { dx, dy
|
|
8
|
-
if (!warp || distance <= optDistance) {
|
|
9
|
-
return distance;
|
|
10
|
-
}
|
|
11
|
-
const absDiffs = {
|
|
12
|
-
x: Math.abs(dx),
|
|
13
|
-
y: Math.abs(dy),
|
|
14
|
-
}, warpDistances = {
|
|
6
|
+
function getWarpDistance(pos1, pos2, canvasSize) {
|
|
7
|
+
const { dx, dy } = getDistances(pos1, pos2), absDiffs = { x: Math.abs(dx), y: Math.abs(dy) }, warpDistances = {
|
|
15
8
|
x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
|
|
16
9
|
y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
|
|
17
10
|
};
|
|
@@ -38,15 +31,7 @@ export class Linker extends ParticlesInteractorBase {
|
|
|
38
31
|
if (pos1.x < originPoint.x || pos1.y < originPoint.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
|
|
39
32
|
return;
|
|
40
33
|
}
|
|
41
|
-
const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp;
|
|
42
|
-
let range;
|
|
43
|
-
if (warp) {
|
|
44
|
-
range = new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize);
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
range = new Circle(pos1.x, pos1.y, optDistance);
|
|
48
|
-
}
|
|
49
|
-
const query = container.particles.quadTree.query(range);
|
|
34
|
+
const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp ? new CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new Circle(pos1.x, pos1.y, optDistance), query = container.particles.quadTree.query(range);
|
|
50
35
|
for (const p2 of query) {
|
|
51
36
|
const linkOpt2 = p2.options.links;
|
|
52
37
|
if (p1 === p2 ||
|
|
@@ -63,7 +48,7 @@ export class Linker extends ParticlesInteractorBase {
|
|
|
63
48
|
if (pos2.x < originPoint.x || pos2.y < originPoint.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {
|
|
64
49
|
continue;
|
|
65
50
|
}
|
|
66
|
-
const
|
|
51
|
+
const distDirect = getDistances(pos1, pos2).distance, distWarp = warp && linkOpt2.warp ? getWarpDistance(pos1, pos2, canvasSize) : distDirect, distance = Math.min(distDirect, distWarp);
|
|
67
52
|
if (distance > optDistance) {
|
|
68
53
|
continue;
|
|
69
54
|
}
|
|
@@ -72,6 +57,8 @@ export class Linker extends ParticlesInteractorBase {
|
|
|
72
57
|
p1.links.push({
|
|
73
58
|
destination: p2,
|
|
74
59
|
opacity: opacityLine,
|
|
60
|
+
color: this._getLinkColor(p1, p2),
|
|
61
|
+
isWarped: distWarp < distDirect,
|
|
75
62
|
});
|
|
76
63
|
}
|
|
77
64
|
}
|
|
@@ -86,7 +73,17 @@ export class Linker extends ParticlesInteractorBase {
|
|
|
86
73
|
}
|
|
87
74
|
reset() {
|
|
88
75
|
}
|
|
89
|
-
|
|
76
|
+
_getLinkColor(p1, p2) {
|
|
77
|
+
const container = this.container, linksOptions = p1.options.links;
|
|
78
|
+
if (!linksOptions) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const linkColor = linksOptions.id !== undefined
|
|
82
|
+
? container.particles.linksColors.get(linksOptions.id)
|
|
83
|
+
: container.particles.linksColor;
|
|
84
|
+
return getLinkColor(p1, p2, linkColor);
|
|
85
|
+
}
|
|
86
|
+
_setColor(p1) {
|
|
90
87
|
if (!p1.options.links) {
|
|
91
88
|
return;
|
|
92
89
|
}
|
|
@@ -97,13 +94,12 @@ export class Linker extends ParticlesInteractorBase {
|
|
|
97
94
|
if (linkColor) {
|
|
98
95
|
return;
|
|
99
96
|
}
|
|
100
|
-
|
|
101
|
-
linkColor = getLinkRandomColor(this._engine, optColor, linksOptions.blink, linksOptions.consent);
|
|
97
|
+
linkColor = getLinkRandomColor(this._engine, linksOptions.color, linksOptions.blink, linksOptions.consent);
|
|
102
98
|
if (linksOptions.id === undefined) {
|
|
103
99
|
container.particles.linksColor = linkColor;
|
|
104
100
|
}
|
|
105
101
|
else {
|
|
106
102
|
container.particles.linksColors.set(linksOptions.id, linkColor);
|
|
107
103
|
}
|
|
108
|
-
}
|
|
104
|
+
}
|
|
109
105
|
}
|
package/cjs/Utils.js
CHANGED
|
@@ -1,79 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { drawLine } from "@tsparticles/canvas-utils";
|
|
3
|
-
export function drawTriangle(context, p1, p2, p3) {
|
|
4
|
-
context.beginPath();
|
|
5
|
-
context.moveTo(p1.x, p1.y);
|
|
6
|
-
context.lineTo(p2.x, p2.y);
|
|
7
|
-
context.lineTo(p3.x, p3.y);
|
|
8
|
-
context.closePath();
|
|
9
|
-
}
|
|
10
|
-
export function drawLinkLine(params) {
|
|
11
|
-
let drawn = false;
|
|
12
|
-
const { begin, end, engine, maxDistance, context, canvasSize, width, colorLine, opacity, links, hdr } = params;
|
|
13
|
-
if (getDistance(begin, end) <= maxDistance) {
|
|
14
|
-
drawLine(context, begin, end);
|
|
15
|
-
drawn = true;
|
|
16
|
-
}
|
|
17
|
-
else if (links.warp) {
|
|
18
|
-
let pi1, pi2;
|
|
19
|
-
const endNE = {
|
|
20
|
-
x: end.x - canvasSize.width,
|
|
21
|
-
y: end.y,
|
|
22
|
-
}, d1 = getDistances(begin, endNE);
|
|
23
|
-
if (d1.distance <= maxDistance) {
|
|
24
|
-
const yi = begin.y - (d1.dy / d1.dx) * begin.x;
|
|
25
|
-
pi1 = { x: 0, y: yi };
|
|
26
|
-
pi2 = { x: canvasSize.width, y: yi };
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
const endSW = {
|
|
30
|
-
x: end.x,
|
|
31
|
-
y: end.y - canvasSize.height,
|
|
32
|
-
}, d2 = getDistances(begin, endSW);
|
|
33
|
-
if (d2.distance <= maxDistance) {
|
|
34
|
-
const yi = begin.y - (d2.dy / d2.dx) * begin.x, xi = -yi / (d2.dy / d2.dx);
|
|
35
|
-
pi1 = { x: xi, y: 0 };
|
|
36
|
-
pi2 = { x: xi, y: canvasSize.height };
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
const endSE = {
|
|
40
|
-
x: end.x - canvasSize.width,
|
|
41
|
-
y: end.y - canvasSize.height,
|
|
42
|
-
}, d3 = getDistances(begin, endSE);
|
|
43
|
-
if (d3.distance <= maxDistance) {
|
|
44
|
-
const yi = begin.y - (d3.dy / d3.dx) * begin.x, xi = -yi / (d3.dy / d3.dx);
|
|
45
|
-
pi1 = { x: xi, y: yi };
|
|
46
|
-
pi2 = { x: pi1.x + canvasSize.width, y: pi1.y + canvasSize.height };
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (pi1 && pi2) {
|
|
51
|
-
drawLine(context, begin, pi1);
|
|
52
|
-
drawLine(context, end, pi2);
|
|
53
|
-
drawn = true;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
if (!drawn) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
context.lineWidth = width;
|
|
60
|
-
context.strokeStyle = getStyleFromRgb(colorLine, hdr, opacity);
|
|
61
|
-
const { shadow } = links;
|
|
62
|
-
if (shadow.enable) {
|
|
63
|
-
const shadowColor = rangeColorToRgb(engine, shadow.color);
|
|
64
|
-
if (shadowColor) {
|
|
65
|
-
context.shadowBlur = shadow.blur;
|
|
66
|
-
context.shadowColor = getStyleFromRgb(shadowColor, hdr);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
context.stroke();
|
|
70
|
-
}
|
|
71
|
-
export function drawLinkTriangle(params) {
|
|
72
|
-
const { context, hdr, pos1, pos2, pos3, colorTriangle, opacityTriangle } = params;
|
|
73
|
-
drawTriangle(context, pos1, pos2, pos3);
|
|
74
|
-
context.fillStyle = getStyleFromRgb(colorTriangle, hdr, opacityTriangle);
|
|
75
|
-
context.fill();
|
|
76
|
-
}
|
|
1
|
+
import { getRandom } from "@tsparticles/engine";
|
|
77
2
|
export function getLinkKey(ids) {
|
|
78
3
|
ids.sort((a, b) => a - b);
|
|
79
4
|
return ids.join("_");
|
package/cjs/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export async function loadParticlesLinksInteraction(engine) {
|
|
2
|
-
engine.checkVersion("4.0.0-alpha.
|
|
2
|
+
engine.checkVersion("4.0.0-alpha.23");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const [{ ensureInteractivityPluginLoaded }, { LinksPlugin },] = await Promise.all([
|
|
5
5
|
import("@tsparticles/plugin-interactivity"),
|
|
@@ -9,7 +9,7 @@ export async function loadParticlesLinksInteraction(engine) {
|
|
|
9
9
|
e.addPlugin(new LinksPlugin(e));
|
|
10
10
|
e.addInteractor?.("particlesLinks", async (container) => {
|
|
11
11
|
const { Linker } = await import("./Linker.js");
|
|
12
|
-
return new Linker(container,
|
|
12
|
+
return new Linker(container, e);
|
|
13
13
|
});
|
|
14
14
|
});
|
|
15
15
|
}
|
|
@@ -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
|
-
* v4.0.0-alpha.
|
|
7
|
+
* v4.0.0-alpha.23
|
|
8
8
|
*/
|
|
9
9
|
"use strict";
|
|
10
10
|
/*
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
\**************************************/
|
|
24
24
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
25
25
|
|
|
26
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ LinkInstance: () => (/* binding */ LinkInstance)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\n\nconst minOpacity = 0, minWidth = 0, minDistance = 0, maxFrequency = 1;\nclass LinkInstance {\n _container;\n _engine;\n _freqs;\n constructor(container, engine){\n this._container = container;\n this._engine = engine;\n this._freqs = {\n links: new Map(),\n triangles: new Map()\n };\n }\n drawParticle(_context, particle) {\n const { links, options } = particle;\n if (!links?.length) {\n return;\n }\n const p1Links = links.filter((l)=>options.links && (options.links.frequency >= maxFrequency || this._getLinkFrequency(particle, l.destination) <= options.links.frequency));\n for (const link of p1Links){\n this._drawTriangles(options, particle, link, p1Links);\n if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {\n this._drawLinkLine(particle, link);\n }\n }\n }\n async init() {\n this._freqs.links = new Map();\n this._freqs.triangles = new Map();\n await Promise.resolve();\n }\n particleCreated(particle) {\n particle.links = [];\n if (!particle.options.links) {\n return;\n }\n const ratio = this._container.retina.pixelRatio, { retina } = particle, { distance, width } = particle.options.links;\n retina.linksDistance = distance * ratio;\n retina.linksWidth = width * ratio;\n }\n particleDestroyed(particle) {\n particle.links = [];\n }\n _drawLinkLine = (p1, link)=>{\n const p1LinksOptions = p1.options.links;\n if (!p1LinksOptions?.enable) {\n return;\n }\n const container = this._container, p2 = link.destination, pos1 = p1.getPosition(), pos2 = p2.getPosition();\n let opacity = link.opacity;\n container.canvas.draw((ctx)=>{\n let colorLine;\n const twinkle = p1.options[\"twinkle\"]?.lines;\n if (twinkle?.enable) {\n const twinkleFreq = twinkle.frequency, twinkleRgb = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToRgb)(this._engine, twinkle.color), twinkling = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() < twinkleFreq;\n if (twinkling && twinkleRgb) {\n colorLine = twinkleRgb;\n opacity = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(twinkle.opacity);\n }\n }\n if (!colorLine) {\n const linkColor = p1LinksOptions.id !== undefined ? container.particles.linksColors.get(p1LinksOptions.id) : container.particles.linksColor;\n colorLine = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkColor)(p1, p2, linkColor);\n }\n if (!colorLine) {\n return;\n }\n const width = p1.retina.linksWidth ?? minWidth, maxDistance = p1.retina.linksDistance ?? minDistance;\n (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.drawLinkLine)({\n context: ctx,\n width,\n begin: pos1,\n end: pos2,\n engine: this._engine,\n maxDistance,\n canvasSize: container.canvas.size,\n links: p1LinksOptions,\n colorLine,\n opacity,\n hdr: container.hdr\n });\n });\n };\n _drawLinkTriangle = (p1, link1, link2)=>{\n const linksOptions = p1.options.links;\n if (!linksOptions?.enable) {\n return;\n }\n const triangleOptions = linksOptions.triangles;\n if (!triangleOptions.enable) {\n return;\n }\n const container = this._container, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half;\n if (opacityTriangle <= minOpacity) {\n return;\n }\n container.canvas.draw((ctx)=>{\n const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? minDistance;\n if ((0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(pos1, pos2) > linksDistance || (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(pos3, pos2) > linksDistance || (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistance)(pos3, pos1) > linksDistance) {\n return;\n }\n let colorTriangle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToRgb)(this._engine, triangleOptions.color);\n if (!colorTriangle) {\n const linkColor = linksOptions.id !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor;\n colorTriangle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkColor)(p1, p2, linkColor);\n }\n if (!colorTriangle) {\n return;\n }\n (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.drawLinkTriangle)({\n context: ctx,\n pos1,\n pos2,\n pos3,\n colorTriangle,\n opacityTriangle,\n hdr: container.hdr\n });\n });\n };\n _drawTriangles = (options, p1, link, p1Links)=>{\n const p2 = link.destination;\n if (!(options.links?.triangles.enable && p2.options.links?.triangles.enable)) {\n return;\n }\n const vertices = p2.links?.filter((t)=>{\n const linkFreq = this._getLinkFrequency(p2, t.destination), minCount = 0;\n return p2.options.links && linkFreq <= p2.options.links.frequency && p1Links.findIndex((l)=>l.destination === t.destination) >= minCount;\n });\n if (!vertices?.length) {\n return;\n }\n for (const vertex of vertices){\n const p3 = vertex.destination, triangleFreq = this._getTriangleFrequency(p1, p2, p3);\n if (triangleFreq > options.links.triangles.frequency) {\n continue;\n }\n this._drawLinkTriangle(p1, link, vertex);\n }\n };\n _getLinkFrequency = (p1, p2)=>{\n return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.setLinkFrequency)([\n p1,\n p2\n ], this._freqs.links);\n };\n _getTriangleFrequency = (p1, p2, p3)=>{\n return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.setLinkFrequency)([\n p1,\n p2,\n p3\n ], this._freqs.triangles);\n };\n}\n\n\n//# sourceURL=webpack://@tsparticles/interaction-particles-links/./dist/browser/LinkInstance.js?\n}");
|
|
26
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ LinkInstance: () => (/* binding */ LinkInstance)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _Utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Utils.js */ \"./dist/browser/Utils.js\");\n\n\nconst minOpacity = 0, minDistance = 0, minWidth = 0, maxFrequency = 1, defaultFrequency = 0, opacitySteps = 10, defaultWidth = 0, triangleCoordsCount = 6, lineCoordsCount = 4, x1Offset = 0, y1Offset = 1, x2Offset = 2, y2Offset = 3, x3Offset = 4, y3Offset = 5;\nclass LinkInstance {\n _colorCache = new Map();\n _container;\n _engine;\n _freqs;\n _lineBatches = new Map();\n _triangleBatches = new Map();\n constructor(container, engine){\n this._container = container;\n this._engine = engine;\n this._freqs = {\n links: new Map(),\n triangles: new Map()\n };\n }\n draw(context) {\n for (const [, batch] of this._triangleBatches){\n context.save();\n context.fillStyle = batch.colorStyle;\n context.globalAlpha = batch.opacity;\n context.beginPath();\n for(let i = 0; i < batch.coords.length; i += triangleCoordsCount){\n const x1 = batch.coords[i + x1Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, y1 = batch.coords[i + y1Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y, x2 = batch.coords[i + x2Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, y2 = batch.coords[i + y2Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y, x3 = batch.coords[i + x3Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, y3 = batch.coords[i + y3Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y;\n context.moveTo(x1, y1);\n context.lineTo(x2, y2);\n context.lineTo(x3, y3);\n }\n context.fill();\n context.restore();\n }\n for (const [, batch] of this._lineBatches){\n context.save();\n context.strokeStyle = batch.colorStyle;\n context.lineWidth = batch.width;\n context.globalAlpha = batch.opacity;\n context.beginPath();\n for(let i = 0; i < batch.coords.length; i += lineCoordsCount){\n const x1 = batch.coords[i + x1Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, y1 = batch.coords[i + y1Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y, x2 = batch.coords[i + x2Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, y2 = batch.coords[i + y2Offset] ?? _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y;\n context.moveTo(x1, y1);\n context.lineTo(x2, y2);\n }\n context.stroke();\n context.restore();\n }\n this._lineBatches.clear();\n this._triangleBatches.clear();\n }\n drawParticle(_context, particle) {\n const { links, options } = particle;\n if (!links?.length || !options.links) {\n return;\n }\n const canvasSize = this._container.canvas.size, p1Links = links.filter((l)=>options.links && (options.links.frequency >= maxFrequency || this._getLinkFrequency(particle, l.destination) <= options.links.frequency)), pos1 = particle.getPosition();\n for (const link of p1Links){\n if (!link.isWarped) {\n this._collectTriangles(options, particle, link, p1Links);\n }\n if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {\n let opacity = link.opacity, colorLine = link.color;\n const twinkle = particle.options[\"twinkle\"]?.lines;\n if (twinkle?.enable && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() < twinkle.frequency) {\n const twinkleRgb = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToRgb)(this._engine, twinkle.color);\n if (twinkleRgb) {\n colorLine = twinkleRgb;\n opacity = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(twinkle.opacity);\n }\n }\n if (!colorLine) {\n const linkColor = options.links.id !== undefined ? this._container.particles.linksColors.get(options.links.id) : this._container.particles.linksColor;\n colorLine = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkColor)(particle, link.destination, linkColor);\n }\n if (colorLine) {\n const qOpacity = Math.ceil(opacity * opacitySteps) / opacitySteps, colorStyle = this._getCachedStyle(colorLine), width = particle.retina.linksWidth ?? defaultWidth, key = `${colorStyle}_${qOpacity}_${width}`;\n let batch = this._lineBatches.get(key);\n if (!batch) {\n batch = {\n colorStyle,\n opacity: qOpacity,\n width,\n coords: []\n };\n this._lineBatches.set(key, batch);\n }\n const pos2 = link.destination.getPosition();\n if (link.isWarped) {\n const dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;\n let sx = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x, sy = _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y;\n if (Math.abs(dx) > canvasSize.width * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half) {\n sx = dx > minDistance ? -canvasSize.width : canvasSize.width;\n }\n if (Math.abs(dy) > canvasSize.height * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half) {\n sy = dy > minDistance ? -canvasSize.height : canvasSize.height;\n }\n const v2 = {\n x: pos2.x + sx,\n y: pos2.y + sy\n }, v1 = {\n x: pos1.x - sx,\n y: pos1.y - sy\n };\n batch.coords.push(pos1.x, pos1.y, v2.x, v2.y);\n batch.coords.push(v1.x, v1.y, pos2.x, pos2.y);\n } else {\n batch.coords.push(pos1.x, pos1.y, pos2.x, pos2.y);\n }\n }\n }\n }\n }\n async init() {\n this._freqs.links.clear();\n this._freqs.triangles.clear();\n this._colorCache.clear();\n await Promise.resolve();\n }\n particleCreated(particle) {\n particle.links = [];\n if (!particle.options.links) {\n return;\n }\n const ratio = this._container.retina.pixelRatio;\n particle.retina.linksDistance = particle.options.links.distance * ratio;\n particle.retina.linksWidth = particle.options.links.width * ratio;\n }\n particleDestroyed(particle) {\n particle.links = [];\n }\n _collectTriangles(options, p1, link, p1Links) {\n const p2 = link.destination, triangleOptions = options.links?.triangles;\n if (!triangleOptions?.enable || !p2.options.links?.triangles.enable) {\n return;\n }\n const vertices = p2.links?.filter((t)=>{\n return !t.isWarped && p2.options.links && this._getLinkFrequency(p2, t.destination) <= p2.options.links.frequency && p1Links.some((l)=>l.destination === t.destination);\n });\n if (!vertices?.length) {\n return;\n }\n for (const vertex of vertices){\n const p3 = vertex.destination;\n if (this._getTriangleFrequency(p1, p2, p3) > (options.links?.triangles.frequency ?? defaultFrequency)) {\n continue;\n }\n const opacityTriangle = Math.ceil((link.opacity + vertex.opacity) * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half * opacitySteps) / opacitySteps, colorTriangle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToRgb)(this._engine, triangleOptions.color) ?? link.color;\n if (!colorTriangle) {\n continue;\n }\n const colorStyle = this._getCachedStyle(colorTriangle), key = `${colorStyle}_${opacityTriangle}`;\n let batch = this._triangleBatches.get(key);\n if (!batch) {\n batch = {\n colorStyle,\n opacity: opacityTriangle,\n coords: []\n };\n this._triangleBatches.set(key, batch);\n }\n const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition();\n batch.coords.push(pos1.x, pos1.y, pos2.x, pos2.y, pos3.x, pos3.y);\n }\n }\n _getCachedStyle(rgb) {\n const key = `${rgb.r},${rgb.g},${rgb.b}`;\n let style = this._colorCache.get(key);\n if (!style) {\n style = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getStyleFromRgb)(rgb, this._container.hdr);\n this._colorCache.set(key, style);\n }\n return style;\n }\n _getLinkFrequency(p1, p2) {\n return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.setLinkFrequency)([\n p1,\n p2\n ], this._freqs.links);\n }\n _getTriangleFrequency(p1, p2, p3) {\n return (0,_Utils_js__WEBPACK_IMPORTED_MODULE_1__.setLinkFrequency)([\n p1,\n p2,\n p3\n ], this._freqs.triangles);\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/interaction-particles-links/./dist/browser/LinkInstance.js?\n}");
|
|
27
27
|
|
|
28
28
|
/***/ },
|
|
29
29
|
|
|
@@ -33,7 +33,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
|
|
|
33
33
|
\*******************************/
|
|
34
34
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
35
35
|
|
|
36
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */
|
|
36
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ getLinkKey: () => (/* binding */ getLinkKey),\n/* harmony export */ setLinkFrequency: () => (/* binding */ setLinkFrequency)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n\nfunction getLinkKey(ids) {\n ids.sort((a, b)=>a - b);\n return ids.join(\"_\");\n}\nfunction setLinkFrequency(particles, dictionary) {\n const key = getLinkKey(particles.map((t)=>t.id));\n let res = dictionary.get(key);\n if (res === undefined) {\n res = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)();\n dictionary.set(key, res);\n }\n return res;\n}\n\n\n//# sourceURL=webpack://@tsparticles/interaction-particles-links/./dist/browser/Utils.js?\n}");
|
|
37
37
|
|
|
38
38
|
/***/ }
|
|
39
39
|
|