@tsparticles/plugin-canvas-mask
Version:
tsParticles canvas mask plugin
64 lines (63 loc) • 2.44 kB
JavaScript
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()];