@tsparticles/interaction-particles-links 4.0.0-alpha.23 → 4.0.0-alpha.25

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/282.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[282],{282(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(37).then(t.bind(t,37));return new i(n,this._engine)}loadOptions(){}needsPlugin(){return!0}}}}]);
package/37.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[37],{37(i,t,e){e.d(t,{LinkInstance:()=>s});var n=e(303);function o(i,t){var e;let o=((e=i.map(i=>i.id)).sort((i,t)=>i-t),e.join("_")),s=t.get(o);return void 0===s&&(s=(0,n.getRandom)(),t.set(o,s)),s}class s{_colorCache=new Map;_container;_engine;_freqs;_lineBatches=new Map;_triangleBatches=new Map;constructor(i,t){this._container=i,this._engine=t,this._freqs={links:new Map,triangles:new Map}}draw(i){for(let[,t]of this._triangleBatches){i.save(),i.fillStyle=t.colorStyle,i.globalAlpha=t.opacity,i.beginPath();for(let e=0;e<t.coords.length;e+=6){let o=t.coords[e+0]??n.originPoint.x,s=t.coords[e+1]??n.originPoint.y,l=t.coords[e+2]??n.originPoint.x,r=t.coords[e+3]??n.originPoint.y,a=t.coords[e+4]??n.originPoint.x,c=t.coords[e+5]??n.originPoint.y;i.moveTo(o,s),i.lineTo(l,r),i.lineTo(a,c)}i.fill(),i.restore()}for(let[,t]of this._lineBatches){i.save(),i.strokeStyle=t.colorStyle,i.lineWidth=t.width,i.globalAlpha=t.opacity,i.beginPath();for(let e=0;e<t.coords.length;e+=4){let o=t.coords[e+0]??n.originPoint.x,s=t.coords[e+1]??n.originPoint.y,l=t.coords[e+2]??n.originPoint.x,r=t.coords[e+3]??n.originPoint.y;i.moveTo(o,s),i.lineTo(l,r)}i.stroke(),i.restore()}this._lineBatches.clear(),this._triangleBatches.clear()}drawParticle(i,t){let{links:e,options:o}=t;if(!e?.length||!o.links)return;let s=this._container.canvas.size,l=e.filter(i=>o.links&&(o.links.frequency>=1||this._getLinkFrequency(t,i.destination)<=o.links.frequency)),r=t.getPosition();for(let i of l)if(i.isWarped||this._collectTriangles(o,t,i,l),i.opacity>0&&(t.retina.linksWidth??0)>0){let e=i.opacity,l=i.color,a=t.options.twinkle?.lines;if(a?.enable&&(0,n.getRandom)()<a.frequency){let i=(0,n.rangeColorToRgb)(this._engine,a.color);i&&(l=i,e=(0,n.getRangeValue)(a.opacity))}if(!l){let e=void 0!==o.links.id?this._container.particles.linksColors.get(o.links.id):this._container.particles.linksColor;l=(0,n.getLinkColor)(t,i.destination,e)}if(l){let o=Math.ceil(10*e)/10,a=this._getCachedStyle(l),c=t.retina.linksWidth??0,h=`${a}_${o}_${c}`,g=this._lineBatches.get(h);g||(g={colorStyle:a,opacity:o,width:c,coords:[]},this._lineBatches.set(h,g));let d=i.destination.getPosition();if(i.isWarped){let i=d.x-r.x,t=d.y-r.y,e=n.originPoint.x,o=n.originPoint.y;Math.abs(i)>s.width*n.half&&(e=i>0?-s.width:s.width),Math.abs(t)>s.height*n.half&&(o=t>0?-s.height:s.height);let l={x:d.x+e,y:d.y+o},a={x:r.x-e,y:r.y-o};g.coords.push(r.x,r.y,l.x,l.y),g.coords.push(a.x,a.y,d.x,d.y)}else g.coords.push(r.x,r.y,d.x,d.y)}}}async init(){this._freqs.links.clear(),this._freqs.triangles.clear(),this._colorCache.clear(),await Promise.resolve()}particleCreated(i){if(i.links=[],!i.options.links)return;i.linksDistance=i.options.links.distance,i.linksWidth=i.options.links.width;let t=this._container.retina.pixelRatio;i.retina.linksDistance=i.linksDistance*t,i.retina.linksWidth=i.linksWidth*t}particleDestroyed(i){i.links=[]}_collectTriangles(i,t,e,o){let s=e.destination,l=i.links?.triangles;if(!l?.enable||!s.options.links?.triangles.enable)return;let r=s.links?.filter(i=>!i.isWarped&&s.options.links&&this._getLinkFrequency(s,i.destination)<=s.options.links.frequency&&o.some(t=>t.destination===i.destination));if(r?.length)for(let o of r){let r=o.destination;if(this._getTriangleFrequency(t,s,r)>(i.links?.triangles.frequency??0))continue;let a=Math.ceil((e.opacity+o.opacity)*n.half*10)/10,c=(0,n.rangeColorToRgb)(this._engine,l.color)??e.color;if(!c)continue;let h=this._getCachedStyle(c),g=`${h}_${a}`,d=this._triangleBatches.get(g);d||(d={colorStyle:h,opacity:a,coords:[]},this._triangleBatches.set(g,d));let _=t.getPosition(),y=s.getPosition(),k=r.getPosition();d.coords.push(_.x,_.y,y.x,y.y,k.x,k.y)}}_getCachedStyle(i){let t=`${i.r},${i.g},${i.b}`,e=this._colorCache.get(t);return e||(e=(0,n.getStyleFromRgb)(i,this._container.hdr),this._colorCache.set(t,e)),e}_getLinkFrequency(i,t){return o([i,t],this._freqs.links)}_getTriangleFrequency(i,t,e){return o([i,t,e],this._freqs.triangles)}}}}]);
package/995.min.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[995],{995(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(163),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))}}}}]);
@@ -112,9 +112,11 @@ export class LinkInstance {
112
112
  if (!particle.options.links) {
113
113
  return;
114
114
  }
115
+ particle.linksDistance = particle.options.links.distance;
116
+ particle.linksWidth = particle.options.links.width;
115
117
  const ratio = this._container.retina.pixelRatio;
116
- particle.retina.linksDistance = particle.options.links.distance * ratio;
117
- particle.retina.linksWidth = particle.options.links.width * ratio;
118
+ particle.retina.linksDistance = particle.linksDistance * ratio;
119
+ particle.retina.linksWidth = particle.linksWidth * ratio;
118
120
  }
