UNPKG

@tsparticles/interaction-external-grab

Version:

tsParticles grab external interaction

77 lines (76 loc) 3.32 kB
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() { } }