FabricJS - 自由绘图模式下画布混合模式

5
在使用自由绘制模式时,我想向画布添加具有不透明度的不同线条。这些线条在相互绘制时不应该累加它们的不透明度。因此,我将画布混合模式更改为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>


相关链接:https://dev59.com/2F7Va4cB1Zd3GeqPFwjo - Fidel90
只需访问此页面:http://fabricjs.com/freedrawing - Rohit Tagadiya
2个回答

5
在freeDrawing期间,您是在upperCanvasEl上进行绘图的,它是放置在lowerCanvasEl上方的画布元素。 这些元素的上下文始终准备好获取属性:canvas.contextTopcanvas.contextContainer
您可以在传递到lowerCanvas时将单个路径globalCompositeOperation设置为“xor”。有一个事件(path:created)可供使用。 我将背景移动到单独的画布中(但它也可以只是放置在画布下面的图像),以便线条不会与背景本身异或。

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>


嗨,Andrea。感谢您的回复。不幸的是,与我上面的示例相比,我无法看到任何结果上的差异。我错过了什么吗? - Fidel90
不好意思,我误解了问题。不同的线条在不同的时刻绘制。让我检查一下。 - AndreaBogazzi
1
更改了答案。我没有正确理解问题。 - AndreaBogazzi
有没有办法在绘制现有路径时不累加不透明度?我猜问题在于不同的画布层,所以 globalCompositeOperation 不起作用。 - Fidel90

0
+AndreaBogazzi 刚刚发现,提供的答案仅在不透明度为0.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)";

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接