跳到主要内容

如何同时为多个图形应用透明度?

可以同时为多个图形设置不透明度吗?

可以使用 opacity 属性更改任意 Konva 节点的 Alpha 通道。由于 Canvas 的工作方式,每个图形都有独立的不透明度值。

这意味着,如果一个组包含多个图形,并且该组设置了 group.opacity(0.5),其外观将与以下设置完全相同:组内每个图形设置 shape.opacity(0.5),组设置 group.opacity(1)。因此,你会看到这些图形的重叠区域。

如果不想看到透明图形的重叠区域,该怎么办?

可以修正这种默认行为。只需使用 group.cache() 缓存组。缓存组会将其转换为位图,并绘制到外部 Canvas。下次绘制时,Konva 会使用生成的 Canvas 绘制整个组,并将不透明度应用到整个图像。

因此,Konva 为此类组创建位图缓存时,会忽略组的透明度来绘制内部图形。

请记住,缓存组会受到缓存节点的一些限制。如果进行了内部更改(例如更改图形属性),必须重新缓存该组。此操作开销较大,因此不要频繁执行,例如在动画中或每次 mousemove 时执行。

在以下示例中,左侧显示默认行为,右侧显示使用缓存组修正后的行为。

尝试拖动两个组,查看透明度应用方式的差异。左侧组显示默认行为,可看到重叠区域。右侧组显示缓存后的行为,整个组被视为一个透明单元。

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