@tsparticles/interaction-particles-links
Version:
tsParticles links particles interaction
161 lines (160 loc) • 7.06 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LinkInstance = void 0;
const engine_1 = require("@tsparticles/engine");
const Utils_js_1 = require("./Utils.js");
const minOpacity = 0, minWidth = 0, minDistance = 0, half = 0.5, maxFrequency = 1;
class LinkInstance {
constructor(container, engine) {
this._drawLinkLine = (p1, link) => {
const p1LinksOptions = p1.options.links;
if (!p1LinksOptions?.enable) {
return;
}
const container = this._container, options = container.actualOptions, p2 = link.destination, pos1 = p1.getPosition(), pos2 = p2.getPosition();
let opacity = link.opacity;
container.canvas.draw(ctx => {
let colorLine;
const twinkle = p1.options.twinkle?.lines;
if (twinkle?.enable) {
const twinkleFreq = twinkle.frequency, twinkleRgb = (0, engine_1.rangeColorToRgb)(this._engine, twinkle.color), twinkling = (0, engine_1.getRandom)() < twinkleFreq;
if (twinkling && twinkleRgb) {
colorLine = twinkleRgb;
opacity = (0, engine_1.getRangeValue)(twinkle.opacity);
}
}
if (!colorLine) {
const linkColor = p1LinksOptions.id !== undefined
? container.particles.linksColors.get(p1LinksOptions.id)
: container.particles.linksColor;
colorLine = (0, engine_1.getLinkColor)(p1, p2, linkColor);
}
if (!colorLine) {
return;
}
const width = p1.retina.linksWidth ?? minWidth, maxDistance = p1.retina.linksDistance ?? minDistance, { backgroundMask } = options;
(0, Utils_js_1.drawLinkLine)({
context: ctx,
width,
begin: pos1,
end: pos2,
engine: this._engine,
maxDistance,
canvasSize: container.canvas.size,
links: p1LinksOptions,
backgroundMask: backgroundMask,
colorLine,
opacity,
});
});
};
this._drawLinkTriangle = (p1, link1, link2) => {
const linksOptions = p1.options.links;
if (!linksOptions?.enable) {
return;
}
const triangleOptions = linksOptions.triangles;
if (!triangleOptions.enable) {
return;
}
const container = this._container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, opacityTriangle = triangleOptions.opacity ?? (link1.opacity + link2.opacity) * half;
if (opacityTriangle <= minOpacity) {
return;
}
container.canvas.draw(ctx => {
const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = p1.retina.linksDistance ?? minDistance;
if ((0, engine_1.getDistance)(pos1, pos2) > linksDistance ||
(0, engine_1.getDistance)(pos3, pos2) > linksDistance ||
(0, engine_1.getDistance)(pos3, pos1) > linksDistance) {
return;
}
let colorTriangle = (0, engine_1.rangeColorToRgb)(this._engine, triangleOptions.color);
if (!colorTriangle) {
const linkColor = linksOptions.id !== undefined
? container.particles.linksColors.get(linksOptions.id)
: container.particles.linksColor;
colorTriangle = (0, engine_1.getLinkColor)(p1, p2, linkColor);
}
if (!colorTriangle) {
return;
}
(0, Utils_js_1.drawLinkTriangle)({
context: ctx,
pos1,
pos2,
pos3,
backgroundMask: options.backgroundMask,
colorTriangle,
opacityTriangle,
});
});
};
this._drawTriangles = (options, p1, link, p1Links) => {
const p2 = link.destination;
if (!(options.links?.triangles.enable && p2.options.links?.triangles.enable)) {
return;
}
const vertices = p2.links?.filter(t => {
const linkFreq = this._getLinkFrequency(p2, t.destination), minCount = 0;
return (p2.options.links &&
linkFreq <= p2.options.links.frequency &&
p1Links.findIndex(l => l.destination === t.destination) >= minCount);
});
if (!vertices?.length) {
return;
}
for (const vertex of vertices) {
const p3 = vertex.destination, triangleFreq = this._getTriangleFrequency(p1, p2, p3);
if (triangleFreq > options.links.triangles.frequency) {
continue;
}
this._drawLinkTriangle(p1, link, vertex);
}
};
this._getLinkFrequency = (p1, p2) => {
return (0, Utils_js_1.setLinkFrequency)([p1, p2], this._freqs.links);
};
this._getTriangleFrequency = (p1, p2, p3) => {
return (0, Utils_js_1.setLinkFrequency)([p1, p2, p3], this._freqs.triangles);
};
this._container = container;
this._engine = engine;
this._freqs = {
links: new Map(),
triangles: new Map(),
};
}
drawParticle(context, particle) {
const { links, options } = particle;
if (!links?.length) {
return;
}
const p1Links = links.filter(l => options.links &&
(options.links.frequency >= maxFrequency ||
this._getLinkFrequency(particle, l.destination) <= options.links.frequency));
for (const link of p1Links) {
this._drawTriangles(options, particle, link, p1Links);
if (link.opacity > minOpacity && (particle.retina.linksWidth ?? minWidth) > minWidth) {
this._drawLinkLine(particle, link);
}
}
}
async init() {
this._freqs.links = new Map();
this._freqs.triangles = new Map();
await Promise.resolve();
}
particleCreated(particle) {
particle.links = [];
if (!particle.options.links) {
return;
}
const ratio = this._container.retina.pixelRatio, { retina } = particle, { distance, width } = particle.options.links;
retina.linksDistance = distance * ratio;
retina.linksWidth = width * ratio;
}
particleDestroyed(particle) {
particle.links = [];
}
}
exports.LinkInstance = LinkInstance;