UNPKG

@tsparticles/interaction-particles-attract

Version:

tsParticles attract particles interaction

54 lines (53 loc) 2.06 kB
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() { } }