npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tsparticles/plugin-background-mask

v4.3.2

Published

tsParticles background mask plugin

Readme

banner

tsParticles Background Mask Plugin

jsDelivr npmjs npmjs GitHub Sponsors

tsParticles plugin for handling background mask feature.

Quick checklist

  1. Install @tsparticles/engine (or use the CDN bundle below)
  2. Call the package loader function(s) before tsParticles.load(...)
  3. Apply the package options in your tsParticles.load(...) config

How to use it

CDN / Vanilla JS / jQuery

The 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;

Usage

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 */},
  });
})();

ESM / CommonJS

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);
})();

Option mapping

  • Primary options key: backgroundMask
{
  "backgroundMask": {}
}

Common pitfalls

  • Calling tsParticles.load(...) before loadBackgroundMaskPlugin(...)
  • Verify required peer packages before enabling advanced options
  • Change one option group at a time to isolate regressions quickly
  • When using 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.
  • The draw callback receives a fake delta ({ value: 0, factor: 1 }) because canvasPaint() doesn't have access to the real frame delta.

Dynamic Mask Sources (since 4.3.0)

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.

Layer order

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.element

Type: 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.draw

Type: (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);
        },
      },
    },
  },
});

Using both element and draw

If both are set, element is auto-drawn first, then draw is called. Both layers are independent.

Legacy behavior unchanged

Configs without element or draw work identically to before (static color/image cover).

Element resolution rules

  • Direct reference (HTMLCanvasElement | OffscreenCanvas | HTMLVideoElement | HTMLImageElement): stored directly
  • CSS selector string: resolved via document.querySelector() in DOM environments
    • Matched drawable element → stored
    • Matched non-drawable element → warning logged once (mask-element-not-supported)
    • No match → warning logged once (mask-element-not-found)
  • undefined/null: skipped, static cover used

Warning keys (logged once per key)

| 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 |

Environment notes

  • Non-DOM environments safely skip CSS selector resolution
  • drawImage() auto-scales the element to fill the canvas
  • Video frame playback is managed externally (plugin reads current frame only)
  • OffscreenCanvas must be controlled externally

Demo configs

Two demo configurations are available in utils/configs/src/b/:

  • Background Mask Draw (key: "backgroundMaskDraw") — animated HSL gradient via cover.draw
  • Background Mask Element (key: "backgroundMaskElement") — CSS selector #mask-video via cover.element

Both require backgroundMask.enable: true and load via the @tsparticles/configs package. Use the tsparticles all bundle (loadAll) or load the background mask plugin manually.

Related docs