tsParticles plugin for handling background mask feature.
@tsparticles/engine (or use the CDN bundle below)tsParticles.load(...)tsParticles.load(...) configThe CDN/Vanilla version JS has one required file in vanilla configuration:
Including the tsparticles.plugin.backgroundMask.min.js file will export the function to load the plugin:
loadBackgroundMaskPlugin;
Once the scripts are loaded you can set up tsParticles and the plugin like this:
(async () => {
await loadBackgroundMaskPlugin(tsParticles);
await tsParticles.load({
id: "tsparticles",
options: {/* options */},
});
})();
This package is compatible also with ES or CommonJS modules, firstly this needs to be installed, like this:
$ npm install @tsparticles/plugin-background-mask
or
$ yarn add @tsparticles/plugin-background-mask
Then you need to import it in the app, like this:
const { tsParticles } = require("@tsparticles/engine");
const { loadBackgroundMaskPlugin } = require("@tsparticles/plugin-background-mask");
(async () => {
await loadBackgroundMaskPlugin(tsParticles);
})();
or
import { tsParticles } from "@tsparticles/engine";
import { loadBackgroundMaskPlugin } from "@tsparticles/plugin-background-mask";
(async () => {
await loadBackgroundMaskPlugin(tsParticles);
})();
backgroundMask{
"backgroundMask": {}
}
tsParticles.load(...) before loadBackgroundMaskPlugin(...)cover.draw or cover.element, cover.color and cover.image become optional. If none of the four are set, the mask cover is transparent (no static fallback). Fixed in 4.3.0 — earlier builds hang if both color and image are omitted.draw callback receives a fake delta ({ value: 0, factor: 1 }) because canvasPaint() doesn't have access to the real frame delta.The cover object now supports two dynamic sources: element (auto-draw external visual source) and draw (custom callback). When either is set, the static cover (color/image) is skipped.
clear() ← canvas pixel clear
cover.element auto-draw ← ctx.drawImage() of external element (if set)
cover.draw callback ← custom draw function on main context (if set)
static cover (color/image) ← fallback, only if neither element nor draw is set
globalCompositeOperation ← activated by drawSettingsSetup (unchanged)
particles ← unmasked particles (unchanged)
cover.elementType: string | HTMLCanvasElement | OffscreenCanvas | HTMLVideoElement | HTMLImageElement
Auto-draws an external element onto the canvas every frame via ctx.drawImage(), before the mask composite mode is applied. The element's rendering/playback is managed by external code — the plugin only reads its visual content.
// JS config — direct canvas reference
const animCanvas = document.getElementById("myAnimation") as HTMLCanvasElement;
await tsParticles.load({
id: "tsparticles",
options: {
backgroundMask: {
enable: true,
cover: {
element: animCanvas,
opacity: 1,
},
},
},
});
// JSON config — CSS selector for a video element in the DOM
{
"backgroundMask": {
"enable": true,
"cover": {
"element": "#webcam",
"opacity": 0.8,
},
},
}
cover.drawType: (context: BackgroundDrawContext, delta: IDelta) => void
Custom draw callback executed every frame during canvasPaint(). Receives the main canvas context (never the element context). Note: delta is currently a fallback { value: 0, factor: 1 } since canvasPaint() does not receive a real delta.
// JS config — animated gradient as mask
await tsParticles.load({
id: "tsparticles",
options: {
backgroundMask: {
enable: true,
cover: {
draw: (ctx, delta) => {
const t = performance.now() * 0.001;
ctx.fillStyle = `hsl(${(t * 50) % 360}, 70%, 50%)`;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
},
},
},
},
});
element and drawIf both are set, element is auto-drawn first, then draw is called. Both layers are independent.
Configs without element or draw work identically to before (static color/image cover).
HTMLCanvasElement | OffscreenCanvas | HTMLVideoElement | HTMLImageElement): stored directlydocument.querySelector() in DOM environments
mask-element-not-supported)mask-element-not-found)undefined/null: skipped, static cover used| Key | Message | Condition |
|---|---|---|
mask-element-not-found |
Mask cover element selector "..." not found in the DOM |
CSS selector didn't match any element |
mask-element-not-supported |
Mask cover element "..." matched a non-drawable element (expected canvas, video, or img) |
selector matched a non-drawable element |
mask-element-draw-error |
Error drawing background mask cover element onto canvas |
ctx.drawImage() threw during element auto-draw |
mask-draw-error |
Error in mask cover.draw callback |
the cover.draw callback threw |
drawImage() auto-scales the element to fill the canvasOffscreenCanvas must be controlled externallyTwo demo configurations are available in utils/configs/src/b/:
key: "backgroundMaskDraw") — animated HSL gradient via cover.drawkey: "backgroundMaskElement") — CSS selector #mask-video via cover.elementBoth require backgroundMask.enable: true and load via the @tsparticles/configs package. Use the tsparticles all bundle (loadAll) or load the background mask plugin manually.