UNPKG

@tsparticles/plugin-canvas-mask

Version:

tsParticles canvas mask plugin

299 lines (283 loc) 14 kB
(function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this); /* Plugin v4.3.2 */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tsparticles/engine'), require('@tsparticles/canvas-utils')) : typeof define === 'function' && define.amd ? define(['exports', '@tsparticles/engine', '@tsparticles/canvas-utils'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.__tsParticlesInternals = global.__tsParticlesInternals || {}, global.__tsParticlesInternals.plugins = global.__tsParticlesInternals.plugins || {}, global.__tsParticlesInternals.plugins.canvasMask = global.__tsParticlesInternals.plugins.canvasMask || {}), global.__tsParticlesInternals.engine, global.__tsParticlesInternals.canvas.utils)); })(this, (function (exports, engine, canvasUtils) { 'use strict'; class CanvasMaskOverride { color = true; opacity = false; load(data) { if (engine.isNull(data)) { return; } engine.loadProperty(this, "color", data.color); engine.loadProperty(this, "opacity", data.opacity); } } const minAlpha = 0; class CanvasMaskPixels { offset = 4; filter = (pixel) => pixel.a > minAlpha; load(data) { if (engine.isNull(data)) { return; } if (data.filter !== undefined) { if (engine.isString(data.filter)) { if (data.filter in globalThis) { const filter = globalThis[data.filter]; if (engine.isFunction(filter)) { this.filter = filter; } } } else { this.filter = data.filter; } } engine.loadProperty(this, "offset", data.offset); } } class ImageMask { src = ""; load(data) { if (engine.isNull(data)) { return; } engine.loadProperty(this, "src", data.src); } } class FontTextMask { family = "sans-serif"; size = 100; style = ""; variant = ""; weight = ""; load(data) { if (engine.isNull(data)) { return; } engine.loadProperty(this, "family", data.family); engine.loadProperty(this, "size", data.size); engine.loadProperty(this, "style", data.style); engine.loadProperty(this, "variant", data.variant); engine.loadProperty(this, "weight", data.weight); } } class TextMaskLine { separator = "\n"; spacing = 10; load(data) { if (engine.isNull(data)) { return; } engine.loadProperty(this, "separator", data.separator); engine.loadProperty(this, "spacing", data.spacing); } } class TextMask { color = "#000000"; fill = true; font = new FontTextMask(); lines = new TextMaskLine(); text = ""; load(data) { if (engine.isNull(data)) { return; } engine.loadProperty(this, "color", data.color); engine.loadProperty(this, "fill", data.fill); this.font.load(data.font); this.lines.load(data.lines); engine.loadProperty(this, "text", data.text); } } class CanvasMask { element; enable = false; image; override = new CanvasMaskOverride(); pixels = new CanvasMaskPixels(); position; scale = 1; selector; text; constructor() { this.position = { x: 50, y: 50, }; } load(data) { if (engine.isNull(data)) { return; } if (data.element !== undefined && data.element instanceof HTMLCanvasElement) { this.element = data.element; } engine.loadProperty(this, "enable", data.enable); if (data.image) { this.image ??= new ImageMask(); this.image.load(data.image); } this.pixels.load(data.pixels); if (data.position) { this.position = { x: data.position.x ?? this.position.x, y: data.position.y ?? this.position.y, }; } this.override.load(data.override); engine.loadProperty(this, "scale", data.scale); engine.loadProperty(this, "selector", data.selector); if (data.text) { this.text ??= new TextMask(); this.text.load(data.text); } } } class CanvasMaskPlugin { id = "canvas-mask"; async getPlugin(container) { const { CanvasMaskPluginInstance } = await Promise.resolve().then(function () { return CanvasMaskPluginInstance$1; }); return new CanvasMaskPluginInstance(container); } loadOptions(_container, options, source) { if (!this.needsPlugin(options) && !this.needsPlugin(source)) { return; } let canvasMaskOptions = options.canvasMask; if (canvasMaskOptions?.load === undefined) { options.canvasMask = canvasMaskOptions = new CanvasMask(); } canvasMaskOptions.load(source?.canvasMask); } needsPlugin(options) { return options?.canvasMask?.enable ?? false; } } async function loadCanvasMaskPlugin(engine) { engine.checkVersion("4.3.2"); await engine.pluginManager.register(e => { e.pluginManager.addPlugin(new CanvasMaskPlugin()); }); } const globalObject = globalThis; globalObject.__tsParticlesInternals = globalObject.__tsParticlesInternals ?? {}; globalObject.loadCanvasMaskPlugin = loadCanvasMaskPlugin; function addParticlesFromCanvasPixels(container, data, position, scale, override, filter) { const { height, width } = data, numPixels = height * width, indexArray = shuffle(range(numPixels)), maxParticles = Math.min(numPixels, container.actualOptions.particles.number.value), canvasSize = container.canvas.size; let selectedPixels = 0; const positionOffset = { x: (canvasSize.width * position.x) / engine.percentDenominator - width * scale * engine.half, y: (canvasSize.height * position.y) / engine.percentDenominator - height * scale * engine.half, }; while (selectedPixels < maxParticles && indexArray.length) { const defaultIndex = 0, nextIndex = indexArray.pop() ?? defaultIndex, pixelPos = { x: nextIndex % width, y: Math.floor(nextIndex / width), }, row = data.pixels[pixelPos.y]; if (!row) { continue; } const pixel = row[pixelPos.x]; if (!pixel) { continue; } const shouldCreateParticle = filter(pixel); if (!shouldCreateParticle) { continue; } const pos = { x: pixelPos.x * scale + positionOffset.x, y: pixelPos.y * scale + positionOffset.y, }, pOptions = {}; if (override.color) { pOptions.paint = { fill: { color: { value: pixel, }, enable: true, }, }; } if (override.opacity) { pOptions["opacity"] = { value: pixel.a, }; } container.particles.addParticle(pos, pOptions); selectedPixels++; } } function shuffle(array) { const lengthOffset = 1, minIndex = 0; for (let currentIndex = array.length - lengthOffset; currentIndex >= minIndex; currentIndex--) { const randomIndex = Math.floor(engine.getRandom() * currentIndex), currentItem = array[currentIndex], randomItem = array[randomIndex]; if (randomItem === currentItem) { continue; } if (randomItem === undefined || currentItem === undefined) { continue; } array[currentIndex] = randomItem; array[randomIndex] = currentItem; } return array; } const range = (n) => [...Array(n).keys()]; class CanvasMaskPluginInstance { #container; constructor(container) { this.#container = container; } async init() { const container = this.#container, options = container.actualOptions.canvasMask; if (!options?.enable) { return; } let pixelData = { pixels: [], height: 0, width: 0, }; const offset = options.pixels.offset; if (options.image) { const url = options.image.src; if (!url) { return; } pixelData = await canvasUtils.getImageData(url, offset, container.canvas.render.settings); } else if (options.text) { const textOptions = options.text, data = canvasUtils.getTextData(textOptions, offset, textOptions.fill, container.canvas.render.settings); if (engine.isNull(data)) { return; } pixelData = data; } else if (options.element ?? options.selector) { const canvas = options.element ?? (options.selector && engine.safeDocument().querySelector(options.selector)); if (!canvas) { return; } const context = canvas.getContext("2d", container.canvas.render.settings); if (!context) { return; } pixelData = canvasUtils.getCanvasImageData(context, canvas, offset); } addParticlesFromCanvasPixels(container, pixelData, options.position, options.scale, options.override, options.pixels.filter); } } var CanvasMaskPluginInstance$1 = /*#__PURE__*/Object.freeze({ __proto__: null, CanvasMaskPluginInstance: CanvasMaskPluginInstance }); exports.loadCanvasMaskPlugin = loadCanvasMaskPlugin; })); Object.assign(globalThis.window || globalThis, { loadCanvasMaskPlugin: (globalThis.__tsParticlesInternals.plugins.canvasMask || {}).loadCanvasMaskPlugin }); delete (globalThis.window || globalThis).tsparticlesInternalExports;