@tsparticles/interaction-particles-attract
Version:
tsParticles attract particles interaction
54 lines (53 loc) • 2.06 kB
JavaScript
import { getDistances, getRangeValue, isNull } from "@tsparticles/engine";
import { Attract } from "./Options/Classes/Attract.js";
import { ParticlesInteractorBase } from "@tsparticles/plugin-interactivity";
const attractFactor = 1000, identity = 1;
export class Attractor extends ParticlesInteractorBase {
#maxDistance;
constructor(container) {
super(container);
this.#maxDistance = 0;
}
get maxDistance() {
return this.#maxDistance;
}
clear() {
}
init() {
}
interact(p1) {
if (!p1.options.attract?.enable) {
return;
}
const container = this.container;
if (isNull(p1.attractDistance)) {
const attractDistance = getRangeValue(p1.options.attract.distance);
if (attractDistance > this.#maxDistance) {
this.#maxDistance = attractDistance;
}
p1.attractDistance = attractDistance * container.retina.pixelRatio;
}
const distance = p1.attractDistance, pos1 = p1.getPosition(), query = container.particles.grid.queryCircle(pos1, distance);
for (const p2 of query) {
if (p1 === p2 || !p2.options.attract?.enable || p2.destroyed || p2.spawning) {
continue;
}
const pos2 = p2.getPosition(), { dx, dy } = getDistances(pos1, pos2), rotate = p1.options.attract.rotate, ax = dx / (rotate.x * attractFactor), ay = dy / (rotate.y * attractFactor), p1Factor = p2.size.value / p1.size.value, p2Factor = identity / p1Factor;
p1.velocity.x -= ax * p1Factor;
p1.velocity.y -= ay * p1Factor;
p2.velocity.x += ax * p2Factor;
p2.velocity.y += ay * p2Factor;
}
}
isEnabled(particle) {
return particle.options.attract?.enable ?? false;
}
loadParticlesOptions(options, ...sources) {
options.attract ??= new Attract();
for (const source of sources) {
options.attract.load(source?.attract);
}
}
reset() {
}
}