Pergunta

In HTML5 canvas I'm trying to knock out an object with another object and stroke the final product of this operation. Is that possible at all? I'm using the following code with no success:

var tcan = document.getElementById('test');
var tctx = tcan.getContext('2d');

tctx.beginPath();

tctx.fillStyle = '#F00';
tctx.fillRect(0,0,70,70);

tctx.globalCompositeOperation = "destination-out";

tctx.fillRect(20,20,70,70);
tctx.closePath();

tctx.strokeStyle = '#FF0'; // expecting the final product to have a yellow stroke
tctx.stroke();
Foi útil?

Solução

A Demo: http://jsfiddle.net/m1erickson/x8Maf/

enter image description here

You can use source-atop compositing to draw your yellow stroke only atop your existing knockout:

tctx.beginPath();

tctx.fillStyle = '#F00';
tctx.fillRect(0,0,70,70);

// knock-out compositing
tctx.globalCompositeOperation = "destination-out";

tctx.fillRect(20,20,70,70);
tctx.closePath();

// composite where new drawings appear only where overlapping existing
tctx.globalCompositeOperation = "source-atop";

tctx.strokeStyle = '#FF0'; // expecting the final product to have a yellow stroke
tctx.lineWidth=2;
tctx.strokeRect(20,20,70,70);

// restore the default compositing
tctx.globalCompositeOperation = "source-over";

A couple of hints:

  • You don't need beginPath if you use fillRect or strokeRect (these commands automatically beginPath for you);

  • All canvas strokes are half-inside and half-outside the specified dimensions. So fillRect(20,20,70,70) will actually stroke from 19.50 to 20.50.

[ Addition to answer: Here's how to stroke the knockout shape. ]

var tcan = document.getElementById('test');
var tctx = tcan.getContext('2d');

tctx.lineWidth=2;
tctx.strokeStyle = '#FF0'; 

tctx.fillStyle = '#F00';
tctx.fillRect(50,50,70,70);
tctx.strokeRect(50,50,70,70);

// knock-out compositing
tctx.globalCompositeOperation = "destination-out";

tctx.fillRect(70,70,70,70);
tctx.closePath();

// composite where new drawings appear only where overlapping existing
tctx.globalCompositeOperation = "source-atop";

tctx.lineWidth=4;
tctx.strokeRect(70,70,70,70);

// restore the default compositing
tctx.globalCompositeOperation = "source-over";
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top