@tsparticles/interaction-external-grab
Version:
tsParticles grab external interaction
77 lines (76 loc) • 3.32 kB
JavaScript
import { ExternalInteractorBase, mouseMoveEvent, } from "@tsparticles/plugin-interactivity";
import { getDistance, getLinkColor, getLinkRandomColor, isInArray, } from "@tsparticles/engine";
import { Grab } from "./Options/Classes/Grab.js";
import { drawGrab } from "./Utils.js";
const grabMode = "grab", minDistance = 0, minOpacity = 0;
export class Grabber extends ExternalInteractorBase {
#maxDistance;
#pluginManager;
constructor(pluginManager, container) {
super(container);
this.#pluginManager = pluginManager;
this.#maxDistance = 0;
}
get maxDistance() {
return this.#maxDistance;
}
clear() {
}
init() {
const container = this.container, grab = container.actualOptions.interactivity?.modes.grab;
if (!grab) {
return;
}
this.#maxDistance = grab.distance;
container.retina.grabModeDistance = grab.distance * container.retina.pixelRatio;
}
interact(interactivityData) {
const container = this.container, options = container.actualOptions, interactivity = options.interactivity;
if (!interactivity?.modes.grab ||
!interactivity.events.onHover.enable ||
interactivityData.status !== mouseMoveEvent) {
return;
}
const mousePos = interactivityData.mouse.position;
if (!mousePos) {
return;
}
const distance = container.retina.grabModeDistance;
if (!distance || distance < minDistance) {
return;
}
const query = container.particles.grid.queryCircle(mousePos, distance, p => this.isEnabled(interactivityData, p));
for (const particle of query) {
const pos = particle.getPosition(), pointDistance = getDistance(pos, mousePos);
if (pointDistance > distance) {
continue;
}
const grabLineOptions = interactivity.modes.grab.links, lineOpacity = grabLineOptions.opacity, opacityLine = lineOpacity - (pointDistance * lineOpacity) / distance;
if (opacityLine <= minOpacity) {
continue;
}
const optColor = grabLineOptions.color ?? particle.options.links?.color;
if (!container.particles.grabLineColor && optColor) {
const linksOptions = interactivity.modes.grab.links;
container.particles.grabLineColor = getLinkRandomColor(this.#pluginManager, optColor, linksOptions.blink, linksOptions.consent);
}
const colorLine = getLinkColor(particle, undefined, container.particles.grabLineColor);
if (!colorLine) {
continue;
}
drawGrab(container, particle, colorLine, opacityLine, mousePos);
}
}
isEnabled(interactivityData, particle) {
const container = this.container, mouse = interactivityData.mouse, events = (particle?.interactivity ?? container.actualOptions.interactivity)?.events;
return !!events?.onHover.enable && !!mouse.position && isInArray(grabMode, events.onHover.mode);
}
loadModeOptions(options, ...sources) {
options.grab ??= new Grab();
for (const source of sources) {
options.grab.load(source?.grab);
}
}
reset() {
}
}