2023-02-17 11:06:01 +01:00

144 lines
6.4 KiB
JavaScript

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);
}
}