UNPKG

@tsparticles/plugin-emitters

Version:

tsParticles emitters plugin

117 lines (116 loc) 4.99 kB
import { ExternalInteractorBase, } from "@tsparticles/plugin-interactivity"; import { executeOnSingleOrMultiple, getRandom, isArray, isInArray, itemFromArray, } from "@tsparticles/engine"; import { Emitter } from "./Options/Classes/Emitter.js"; import { defaultRandomOptions } from "./constants.js"; const emittersMode = "emitters"; export class EmittersInteractor extends ExternalInteractorBase { handleClickMode; maxDistance; #instancesManager; constructor(instancesManager, container) { super(container); this.#instancesManager = instancesManager; this.maxDistance = 0; this.handleClickMode = (mode, interactivityData) => { const container = this.container, options = container.actualOptions, modeEmitters = options.interactivity.modes.emitters; if (!modeEmitters || mode !== emittersMode) { return; } let emittersModeOptions; if (isArray(modeEmitters.value)) { const minLength = 0, modeEmittersCount = modeEmitters.value.length; if (modeEmittersCount > minLength && modeEmitters.random.enable) { emittersModeOptions = []; const usedIndexes = new Set(); for (let i = 0; i < modeEmitters.random.count; i++) { const idx = Math.floor(getRandom() * modeEmitters.value.length); if (usedIndexes.has(idx) && usedIndexes.size < modeEmittersCount) { i--; continue; } usedIndexes.add(idx); const selectedOptions = itemFromArray(modeEmitters.value, idx); if (!selectedOptions) { continue; } emittersModeOptions.push(selectedOptions); } } else { emittersModeOptions = modeEmitters.value; } } else { emittersModeOptions = modeEmitters.value; } const emittersOptions = emittersModeOptions, ePosition = interactivityData.mouse.clickPosition; void executeOnSingleOrMultiple(emittersOptions, async (emitter) => { await this.#instancesManager.addEmitter(this.container, emitter, ePosition); }); }; } clear() { } init() { } interact(_interactivityData, delta) { for (const emitter of this.#instancesManager.getArray(this.container)) { emitter.update(delta); } } isEnabled(interactivityData, particle) { const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity).events; if (!mouse.clickPosition || !events.onClick.enable) { return false; } return isInArray(emittersMode, events.onClick.mode); } loadModeOptions(options, ...sources) { options.emitters = { random: defaultRandomOptions, value: [], }; for (const source of sources) { if (!source?.emitters) { continue; } if (isArray(source.emitters)) { for (const emitter of source.emitters) { const tmp = new Emitter(); tmp.load(emitter); options.emitters.value.push(tmp); } } else if ("value" in source.emitters) { const emitterModeOptions = source.emitters; options.emitters.random.enable = emitterModeOptions.random?.enable ?? options.emitters.random.enable; options.emitters.random.count = emitterModeOptions.random?.count ?? options.emitters.random.count; if (isArray(emitterModeOptions.value)) { for (const emitter of emitterModeOptions.value) { const tmp = new Emitter(); tmp.load(emitter); options.emitters.value.push(tmp); } } else { const tmp = new Emitter(); tmp.load(emitterModeOptions.value); options.emitters.value.push(tmp); } } else { const tmp = new Emitter(); tmp.load(source.emitters); options.emitters.value.push(tmp); } } } removeEmitter(emitter) { const index = this.#instancesManager.getArray(this.container).indexOf(emitter), minIndex = 0, deleteCount = 1; if (index >= minIndex) { this.#instancesManager.getArray(this.container).splice(index, deleteCount); } } reset() { } }