FabricJS - Canvas 自由绘图模式下的混合模式

FabricJS - Canvas blend mode in free drawing mode

当使用无结构绘图模式时,我想用不透明度向 canvas 添加不同的线条。当相互绘制时,这些线不应该增加它们的不透明度。因此,我将 canvas 混合模式更改为 xor。无论如何,当彼此画线时,不透明度仍然会增加。我在这里做错了什么?

var canvas = new fabric.Canvas("a", {
  isDrawingMode : true
});

document.getElementById("cbFreeDrawing").onchange = function () {
  canvas.isDrawingMode = this.checked;
};

canvas.setBackgroundImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas.renderAll.bind(canvas));

canvas.freeDrawingBrush.width = 25;
canvas.freeDrawingBrush.color = "rgba(255,0,0,.5)";
//this seems not to work
canvas.getContext().globalCompositeOperation = 'xor';
canvas {
  border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.min.js"></script>
Drawing Mode: <input id="cbFreeDrawing" type="checkbox" checked="true"/><br/>
<canvas id="a" width="400" height="300"></canvas>

在 freeDrawing 期间,您正在 upperCanvasEl 上绘图,canvas 元素放置在 lowerCanvasEl 上。 这些元素的上下文总是准备好获取属性: canvas.contextTopcanvas.contextContainer.

您可以做的是在传递给 lowerCanvas 时将单一路径 globalCompositeOperation 设置为 'xor'。您可以使用一个事件 (path:created)。 我将背景移动到单独的 canvas 中(但它可以只是放置在 canvas 下方的图像),这样线条就不会与背景本身异或。

var canvas = new fabric.Canvas("a", {
  isDrawingMode : true
});
var canvas2 = new fabric.StaticCanvas("b");
canvas.lowerCanvasEl.parentNode.appendChild(canvas2.lowerCanvasEl)

document.getElementById("cbFreeDrawing").onchange = function () {
  canvas.isDrawingMode = this.checked;
};
canvas.on('path:created', function(opt) {
  opt.path.globalCompositeOperation = 'xor';
  canvas.renderAll();
});
canvas2.setBackgroundImage('http://fabricjs.com/assets/jail_cell_bars.png', canvas2.renderAll.bind(canvas2));

canvas.freeDrawingBrush.width = 25;
canvas.freeDrawingBrush.color = "rgba(255,0,0,.5)";
//this seems not to work
canvas.contextTop.globalCompositeOperation = 'xor';
canvas {
  border: 1px solid;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.6.3/fabric.min.js"></script>
Drawing Mode: <input id="cbFreeDrawing" type="checkbox" checked="true"/><br/>
<canvas id="a" width="400" height="300"></canvas>
<canvas id="b" width="400" height="300"></canvas>

+AndreaBogazzi 刚刚发现提供的答案仅在不透明度为 .5 时有效,前提是将其设置为另一个值不透明度重叠/组合/以另一种方式表现。

Fiddle(为更好理解而简化):https://jsfiddle.net/c8mf391q/

var canvas = new fabric.Canvas("a", {
        isDrawingMode : true
});



canvas.on('path:created', function(opt) {
  opt.path.globalCompositeOperation = 'xor';
  canvas.renderAll();
});


canvas.freeDrawingBrush.width = 25;
canvas.freeDrawingBrush.color = "rgba(255,0,0,.3)";