Applying Visual Overlays to Mask Canvas Content in Fabric.js

When using Fabric.js, the overlayColor property provides a straightforward way to mask everything on a canvas by drawing a layer above all visual content.

Configuring the Overlay Layer

During instantiation, pass overlayColor along with other canvas options:

<canvas id="surface"></canvas>

<script>
  const surface = new fabric.Canvas('surface', {
    overlayColor: 'hotpink',
    backgroundColor: 'indigo'
  });
</script>

The hotpink overlay sits above the indigo background, completely concealing it.

Impact on Background Images

Loading a background image dynamically does not affect the overlay stacking order:

<canvas id="surface"></canvas>

<script>
  const surface = new fabric.Canvas('surface', {
    overlayColor: 'hotpink'
  });

  surface.setBackgroundImage(
    'https://picsum.photos/800/600',
    () => surface.renderAll()
  );
</script>

The image remains hidden behind the overlay until the mask is removed.

Impact on Canvas Objects

Objects promoted to the highest z-index are still rendered beneath the overlay:

<canvas id="surface"></canvas>

<script>
  const surface = new fabric.Canvas('surface', {
    overlayColor: 'hotpink'
  });

  const block = new fabric.Rect({
    width: 120,
    height: 90,
    fill: 'yellow'
  });

  surface.add(block);
  block.bringToFront();
</script>

Even after bringToFront(), the rectangle stays below the global overlay.

Clearing the Mask Programmatically

To reveal the scene, reset overlayColor and refresh the canvas:

<canvas id="surface"></canvas>

<script>
  const surface = new fabric.Canvas('surface', {
    overlayColor: 'hotpink'
  });

  surface.setBackgroundImage(
    'https://picsum.photos/800/600',
    () => surface.renderAll()
  );

  const block = new fabric.Rect({ width: 120, height: 90, fill: 'yellow' });
  surface.add(block);

  setTimeout(() => {
    surface.overlayColor = null;
    surface.renderAll();
  }, 1000);
</script>

Assigning null, transparent, or an empty string to overlayColor removes the mask. A manual render call is necessary because Fabric.js does not repaint automatically when this property changes directly.

Runtime Overlay Control with setOverlayColor

Instead of mutating the property directly, use setOverlayColor(overlayColor, callback) to apply masks dynamically and ensure the canvas refreshes.

Applying a solid color:

surface.setOverlayColor(
  'steelblue',
  () => surface.renderAll()
);

The callback fires after the overlay is applied, making it convenient to chain updates:

surface.setOverlayColor('tomato', () => {
  console.log('Mask active');
  surface.renderAll();
});

Applying a tiled pattern:

surface.setOverlayColor(
  { source: '/textures/grid.png' },
  () => surface.renderAll()
);

Fabric.js repeats the image automatically to fill the entire canvas. You can oevrride tiling and positioning behavior:

surface.setOverlayColor(
  {
    source: '/textures/grid.png',
    repeat: 'no-repeat',
    offsetX: 100,
    offsetY: 80
  },
  () => surface.renderAll()
);

Event Interactions Under the Overlay

Because the overlay is a visual property rather than an interactive element, it does not block mouse or touch events. Users can still select, drag, and modify objects underneath the mask. Cursor changes indicate that hidden elements remain fully interactive.

Tags: fabric.js Canvas javascript web development frontend

Posted on Fri, 11 Sep 2026 16:14:13 +0000 by crusty_php