@tsparticles/engine
Version:
Easily create highly customizable particle, confetti and fireworks animations and use them as animated backgrounds for your website. Ready to use components available also for React, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Riot.js, Inferno.
146 lines (145 loc) • 4.65 kB
JavaScript
import { getItemMapFromInitializer, getItemsFromInitializer } from "../../Utils/Utils.js";
import { EventType } from "../../Enums/Types/EventType.js";
export class PluginManager {
colorManagers = new Map();
easingFunctions = new Map();
effectDrawers = new Map();
initializers = {
effects: new Map(),
shapes: new Map(),
updaters: new Map(),
};
palettes = new Map();
plugins = [];
presets = new Map();
shapeDrawers = new Map();
updaters = new Map();
#allLoadersSet = new Set();
#configs = new Map();
#engine;
#executedSet = new Set();
#initialized = false;
#isRunningLoaders = false;
#loadPromises = new Set();
constructor(engine) {
this.#engine = engine;
}
get configs() {
const res = {};
for (const [name, config] of this.#configs) {
res[name] = config;
}
return res;
}
addColorManager(name, manager) {
this.colorManagers.set(name, manager);
}
addConfig(config) {
const key = config.key ?? config.name ?? "default";
this.#configs.set(key, config);
this.#engine.dispatchEvent(EventType.configAdded, { data: { name: key, config } });
}
addEasing(name, easing) {
if (this.easingFunctions.get(name)) {
return;
}
this.easingFunctions.set(name, easing);
}
addEffect(effect, drawer) {
this.initializers.effects.set(effect, drawer);
}
addPalette(name, palette) {
this.palettes.set(name, palette);
}
addParticleUpdater(name, updaterInitializer) {
this.initializers.updaters.set(name, updaterInitializer);
}
addPlugin(plugin) {
if (this.getPlugin(plugin.id)) {
return;
}
this.plugins.push(plugin);
}
addPreset(preset, options, override = false) {
if (!(override || !this.getPreset(preset))) {
return;
}
this.presets.set(preset, options);
}
addShape(shapes, drawer) {
for (const shape of shapes) {
this.initializers.shapes.set(shape, drawer);
}
}
clearPlugins(container) {
this.effectDrawers.delete(container);
this.shapeDrawers.delete(container);
this.updaters.delete(container);
}
getEasing(name) {
return this.easingFunctions.get(name) ?? ((value) => value);
}
getEffectDrawers(container, force = false) {
return getItemMapFromInitializer(container, this.effectDrawers, this.initializers.effects, force);
}
getPalette(name) {
return this.palettes.get(name);
}
getPlugin(plugin) {
return this.plugins.find(t => t.id === plugin);
}
getPreset(preset) {
return this.presets.get(preset);
}
async getShapeDrawers(container, force = false) {
return getItemMapFromInitializer(container, this.shapeDrawers, this.initializers.shapes, force);
}
async getUpdaters(container, force = false) {
return getItemsFromInitializer(container, this.updaters, this.initializers.updaters, force);
}
async init() {
if (this.#initialized || this.#isRunningLoaders) {
return;
}
this.#isRunningLoaders = true;
this.#executedSet = new Set();
this.#allLoadersSet = new Set(this.#loadPromises);
try {
for (const loader of this.#allLoadersSet) {
await this.#runLoader(loader, this.#executedSet, this.#allLoadersSet);
}
}
finally {
this.#loadPromises.clear();
this.#isRunningLoaders = false;
this.#initialized = true;
}
}
loadParticlesOptions(container, options, ...sourceOptions) {
const updaters = this.updaters.get(container);
if (!updaters) {
return;
}
updaters.forEach(updater => updater.loadOptions?.(options, ...sourceOptions));
}
async register(...loaders) {
if (this.#initialized) {
throw new Error("Register plugins can only be done before calling tsParticles.load()");
}
for (const loader of loaders) {
if (this.#isRunningLoaders) {
await this.#runLoader(loader, this.#executedSet, this.#allLoadersSet);
}
else {
this.#loadPromises.add(loader);
}
}
}
async #runLoader(loader, executed, allLoaders) {
if (executed.has(loader))
return;
executed.add(loader);
allLoaders.add(loader);
await loader(this.#engine);
}
}