我正在尝试在 Konva React 画布中创建一个“战争迷雾”系统,类似于您在 Roll20 或其他虚拟桌面上可能找到的系统。画布上的矩形应该隐藏(显示黑色区域)或显示(将任何黑色区域变为透明)。这里的简单解决方案是使用异或运算的全局复合区域,但这不能解释在“显示”区域之上绘制的“隐藏”区域。最新的(或者如果您愿意的话,形状列表中稍后的元素)应优先。例如,如果整个画布上有一个“显示”区域,而另一个“隐藏”形状位于其顶部,则该形状仍应为黑色。 XOR 运算仍然会显示整个区域。如何创建这种保留隐藏和显示区域顺序的堆叠全局复合操作。
我提到我已经尝试过全局复合,但下面的代码最能代表理想的方法。
const applyShapes = () => {
// Initialize visibility to true
const newPixelVisibility = Array(stageWidth * stageHeight).fill(true);
// Apply hide shapes
fowShapes.forEach((shape) => {
if (shape.type === TOOL_ENUM.REVEAL) {
for (let x = shape.x; x < shape.x + shape.width; x++) {
for (let y = shape.y; y < shape.y + shape.height; y++) {
if (x >= 0 && x < stageWidth && y >= 0 && y < stageHeight) {
const index = y * stageWidth + x;
newPixelVisibility[index] = shape.layer === FOW_ENUM.HIDE;
}
}
}
}
});
setPixelVisibility(newPixelVisibility);
};
}
return (
<>
{pixelVisibility.map((visible, index) => (
<Rect
key={index}
x={index % stageWidth}
y={Math.floor(index / stageWidth)}
width={1}
height={1}
opacity={visible ? 1 : 0}
fill={'black'}
/>
))}
</>
);
然而,这段代码太慢了,即使在 100x100 的画布中,我每次也会渲染 1000 个矩形,而且我的画布可能会更大。是否有任何方法可以通过计算有效的方式实现上述预期结果?
我把它修好了,把这个留给后代。 “xor”操作不起作用,但“destination-out”操作却可以做到这一点。坦率地说,在学习了所有 HTML 画布的笔和橡皮擦教程之后,我应该早点意识到这一点。