I've read and tried the solution in this thread: How to use Konva.Group with Mask, but I couldn't figure out how to make it work.
My goal is to apply a grayscale image as an opacity mask to a Konva.Group (or even an entire layer) so that the mask controls the transparency of the group based on the grayscale values of the image.
Here’s the structure of my "stack":
Konva.Stage
Konva.Layer // Background layer
Konva.Image // Background image
Konva.Layer // Main content layer
Konva.Group // Group #1 with shapes, images
Konva.Group // Group #2 with shapes, images
Konva.Group // ... (other groups)
Konva.Layer // Mask layer
Konva.Image // Grayscale image for masking
I want the grayscale image from the mask layer to act as a mask for the content in the main content layer or specific groups within it.
Thank you 🇫🇷
Yes, you can achieve this using just the Konva API, including using the globalCompositeOperation = destination-in
for top mask image. Make sure to put the mask image in the same layer as content.
const stage = new Konva.Stage({
container: 'container',
width: window.innerWidth,
height: window.innerHeight,
});
const mainLayer = new Konva.Layer();
stage.add(mainLayer);
// Create the main group and content
const group = new Konva.Group();
mainLayer.add(group);
for (let i = 0; i < 20; i++) {
const circle = new Konva.Circle({
x: Math.random() * stage.width(),
y: Math.random() * stage.height(),
radius: 50 + Math.random() * 30,
fill: Konva.Util.getRandomColor(),
});
group.add(circle);
}
// Mask Image
const maskImageObj = new Image();
maskImageObj.src = 'https://konvajs.org/assets/lion.png'; // Grayscale image
maskImageObj.onload = () => {
const mask = new Konva.Image({
image: maskImageObj,
x: 50,
y: 50,
width: 200,
height: 200,
draggable: true,
globalCompositeOperation: 'destination-in', // Blend mode
});
mainLayer.add(mask);
mainLayer.batchDraw();
};
// Batch draw to update the stage with new content
mainLayer.batchDraw();
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Konva Mask with Global Composite Operation</title>
<script src="https://cdn.jsdelivr.net/npm/konva/konva.min.js"></script>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>