@tsparticles/interaction-particles-links 4.0.0-alpha.26 → 4.0.0-alpha.28
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/13.min.js +1 -0
- package/{520.min.js → 342.min.js} +1 -1
- package/823.min.js +1 -0
- package/browser/LinkInstance.js +56 -69
- package/browser/index.js +1 -1
- package/cjs/LinkInstance.js +56 -69
- package/cjs/index.js +1 -1
- package/dist_browser_LinkInstance_js.js +2 -2
- package/dist_browser_Linker_js.js +1 -1
- package/dist_browser_LinksPlugin_js.js +1 -1
- package/esm/LinkInstance.js +56 -69
- package/esm/index.js +1 -1
- package/package.json +4 -4
- package/report.html +1 -1
- package/tsparticles.interaction.particles.links.js +8 -8
- package/tsparticles.interaction.particles.links.min.js +2 -2
- package/types/Interfaces.d.ts +1 -1
- package/types/LinkInstance.d.ts +2 -5
- package/umd/LinkInstance.js +56 -69
- package/umd/index.js +1 -1
- package/463.min.js +0 -1
- package/628.min.js +0 -1
package/13.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[13],{13(n,i,t){t.r(i),t.d(i,{LinksPlugin:()=>e});class e{id="links";_engine;constructor(n){this._engine=n}async getPlugin(n){let{LinkInstance:i}=await t.e(823).then(t.bind(t,823));return new i(n,this._engine)}loadOptions(){}needsPlugin(){return!0}}}}]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[
|
|
1
|
+
"use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[342],{342(i,t,n){n.d(t,{Linker:()=>a});var s=n(303);class e extends s.Circle{canvasSize;constructor(i,t,n,s){super(i,t,n),this.canvasSize=s}contains(i){if(super.contains(i))return!0;let{width:t,height:n}=this.canvasSize,{x:s,y:e}=i;return super.contains({x:s-t,y:e})||super.contains({x:s+t,y:e})||super.contains({x:s,y:e-n})||super.contains({x:s,y:e+n})||super.contains({x:s-t,y:e-n})||super.contains({x:s+t,y:e+n})||super.contains({x:s-t,y:e+n})||super.contains({x:s+t,y:e-n})}intersects(i){if(super.intersects(i))return!0;let{width:t,height:n}=this.canvasSize,e=i.position;for(let r of[{x:-t,y:0},{x:t,y:0},{x:0,y:-n},{x:0,y:n},{x:-t,y:-n},{x:t,y:n},{x:-t,y:n},{x:t,y:-n}]){let t,n={x:e.x+r.x,y:e.y+r.y};if(t=i instanceof s.Circle?new s.Circle(n.x,n.y,i.radius):new s.Rectangle(n.x,n.y,i.size.width,i.size.height),super.intersects(t))return!0}return!1}}var r=n(348),o=n(702);class a extends o.ParticlesInteractorBase{_engine;_maxDistance;constructor(i,t){super(i),this._engine=t,this._maxDistance=0}get maxDistance(){return this._maxDistance}clear(){}init(){this.container.particles.linksColor=void 0,this.container.particles.linksColors=new Map}interact(i){if(!i.options.links)return;i.links=[],i.linksDistance&&i.linksDistance>this._maxDistance&&(this._maxDistance=i.linksDistance);let t=i.getPosition(),n=this.container,r=n.canvas.size;if(t.x<s.originPoint.x||t.y<s.originPoint.y||t.x>r.width||t.y>r.height)return;let o=i.options.links,a=o.opacity,l=i.retina.linksDistance??0,c=o.warp,p=c?new e(t.x,t.y,l,r):new s.Circle(t.x,t.y,l);for(let e of n.particles.grid.query(p)){let n=e.options.links;if(i===e||!n?.enable||o.id!==n.id||e.spawning||e.destroyed||!e.links||i.links.some(i=>i.destination===e)||e.links.some(t=>t.destination===i))continue;let p=e.getPosition();if(p.x<s.originPoint.x||p.y<s.originPoint.y||p.x>r.width||p.y>r.height)continue;let h=(0,s.getDistances)(t,p).distance,x=c&&n.warp?function(i,t,n){let{dx:e,dy:r}=(0,s.getDistances)(i,t),o={x:Math.abs(e),y:Math.abs(r)},a={x:Math.min(o.x,n.width-o.x),y:Math.min(o.y,n.height-o.y)};return Math.hypot(a.x,a.y)}(t,p,r):h,k=Math.min(h,x);if(k>l)continue;let u=(1-k/l)*a;this._setColor(i),i.links.push({destination:e,opacity:u,color:this._getLinkColor(i,e),isWarped:x<h})}}isEnabled(i){return!!i.options.links?.enable}loadParticlesOptions(i,...t){for(let n of(i.links??=new r.q,t))i.links.load(n?.links)}reset(){}_getLinkColor(i,t){let n=this.container,e=i.options.links;if(!e)return;let r=void 0!==e.id?n.particles.linksColors.get(e.id):n.particles.linksColor;return(0,s.getLinkColor)(i,t,r)}_setColor(i){if(!i.options.links)return;let t=this.container,n=i.options.links,e=void 0===n.id?t.particles.linksColor:t.particles.linksColors.get(n.id);e||(e=(0,s.getLinkRandomColor)(this._engine,n.color,n.blink,n.consent),void 0===n.id?t.particles.linksColor=e:t.particles.linksColors.set(n.id,e))}}}}]);
|
package/823.min.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[823],{823(e,i,t){t.d(i,{LinkInstance:()=>s});var n=t(303);function l(e,i){let t=[...e.map(e=>e.id)].sort((e,i)=>e-i).join("_"),l=i.get(t);return void 0===l&&(l=(0,n.getRandom)(),i.set(t,l)),l}class s{_colorCache=new Map;_container;_engine;_freqs;constructor(e,i){this._container=e,this._engine=i,this._freqs={links:new Map,triangles:new Map}}drawParticle(e,i){let{links:t,options:l}=i;if(!t?.length||!l.links)return;let s=l.links,o=i.retina.linksWidth??0,a=i.getPosition(),r=i.options.twinkle?.links,c=s.triangles.enable,h=c?new Set(t.map(e=>e.destination.id)):null,g=e.globalAlpha,d="",_=-1,k=-1,p=!1,y=()=>{p&&(e.stroke(),p=!1)};for(let g of t){if(s.frequency<1&&this._getLinkFrequency(i,g.destination)>s.frequency)continue;let t=g.destination.getPosition();if(c&&!g.isWarped&&h&&(y(),this._drawTriangles(l,i,g,h,a,t,e)),g.opacity<=0||o<=0||!s.enable)continue;let f=g.opacity,u=g.color,b=r?.enable&&(0,n.getRandom)()<r.frequency?(0,n.rangeColorToRgb)(this._engine,r.color):void 0;if(r&&b&&(u=b,f=(0,n.getRangeValue)(r.opacity)),!u){let e=void 0!==s.id?this._container.particles.linksColors.get(s.id):this._container.particles.linksColor;u=(0,n.getLinkColor)(i,g.destination,e)}if(!u)continue;let q=this._getCachedStyle(u);if((q!==d||o!==_||f!==k)&&(y(),e.strokeStyle=q,e.lineWidth=o,e.globalAlpha=f,d=q,_=o,k=f,e.beginPath(),p=!0),g.isWarped){let i=this._container.canvas.size,l=t.x-a.x,s=t.y-a.y,o=n.originPoint.x,r=n.originPoint.y;Math.abs(l)>i.width*n.half&&(o=l>0?-i.width:i.width),Math.abs(s)>i.height*n.half&&(r=s>0?-i.height:i.height),e.moveTo(a.x,a.y),e.lineTo(t.x+o,t.y+r),e.moveTo(a.x-o,a.y-r),e.lineTo(t.x,t.y)}else e.moveTo(a.x,a.y),e.lineTo(t.x,t.y)}y(),e.globalAlpha=g}init(){return this._freqs.links.clear(),this._freqs.triangles.clear(),this._colorCache.clear(),Promise.resolve()}particleCreated(e){if(e.links=[],!e.options.links)return;e.linksDistance=e.options.links.distance,e.linksWidth=e.options.links.width;let i=this._container.retina.pixelRatio;e.retina.linksDistance=e.linksDistance*i,e.retina.linksWidth=e.linksWidth*i}particleDestroyed(e){e.links=[]}_drawTriangles(e,i,t,l,s,o,a){let r=t.destination,c=e.links?.triangles;if(!c?.enable||!r.options.links?.triangles.enable)return;let h=r.links;if(h?.length)for(let g of h){if(g.isWarped||this._getLinkFrequency(r,g.destination)>r.options.links.frequency||!l.has(g.destination.id))continue;let h=g.destination;if(this._getTriangleFrequency(i,r,h)>(e.links?.triangles.frequency??0))continue;let d=c.opacity??(t.opacity+g.opacity)*n.half,_=(0,n.rangeColorToRgb)(this._engine,c.color)??t.color;if(!_||d<=0)continue;let k=h.getPosition();a.save(),a.fillStyle=this._getCachedStyle(_),a.globalAlpha=d,a.beginPath(),a.moveTo(s.x,s.y),a.lineTo(o.x,o.y),a.lineTo(k.x,k.y),a.closePath(),a.fill(),a.restore()}}_getCachedStyle(e){let i=`${e.r},${e.g},${e.b}`,t=this._colorCache.get(i);return t||(t=(0,n.getStyleFromRgb)(e,this._container.hdr),this._colorCache.set(i,t)),t}_getLinkFrequency(e,i){return l([e,i],this._freqs.links)}_getTriangleFrequency(e,i,t){return l([e,i,t],this._freqs.triangles)}}}}]);
|
package/browser/LinkInstance.js
CHANGED
|
@@ -1,75 +1,50 @@
|
|
|
1
1
|
import { getLinkColor as engineGetLinkColor, getRandom, getRangeValue, getStyleFromRgb, half, originPoint, rangeColorToRgb, } from "@tsparticles/engine";
|
|
2
2
|
import { setLinkFrequency } from "./Utils.js";
|
|
3
|
-
const minOpacity = 0,
|
|
3
|
+
const minOpacity = 0, minWidth = 0, minDistance = 0, maxFrequency = 1, defaultFrequency = 0;
|
|
4
4
|
export class LinkInstance {
|
|
5
5
|
_colorCache = new Map();
|
|
6
6
|
_container;
|
|
7
7
|
_engine;
|
|
8
8
|
_freqs;
|
|
9
|
-
_lineBatches = new Map();
|
|
10
|
-
_triangleBatches = new Map();
|
|
11
9
|
constructor(container, engine) {
|
|
12
10
|
this._container = container;
|
|
13
11
|
this._engine = engine;
|
|
14
12
|
this._freqs = { links: new Map(), triangles: new Map() };
|
|
15
13
|
}
|
|
16
|
-
|
|
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();
|
|
47
|
-
}
|
|
48
|
-
drawParticle(_context, particle) {
|
|
14
|
+
drawParticle(context, particle) {
|
|
49
15
|
const { links, options } = particle;
|
|
50
16
|
if (!links?.length || !options.links) {
|
|
51
17
|
return;
|
|
52
18
|
}
|
|
53
|
-
const
|
|
19
|
+
const linkOpts = options.links, width = particle.retina.linksWidth ?? minWidth, pos1 = particle.getPosition(), twinkle = particle.options["twinkle"]?.links, trianglesEnabled = linkOpts.triangles.enable, p1Destinations = trianglesEnabled ? new Set(links.map(l => l.destination.id)) : null, originalAlpha = context.globalAlpha;
|
|
20
|
+
let currentColorStyle = "", currentWidth = -1, currentAlpha = -1, pathOpen = false;
|
|
21
|
+
const flushLines = () => {
|
|
22
|
+
if (pathOpen) {
|
|
23
|
+
context.stroke();
|
|
24
|
+
pathOpen = false;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
54
27
|
for (const link of links) {
|
|
55
28
|
if (linkOpts.frequency < maxFrequency &&
|
|
56
29
|
this._getLinkFrequency(particle, link.destination) > linkOpts.frequency) {
|
|
57
30
|
continue;
|
|
58
31
|
}
|
|
59
|
-
|
|
60
|
-
|
|
32
|
+
const pos2 = link.destination.getPosition();
|
|
33
|
+
if (trianglesEnabled && !link.isWarped && p1Destinations) {
|
|
34
|
+
flushLines();
|
|
35
|
+
this._drawTriangles(options, particle, link, p1Destinations, pos1, pos2, context);
|
|
36
|
+
}
|
|
37
|
+
if (link.opacity <= minOpacity || width <= minWidth) {
|
|
38
|
+
continue;
|
|
61
39
|
}
|
|
62
|
-
if (
|
|
40
|
+
if (!linkOpts.enable) {
|
|
63
41
|
continue;
|
|
64
42
|
}
|
|
65
43
|
let opacity = link.opacity, colorLine = link.color;
|
|
66
|
-
const
|
|
67
|
-
if (twinkle
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
colorLine = twinkleRgb;
|
|
71
|
-
opacity = getRangeValue(twinkle.opacity);
|
|
72
|
-
}
|
|
44
|
+
const twinkleRgb = twinkle?.enable && getRandom() < twinkle.frequency ? rangeColorToRgb(this._engine, twinkle.color) : undefined;
|
|
45
|
+
if (twinkle && twinkleRgb) {
|
|
46
|
+
colorLine = twinkleRgb;
|
|
47
|
+
opacity = getRangeValue(twinkle.opacity);
|
|
73
48
|
}
|
|
74
49
|
if (!colorLine) {
|
|
75
50
|
const linkColor = linkOpts.id !== undefined
|
|
@@ -80,15 +55,20 @@ export class LinkInstance {
|
|
|
80
55
|
if (!colorLine) {
|
|
81
56
|
continue;
|
|
82
57
|
}
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
58
|
+
const colorStyle = this._getCachedStyle(colorLine);
|
|
59
|
+
if (colorStyle !== currentColorStyle || width !== currentWidth || opacity !== currentAlpha) {
|
|
60
|
+
flushLines();
|
|
61
|
+
context.strokeStyle = colorStyle;
|
|
62
|
+
context.lineWidth = width;
|
|
63
|
+
context.globalAlpha = opacity;
|
|
64
|
+
currentColorStyle = colorStyle;
|
|
65
|
+
currentWidth = width;
|
|
66
|
+
currentAlpha = opacity;
|
|
67
|
+
context.beginPath();
|
|
68
|
+
pathOpen = true;
|
|
88
69
|
}
|
|
89
|
-
const pos2 = link.destination.getPosition();
|
|
90
70
|
if (link.isWarped) {
|
|
91
|
-
const dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
71
|
+
const canvasSize = this._container.canvas.size, dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
92
72
|
let sx = originPoint.x, sy = originPoint.y;
|
|
93
73
|
if (Math.abs(dx) > canvasSize.width * half) {
|
|
94
74
|
sx = dx > minDistance ? -canvasSize.width : canvasSize.width;
|
|
@@ -96,13 +76,18 @@ export class LinkInstance {
|
|
|
96
76
|
if (Math.abs(dy) > canvasSize.height * half) {
|
|
97
77
|
sy = dy > minDistance ? -canvasSize.height : canvasSize.height;
|
|
98
78
|
}
|
|
99
|
-
|
|
100
|
-
|
|
79
|
+
context.moveTo(pos1.x, pos1.y);
|
|
80
|
+
context.lineTo(pos2.x + sx, pos2.y + sy);
|
|
81
|
+
context.moveTo(pos1.x - sx, pos1.y - sy);
|
|
82
|
+
context.lineTo(pos2.x, pos2.y);
|
|
101
83
|
}
|
|
102
84
|
else {
|
|
103
|
-
|
|
85
|
+
context.moveTo(pos1.x, pos1.y);
|
|
86
|
+
context.lineTo(pos2.x, pos2.y);
|
|
104
87
|
}
|
|
105
88
|
}
|
|
89
|
+
flushLines();
|
|
90
|
+
context.globalAlpha = originalAlpha;
|
|
106
91
|
}
|
|
107
92
|
init() {
|
|
108
93
|
this._freqs.links.clear();
|
|
@@ -124,16 +109,15 @@ export class LinkInstance {
|
|
|
124
109
|
particleDestroyed(particle) {
|
|
125
110
|
particle.links = [];
|
|
126
111
|
}
|
|
127
|
-
|
|
112
|
+
_drawTriangles(options, p1, link, p1Destinations, pos1, pos2, context) {
|
|
128
113
|
const p2 = link.destination, triangleOptions = options.links?.triangles;
|
|
129
114
|
if (!triangleOptions?.enable || !p2.options.links?.triangles.enable) {
|
|
130
115
|
return;
|
|
131
116
|
}
|
|
132
|
-
const
|
|
117
|
+
const p2Links = p2.links;
|
|
133
118
|
if (!p2Links?.length) {
|
|
134
119
|
return;
|
|
135
120
|
}
|
|
136
|
-
const pos2 = p2.getPosition();
|
|
137
121
|
for (const vertex of p2Links) {
|
|
138
122
|
if (vertex.isWarped ||
|
|
139
123
|
this._getLinkFrequency(p2, vertex.destination) > p2.options.links.frequency ||
|
|
@@ -144,18 +128,21 @@ export class LinkInstance {
|
|
|
144
128
|
if (this._getTriangleFrequency(p1, p2, p3) > (options.links?.triangles.frequency ?? defaultFrequency)) {
|
|
145
129
|
continue;
|
|
146
130
|
}
|
|
147
|
-
const opacityTriangle =
|
|
148
|
-
if (!colorTriangle) {
|
|
131
|
+
const opacityTriangle = triangleOptions.opacity ?? (link.opacity + vertex.opacity) * half, colorTriangle = rangeColorToRgb(this._engine, triangleOptions.color) ?? link.color;
|
|
132
|
+
if (!colorTriangle || opacityTriangle <= minOpacity) {
|
|
149
133
|
continue;
|
|
150
134
|
}
|
|
151
|
-
const colorStyle = this._getCachedStyle(colorTriangle), key = `${colorStyle}_${opacityTriangle}`;
|
|
152
|
-
let batch = this._triangleBatches.get(key);
|
|
153
|
-
if (!batch) {
|
|
154
|
-
batch = { colorStyle, opacity: opacityTriangle, coords: [] };
|
|
155
|
-
this._triangleBatches.set(key, batch);
|
|
156
|
-
}
|
|
157
135
|
const pos3 = p3.getPosition();
|
|
158
|
-
|
|
136
|
+
context.save();
|
|
137
|
+
context.fillStyle = this._getCachedStyle(colorTriangle);
|
|
138
|
+
context.globalAlpha = opacityTriangle;
|
|
139
|
+
context.beginPath();
|
|
140
|
+
context.moveTo(pos1.x, pos1.y);
|
|
141
|
+
context.lineTo(pos2.x, pos2.y);
|
|
142
|
+
context.lineTo(pos3.x, pos3.y);
|
|
143
|
+
context.closePath();
|
|
144
|
+
context.fill();
|
|
145
|
+
context.restore();
|
|
159
146
|
}
|
|
160
147
|
}
|
|
161
148
|
_getCachedStyle(rgb) {
|
package/browser/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.28");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const [{ ensureInteractivityPluginLoaded }, { LinksPlugin },] = await Promise.all([
|
|
5
5
|
import("@tsparticles/plugin-interactivity"),
|
package/cjs/LinkInstance.js
CHANGED
|
@@ -1,75 +1,50 @@
|
|
|
1
1
|
import { getLinkColor as engineGetLinkColor, getRandom, getRangeValue, getStyleFromRgb, half, originPoint, rangeColorToRgb, } from "@tsparticles/engine";
|
|
2
2
|
import { setLinkFrequency } from "./Utils.js";
|
|
3
|
-
const minOpacity = 0,
|
|
3
|
+
const minOpacity = 0, minWidth = 0, minDistance = 0, maxFrequency = 1, defaultFrequency = 0;
|
|
4
4
|
export class LinkInstance {
|
|
5
5
|
_colorCache = new Map();
|
|
6
6
|
_container;
|
|
7
7
|
_engine;
|
|
8
8
|
_freqs;
|
|
9
|
-
_lineBatches = new Map();
|
|
10
|
-
_triangleBatches = new Map();
|
|
11
9
|
constructor(container, engine) {
|
|
12
10
|
this._container = container;
|
|
13
11
|
this._engine = engine;
|
|
14
12
|
this._freqs = { links: new Map(), triangles: new Map() };
|
|
15
13
|
}
|
|
16
|
-
|
|
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();
|
|
47
|
-
}
|
|
48
|
-
drawParticle(_context, particle) {
|
|
14
|
+
drawParticle(context, particle) {
|
|
49
15
|
const { links, options } = particle;
|
|
50
16
|
if (!links?.length || !options.links) {
|
|
51
17
|
return;
|
|
52
18
|
}
|
|
53
|
-
const
|
|
19
|
+
const linkOpts = options.links, width = particle.retina.linksWidth ?? minWidth, pos1 = particle.getPosition(), twinkle = particle.options["twinkle"]?.links, trianglesEnabled = linkOpts.triangles.enable, p1Destinations = trianglesEnabled ? new Set(links.map(l => l.destination.id)) : null, originalAlpha = context.globalAlpha;
|
|
20
|
+
let currentColorStyle = "", currentWidth = -1, currentAlpha = -1, pathOpen = false;
|
|
21
|
+
const flushLines = () => {
|
|
22
|
+
if (pathOpen) {
|
|
23
|
+
context.stroke();
|
|
24
|
+
pathOpen = false;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
54
27
|
for (const link of links) {
|
|
55
28
|
if (linkOpts.frequency < maxFrequency &&
|
|
56
29
|
this._getLinkFrequency(particle, link.destination) > linkOpts.frequency) {
|
|
57
30
|
continue;
|
|
58
31
|
}
|
|
59
|
-
|
|
60
|
-
|
|
32
|
+
const pos2 = link.destination.getPosition();
|
|
33
|
+
if (trianglesEnabled && !link.isWarped && p1Destinations) {
|
|
34
|
+
flushLines();
|
|
35
|
+
this._drawTriangles(options, particle, link, p1Destinations, pos1, pos2, context);
|
|
36
|
+
}
|
|
37
|
+
if (link.opacity <= minOpacity || width <= minWidth) {
|
|
38
|
+
continue;
|
|
61
39
|
}
|
|
62
|
-
if (
|
|
40
|
+
if (!linkOpts.enable) {
|
|
63
41
|
continue;
|
|
64
42
|
}
|
|
65
43
|
let opacity = link.opacity, colorLine = link.color;
|
|
66
|
-
const
|
|
67
|
-
if (twinkle
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
colorLine = twinkleRgb;
|
|
71
|
-
opacity = getRangeValue(twinkle.opacity);
|
|
72
|
-
}
|
|
44
|
+
const twinkleRgb = twinkle?.enable && getRandom() < twinkle.frequency ? rangeColorToRgb(this._engine, twinkle.color) : undefined;
|
|
45
|
+
if (twinkle && twinkleRgb) {
|
|
46
|
+
colorLine = twinkleRgb;
|
|
47
|
+
opacity = getRangeValue(twinkle.opacity);
|
|
73
48
|
}
|
|
74
49
|
if (!colorLine) {
|
|
75
50
|
const linkColor = linkOpts.id !== undefined
|
|
@@ -80,15 +55,20 @@ export class LinkInstance {
|
|
|
80
55
|
if (!colorLine) {
|
|
81
56
|
continue;
|
|
82
57
|
}
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
58
|
+
const colorStyle = this._getCachedStyle(colorLine);
|
|
59
|
+
if (colorStyle !== currentColorStyle || width !== currentWidth || opacity !== currentAlpha) {
|
|
60
|
+
flushLines();
|
|
61
|
+
context.strokeStyle = colorStyle;
|
|
62
|
+
context.lineWidth = width;
|
|
63
|
+
context.globalAlpha = opacity;
|
|
64
|
+
currentColorStyle = colorStyle;
|
|
65
|
+
currentWidth = width;
|
|
66
|
+
currentAlpha = opacity;
|
|
67
|
+
context.beginPath();
|
|
68
|
+
pathOpen = true;
|
|
88
69
|
}
|
|
89
|
-
const pos2 = link.destination.getPosition();
|
|
90
70
|
if (link.isWarped) {
|
|
91
|
-
const dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
71
|
+
const canvasSize = this._container.canvas.size, dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
92
72
|
let sx = originPoint.x, sy = originPoint.y;
|
|
93
73
|
if (Math.abs(dx) > canvasSize.width * half) {
|
|
94
74
|
sx = dx > minDistance ? -canvasSize.width : canvasSize.width;
|
|
@@ -96,13 +76,18 @@ export class LinkInstance {
|
|
|
96
76
|
if (Math.abs(dy) > canvasSize.height * half) {
|
|
97
77
|
sy = dy > minDistance ? -canvasSize.height : canvasSize.height;
|
|
98
78
|
}
|
|
99
|
-
|
|
100
|
-
|
|
79
|
+
context.moveTo(pos1.x, pos1.y);
|
|
80
|
+
context.lineTo(pos2.x + sx, pos2.y + sy);
|
|
81
|
+
context.moveTo(pos1.x - sx, pos1.y - sy);
|
|
82
|
+
context.lineTo(pos2.x, pos2.y);
|
|
101
83
|
}
|
|
102
84
|
else {
|
|
103
|
-
|
|
85
|
+
context.moveTo(pos1.x, pos1.y);
|
|
86
|
+
context.lineTo(pos2.x, pos2.y);
|
|
104
87
|
}
|
|
105
88
|
}
|
|
89
|
+
flushLines();
|
|
90
|
+
context.globalAlpha = originalAlpha;
|
|
106
91
|
}
|
|
107
92
|
init() {
|
|
108
93
|
this._freqs.links.clear();
|
|
@@ -124,16 +109,15 @@ export class LinkInstance {
|
|
|
124
109
|
particleDestroyed(particle) {
|
|
125
110
|
particle.links = [];
|
|
126
111
|
}
|
|
127
|
-
|
|
112
|
+
_drawTriangles(options, p1, link, p1Destinations, pos1, pos2, context) {
|
|
128
113
|
const p2 = link.destination, triangleOptions = options.links?.triangles;
|
|
129
114
|
if (!triangleOptions?.enable || !p2.options.links?.triangles.enable) {
|
|
130
115
|
return;
|
|
131
116
|
}
|
|
132
|
-
const
|
|
117
|
+
const p2Links = p2.links;
|
|
133
118
|
if (!p2Links?.length) {
|
|
134
119
|
return;
|
|
135
120
|
}
|
|
136
|
-
const pos2 = p2.getPosition();
|
|
137
121
|
for (const vertex of p2Links) {
|
|
138
122
|
if (vertex.isWarped ||
|
|
139
123
|
this._getLinkFrequency(p2, vertex.destination) > p2.options.links.frequency ||
|
|
@@ -144,18 +128,21 @@ export class LinkInstance {
|
|
|
144
128
|
if (this._getTriangleFrequency(p1, p2, p3) > (options.links?.triangles.frequency ?? defaultFrequency)) {
|
|
145
129
|
continue;
|
|
146
130
|
}
|
|
147
|
-
const opacityTriangle =
|
|
148
|
-
if (!colorTriangle) {
|
|
131
|
+
const opacityTriangle = triangleOptions.opacity ?? (link.opacity + vertex.opacity) * half, colorTriangle = rangeColorToRgb(this._engine, triangleOptions.color) ?? link.color;
|
|
132
|
+
if (!colorTriangle || opacityTriangle <= minOpacity) {
|
|
149
133
|
continue;
|
|
150
134
|
}
|
|
151
|
-
const colorStyle = this._getCachedStyle(colorTriangle), key = `${colorStyle}_${opacityTriangle}`;
|
|
152
|
-
let batch = this._triangleBatches.get(key);
|
|
153
|
-
if (!batch) {
|
|
154
|
-
batch = { colorStyle, opacity: opacityTriangle, coords: [] };
|
|
155
|
-
this._triangleBatches.set(key, batch);
|
|
156
|
-
}
|
|
157
135
|
const pos3 = p3.getPosition();
|
|
158
|
-
|
|
136
|
+
context.save();
|
|
137
|
+
context.fillStyle = this._getCachedStyle(colorTriangle);
|
|
138
|
+
context.globalAlpha = opacityTriangle;
|
|
139
|
+
context.beginPath();
|
|
140
|
+
context.moveTo(pos1.x, pos1.y);
|
|
141
|
+
context.lineTo(pos2.x, pos2.y);
|
|
142
|
+
context.lineTo(pos3.x, pos3.y);
|
|
143
|
+
context.closePath();
|
|
144
|
+
context.fill();
|
|
145
|
+
context.restore();
|
|
159
146
|
}
|
|
160
147
|
}
|
|
161
148
|
_getCachedStyle(rgb) {
|
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.28");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const [{ ensureInteractivityPluginLoaded }, { LinksPlugin },] = await Promise.all([
|
|
5
5
|
import("@tsparticles/plugin-interactivity"),
|
|
@@ -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.28
|
|
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, 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, pos1 = particle.getPosition(), linkOpts = options.links;\n for (const link of links){\n if (linkOpts.frequency < maxFrequency && this._getLinkFrequency(particle, link.destination) > linkOpts.frequency) {\n continue;\n }\n if (!link.isWarped) {\n this._collectTriangles(options, particle, link, links, pos1);\n }\n if (link.opacity <= minOpacity || (particle.retina.linksWidth ?? minWidth) <= minWidth) {\n continue;\n }\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 = linkOpts.id !== undefined ? this._container.particles.linksColors.get(linkOpts.id) : this._container.particles.linksColor;\n colorLine = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkColor)(particle, link.destination, linkColor);\n }\n if (!colorLine) {\n continue;\n }\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, 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 init() {\n this._freqs.links.clear();\n this._freqs.triangles.clear();\n this._colorCache.clear();\n return Promise.resolve();\n }\n particleCreated(particle) {\n particle.links = [];\n if (!particle.options.links) {\n return;\n }\n particle.linksDistance = particle.options.links.distance;\n particle.linksWidth = particle.options.links.width;\n const ratio = this._container.retina.pixelRatio;\n particle.retina.linksDistance = particle.linksDistance * ratio;\n particle.retina.linksWidth = particle.linksWidth * ratio;\n }\n particleDestroyed(particle) {\n particle.links = [];\n }\n _collectTriangles(options, p1, link, p1Links, pos1) {\n const p2 = link.destination, triangleOptions = options.links?.triangles;\n if (!triangleOptions?.enable || !p2.options.links?.triangles.enable) {\n return;\n }\n const p1Destinations = new Set(p1Links.map((l)=>l.destination.id)), p2Links = p2.links;\n if (!p2Links?.length) {\n return;\n }\n const pos2 = p2.getPosition();\n for (const vertex of p2Links){\n if (vertex.isWarped || this._getLinkFrequency(p2, vertex.destination) > p2.options.links.frequency || !p1Destinations.has(vertex.destination.id)) {\n continue;\n }\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 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}");
|
|
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, defaultFrequency = 0;\nclass LinkInstance {\n _colorCache = new Map();\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 || !options.links) {\n return;\n }\n const linkOpts = options.links, width = particle.retina.linksWidth ?? minWidth, pos1 = particle.getPosition(), twinkle = particle.options[\"twinkle\"]?.links, trianglesEnabled = linkOpts.triangles.enable, p1Destinations = trianglesEnabled ? new Set(links.map((l)=>l.destination.id)) : null, originalAlpha = context.globalAlpha;\n let currentColorStyle = \"\", currentWidth = -1, currentAlpha = -1, pathOpen = false;\n const flushLines = ()=>{\n if (pathOpen) {\n context.stroke();\n pathOpen = false;\n }\n };\n for (const link of links){\n if (linkOpts.frequency < maxFrequency && this._getLinkFrequency(particle, link.destination) > linkOpts.frequency) {\n continue;\n }\n const pos2 = link.destination.getPosition();\n if (trianglesEnabled && !link.isWarped && p1Destinations) {\n flushLines();\n this._drawTriangles(options, particle, link, p1Destinations, pos1, pos2, context);\n }\n if (link.opacity <= minOpacity || width <= minWidth) {\n continue;\n }\n if (!linkOpts.enable) {\n continue;\n }\n let opacity = link.opacity, colorLine = link.color;\n const twinkleRgb = twinkle?.enable && (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRandom)() < twinkle.frequency ? (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToRgb)(this._engine, twinkle.color) : undefined;\n if (twinkle && twinkleRgb) {\n colorLine = twinkleRgb;\n opacity = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getRangeValue)(twinkle.opacity);\n }\n if (!colorLine) {\n const linkColor = linkOpts.id !== undefined ? this._container.particles.linksColors.get(linkOpts.id) : this._container.particles.linksColor;\n colorLine = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkColor)(particle, link.destination, linkColor);\n }\n if (!colorLine) {\n continue;\n }\n const colorStyle = this._getCachedStyle(colorLine);\n if (colorStyle !== currentColorStyle || width !== currentWidth || opacity !== currentAlpha) {\n flushLines();\n context.strokeStyle = colorStyle;\n context.lineWidth = width;\n context.globalAlpha = opacity;\n currentColorStyle = colorStyle;\n currentWidth = width;\n currentAlpha = opacity;\n context.beginPath();\n pathOpen = true;\n }\n if (link.isWarped) {\n const canvasSize = this._container.canvas.size, 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 context.moveTo(pos1.x, pos1.y);\n context.lineTo(pos2.x + sx, pos2.y + sy);\n context.moveTo(pos1.x - sx, pos1.y - sy);\n context.lineTo(pos2.x, pos2.y);\n } else {\n context.moveTo(pos1.x, pos1.y);\n context.lineTo(pos2.x, pos2.y);\n }\n }\n flushLines();\n context.globalAlpha = originalAlpha;\n }\n init() {\n this._freqs.links.clear();\n this._freqs.triangles.clear();\n this._colorCache.clear();\n return Promise.resolve();\n }\n particleCreated(particle) {\n particle.links = [];\n if (!particle.options.links) {\n return;\n }\n particle.linksDistance = particle.options.links.distance;\n particle.linksWidth = particle.options.links.width;\n const ratio = this._container.retina.pixelRatio;\n particle.retina.linksDistance = particle.linksDistance * ratio;\n particle.retina.linksWidth = particle.linksWidth * ratio;\n }\n particleDestroyed(particle) {\n particle.links = [];\n }\n _drawTriangles(options, p1, link, p1Destinations, pos1, pos2, context) {\n const p2 = link.destination, triangleOptions = options.links?.triangles;\n if (!triangleOptions?.enable || !p2.options.links?.triangles.enable) {\n return;\n }\n const p2Links = p2.links;\n if (!p2Links?.length) {\n return;\n }\n for (const vertex of p2Links){\n if (vertex.isWarped || this._getLinkFrequency(p2, vertex.destination) > p2.options.links.frequency || !p1Destinations.has(vertex.destination.id)) {\n continue;\n }\n const p3 = vertex.destination;\n if (this._getTriangleFrequency(p1, p2, p3) > (options.links?.triangles.frequency ?? defaultFrequency)) {\n continue;\n }\n const opacityTriangle = triangleOptions.opacity ?? (link.opacity + vertex.opacity) * _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.half, colorTriangle = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.rangeColorToRgb)(this._engine, triangleOptions.color) ?? link.color;\n if (!colorTriangle || opacityTriangle <= minOpacity) {\n continue;\n }\n const pos3 = p3.getPosition();\n context.save();\n context.fillStyle = this._getCachedStyle(colorTriangle);\n context.globalAlpha = opacityTriangle;\n context.beginPath();\n context.moveTo(pos1.x, pos1.y);\n context.lineTo(pos2.x, pos2.y);\n context.lineTo(pos3.x, pos3.y);\n context.closePath();\n context.fill();\n context.restore();\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
|
|
package/esm/LinkInstance.js
CHANGED
|
@@ -1,75 +1,50 @@
|
|
|
1
1
|
import { getLinkColor as engineGetLinkColor, getRandom, getRangeValue, getStyleFromRgb, half, originPoint, rangeColorToRgb, } from "@tsparticles/engine";
|
|
2
2
|
import { setLinkFrequency } from "./Utils.js";
|
|
3
|
-
const minOpacity = 0,
|
|
3
|
+
const minOpacity = 0, minWidth = 0, minDistance = 0, maxFrequency = 1, defaultFrequency = 0;
|
|
4
4
|
export class LinkInstance {
|
|
5
5
|
_colorCache = new Map();
|
|
6
6
|
_container;
|
|
7
7
|
_engine;
|
|
8
8
|
_freqs;
|
|
9
|
-
_lineBatches = new Map();
|
|
10
|
-
_triangleBatches = new Map();
|
|
11
9
|
constructor(container, engine) {
|
|
12
10
|
this._container = container;
|
|
13
11
|
this._engine = engine;
|
|
14
12
|
this._freqs = { links: new Map(), triangles: new Map() };
|
|
15
13
|
}
|
|
16
|
-
|
|
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();
|
|
47
|
-
}
|
|
48
|
-
drawParticle(_context, particle) {
|
|
14
|
+
drawParticle(context, particle) {
|
|
49
15
|
const { links, options } = particle;
|
|
50
16
|
if (!links?.length || !options.links) {
|
|
51
17
|
return;
|
|
52
18
|
}
|
|
53
|
-
const
|
|
19
|
+
const linkOpts = options.links, width = particle.retina.linksWidth ?? minWidth, pos1 = particle.getPosition(), twinkle = particle.options["twinkle"]?.links, trianglesEnabled = linkOpts.triangles.enable, p1Destinations = trianglesEnabled ? new Set(links.map(l => l.destination.id)) : null, originalAlpha = context.globalAlpha;
|
|
20
|
+
let currentColorStyle = "", currentWidth = -1, currentAlpha = -1, pathOpen = false;
|
|
21
|
+
const flushLines = () => {
|
|
22
|
+
if (pathOpen) {
|
|
23
|
+
context.stroke();
|
|
24
|
+
pathOpen = false;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
54
27
|
for (const link of links) {
|
|
55
28
|
if (linkOpts.frequency < maxFrequency &&
|
|
56
29
|
this._getLinkFrequency(particle, link.destination) > linkOpts.frequency) {
|
|
57
30
|
continue;
|
|
58
31
|
}
|
|
59
|
-
|
|
60
|
-
|
|
32
|
+
const pos2 = link.destination.getPosition();
|
|
33
|
+
if (trianglesEnabled && !link.isWarped && p1Destinations) {
|
|
34
|
+
flushLines();
|
|
35
|
+
this._drawTriangles(options, particle, link, p1Destinations, pos1, pos2, context);
|
|
36
|
+
}
|
|
37
|
+
if (link.opacity <= minOpacity || width <= minWidth) {
|
|
38
|
+
continue;
|
|
61
39
|
}
|
|
62
|
-
if (
|
|
40
|
+
if (!linkOpts.enable) {
|
|
63
41
|
continue;
|
|
64
42
|
}
|
|
65
43
|
let opacity = link.opacity, colorLine = link.color;
|
|
66
|
-
const
|
|
67
|
-
if (twinkle
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
colorLine = twinkleRgb;
|
|
71
|
-
opacity = getRangeValue(twinkle.opacity);
|
|
72
|
-
}
|
|
44
|
+
const twinkleRgb = twinkle?.enable && getRandom() < twinkle.frequency ? rangeColorToRgb(this._engine, twinkle.color) : undefined;
|
|
45
|
+
if (twinkle && twinkleRgb) {
|
|
46
|
+
colorLine = twinkleRgb;
|
|
47
|
+
opacity = getRangeValue(twinkle.opacity);
|
|
73
48
|
}
|
|
74
49
|
if (!colorLine) {
|
|
75
50
|
const linkColor = linkOpts.id !== undefined
|
|
@@ -80,15 +55,20 @@ export class LinkInstance {
|
|
|
80
55
|
if (!colorLine) {
|
|
81
56
|
continue;
|
|
82
57
|
}
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
58
|
+
const colorStyle = this._getCachedStyle(colorLine);
|
|
59
|
+
if (colorStyle !== currentColorStyle || width !== currentWidth || opacity !== currentAlpha) {
|
|
60
|
+
flushLines();
|
|
61
|
+
context.strokeStyle = colorStyle;
|
|
62
|
+
context.lineWidth = width;
|
|
63
|
+
context.globalAlpha = opacity;
|
|
64
|
+
currentColorStyle = colorStyle;
|
|
65
|
+
currentWidth = width;
|
|
66
|
+
currentAlpha = opacity;
|
|
67
|
+
context.beginPath();
|
|
68
|
+
pathOpen = true;
|
|
88
69
|
}
|
|
89
|
-
const pos2 = link.destination.getPosition();
|
|
90
70
|
if (link.isWarped) {
|
|
91
|
-
const dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
71
|
+
const canvasSize = this._container.canvas.size, dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
92
72
|
let sx = originPoint.x, sy = originPoint.y;
|
|
93
73
|
if (Math.abs(dx) > canvasSize.width * half) {
|
|
94
74
|
sx = dx > minDistance ? -canvasSize.width : canvasSize.width;
|
|
@@ -96,13 +76,18 @@ export class LinkInstance {
|
|
|
96
76
|
if (Math.abs(dy) > canvasSize.height * half) {
|
|
97
77
|
sy = dy > minDistance ? -canvasSize.height : canvasSize.height;
|
|
98
78
|
}
|
|
99
|
-
|
|
100
|
-
|
|
79
|
+
context.moveTo(pos1.x, pos1.y);
|
|
80
|
+
context.lineTo(pos2.x + sx, pos2.y + sy);
|
|
81
|
+
context.moveTo(pos1.x - sx, pos1.y - sy);
|
|
82
|
+
context.lineTo(pos2.x, pos2.y);
|
|
101
83
|
}
|
|
102
84
|
else {
|
|
103
|
-
|
|
85
|
+
context.moveTo(pos1.x, pos1.y);
|
|
86
|
+
context.lineTo(pos2.x, pos2.y);
|
|
104
87
|
}
|
|
105
88
|
}
|
|
89
|
+
flushLines();
|
|
90
|
+
context.globalAlpha = originalAlpha;
|
|
106
91
|
}
|
|
107
92
|
init() {
|
|
108
93
|
this._freqs.links.clear();
|
|
@@ -124,16 +109,15 @@ export class LinkInstance {
|
|
|
124
109
|
particleDestroyed(particle) {
|
|
125
110
|
particle.links = [];
|
|
126
111
|
}
|
|
127
|
-
|
|
112
|
+
_drawTriangles(options, p1, link, p1Destinations, pos1, pos2, context) {
|
|
128
113
|
const p2 = link.destination, triangleOptions = options.links?.triangles;
|
|
129
114
|
if (!triangleOptions?.enable || !p2.options.links?.triangles.enable) {
|
|
130
115
|
return;
|
|
131
116
|
}
|
|
132
|
-
const
|
|
117
|
+
const p2Links = p2.links;
|
|
133
118
|
if (!p2Links?.length) {
|
|
134
119
|
return;
|
|
135
120
|
}
|
|
136
|
-
const pos2 = p2.getPosition();
|
|
137
121
|
for (const vertex of p2Links) {
|
|
138
122
|
if (vertex.isWarped ||
|
|
139
123
|
this._getLinkFrequency(p2, vertex.destination) > p2.options.links.frequency ||
|
|
@@ -144,18 +128,21 @@ export class LinkInstance {
|
|
|
144
128
|
if (this._getTriangleFrequency(p1, p2, p3) > (options.links?.triangles.frequency ?? defaultFrequency)) {
|
|
145
129
|
continue;
|
|
146
130
|
}
|
|
147
|
-
const opacityTriangle =
|
|
148
|
-
if (!colorTriangle) {
|
|
131
|
+
const opacityTriangle = triangleOptions.opacity ?? (link.opacity + vertex.opacity) * half, colorTriangle = rangeColorToRgb(this._engine, triangleOptions.color) ?? link.color;
|
|
132
|
+
if (!colorTriangle || opacityTriangle <= minOpacity) {
|
|
149
133
|
continue;
|
|
150
134
|
}
|
|
151
|
-
const colorStyle = this._getCachedStyle(colorTriangle), key = `${colorStyle}_${opacityTriangle}`;
|
|
152
|
-
let batch = this._triangleBatches.get(key);
|
|
153
|
-
if (!batch) {
|
|
154
|
-
batch = { colorStyle, opacity: opacityTriangle, coords: [] };
|
|
155
|
-
this._triangleBatches.set(key, batch);
|
|
156
|
-
}
|
|
157
135
|
const pos3 = p3.getPosition();
|
|
158
|
-
|
|
136
|
+
context.save();
|
|
137
|
+
context.fillStyle = this._getCachedStyle(colorTriangle);
|
|
138
|
+
context.globalAlpha = opacityTriangle;
|
|
139
|
+
context.beginPath();
|
|
140
|
+
context.moveTo(pos1.x, pos1.y);
|
|
141
|
+
context.lineTo(pos2.x, pos2.y);
|
|
142
|
+
context.lineTo(pos3.x, pos3.y);
|
|
143
|
+
context.closePath();
|
|
144
|
+
context.fill();
|
|
145
|
+
context.restore();
|
|
159
146
|
}
|
|
160
147
|
}
|
|
161
148
|
_getCachedStyle(rgb) {
|
package/esm/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.28");
|
|
3
3
|
await engine.register(async (e) => {
|
|
4
4
|
const [{ ensureInteractivityPluginLoaded }, { LinksPlugin },] = await Promise.all([
|
|
5
5
|
import("@tsparticles/plugin-interactivity"),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsparticles/interaction-particles-links",
|
|
3
|
-
"version": "4.0.0-alpha.
|
|
3
|
+
"version": "4.0.0-alpha.28",
|
|
4
4
|
"description": "tsParticles links particles interaction",
|
|
5
5
|
"homepage": "https://particles.js.org",
|
|
6
6
|
"repository": {
|
|
@@ -87,9 +87,9 @@
|
|
|
87
87
|
"./package.json": "./package.json"
|
|
88
88
|
},
|
|
89
89
|
"dependencies": {
|
|
90
|
-
"@tsparticles/canvas-utils": "4.0.0-alpha.
|
|
91
|
-
"@tsparticles/engine": "4.0.0-alpha.
|
|
92
|
-
"@tsparticles/plugin-interactivity": "4.0.0-alpha.
|
|
90
|
+
"@tsparticles/canvas-utils": "4.0.0-alpha.28",
|
|
91
|
+
"@tsparticles/engine": "4.0.0-alpha.28",
|
|
92
|
+
"@tsparticles/plugin-interactivity": "4.0.0-alpha.28"
|
|
93
93
|
},
|
|
94
94
|
"publishConfig": {
|
|
95
95
|
"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 [15 Mar 2026 at 13:48]</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>
|
|
@@ -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.28
|
|
8
8
|
*/
|
|
9
9
|
/*
|
|
10
10
|
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
|
|
@@ -84,7 +84,7 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
|
|
|
84
84
|
\*******************************/
|
|
85
85
|
(__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) {
|
|
86
86
|
|
|
87
|
-
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Links: () => (/* reexport safe */ _Options_Classes_Links_js__WEBPACK_IMPORTED_MODULE_0__.Links),\n/* harmony export */ LinksShadow: () => (/* reexport safe */ _Options_Classes_LinksShadow_js__WEBPACK_IMPORTED_MODULE_1__.LinksShadow),\n/* harmony export */ LinksTriangle: () => (/* reexport safe */ _Options_Classes_LinksTriangle_js__WEBPACK_IMPORTED_MODULE_2__.LinksTriangle),\n/* harmony export */ loadParticlesLinksInteraction: () => (/* binding */ loadParticlesLinksInteraction)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_Links_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/Links.js */ \"./dist/browser/Options/Classes/Links.js\");\n/* harmony import */ var _Options_Classes_LinksShadow_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/LinksShadow.js */ \"./dist/browser/Options/Classes/LinksShadow.js\");\n/* harmony import */ var _Options_Classes_LinksTriangle_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/LinksTriangle.js */ \"./dist/browser/Options/Classes/LinksTriangle.js\");\nasync function loadParticlesLinksInteraction(engine) {\n engine.checkVersion(\"4.0.0-alpha.
|
|
87
|
+
eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Links: () => (/* reexport safe */ _Options_Classes_Links_js__WEBPACK_IMPORTED_MODULE_0__.Links),\n/* harmony export */ LinksShadow: () => (/* reexport safe */ _Options_Classes_LinksShadow_js__WEBPACK_IMPORTED_MODULE_1__.LinksShadow),\n/* harmony export */ LinksTriangle: () => (/* reexport safe */ _Options_Classes_LinksTriangle_js__WEBPACK_IMPORTED_MODULE_2__.LinksTriangle),\n/* harmony export */ loadParticlesLinksInteraction: () => (/* binding */ loadParticlesLinksInteraction)\n/* harmony export */ });\n/* harmony import */ var _Options_Classes_Links_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Options/Classes/Links.js */ \"./dist/browser/Options/Classes/Links.js\");\n/* harmony import */ var _Options_Classes_LinksShadow_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./Options/Classes/LinksShadow.js */ \"./dist/browser/Options/Classes/LinksShadow.js\");\n/* harmony import */ var _Options_Classes_LinksTriangle_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/LinksTriangle.js */ \"./dist/browser/Options/Classes/LinksTriangle.js\");\nasync function loadParticlesLinksInteraction(engine) {\n engine.checkVersion(\"4.0.0-alpha.28\");\n await engine.register(async (e)=>{\n const [{ ensureInteractivityPluginLoaded }, { LinksPlugin }] = await Promise.all([\n Promise.resolve(/*! import() */).then(__webpack_require__.t.bind(__webpack_require__, /*! @tsparticles/plugin-interactivity */ \"@tsparticles/plugin-interactivity\", 19)),\n __webpack_require__.e(/*! import() */ \"dist_browser_LinksPlugin_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./LinksPlugin.js */ \"./dist/browser/LinksPlugin.js\"))\n ]);\n ensureInteractivityPluginLoaded(e);\n e.addPlugin(new LinksPlugin(e));\n e.addInteractor?.(\"particlesLinks\", async (container)=>{\n const { Linker } = await __webpack_require__.e(/*! import() */ \"dist_browser_Linker_js\").then(__webpack_require__.bind(__webpack_require__, /*! ./Linker.js */ \"./dist/browser/Linker.js\"));\n return new Linker(container, e);\n });\n });\n}\n\n\n\n\n\n//# sourceURL=webpack://@tsparticles/interaction-particles-links/./dist/browser/index.js?\n}");
|
|
88
88
|
|
|
89
89
|
/***/ }
|
|
90
90
|
|
|
@@ -100,12 +100,6 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
|
|
|
100
100
|
/******/ if (cachedModule !== undefined) {
|
|
101
101
|
/******/ return cachedModule.exports;
|
|
102
102
|
/******/ }
|
|
103
|
-
/******/ // Check if module exists (development only)
|
|
104
|
-
/******/ if (__webpack_modules__[moduleId] === undefined) {
|
|
105
|
-
/******/ var e = new Error("Cannot find module '" + moduleId + "'");
|
|
106
|
-
/******/ e.code = 'MODULE_NOT_FOUND';
|
|
107
|
-
/******/ throw e;
|
|
108
|
-
/******/ }
|
|
109
103
|
/******/ // Create a new module (and put it into the cache)
|
|
110
104
|
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
111
105
|
/******/ // no module.id needed
|
|
@@ -114,6 +108,12 @@ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpa
|
|
|
114
108
|
/******/ };
|
|
115
109
|
/******/
|
|
116
110
|
/******/ // Execute the module function
|
|
111
|
+
/******/ if (!(moduleId in __webpack_modules__)) {
|
|
112
|
+
/******/ delete __webpack_module_cache__[moduleId];
|
|
113
|
+
/******/ var e = new Error("Cannot find module '" + moduleId + "'");
|
|
114
|
+
/******/ e.code = 'MODULE_NOT_FOUND';
|
|
115
|
+
/******/ throw e;
|
|
116
|
+
/******/ }
|
|
117
117
|
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
118
118
|
/******/
|
|
119
119
|
/******/ // Return the exports of the module
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"),require("@tsparticles/plugin-interactivity"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine","@tsparticles/plugin-interactivity"],t);else{var r="object"==typeof exports?t(require("@tsparticles/engine"),require("@tsparticles/plugin-interactivity")):t(e.window,e.window);for(var i in r)("object"==typeof exports?exports:e)[i]=r[i]}}(this,(e,t)=>(()=>{"use strict";var r,i,o,n={303(t){t.exports=e},702(e){e.exports=t},
|
|
2
|
-
(`+o+": "+n+")",s.name="ChunkLoadError",s.type=o,s.request=n,i[1](s)}},"chunk-"+e,e)}},i=(e,t)=>{var i,o,[n,s,l]=t,c=0;if(n.some(e=>0!==r[e])){for(i in s)a.o(s,i)&&(a.m[i]=s[i]);l&&l(a)}for(e&&e(t);c<n.length;c++)o=n[c],a.o(r,o)&&r[o]&&r[o][0](),r[o]=0},(o=this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).forEach(i.bind(null,0)),o.push=i.bind(null,o.push.bind(o));var b={};a.r(b),a.d(b,{Links:()=>v.q,LinksShadow:()=>y.s,LinksTriangle:()=>g.G,loadParticlesLinksInteraction:()=>w});var v=a(
|
|
1
|
+
!function(e,t){if("object"==typeof exports&&"object"==typeof module)module.exports=t(require("@tsparticles/engine"),require("@tsparticles/plugin-interactivity"));else if("function"==typeof define&&define.amd)define(["@tsparticles/engine","@tsparticles/plugin-interactivity"],t);else{var r="object"==typeof exports?t(require("@tsparticles/engine"),require("@tsparticles/plugin-interactivity")):t(e.window,e.window);for(var i in r)("object"==typeof exports?exports:e)[i]=r[i]}}(this,(e,t)=>(()=>{"use strict";var r,i,o,n={303(t){t.exports=e},702(e){e.exports=t},348(e,t,r){r.d(t,{q:()=>s});var i=r(303),o=r(724),n=r(200);class s{blink;color;consent;distance;enable;frequency;id;opacity;shadow;triangles;warp;width;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 o.s,this.triangles=new n.G,this.width=1,this.warp=!1}load(e){(0,i.isNull)(e)||(void 0!==e.id&&(this.id=e.id),void 0!==e.blink&&(this.blink=e.blink),this.color=i.OptionsColor.create(this.color,e.color),void 0!==e.consent&&(this.consent=e.consent),void 0!==e.distance&&(this.distance=e.distance),void 0!==e.enable&&(this.enable=e.enable),void 0!==e.frequency&&(this.frequency=e.frequency),void 0!==e.opacity&&(this.opacity=e.opacity),this.shadow.load(e.shadow),this.triangles.load(e.triangles),void 0!==e.width&&(this.width=e.width),void 0!==e.warp&&(this.warp=e.warp))}}},724(e,t,r){r.d(t,{s:()=>o});var i=r(303);class o{blur;color;enable;constructor(){this.blur=5,this.color=new i.OptionsColor,this.color.value="#000",this.enable=!1}load(e){(0,i.isNull)(e)||(void 0!==e.blur&&(this.blur=e.blur),this.color=i.OptionsColor.create(this.color,e.color),void 0!==e.enable&&(this.enable=e.enable))}}},200(e,t,r){r.d(t,{G:()=>o});var i=r(303);class o{color;enable;frequency;opacity;constructor(){this.enable=!1,this.frequency=1}load(e){(0,i.isNull)(e)||(void 0!==e.color&&(this.color=i.OptionsColor.create(this.color,e.color)),void 0!==e.enable&&(this.enable=e.enable),void 0!==e.frequency&&(this.frequency=e.frequency),void 0!==e.opacity&&(this.opacity=e.opacity))}}}},s={};function a(e){var t=s[e];if(void 0!==t)return t.exports;var r=s[e]={exports:{}};return n[e](r,r.exports,a),r.exports}a.m=n,c=Object.getPrototypeOf?e=>Object.getPrototypeOf(e):e=>e.__proto__,a.t=function(e,t){if(1&t&&(e=this(e)),8&t||"object"==typeof e&&e&&(4&t&&e.__esModule||16&t&&"function"==typeof e.then))return e;var r=Object.create(null);a.r(r);var i={};l=l||[null,c({}),c([]),c(c)];for(var o=2&t&&e;("object"==typeof o||"function"==typeof o)&&!~l.indexOf(o);o=c(o))Object.getOwnPropertyNames(o).forEach(t=>i[t]=()=>e[t]);return i.default=()=>e,a.d(r,i),r},a.d=(e,t)=>{for(var r in t)a.o(t,r)&&!a.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},a.f={},a.e=e=>Promise.all(Object.keys(a.f).reduce((t,r)=>(a.f[r](e,t),t),[])),a.u=e=>""+e+".min.js",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||Function("return this")()}catch(e){if("object"==typeof window)return window}}(),a.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),p={},a.l=(e,t,r,i)=>{if(p[e])return void p[e].push(t);if(void 0!==r)for(var o,n,s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var c=s[l];if(c.getAttribute("src")==e||c.getAttribute("data-webpack")=="@tsparticles/interaction-particles-links:"+r){o=c;break}}o||(n=!0,(o=document.createElement("script")).charset="utf-8",a.nc&&o.setAttribute("nonce",a.nc),o.setAttribute("data-webpack","@tsparticles/interaction-particles-links:"+r),o.src=e),p[e]=[t];var d=(t,r)=>{o.onerror=o.onload=null,clearTimeout(u);var i=p[e];if(delete p[e],o.parentNode&&o.parentNode.removeChild(o),i&&i.forEach(e=>e(r)),t)return t(r)},u=setTimeout(d.bind(null,void 0,{type:"timeout",target:o}),12e4);o.onerror=d.bind(null,o.onerror),o.onload=d.bind(null,o.onload),n&&document.head.appendChild(o)},a.r=e=>{"u">typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.g.importScripts&&(d=a.g.location+"");var l,c,p,d,u=a.g.document;if(!d&&u&&(u.currentScript&&"SCRIPT"===u.currentScript.tagName.toUpperCase()&&(d=u.currentScript.src),!d)){var h=u.getElementsByTagName("script");if(h.length)for(var f=h.length-1;f>-1&&(!d||!/^http(s?):/.test(d));)d=h[f--].src}if(!d)throw Error("Automatic publicPath is not supported in this browser");a.p=d=d.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),r={203:0},a.f.j=(e,t)=>{var i=a.o(r,e)?r[e]:void 0;if(0!==i)if(i)t.push(i[2]);else{var o=new Promise((t,o)=>i=r[e]=[t,o]);t.push(i[2]=o);var n=a.p+a.u(e),s=Error();a.l(n,t=>{if(a.o(r,e)&&(0!==(i=r[e])&&(r[e]=void 0),i)){var o=t&&("load"===t.type?"missing":t.type),n=t&&t.target&&t.target.src;s.message="Loading chunk "+e+` failed.
|
|
2
|
+
(`+o+": "+n+")",s.name="ChunkLoadError",s.type=o,s.request=n,i[1](s)}},"chunk-"+e,e)}},i=(e,t)=>{var i,o,[n,s,l]=t,c=0;if(n.some(e=>0!==r[e])){for(i in s)a.o(s,i)&&(a.m[i]=s[i]);l&&l(a)}for(e&&e(t);c<n.length;c++)o=n[c],a.o(r,o)&&r[o]&&r[o][0](),r[o]=0},(o=this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).forEach(i.bind(null,0)),o.push=i.bind(null,o.push.bind(o));var b={};a.r(b),a.d(b,{Links:()=>v.q,LinksShadow:()=>y.s,LinksTriangle:()=>g.G,loadParticlesLinksInteraction:()=>w});var v=a(348),y=a(724),g=a(200);async function w(e){e.checkVersion("4.0.0-alpha.28"),await e.register(async e=>{let[{ensureInteractivityPluginLoaded:t},{LinksPlugin:r}]=await Promise.all([Promise.resolve().then(a.t.bind(a,702,19)),a.e(13).then(a.bind(a,13))]);t(e),e.addPlugin(new r(e)),e.addInteractor?.("particlesLinks",async t=>{let{Linker:r}=await a.e(342).then(a.bind(a,342));return new r(t,e)})})}return b})());
|
package/types/Interfaces.d.ts
CHANGED
package/types/LinkInstance.d.ts
CHANGED
|
@@ -5,15 +5,12 @@ export declare class LinkInstance implements IContainerPlugin {
|
|
|
5
5
|
private readonly _container;
|
|
6
6
|
private readonly _engine;
|
|
7
7
|
private readonly _freqs;
|
|
8
|
-
private readonly _lineBatches;
|
|
9
|
-
private readonly _triangleBatches;
|
|
10
8
|
constructor(container: LinkContainer, engine: Engine);
|
|
11
|
-
|
|
12
|
-
drawParticle(_context: CanvasRenderingContext2D, particle: LinkParticle): void;
|
|
9
|
+
drawParticle(context: CanvasRenderingContext2D, particle: LinkParticle): void;
|
|
13
10
|
init(): Promise<void>;
|
|
14
11
|
particleCreated(particle: LinkParticle): void;
|
|
15
12
|
particleDestroyed(particle: LinkParticle): void;
|
|
16
|
-
private
|
|
13
|
+
private _drawTriangles;
|
|
17
14
|
private _getCachedStyle;
|
|
18
15
|
private _getLinkFrequency;
|
|
19
16
|
private _getTriangleFrequency;
|
package/umd/LinkInstance.js
CHANGED
|
@@ -12,76 +12,51 @@
|
|
|
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,
|
|
15
|
+
const minOpacity = 0, minWidth = 0, minDistance = 0, maxFrequency = 1, defaultFrequency = 0;
|
|
16
16
|
class LinkInstance {
|
|
17
17
|
_colorCache = new Map();
|
|
18
18
|
_container;
|
|
19
19
|
_engine;
|
|
20
20
|
_freqs;
|
|
21
|
-
_lineBatches = new Map();
|
|
22
|
-
_triangleBatches = new Map();
|
|
23
21
|
constructor(container, engine) {
|
|
24
22
|
this._container = container;
|
|
25
23
|
this._engine = engine;
|
|
26
24
|
this._freqs = { links: new Map(), triangles: new Map() };
|
|
27
25
|
}
|
|
28
|
-
|
|
29
|
-
for (const [, batch] of this._triangleBatches) {
|
|
30
|
-
context.save();
|
|
31
|
-
context.fillStyle = batch.colorStyle;
|
|
32
|
-
context.globalAlpha = batch.opacity;
|
|
33
|
-
context.beginPath();
|
|
34
|
-
for (let i = 0; i < batch.coords.length; i += triangleCoordsCount) {
|
|
35
|
-
const x1 = batch.coords[i + x1Offset] ?? engine_1.originPoint.x, y1 = batch.coords[i + y1Offset] ?? engine_1.originPoint.y, x2 = batch.coords[i + x2Offset] ?? engine_1.originPoint.x, y2 = batch.coords[i + y2Offset] ?? engine_1.originPoint.y, x3 = batch.coords[i + x3Offset] ?? engine_1.originPoint.x, y3 = batch.coords[i + y3Offset] ?? engine_1.originPoint.y;
|
|
36
|
-
context.moveTo(x1, y1);
|
|
37
|
-
context.lineTo(x2, y2);
|
|
38
|
-
context.lineTo(x3, y3);
|
|
39
|
-
}
|
|
40
|
-
context.fill();
|
|
41
|
-
context.restore();
|
|
42
|
-
}
|
|
43
|
-
for (const [, batch] of this._lineBatches) {
|
|
44
|
-
context.save();
|
|
45
|
-
context.strokeStyle = batch.colorStyle;
|
|
46
|
-
context.lineWidth = batch.width;
|
|
47
|
-
context.globalAlpha = batch.opacity;
|
|
48
|
-
context.beginPath();
|
|
49
|
-
for (let i = 0; i < batch.coords.length; i += lineCoordsCount) {
|
|
50
|
-
const x1 = batch.coords[i + x1Offset] ?? engine_1.originPoint.x, y1 = batch.coords[i + y1Offset] ?? engine_1.originPoint.y, x2 = batch.coords[i + x2Offset] ?? engine_1.originPoint.x, y2 = batch.coords[i + y2Offset] ?? engine_1.originPoint.y;
|
|
51
|
-
context.moveTo(x1, y1);
|
|
52
|
-
context.lineTo(x2, y2);
|
|
53
|
-
}
|
|
54
|
-
context.stroke();
|
|
55
|
-
context.restore();
|
|
56
|
-
}
|
|
57
|
-
this._lineBatches.clear();
|
|
58
|
-
this._triangleBatches.clear();
|
|
59
|
-
}
|
|
60
|
-
drawParticle(_context, particle) {
|
|
26
|
+
drawParticle(context, particle) {
|
|
61
27
|
const { links, options } = particle;
|
|
62
28
|
if (!links?.length || !options.links) {
|
|
63
29
|
return;
|
|
64
30
|
}
|
|
65
|
-
const
|
|
31
|
+
const linkOpts = options.links, width = particle.retina.linksWidth ?? minWidth, pos1 = particle.getPosition(), twinkle = particle.options["twinkle"]?.links, trianglesEnabled = linkOpts.triangles.enable, p1Destinations = trianglesEnabled ? new Set(links.map(l => l.destination.id)) : null, originalAlpha = context.globalAlpha;
|
|
32
|
+
let currentColorStyle = "", currentWidth = -1, currentAlpha = -1, pathOpen = false;
|
|
33
|
+
const flushLines = () => {
|
|
34
|
+
if (pathOpen) {
|
|
35
|
+
context.stroke();
|
|
36
|
+
pathOpen = false;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
66
39
|
for (const link of links) {
|
|
67
40
|
if (linkOpts.frequency < maxFrequency &&
|
|
68
41
|
this._getLinkFrequency(particle, link.destination) > linkOpts.frequency) {
|
|
69
42
|
continue;
|
|
70
43
|
}
|
|
71
|
-
|
|
72
|
-
|
|
44
|
+
const pos2 = link.destination.getPosition();
|
|
45
|
+
if (trianglesEnabled && !link.isWarped && p1Destinations) {
|
|
46
|
+
flushLines();
|
|
47
|
+
this._drawTriangles(options, particle, link, p1Destinations, pos1, pos2, context);
|
|
48
|
+
}
|
|
49
|
+
if (link.opacity <= minOpacity || width <= minWidth) {
|
|
50
|
+
continue;
|
|
73
51
|
}
|
|
74
|
-
if (
|
|
52
|
+
if (!linkOpts.enable) {
|
|
75
53
|
continue;
|
|
76
54
|
}
|
|
77
55
|
let opacity = link.opacity, colorLine = link.color;
|
|
78
|
-
const
|
|
79
|
-
if (twinkle
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
colorLine = twinkleRgb;
|
|
83
|
-
opacity = (0, engine_1.getRangeValue)(twinkle.opacity);
|
|
84
|
-
}
|
|
56
|
+
const twinkleRgb = twinkle?.enable && (0, engine_1.getRandom)() < twinkle.frequency ? (0, engine_1.rangeColorToRgb)(this._engine, twinkle.color) : undefined;
|
|
57
|
+
if (twinkle && twinkleRgb) {
|
|
58
|
+
colorLine = twinkleRgb;
|
|
59
|
+
opacity = (0, engine_1.getRangeValue)(twinkle.opacity);
|
|
85
60
|
}
|
|
86
61
|
if (!colorLine) {
|
|
87
62
|
const linkColor = linkOpts.id !== undefined
|
|
@@ -92,15 +67,20 @@
|
|
|
92
67
|
if (!colorLine) {
|
|
93
68
|
continue;
|
|
94
69
|
}
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
70
|
+
const colorStyle = this._getCachedStyle(colorLine);
|
|
71
|
+
if (colorStyle !== currentColorStyle || width !== currentWidth || opacity !== currentAlpha) {
|
|
72
|
+
flushLines();
|
|
73
|
+
context.strokeStyle = colorStyle;
|
|
74
|
+
context.lineWidth = width;
|
|
75
|
+
context.globalAlpha = opacity;
|
|
76
|
+
currentColorStyle = colorStyle;
|
|
77
|
+
currentWidth = width;
|
|
78
|
+
currentAlpha = opacity;
|
|
79
|
+
context.beginPath();
|
|
80
|
+
pathOpen = true;
|
|
100
81
|
}
|
|
101
|
-
const pos2 = link.destination.getPosition();
|
|
102
82
|
if (link.isWarped) {
|
|
103
|
-
const dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
83
|
+
const canvasSize = this._container.canvas.size, dx = pos2.x - pos1.x, dy = pos2.y - pos1.y;
|
|
104
84
|
let sx = engine_1.originPoint.x, sy = engine_1.originPoint.y;
|
|
105
85
|
if (Math.abs(dx) > canvasSize.width * engine_1.half) {
|
|
106
86
|
sx = dx > minDistance ? -canvasSize.width : canvasSize.width;
|
|
@@ -108,13 +88,18 @@
|
|
|
108
88
|
if (Math.abs(dy) > canvasSize.height * engine_1.half) {
|
|
109
89
|
sy = dy > minDistance ? -canvasSize.height : canvasSize.height;
|
|
110
90
|
}
|
|
111
|
-
|
|
112
|
-
|
|
91
|
+
context.moveTo(pos1.x, pos1.y);
|
|
92
|
+
context.lineTo(pos2.x + sx, pos2.y + sy);
|
|
93
|
+
context.moveTo(pos1.x - sx, pos1.y - sy);
|
|
94
|
+
context.lineTo(pos2.x, pos2.y);
|
|
113
95
|
}
|
|
114
96
|
else {
|
|
115
|
-
|
|
97
|
+
context.moveTo(pos1.x, pos1.y);
|
|
98
|
+
context.lineTo(pos2.x, pos2.y);
|
|
116
99
|
}
|
|
117
100
|
}
|
|
101
|
+
flushLines();
|
|
102
|
+
context.globalAlpha = originalAlpha;
|
|
118
103
|
}
|
|
119
104
|
init() {
|
|
120
105
|
this._freqs.links.clear();
|
|
@@ -136,16 +121,15 @@
|
|
|
136
121
|
particleDestroyed(particle) {
|
|
137
122
|
particle.links = [];
|
|
138
123
|
}
|
|
139
|
-
|
|
124
|
+
_drawTriangles(options, p1, link, p1Destinations, pos1, pos2, context) {
|
|
140
125
|
const p2 = link.destination, triangleOptions = options.links?.triangles;
|
|
141
126
|
if (!triangleOptions?.enable || !p2.options.links?.triangles.enable) {
|
|
142
127
|
return;
|
|
143
128
|
}
|
|
144
|
-
const
|
|
129
|
+
const p2Links = p2.links;
|
|
145
130
|
if (!p2Links?.length) {
|
|
146
131
|
return;
|
|
147
132
|
}
|
|
148
|
-
const pos2 = p2.getPosition();
|
|
149
133
|
for (const vertex of p2Links) {
|
|
150
134
|
if (vertex.isWarped ||
|
|
151
135
|
this._getLinkFrequency(p2, vertex.destination) > p2.options.links.frequency ||
|
|
@@ -156,18 +140,21 @@
|
|
|
156
140
|
if (this._getTriangleFrequency(p1, p2, p3) > (options.links?.triangles.frequency ?? defaultFrequency)) {
|
|
157
141
|
continue;
|
|
158
142
|
}
|
|
159
|
-
const opacityTriangle =
|
|
160
|
-
if (!colorTriangle) {
|
|
143
|
+
const opacityTriangle = triangleOptions.opacity ?? (link.opacity + vertex.opacity) * engine_1.half, colorTriangle = (0, engine_1.rangeColorToRgb)(this._engine, triangleOptions.color) ?? link.color;
|
|
144
|
+
if (!colorTriangle || opacityTriangle <= minOpacity) {
|
|
161
145
|
continue;
|
|
162
146
|
}
|
|
163
|
-
const colorStyle = this._getCachedStyle(colorTriangle), key = `${colorStyle}_${opacityTriangle}`;
|
|
164
|
-
let batch = this._triangleBatches.get(key);
|
|
165
|
-
if (!batch) {
|
|
166
|
-
batch = { colorStyle, opacity: opacityTriangle, coords: [] };
|
|
167
|
-
this._triangleBatches.set(key, batch);
|
|
168
|
-
}
|
|
169
147
|
const pos3 = p3.getPosition();
|
|
170
|
-
|
|
148
|
+
context.save();
|
|
149
|
+
context.fillStyle = this._getCachedStyle(colorTriangle);
|
|
150
|
+
context.globalAlpha = opacityTriangle;
|
|
151
|
+
context.beginPath();
|
|
152
|
+
context.moveTo(pos1.x, pos1.y);
|
|
153
|
+
context.lineTo(pos2.x, pos2.y);
|
|
154
|
+
context.lineTo(pos3.x, pos3.y);
|
|
155
|
+
context.closePath();
|
|
156
|
+
context.fill();
|
|
157
|
+
context.restore();
|
|
171
158
|
}
|
|
172
159
|
}
|
|
173
160
|
_getCachedStyle(rgb) {
|
package/umd/index.js
CHANGED
|
@@ -48,7 +48,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
49
|
exports.loadParticlesLinksInteraction = loadParticlesLinksInteraction;
|
|
50
50
|
async function loadParticlesLinksInteraction(engine) {
|
|
51
|
-
engine.checkVersion("4.0.0-alpha.
|
|
51
|
+
engine.checkVersion("4.0.0-alpha.28");
|
|
52
52
|
await engine.register(async (e) => {
|
|
53
53
|
const [{ ensureInteractivityPluginLoaded }, { LinksPlugin },] = await Promise.all([
|
|
54
54
|
__syncRequire ? Promise.resolve().then(() => __importStar(require("@tsparticles/plugin-interactivity"))) : new Promise((resolve_1, reject_1) => { require(["@tsparticles/plugin-interactivity"], resolve_1, reject_1); }).then(__importStar),
|
package/463.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[463],{463(i,e,t){t.d(e,{LinkInstance:()=>s});var n=t(303);function o(i,e){let t=[...i.map(i=>i.id)].sort((i,e)=>i-e).join("_"),o=e.get(t);return void 0===o&&(o=(0,n.getRandom)(),e.set(t,o)),o}class s{_colorCache=new Map;_container;_engine;_freqs;_lineBatches=new Map;_triangleBatches=new Map;constructor(i,e){this._container=i,this._engine=e,this._freqs={links:new Map,triangles:new Map}}draw(i){for(let[,e]of this._triangleBatches){i.save(),i.fillStyle=e.colorStyle,i.globalAlpha=e.opacity,i.beginPath();for(let t=0;t<e.coords.length;t+=6){let o=e.coords[t+0]??n.originPoint.x,s=e.coords[t+1]??n.originPoint.y,r=e.coords[t+2]??n.originPoint.x,l=e.coords[t+3]??n.originPoint.y,a=e.coords[t+4]??n.originPoint.x,c=e.coords[t+5]??n.originPoint.y;i.moveTo(o,s),i.lineTo(r,l),i.lineTo(a,c)}i.fill(),i.restore()}for(let[,e]of this._lineBatches){i.save(),i.strokeStyle=e.colorStyle,i.lineWidth=e.width,i.globalAlpha=e.opacity,i.beginPath();for(let t=0;t<e.coords.length;t+=4){let o=e.coords[t+0]??n.originPoint.x,s=e.coords[t+1]??n.originPoint.y,r=e.coords[t+2]??n.originPoint.x,l=e.coords[t+3]??n.originPoint.y;i.moveTo(o,s),i.lineTo(r,l)}i.stroke(),i.restore()}this._lineBatches.clear(),this._triangleBatches.clear()}drawParticle(i,e){let{links:t,options:o}=e;if(!t?.length||!o.links)return;let s=this._container.canvas.size,r=e.getPosition(),l=o.links;for(let i of t){if(l.frequency<1&&this._getLinkFrequency(e,i.destination)>l.frequency||(i.isWarped||this._collectTriangles(o,e,i,t,r),i.opacity<=0||(e.retina.linksWidth??0)<=0))continue;let a=i.opacity,c=i.color,h=e.options.twinkle?.lines;if(h?.enable&&(0,n.getRandom)()<h.frequency){let i=(0,n.rangeColorToRgb)(this._engine,h.color);i&&(c=i,a=(0,n.getRangeValue)(h.opacity))}if(!c){let t=void 0!==l.id?this._container.particles.linksColors.get(l.id):this._container.particles.linksColor;c=(0,n.getLinkColor)(e,i.destination,t)}if(!c)continue;let g=Math.ceil(10*a)/10,d=this._getCachedStyle(c),_=e.retina.linksWidth??0,y=`${d}_${g}_${_}`,p=this._lineBatches.get(y);p||(p={colorStyle:d,opacity:g,width:_,coords:[]},this._lineBatches.set(y,p));let f=i.destination.getPosition();if(i.isWarped){let i=f.x-r.x,e=f.y-r.y,t=n.originPoint.x,o=n.originPoint.y;Math.abs(i)>s.width*n.half&&(t=i>0?-s.width:s.width),Math.abs(e)>s.height*n.half&&(o=e>0?-s.height:s.height);let l={x:f.x+t,y:f.y+o},a={x:r.x-t,y:r.y-o};p.coords.push(r.x,r.y,l.x,l.y,a.x,a.y,f.x,f.y)}else p.coords.push(r.x,r.y,f.x,f.y)}}init(){return this._freqs.links.clear(),this._freqs.triangles.clear(),this._colorCache.clear(),Promise.resolve()}particleCreated(i){if(i.links=[],!i.options.links)return;i.linksDistance=i.options.links.distance,i.linksWidth=i.options.links.width;let e=this._container.retina.pixelRatio;i.retina.linksDistance=i.linksDistance*e,i.retina.linksWidth=i.linksWidth*e}particleDestroyed(i){i.links=[]}_collectTriangles(i,e,t,o,s){let r=t.destination,l=i.links?.triangles;if(!l?.enable||!r.options.links?.triangles.enable)return;let a=new Set(o.map(i=>i.destination.id)),c=r.links;if(!c?.length)return;let h=r.getPosition();for(let o of c){if(o.isWarped||this._getLinkFrequency(r,o.destination)>r.options.links.frequency||!a.has(o.destination.id))continue;let c=o.destination;if(this._getTriangleFrequency(e,r,c)>(i.links?.triangles.frequency??0))continue;let g=Math.ceil((t.opacity+o.opacity)*n.half*10)/10,d=(0,n.rangeColorToRgb)(this._engine,l.color)??t.color;if(!d)continue;let _=this._getCachedStyle(d),y=`${_}_${g}`,p=this._triangleBatches.get(y);p||(p={colorStyle:_,opacity:g,coords:[]},this._triangleBatches.set(y,p));let f=c.getPosition();p.coords.push(s.x,s.y,h.x,h.y,f.x,f.y)}}_getCachedStyle(i){let e=`${i.r},${i.g},${i.b}`,t=this._colorCache.get(e);return t||(t=(0,n.getStyleFromRgb)(i,this._container.hdr),this._colorCache.set(e,t)),t}_getLinkFrequency(i,e){return o([i,e],this._freqs.links)}_getTriangleFrequency(i,e,t){return o([i,e,t],this._freqs.triangles)}}}}]);
|
package/628.min.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[628],{628(n,i,t){t.r(i),t.d(i,{LinksPlugin:()=>e});class e{id="links";_engine;constructor(n){this._engine=n}async getPlugin(n){let{LinkInstance:i}=await t.e(463).then(t.bind(t,463));return new i(n,this._engine)}loadOptions(){}needsPlugin(){return!0}}}}]);
|