仅绘制来自其他两个 canvas 的 canvas 上的重叠像素

Draw only overlapping pixels on a canvas from two other canvasses

我有 2 个相同的画布,我用鼠标在上面绘制,还有第 3 个(仍然相同的宽度和高度),我想通过只显示重叠像素来获得其他 2 个的 'combination' , 表示与最初的 2 个画布具有相同坐标的那些。

类似于:

const left = document.querySelector('#canvasLeft');
const right = document.querySelector('#canvasRight');
const combined = document.querySelector('#canvasCombined');
        
const draw = () => {
   // do drawing on each canvas...
    
   // get image data from the canvasses...
   const imageDataRight = right.ctx.getImageData(0, 0, right.canvas.width, right.canvas.height);
   const imageDataLeft = left.ctx.getImageData(0, 0, left.canvas.width, left.canvas.height);
    
   // do something with the image data picking only the matching pixels from each canvas --> PLEASE HELP!       
   combined.ctx.putImageData(imageDataCombined, 0, 0);
        
}

更新:请参阅下图,更好地解释我要实现的目标

我相信你想要的是异或复合模式的反面。您应该通过在“正常”复合模式下将 2 个画布绘制到第 3 个画布中来获得所需的结果。然后再异或模式绘制。

let canvas1 = document.getElementById("canvas1");
let canvas2 = document.getElementById("canvas2");
let canvas3 = document.getElementById("canvas3");

let c1 = canvas1.getContext("2d");
let c2 = canvas2.getContext("2d");
let c3 = canvas3.getContext("2d");

// Draw into canvas1
c1.fillStyle = "#000000";
c1.beginPath();
c1.fillRect(0, 0, 60, 60);
c1.stroke();

// Draw into canvas2
c2.fillStyle = "#000000";
c2.beginPath();
c2.fillRect(40, 40, 60, 60);
c2.stroke();

// Reset composite mode to default
c3.globalCompositeOperation = 'source-over';
// Draw 1 and 2 into 3
c3.drawImage(canvas1, 0, 0);
c3.drawImage(canvas2, 0, 0);
// Turn on xor
c3.globalCompositeOperation = 'xor';
// Draw 1 and 2 into 3 again
c3.drawImage(canvas1, 0, 0);
c3.drawImage(canvas2, 0, 0);
canvas {
  border: 1px solid red;
}
<canvas id="canvas1" width="100" height="100"></canvas>
<canvas id="canvas2" width="100" height="100"></canvas>
<canvas id="canvas3" width="100" height="100"></canvas>

我用一个圆圈试了一下,它在圆角线上的抗锯齿方面有问题。所以这是使用图像数据的另一种方式。

let canvas1 = document.getElementById("canvas1");
let canvas2 = document.getElementById("canvas2");
let canvas3 = document.getElementById("canvas3");

let c1 = canvas1.getContext("2d");
let c2 = canvas2.getContext("2d");
let c3 = canvas3.getContext("2d");

// Draw into canvas1
c1.beginPath();
c1.fillRect(0, 0, 60, 60);
c1.stroke();

// Draw into canvas2
c2.beginPath();
c2.arc(60, 60, 20, 0, 2 * Math.PI, false);
c2.fill();
c2.lineWidth = 1;
c2.stroke();

var data1 = c1.getImageData(0, 0, 100, 100);
var data2 = c2.getImageData(0, 0, 100, 100);
var data3 = c3.getImageData(0, 0, 100, 100);

for (let pixel = 0; pixel < data3.data.length; pixel += 4) {
    if (data1.data[pixel+3] > 0 && data2.data[pixel+3] > 0) {
    data3.data[pixel]   = 0;
    data3.data[pixel+1] = 0;
    data3.data[pixel+2] = 0;
    data3.data[pixel+3] = 255;
  }
}
c3.putImageData(data3, 0, 0);
canvas {
  border: 1px solid red;
}
<canvas id="canvas1" width="100" height="100"></canvas>
<canvas id="canvas2" width="100" height="100"></canvas>
<canvas id="canvas3" width="100" height="100"></canvas>