When you need more visual flexibility than a solid color overlay for your Fabric.js canvas, the library supports image-based foreground masking. Unlike solid color overlays that automatically span the entire canvas regardless of viewport changes, image overlays require consideration of their inherent dimensions and interactions with panning and zooming operations.
To apply an image overlay directly during canvas initialization, set the overlayImage configuration property to a valid image URL. This overlay will obscure all underlying canvas content, including background colors, background images, and added objects.
<canvas id="fabricStage" width="500" height="500"></canvas>
<script>
const stage = new fabric.Canvas('fabricStage', {
overlayImage: 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=400&w=400',
backgroundColor: 'teal'
});
const displayBox = new fabric.Rect({
width: 100,
height: 100,
fill: 'gold',
top: 120,
left: 120
});
stage.add(displayBox);
</script>
By default, image overlays adhere to viewport transformations, meaning panning or zooming the canvas will shift or resize the overlay, potentially exposing the underlying background. To lock the overlay in place relative to the canvas container instead of the virtual canvas space, set overlayVpt to false.
<canvas id="fabricStage" width="500" height="500"></canvas>
<script>
const stage = new fabric.Canvas('fabricStage', {
overlayImage: 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=400&w=400',
overlayVpt: false,
backgroundColor: 'teal'
});
const displayBox = new fabric.Rect({
width: 100,
height: 100,
fill: 'gold',
top: 120,
left: 120
});
stage.add(displayBox);
// Mouse wheel zoom handler
stage.on('mouse:wheel', event => {
const scrollDelta = event.e.deltaY;
let currentZoom = stage.getZoom();
currentZoom *= 0.998 ** scrollDelta;
currentZoom = Math.min(Math.max(currentZoom, 0.05), 15);
stage.zoomToPoint(
{ x: event.e.offsetX, y: event.e.offsetY },
currentZoom
);
event.e.preventDefault();
event.e.stopPropagation();
});
// Canvas panning handlers
stage.on('mouse:down', event => {
stage.dragActive = true;
stage.lastCursorX = event.e.clientX;
stage.lastCursorY = event.e.clientY;
});
stage.on('mouse:move', event => {
if (!stage.dragActive) return;
const transform = stage.viewportTransform;
transform[4] += event.e.clientX - stage.lastCursorX;
transform[5] += event.e.clientY - stage.lastCursorY;
stage.requestRenderAll();
stage.lastCursorX = event.e.clientX;
stage.lastCursorY = event.e.clientY;
});
stage.on('mouse:up', () => {
stage.setViewportTransform(stage.viewportTransform);
stage.dragActive = false;
});
</script>
For granular control over the overlay image’s position, rotation, opacity, and more, use the setOverlayImage method. This method accepts three arguments: an image URL or instance, a callback function to re-render the canvas, and an optional configuration object for image properties.
stage.setOverlayImage(
'https://images.unsplash.com/photo-1517849845537-4d257902454a?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=300&w=300',
stage.renderAll.bind(stage),
{
originX: 'center',
originY: 'center',
top: 250,
left: 250,
opacity: 0.7,
angle: 15
}
);