Skip to main content

How to apply transparency for several shapes at once?

Is it possible to use opacity for several shapes at the same time?

You can use the opacity attribute to change the alpha channel of any Konva node. Due to how canvas works, all shapes have their own independent opacity values.

That means if you have a group with several shapes inside and that group has group.opacity(0.5), it will look exactly the same as if each shape inside the group has shape.opacity(0.5) and the group has group.opacity(1). This means you will see overlapping areas of those shapes.

What if we don't want to see overlapping areas of transparent shapes?

There is a way to fix such default behavior. You just need to cache the group with group.cache(). Caching the group will convert it into a bitmap and draw it into an external canvas. On the next draw call, Konva will use that resulted canvas to draw the whole group with opacity applied to the whole image.

So while Konva is making a bitmap cache for such group, it will draw internal shapes ignoring transparency of the group.

Remember that if a group is cached, it has some limitations of cached nodes. If you are doing any internal changes (like changing shapes attributes), you have to recache the group. This is an expensive operation, so it is not recommended to do it frequently like inside animations or on every mousemove.

In the demo below, on the left you see the default behavior, on the right you see the fixed behavior with a cached group.

Try dragging both groups to see the difference in how transparency is applied. The left group shows the default behavior with visible overlapping areas, while the right group shows the cached behavior where the entire group is treated as a single transparent unit.

import Konva from 'konva';
// Stage setup
const width = window.innerWidth;
const height = window.innerHeight;

const stage = new Konva.Stage({
  container: 'container',
  width: width,
  height: height,
});

const layer = new Konva.Layer();
stage.add(layer);

// lets create default group with two overlapping shapes
const group1 = new Konva.Group({
  opacity: 0.5,
  x: 50,
  y: 50,
  draggable: true,
});
group1.add(
  new Konva.Rect({
    width: 100,
    height: 100,
    fill: 'red',
  })
);
group1.add(
  new Konva.Circle({
    x: 100,
    y: 100,
    radius: 70,
    fill: 'green',
  })
);
layer.add(group1);

// lets create the second group
const group2 = group1.clone({ x: 250 });
layer.add(group2);

// to change opacity behavior we have to cache whole group
group2.cache();