119
121
  particleDestroyed(particle) {
120
122
  particle.links = [];
package/browser/Linker.js CHANGED
@@ -2,19 +2,24 @@ import { Circle, getDistances, getLinkColor, getLinkRandomColor, originPoint, }
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
- const squarePower = 2, opacityOffset = 1, minDistance = 0;
5
+ const opacityOffset = 1, minDistance = 0;
6
6
  function getWarpDistance(pos1, pos2, canvasSize) {
7
7
  const { dx, dy } = getDistances(pos1, pos2), absDiffs = { x: Math.abs(dx), y: Math.abs(dy) }, warpDistances = {
8
8
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
9
9
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
10
10
  };
11
- return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
11
+ return Math.hypot(warpDistances.x, warpDistances.y);
12
12
  }
13
13
  export class Linker extends ParticlesInteractorBase {
14
14
  _engine;
15
+ _maxDistance;
15
16
  constructor(container, engine) {
16
17
  super(container);
17
18
  this._engine = engine;
19
+ this._maxDistance = 0;
20
+ }
21
+ get maxDistance() {
22
+ return this._maxDistance;
18
23
  }
19
24
  clear() {
20
25
  }
@@ -27,11 +32,14 @@ export class Linker extends ParticlesInteractorBase {
27
32
  return;
28
33
  }
29
34
  p1.links = [];
35
+ if (p1.linksDistance && p1.linksDistance > this._maxDistance) {
36
+ this._maxDistance = p1.linksDistance;
37
+ }
30
38
  const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;
31
39
  if (pos1.x < originPoint.x || pos1.y < originPoint.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
32
40
  return;
33
41
  }
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);
42
+ 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.grid.query(range);
35
43
  for (const p2 of query) {
36
44
  const linkOpt2 = p2.options.links;
37
45
  if (p1 === p2 ||
package/browser/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export async function loadParticlesLinksInteraction(engine) {
2
- engine.checkVersion("4.0.0-alpha.23");
2
+ engine.checkVersion("4.0.0-alpha.25");
3
3
  await engine.register(async (e) => {
4
4
  const [{ ensureInteractivityPluginLoaded }, { LinksPlugin },] = await Promise.all([
5
5
  import("@tsparticles/plugin-interactivity"),
@@ -112,9 +112,11 @@ export class LinkInstance {
112
112
  if (!particle.options.links) {
113
113
  return;
114
114
  }
115
+ particle.linksDistance = particle.options.links.distance;
116
+ particle.linksWidth = particle.options.links.width;
115
117
  const ratio = this._container.retina.pixelRatio;
116
- particle.retina.linksDistance = particle.options.links.distance * ratio;
117
- particle.retina.linksWidth = particle.options.links.width * ratio;
118
+ particle.retina.linksDistance = particle.linksDistance * ratio;
119
+ particle.retina.linksWidth = particle.linksWidth * ratio;
118
120
  }
119
121
  particleDestroyed(particle) {
120
122
  particle.links = [];
package/cjs/Linker.js CHANGED
@@ -2,19 +2,24 @@ import { Circle, getDistances, getLinkColor, getLinkRandomColor, originPoint, }
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
- const squarePower = 2, opacityOffset = 1, minDistance = 0;
5
+ const opacityOffset = 1, minDistance = 0;
6
6
  function getWarpDistance(pos1, pos2, canvasSize) {
7
7
  const { dx, dy } = getDistances(pos1, pos2), absDiffs = { x: Math.abs(dx), y: Math.abs(dy) }, warpDistances = {
8
8
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
9
9
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
10
10
  };
11
- return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
11
+ return Math.hypot(warpDistances.x, warpDistances.y);
12
12
  }
13
13
  export class Linker extends ParticlesInteractorBase {
14
14
  _engine;
15
+ _maxDistance;
15
16
  constructor(container, engine) {
16
17
  super(container);
17
18
  this._engine = engine;
19
+ this._maxDistance = 0;
20
+ }
21
+ get maxDistance() {
22
+ return this._maxDistance;
18
23
  }
19
24
  clear() {
20
25
  }
@@ -27,11 +32,14 @@ export class Linker extends ParticlesInteractorBase {
27
32
  return;
28
33
  }
29
34
  p1.links = [];
35
+ if (p1.linksDistance && p1.linksDistance > this._maxDistance) {
36
+ this._maxDistance = p1.linksDistance;
37
+ }
30
38
  const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;
31
39
  if (pos1.x < originPoint.x || pos1.y < originPoint.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
32
40
  return;
33
41
  }
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);
42
+ 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.grid.query(range);
35
43
  for (const p2 of query) {
36
44
  const linkOpt2 = p2.options.links;
37
45
  if (p1 === p2 ||
package/cjs/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export async function loadParticlesLinksInteraction(engine) {
2
- engine.checkVersion("4.0.0-alpha.23");
2
+ engine.checkVersion("4.0.0-alpha.25");
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.23
7
+ * v4.0.0-alpha.25
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, 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}");
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 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) {\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
 
@@ -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.23
7
+ * v4.0.0-alpha.25
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -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 */ Linker: () => (/* binding */ Linker)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _CircleWarp_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CircleWarp.js */ \"./dist/browser/CircleWarp.js\");\n/* harmony import */ var _Options_Classes_Links_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Links.js */ \"./dist/browser/Options/Classes/Links.js\");\n/* harmony import */ var _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @tsparticles/plugin-interactivity */ \"@tsparticles/plugin-interactivity\");\n\n\n\n\nconst squarePower = 2, opacityOffset = 1, minDistance = 0;\nfunction getWarpDistance(pos1, pos2, canvasSize) {\n const { dx, dy } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(pos1, pos2), absDiffs = {\n x: Math.abs(dx),\n y: Math.abs(dy)\n }, warpDistances = {\n x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),\n y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y)\n };\n return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);\n}\nclass Linker extends _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_3__.ParticlesInteractorBase {\n _engine;\n constructor(container, engine){\n super(container);\n this._engine = engine;\n }\n clear() {}\n init() {\n this.container.particles.linksColor = undefined;\n this.container.particles.linksColors = new Map();\n }\n interact(p1) {\n if (!p1.options.links) {\n return;\n }\n p1.links = [];\n const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;\n if (pos1.x < _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x || pos1.y < _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {\n return;\n }\n const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp ? new _CircleWarp_js__WEBPACK_IMPORTED_MODULE_1__.CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(pos1.x, pos1.y, optDistance), query = container.particles.quadTree.query(range);\n for (const p2 of query){\n const linkOpt2 = p2.options.links;\n if (p1 === p2 || !linkOpt2?.enable || linkOpt1.id !== linkOpt2.id || p2.spawning || p2.destroyed || !p2.links || p1.links.some((t)=>t.destination === p2) || p2.links.some((t)=>t.destination === p1)) {\n continue;\n }\n const pos2 = p2.getPosition();\n if (pos2.x < _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x || pos2.y < _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {\n continue;\n }\n const distDirect = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(pos1, pos2).distance, distWarp = warp && linkOpt2.warp ? getWarpDistance(pos1, pos2, canvasSize) : distDirect, distance = Math.min(distDirect, distWarp);\n if (distance > optDistance) {\n continue;\n }\n const opacityLine = (opacityOffset - distance / optDistance) * optOpacity;\n this._setColor(p1);\n p1.links.push({\n destination: p2,\n opacity: opacityLine,\n color: this._getLinkColor(p1, p2),\n isWarped: distWarp < distDirect\n });\n }\n }\n isEnabled(particle) {\n return !!particle.options.links?.enable;\n }\n loadParticlesOptions(options, ...sources) {\n options.links ??= new _Options_Classes_Links_js__WEBPACK_IMPORTED_MODULE_2__.Links();\n for (const source of sources){\n options.links.load(source?.links);\n }\n }\n reset() {}\n _getLinkColor(p1, p2) {\n const container = this.container, linksOptions = p1.options.links;\n if (!linksOptions) {\n return;\n }\n const linkColor = linksOptions.id !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor;\n return (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkColor)(p1, p2, linkColor);\n }\n _setColor(p1) {\n if (!p1.options.links) {\n return;\n }\n const container = this.container, linksOptions = p1.options.links;\n let linkColor = linksOptions.id === undefined ? container.particles.linksColor : container.particles.linksColors.get(linksOptions.id);\n if (linkColor) {\n return;\n }\n linkColor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkRandomColor)(this._engine, linksOptions.color, linksOptions.blink, linksOptions.consent);\n if (linksOptions.id === undefined) {\n container.particles.linksColor = linkColor;\n } else {\n container.particles.linksColors.set(linksOptions.id, linkColor);\n }\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/interaction-particles-links/./dist/browser/Linker.js?\n}");
36
+ eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ Linker: () => (/* binding */ Linker)\n/* harmony export */ });\n/* harmony import */ var _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tsparticles/engine */ \"@tsparticles/engine\");\n/* harmony import */ var _CircleWarp_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CircleWarp.js */ \"./dist/browser/CircleWarp.js\");\n/* harmony import */ var _Options_Classes_Links_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Options/Classes/Links.js */ \"./dist/browser/Options/Classes/Links.js\");\n/* harmony import */ var _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @tsparticles/plugin-interactivity */ \"@tsparticles/plugin-interactivity\");\n\n\n\n\nconst opacityOffset = 1, minDistance = 0;\nfunction getWarpDistance(pos1, pos2, canvasSize) {\n const { dx, dy } = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(pos1, pos2), absDiffs = {\n x: Math.abs(dx),\n y: Math.abs(dy)\n }, warpDistances = {\n x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),\n y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y)\n };\n return Math.hypot(warpDistances.x, warpDistances.y);\n}\nclass Linker extends _tsparticles_plugin_interactivity__WEBPACK_IMPORTED_MODULE_3__.ParticlesInteractorBase {\n _engine;\n _maxDistance;\n constructor(container, engine){\n super(container);\n this._engine = engine;\n this._maxDistance = 0;\n }\n get maxDistance() {\n return this._maxDistance;\n }\n clear() {}\n init() {\n this.container.particles.linksColor = undefined;\n this.container.particles.linksColors = new Map();\n }\n interact(p1) {\n if (!p1.options.links) {\n return;\n }\n p1.links = [];\n if (p1.linksDistance && p1.linksDistance > this._maxDistance) {\n this._maxDistance = p1.linksDistance;\n }\n const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;\n if (pos1.x < _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x || pos1.y < _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {\n return;\n }\n const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp ? new _CircleWarp_js__WEBPACK_IMPORTED_MODULE_1__.CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.Circle(pos1.x, pos1.y, optDistance), query = container.particles.grid.query(range);\n for (const p2 of query){\n const linkOpt2 = p2.options.links;\n if (p1 === p2 || !linkOpt2?.enable || linkOpt1.id !== linkOpt2.id || p2.spawning || p2.destroyed || !p2.links || p1.links.some((t)=>t.destination === p2) || p2.links.some((t)=>t.destination === p1)) {\n continue;\n }\n const pos2 = p2.getPosition();\n if (pos2.x < _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.x || pos2.y < _tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.originPoint.y || pos2.x > canvasSize.width || pos2.y > canvasSize.height) {\n continue;\n }\n const distDirect = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getDistances)(pos1, pos2).distance, distWarp = warp && linkOpt2.warp ? getWarpDistance(pos1, pos2, canvasSize) : distDirect, distance = Math.min(distDirect, distWarp);\n if (distance > optDistance) {\n continue;\n }\n const opacityLine = (opacityOffset - distance / optDistance) * optOpacity;\n this._setColor(p1);\n p1.links.push({\n destination: p2,\n opacity: opacityLine,\n color: this._getLinkColor(p1, p2),\n isWarped: distWarp < distDirect\n });\n }\n }\n isEnabled(particle) {\n return !!particle.options.links?.enable;\n }\n loadParticlesOptions(options, ...sources) {\n options.links ??= new _Options_Classes_Links_js__WEBPACK_IMPORTED_MODULE_2__.Links();\n for (const source of sources){\n options.links.load(source?.links);\n }\n }\n reset() {}\n _getLinkColor(p1, p2) {\n const container = this.container, linksOptions = p1.options.links;\n if (!linksOptions) {\n return;\n }\n const linkColor = linksOptions.id !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor;\n return (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkColor)(p1, p2, linkColor);\n }\n _setColor(p1) {\n if (!p1.options.links) {\n return;\n }\n const container = this.container, linksOptions = p1.options.links;\n let linkColor = linksOptions.id === undefined ? container.particles.linksColor : container.particles.linksColors.get(linksOptions.id);\n if (linkColor) {\n return;\n }\n linkColor = (0,_tsparticles_engine__WEBPACK_IMPORTED_MODULE_0__.getLinkRandomColor)(this._engine, linksOptions.color, linksOptions.blink, linksOptions.consent);\n if (linksOptions.id === undefined) {\n container.particles.linksColor = linkColor;\n } else {\n container.particles.linksColors.set(linksOptions.id, linkColor);\n }\n }\n}\n\n\n//# sourceURL=webpack://@tsparticles/interaction-particles-links/./dist/browser/Linker.js?\n}");
37
37
 
38
38
  /***/ }
39
39
 
@@ -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.23
7
+ * v4.0.0-alpha.25
8
8
  */
9
9
  "use strict";
10
10
  /*
@@ -112,9 +112,11 @@ export class LinkInstance {
112
112
  if (!particle.options.links) {
113
113
  return;
114
114
  }
115
+ particle.linksDistance = particle.options.links.distance;
116
+ particle.linksWidth = particle.options.links.width;
115
117
  const ratio = this._container.retina.pixelRatio;
116
- particle.retina.linksDistance = particle.options.links.distance * ratio;
117
- particle.retina.linksWidth = particle.options.links.width * ratio;
118
+ particle.retina.linksDistance = particle.linksDistance * ratio;
119
+ particle.retina.linksWidth = particle.linksWidth * ratio;
118
120
  }
119
121
  particleDestroyed(particle) {
120
122
  particle.links = [];
package/esm/Linker.js CHANGED
@@ -2,19 +2,24 @@ import { Circle, getDistances, getLinkColor, getLinkRandomColor, originPoint, }
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
- const squarePower = 2, opacityOffset = 1, minDistance = 0;
5
+ const opacityOffset = 1, minDistance = 0;
6
6
  function getWarpDistance(pos1, pos2, canvasSize) {
7
7
  const { dx, dy } = getDistances(pos1, pos2), absDiffs = { x: Math.abs(dx), y: Math.abs(dy) }, warpDistances = {
8
8
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
9
9
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
10
10
  };
11
- return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
11
+ return Math.hypot(warpDistances.x, warpDistances.y);
12
12
  }
13
13
  export class Linker extends ParticlesInteractorBase {
14
14
  _engine;
15
+ _maxDistance;
15
16
  constructor(container, engine) {
16
17
  super(container);
17
18
  this._engine = engine;
19
+ this._maxDistance = 0;
20
+ }
21
+ get maxDistance() {
22
+ return this._maxDistance;
18
23
  }
19
24
  clear() {
20
25
  }
@@ -27,11 +32,14 @@ export class Linker extends ParticlesInteractorBase {
27
32
  return;
28
33
  }
29
34
  p1.links = [];
35
+ if (p1.linksDistance && p1.linksDistance > this._maxDistance) {
36
+ this._maxDistance = p1.linksDistance;
37
+ }
30
38
  const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;
31
39
  if (pos1.x < originPoint.x || pos1.y < originPoint.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
32
40
  return;
33
41
  }
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);
42
+ 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.grid.query(range);
35
43
  for (const p2 of query) {
36
44
  const linkOpt2 = p2.options.links;
37
45
  if (p1 === p2 ||
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export async function loadParticlesLinksInteraction(engine) {
2
- engine.checkVersion("4.0.0-alpha.23");
2
+ engine.checkVersion("4.0.0-alpha.25");
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.23",
3
+ "version": "4.0.0-alpha.25",
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.23",
91
- "@tsparticles/engine": "4.0.0-alpha.23",
92
- "@tsparticles/plugin-interactivity": "4.0.0-alpha.23"
90
+ "@tsparticles/canvas-utils": "4.0.0-alpha.25",
91
+ "@tsparticles/engine": "4.0.0-alpha.25",
92
+ "@tsparticles/plugin-interactivity": "4.0.0-alpha.25"
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 [11 Feb 2026 at 18:25]</title>
6
+ <title>@tsparticles/interaction-particles-links [21 Feb 2026 at 12:49]</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.23
7
+ * v4.0.0-alpha.25
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.23\");\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}");
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.25\");\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
 
@@ -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},153(e,t,r){r.d(t,{q:()=>s});var i=r(303),o=r(889),n=r(337);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))}}},889(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))}}},337(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(153),y=a(889),g=a(337);async function w(e){e.checkVersion("4.0.0-alpha.23"),await e.register(async e=>{let[{ensureInteractivityPluginLoaded:t},{LinksPlugin:r}]=await Promise.all([Promise.resolve().then(a.t.bind(a,702,19)),a.e(272).then(a.bind(a,272))]);t(e),e.addPlugin(new r(e)),e.addInteractor?.("particlesLinks",async t=>{let{Linker:r}=await a.e(973).then(a.bind(a,973));return new r(t,e)})})}return b})());
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},163(e,t,r){r.d(t,{q:()=>s});var i=r(303),o=r(151),n=r(407);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))}}},151(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))}}},407(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(163),y=a(151),g=a(407);async function w(e){e.checkVersion("4.0.0-alpha.25"),await e.register(async e=>{let[{ensureInteractivityPluginLoaded:t},{LinksPlugin:r}]=await Promise.all([Promise.resolve().then(a.t.bind(a,702,19)),a.e(282).then(a.bind(a,282))]);t(e),e.addPlugin(new r(e)),e.addInteractor?.("particlesLinks",async t=>{let{Linker:r}=await a.e(995).then(a.bind(a,995));return new r(t,e)})})}return b})());
package/types/Linker.d.ts CHANGED
@@ -3,7 +3,9 @@ import type { IParticlesLinkOptions, LinkContainer, LinkParticle, ParticlesLinkO
3
3
  import { ParticlesInteractorBase } from "@tsparticles/plugin-interactivity";
4
4
  export declare class Linker extends ParticlesInteractorBase<LinkContainer, LinkParticle> {
5
5
  private readonly _engine;
6
+ private _maxDistance;
6
7
  constructor(container: LinkContainer, engine: Engine);
8
+ get maxDistance(): number;
7
9
  clear(): void;
8
10
  init(): void;
9
11
  interact(p1: LinkParticle): void;
package/types/Types.d.ts CHANGED
@@ -11,6 +11,8 @@ export type LinkContainer = InteractivityContainer & {
11
11
  };
12
12
  export type LinkParticle = InteractivityParticle & {
13
13
  links?: ILink[];
14
+ linksDistance?: number;
15
+ linksWidth?: number;
14
16
  options: ParticlesLinkOptions;
15
17
  retina: {
16
18
  linksDistance?: number;
@@ -124,9 +124,11 @@
124
124
  if (!particle.options.links) {
125
125
  return;
126
126
  }
127
+ particle.linksDistance = particle.options.links.distance;
128
+ particle.linksWidth = particle.options.links.width;
127
129
  const ratio = this._container.retina.pixelRatio;
128
- particle.retina.linksDistance = particle.options.links.distance * ratio;
129
- particle.retina.linksWidth = particle.options.links.width * ratio;
130
+ particle.retina.linksDistance = particle.linksDistance * ratio;
131
+ particle.retina.linksWidth = particle.linksWidth * ratio;
130
132
  }
131
133
  particleDestroyed(particle) {
132
134
  particle.links = [];
package/umd/Linker.js CHANGED
@@ -14,19 +14,24 @@
14
14
  const CircleWarp_js_1 = require("./CircleWarp.js");
15
15
  const Links_js_1 = require("./Options/Classes/Links.js");
16
16
  const plugin_interactivity_1 = require("@tsparticles/plugin-interactivity");
17
- const squarePower = 2, opacityOffset = 1, minDistance = 0;
17
+ const opacityOffset = 1, minDistance = 0;
18
18
  function getWarpDistance(pos1, pos2, canvasSize) {
19
19
  const { dx, dy } = (0, engine_1.getDistances)(pos1, pos2), absDiffs = { x: Math.abs(dx), y: Math.abs(dy) }, warpDistances = {
20
20
  x: Math.min(absDiffs.x, canvasSize.width - absDiffs.x),
21
21
  y: Math.min(absDiffs.y, canvasSize.height - absDiffs.y),
22
22
  };
23
- return Math.sqrt(warpDistances.x ** squarePower + warpDistances.y ** squarePower);
23
+ return Math.hypot(warpDistances.x, warpDistances.y);
24
24
  }
25
25
  class Linker extends plugin_interactivity_1.ParticlesInteractorBase {
26
26
  _engine;
27
+ _maxDistance;
27
28
  constructor(container, engine) {
28
29
  super(container);
29
30
  this._engine = engine;
31
+ this._maxDistance = 0;
32
+ }
33
+ get maxDistance() {
34
+ return this._maxDistance;
30
35
  }
31
36
  clear() {
32
37
  }
@@ -39,11 +44,14 @@
39
44
  return;
40
45
  }
41
46
  p1.links = [];
47
+ if (p1.linksDistance && p1.linksDistance > this._maxDistance) {
48
+ this._maxDistance = p1.linksDistance;
49
+ }
42
50
  const pos1 = p1.getPosition(), container = this.container, canvasSize = container.canvas.size;
43
51
  if (pos1.x < engine_1.originPoint.x || pos1.y < engine_1.originPoint.y || pos1.x > canvasSize.width || pos1.y > canvasSize.height) {
44
52
  return;
45
53
  }
46
- const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp ? new CircleWarp_js_1.CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new engine_1.Circle(pos1.x, pos1.y, optDistance), query = container.particles.quadTree.query(range);
54
+ const linkOpt1 = p1.options.links, optOpacity = linkOpt1.opacity, optDistance = p1.retina.linksDistance ?? minDistance, warp = linkOpt1.warp, range = warp ? new CircleWarp_js_1.CircleWarp(pos1.x, pos1.y, optDistance, canvasSize) : new engine_1.Circle(pos1.x, pos1.y, optDistance), query = container.particles.grid.query(range);
47
55
  for (const p2 of query) {
48
56
  const linkOpt2 = p2.options.links;
49
57
  if (p1 === p2 ||
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.23");
51
+ engine.checkVersion("4.0.0-alpha.25");
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/272.min.js DELETED
@@ -1 +0,0 @@
1
- "use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[272],{272(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(919).then(t.bind(t,919));return new i(n,this._engine)}loadOptions(){}needsPlugin(){return!0}}}}]);
package/919.min.js DELETED
@@ -1 +0,0 @@
1
- "use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[919],{919(i,t,e){e.d(t,{LinkInstance:()=>s});var n=e(303);function o(i,t){var e;let o=((e=i.map(i=>i.id)).sort((i,t)=>i-t),e.join("_")),s=t.get(o);return void 0===s&&(s=(0,n.getRandom)(),t.set(o,s)),s}class s{_colorCache=new Map;_container;_engine;_freqs;_lineBatches=new Map;_triangleBatches=new Map;constructor(i,t){this._container=i,this._engine=t,this._freqs={links:new Map,triangles:new Map}}draw(i){for(let[,t]of this._triangleBatches){i.save(),i.fillStyle=t.colorStyle,i.globalAlpha=t.opacity,i.beginPath();for(let e=0;e<t.coords.length;e+=6){let o=t.coords[e+0]??n.originPoint.x,s=t.coords[e+1]??n.originPoint.y,r=t.coords[e+2]??n.originPoint.x,l=t.coords[e+3]??n.originPoint.y,a=t.coords[e+4]??n.originPoint.x,c=t.coords[e+5]??n.originPoint.y;i.moveTo(o,s),i.lineTo(r,l),i.lineTo(a,c)}i.fill(),i.restore()}for(let[,t]of this._lineBatches){i.save(),i.strokeStyle=t.colorStyle,i.lineWidth=t.width,i.globalAlpha=t.opacity,i.beginPath();for(let e=0;e<t.coords.length;e+=4){let o=t.coords[e+0]??n.originPoint.x,s=t.coords[e+1]??n.originPoint.y,r=t.coords[e+2]??n.originPoint.x,l=t.coords[e+3]??n.originPoint.y;i.moveTo(o,s),i.lineTo(r,l)}i.stroke(),i.restore()}this._lineBatches.clear(),this._triangleBatches.clear()}drawParticle(i,t){let{links:e,options:o}=t;if(!e?.length||!o.links)return;let s=this._container.canvas.size,r=e.filter(i=>o.links&&(o.links.frequency>=1||this._getLinkFrequency(t,i.destination)<=o.links.frequency)),l=t.getPosition();for(let i of r)if(i.isWarped||this._collectTriangles(o,t,i,r),i.opacity>0&&(t.retina.linksWidth??0)>0){let e=i.opacity,r=i.color,a=t.options.twinkle?.lines;if(a?.enable&&(0,n.getRandom)()<a.frequency){let i=(0,n.rangeColorToRgb)(this._engine,a.color);i&&(r=i,e=(0,n.getRangeValue)(a.opacity))}if(!r){let e=void 0!==o.links.id?this._container.particles.linksColors.get(o.links.id):this._container.particles.linksColor;r=(0,n.getLinkColor)(t,i.destination,e)}if(r){let o=Math.ceil(10*e)/10,a=this._getCachedStyle(r),c=t.retina.linksWidth??0,h=`${a}_${o}_${c}`,g=this._lineBatches.get(h);g||(g={colorStyle:a,opacity:o,width:c,coords:[]},this._lineBatches.set(h,g));let d=i.destination.getPosition();if(i.isWarped){let i=d.x-l.x,t=d.y-l.y,e=n.originPoint.x,o=n.originPoint.y;Math.abs(i)>s.width*n.half&&(e=i>0?-s.width:s.width),Math.abs(t)>s.height*n.half&&(o=t>0?-s.height:s.height);let r={x:d.x+e,y:d.y+o},a={x:l.x-e,y:l.y-o};g.coords.push(l.x,l.y,r.x,r.y),g.coords.push(a.x,a.y,d.x,d.y)}else g.coords.push(l.x,l.y,d.x,d.y)}}}async init(){this._freqs.links.clear(),this._freqs.triangles.clear(),this._colorCache.clear(),await Promise.resolve()}particleCreated(i){if(i.links=[],!i.options.links)return;let t=this._container.retina.pixelRatio;i.retina.linksDistance=i.options.links.distance*t,i.retina.linksWidth=i.options.links.width*t}particleDestroyed(i){i.links=[]}_collectTriangles(i,t,e,o){let s=e.destination,r=i.links?.triangles;if(!r?.enable||!s.options.links?.triangles.enable)return;let l=s.links?.filter(i=>!i.isWarped&&s.options.links&&this._getLinkFrequency(s,i.destination)<=s.options.links.frequency&&o.some(t=>t.destination===i.destination));if(l?.length)for(let o of l){let l=o.destination;if(this._getTriangleFrequency(t,s,l)>(i.links?.triangles.frequency??0))continue;let a=Math.ceil((e.opacity+o.opacity)*n.half*10)/10,c=(0,n.rangeColorToRgb)(this._engine,r.color)??e.color;if(!c)continue;let h=this._getCachedStyle(c),g=`${h}_${a}`,d=this._triangleBatches.get(g);d||(d={colorStyle:h,opacity:a,coords:[]},this._triangleBatches.set(g,d));let _=t.getPosition(),y=s.getPosition(),p=l.getPosition();d.coords.push(_.x,_.y,y.x,y.y,p.x,p.y)}}_getCachedStyle(i){let t=`${i.r},${i.g},${i.b}`,e=this._colorCache.get(t);return e||(e=(0,n.getStyleFromRgb)(i,this._container.hdr),this._colorCache.set(t,e)),e}_getLinkFrequency(i,t){return o([i,t],this._freqs.links)}_getTriangleFrequency(i,t,e){return o([i,t,e],this._freqs.triangles)}}}}]);
package/973.min.js DELETED
@@ -1 +0,0 @@
1
- "use strict";(this.webpackChunk_tsparticles_interaction_particles_links=this.webpackChunk_tsparticles_interaction_particles_links||[]).push([[973],{973(i,t,n){n.d(t,{Linker:()=>l});var e=n(303);class s extends e.Circle{canvasSize;constructor(i,t,n,e){super(i,t,n),this.canvasSize=e}contains(i){if(super.contains(i))return!0;let{width:t,height:n}=this.canvasSize,{x:e,y:s}=i;return super.contains({x:e-t,y:s})||super.contains({x:e+t,y:s})||super.contains({x:e,y:s-n})||super.contains({x:e,y:s+n})||super.contains({x:e-t,y:s-n})||super.contains({x:e+t,y:s+n})||super.contains({x:e-t,y:s+n})||super.contains({x:e+t,y:s-n})}intersects(i){if(super.intersects(i))return!0;let{width:t,height:n}=this.canvasSize,s=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:s.x+r.x,y:s.y+r.y};if(t=i instanceof e.Circle?new e.Circle(n.x,n.y,i.radius):new e.Rectangle(n.x,n.y,i.size.width,i.size.height),super.intersects(t))return!0}return!1}}var r=n(153),o=n(702);class l extends o.ParticlesInteractorBase{_engine;constructor(i,t){super(i),this._engine=t}clear(){}init(){this.container.particles.linksColor=void 0,this.container.particles.linksColors=new Map}interact(i){if(!i.options.links)return;i.links=[];let t=i.getPosition(),n=this.container,r=n.canvas.size;if(t.x<e.originPoint.x||t.y<e.originPoint.y||t.x>r.width||t.y>r.height)return;let o=i.options.links,l=o.opacity,a=i.retina.linksDistance??0,c=o.warp,p=c?new s(t.x,t.y,a,r):new e.Circle(t.x,t.y,a);for(let s of n.particles.quadTree.query(p)){let n=s.options.links;if(i===s||!n?.enable||o.id!==n.id||s.spawning||s.destroyed||!s.links||i.links.some(i=>i.destination===s)||s.links.some(t=>t.destination===i))continue;let p=s.getPosition();if(p.x<e.originPoint.x||p.y<e.originPoint.y||p.x>r.width||p.y>r.height)continue;let u=(0,e.getDistances)(t,p).distance,h=c&&n.warp?function(i,t,n){let{dx:s,dy:r}=(0,e.getDistances)(i,t),o={x:Math.abs(s),y:Math.abs(r)},l={x:Math.min(o.x,n.width-o.x),y:Math.min(o.y,n.height-o.y)};return Math.sqrt(l.x**2+l.y**2)}(t,p,r):u,k=Math.min(u,h);if(k>a)continue;let y=(1-k/a)*l;this._setColor(i),i.links.push({destination:s,opacity:y,color:this._getLinkColor(i,s),isWarped:h<u})}}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,s=i.options.links;if(!s)return;let r=void 0!==s.id?n.particles.linksColors.get(s.id):n.particles.linksColor;return(0,e.getLinkColor)(i,t,r)}_setColor(i){if(!i.options.links)return;let t=this.container,n=i.options.links,s=void 0===n.id?t.particles.linksColor:t.particles.linksColors.get(n.id);s||(s=(0,e.getLinkRandomColor)(this._engine,n.color,n.blink,n.consent),void 0===n.id?t.particles.linksColor=s:t.particles.linksColors.set(n.id,s))}}}}]);