import { drawLinkLine, drawLinkTriangle } from "./Utils"; import { getDistance, getLinkColor, getRandom, getRangeValue, rangeColorToRgb } from "tsparticles-engine"; function getLinkKey(ids) { ids.sort((a, b) => a - b); return ids.join("_"); } function setLinkFrequency(particles, dictionary) { const key = getLinkKey(particles.map((t) => t.id)); let res = dictionary.get(key); if (res === undefined) { res = getRandom(); dictionary.set(key, res); } return res; } export class LinkInstance { constructor(container) { this.container = container; this._freqs = { links: new Map(), triangles: new Map(), }; } drawParticle(context, particle) { var _a; const pOptions = particle.options; if (!particle.links || particle.links.length <= 0) { return; } const p1Links = particle.links.filter((l) => pOptions.links && this.getLinkFrequency(particle, l.destination) <= pOptions.links.frequency); for (const link of p1Links) { this.drawTriangles(pOptions, particle, link, p1Links); if (link.opacity > 0 && ((_a = particle.retina.linksWidth) !== null && _a !== void 0 ? _a : 0) > 0) { this.drawLinkLine(particle, link); } } } async init() { this._freqs.links = new Map(); this._freqs.triangles = new Map(); } particleCreated(particle) { particle.links = []; if (!particle.options.links) { return; } const ratio = this.container.retina.pixelRatio; particle.retina.linksDistance = particle.options.links.distance * ratio; particle.retina.linksWidth = particle.options.links.width * ratio; } particleDestroyed(particle) { particle.links = []; } drawLinkLine(p1, link) { const container = this.container, options = container.actualOptions, p2 = link.destination, pos1 = p1.getPosition(), pos2 = p2.getPosition(); let opacity = link.opacity; container.canvas.draw((ctx) => { var _a, _b, _c; if (!p1.options.links) { return; } let colorLine; const twinkle = (_a = p1.options.twinkle) === null || _a === void 0 ? void 0 : _a.lines; if (twinkle === null || twinkle === void 0 ? void 0 : twinkle.enable) { const twinkleFreq = twinkle.frequency, twinkleRgb = rangeColorToRgb(twinkle.color), twinkling = getRandom() < twinkleFreq; if (twinkling && twinkleRgb) { colorLine = twinkleRgb; opacity = getRangeValue(twinkle.opacity); } } if (!colorLine) { const linksOptions = p1.options.links, linkColor = (linksOptions === null || linksOptions === void 0 ? void 0 : linksOptions.id) !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor; colorLine = getLinkColor(p1, p2, linkColor); } if (!colorLine) { return; } const width = (_b = p1.retina.linksWidth) !== null && _b !== void 0 ? _b : 0, maxDistance = (_c = p1.retina.linksDistance) !== null && _c !== void 0 ? _c : 0; drawLinkLine(ctx, width, pos1, pos2, maxDistance, container.canvas.size, p1.options.links.warp, options.backgroundMask.enable, options.backgroundMask.composite, colorLine, opacity, p1.options.links.shadow); }); } drawLinkTriangle(p1, link1, link2) { var _a; if (!p1.options.links) { return; } const container = this.container, options = container.actualOptions, p2 = link1.destination, p3 = link2.destination, triangleOptions = p1.options.links.triangles, opacityTriangle = (_a = triangleOptions.opacity) !== null && _a !== void 0 ? _a : (link1.opacity + link2.opacity) / 2; if (opacityTriangle <= 0) { return; } container.canvas.draw((ctx) => { var _a; const pos1 = p1.getPosition(), pos2 = p2.getPosition(), pos3 = p3.getPosition(), linksDistance = (_a = p1.retina.linksDistance) !== null && _a !== void 0 ? _a : 0; if (getDistance(pos1, pos2) > linksDistance || getDistance(pos3, pos2) > linksDistance || getDistance(pos3, pos1) > linksDistance) { return; } let colorTriangle = rangeColorToRgb(triangleOptions.color); if (!colorTriangle) { const linksOptions = p1.options.links, linkColor = (linksOptions === null || linksOptions === void 0 ? void 0 : linksOptions.id) !== undefined ? container.particles.linksColors.get(linksOptions.id) : container.particles.linksColor; colorTriangle = getLinkColor(p1, p2, linkColor); } if (!colorTriangle) { return; } drawLinkTriangle(ctx, pos1, pos2, pos3, options.backgroundMask.enable, options.backgroundMask.composite, colorTriangle, opacityTriangle); }); } drawTriangles(options, p1, link, p1Links) { var _a, _b, _c; const p2 = link.destination; if (!(((_a = options.links) === null || _a === void 0 ? void 0 : _a.triangles.enable) && ((_b = p2.options.links) === null || _b === void 0 ? void 0 : _b.triangles.enable))) { return; } const vertices = (_c = p2.links) === null || _c === void 0 ? void 0 : _c.filter((t) => { const linkFreq = this.getLinkFrequency(p2, t.destination); return (p2.options.links && linkFreq <= p2.options.links.frequency && p1Links.findIndex((l) => l.destination === t.destination) >= 0); }); if (!(vertices === null || vertices === void 0 ? void 0 : 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); } } getLinkFrequency(p1, p2) { return setLinkFrequency([p1, p2], this._freqs.links); } getTriangleFrequency(p1, p2, p3) { return setLinkFrequency([p1, p2, p3], this._freqs.triangles); } }