UNPKG

@tsparticles/plugin-canvas-mask

Version:

tsParticles canvas mask plugin

64 lines (63 loc) 2.44 kB
import { getRandom, half, percentDenominator, } from "@tsparticles/engine"; export 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) / percentDenominator - width * scale * half, y: (canvasSize.height * position.y) / percentDenominator - height * scale * 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(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()];