如何同时对多个形状应用透明度?

是否可以同时对多个形状使用不透明度?

你可以使用 opacity 属性来改变任何 Konva 节点的 alpha 通道。根据画布的工作方式,所有形状都有其独立的不透明度值。

这意味着如果你有一个包含多个形状的组,并且该组的 group.opacity(0.5),那么它的效果看起来就像每个形状的 shape.opacity(0.5),而该组的 group.opacity(1)。这意味着你会看到那些形状的重叠区域。

如果我们不想看到透明形状的重叠区域呢?

有一种方法可以修复这种默认行为。你只需要使用 group.cache() 来缓存该组。缓存该组会将其转换为位图并绘制到外部画布中。在下一个绘制调用中,Konva 将使用生成的画布绘制整个组,并将不透明度应用到整个图像上。

因此,当 Konva 为这样的组创建位图缓存时,它会忽略组的透明度绘制内部形状。

请记住,如果一个组被缓存,它有一些缓存节点的限制。例如,如果你进行任何内部更改(如更改形状属性),你必须重新缓存该组。这是一个昂贵的操作,因此不推荐频繁进行,比如在动画中或在每次鼠标移动时。

说明:左侧是默认行为,右侧是使用缓存组修复后的行为。

Konva transparent groupview raw
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/konva@9.3.18/konva.min.js"></script>
<meta charset="utf-8" />
<title>Konva Transparency for several Shapes Demo</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #f0f0f0;
background: linear-gradient(
115deg,
transparent 75%,
rgba(255, 255, 255, 0.8) 75%
)
0 0,
linear-gradient(245deg, transparent 75%, rgba(255, 255, 255, 0.8) 75%)
0 0,
linear-gradient(115deg, transparent 75%, rgba(255, 255, 255, 0.8) 75%)
7px -15px,
linear-gradient(245deg, transparent 75%, rgba(255, 255, 255, 0.8) 75%)
7px -15px,
#f0f0f0;
background-size: 15px 30px;
}
</style>
</head>

<body>
<div id="container"></div>
<script>
var width = window.innerWidth;
var height = window.innerHeight;

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

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

// lets create default group with two overlapping shapes
var 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: 'greed',
})
);
layer.add(group1);

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

// to change opacity behavior we have to fix whole group
group2.cache();
</script>
</body>
</html>