4

I use fabric.js and I need a transparent rect to be on a canvas, but I need to use background.
The problem is that I need background to be transparent under the rect.

I've created a fiddle to illustrate my problem: http://jsfiddle.net/goooseman/5xLE4/2/ (I need background to be transparent under the square).

I think that it is impossible to make a hole in a background, but we can use another rect as a background. I've created another fiddle to show it: http://jsfiddle.net/goooseman/cNJwL/1/ I use this code to make background rect:

var backgroundRect = new fabric.Rect({
    left: 0,
    top: 0,
    fill: 'red',
    width: canvas.width,
    height: canvas.height
});

But how can I make a hole in the background rect under the upper rect?

goooseman
  • 619
  • 5
  • 12

3 Answers3

3

Maybe this could help (as found in this question).

You need to first, add the canvas background object to which you want to do the "hole". Then, you create a new object (the cutter), and set the property globalCompositeOperation = 'destination-out', and then you add it to the canvas.

Just like this:

var h = new fabric.Rect({width: canvas.width, height: canvas.height, fill: 'rgba(0,0,0,0.5)'})
var z = new fabric.Circle({radius: 100, top:100, left: 100, globalCompositeOperation: 'destination-out'})
canvas.add(h).add(z)

This way, you add first the global object, and then you add the object as a "cutter". I think it will act as a cutter for everything, so if you have other objects "behind", they will be cut too (haven't tested it).

Hope this helps!!

Community
  • 1
  • 1
Unapedra
  • 2,043
  • 4
  • 25
  • 42
  • Perfect dude. Exactly what I needed. I was aware of 'destination-out' for canvas but wasn't sure how to apply in fabricjs. – Luke Fixt Mar 20 '17 at 02:27
1

If it is just a square that needs to be cut out, you can simply draw 4 squares around it with the background colour.

fabric.StaticCanvas('canvas');
canvas.setHeight(300);
canvas.setWidth(300);

var bgrect = new fabric.Rect({
    left:0,
    top:0,
    fill: 'red',
    width: 100,
    height: 300,
});
canvas.add(bgrect);
bgrect = new fabric.Rect({
    left:200,
    top:0,
    fill: 'red',
    width: 100,
    height: 300,
});
canvas.add(bgrect);
canvas.add(bgrect);
bgrect = new fabric.Rect({
    left:100,
    top:0,
    fill: 'red',
    width: 100,
    height: 100,
});
canvas.add(bgrect);
bgrect = new fabric.Rect({
    left:100,
    top:200,
    fill: 'red',
    width: 100,
    height: 100,
});
canvas.add(bgrect);

See this fiddle

Sumurai8
  • 20,333
  • 11
  • 66
  • 100
0

I know I am late, but this can be useful for some users who can look for an answer

drawRectangleWithHole(document.getElementById('canvas').getContext('2d'), "black", 50, 50, 200, 200, 50, 50, 100, 100)

function drawRectangleWithHole(ctx, color, x, y, width, height, holeX, holeY, holeWidth, holeHeight) {
  ctx.fillStyle = color
  ctx.fillRect(x, y, holeX, height)
  ctx.fillRect(x, y, width, holeY)
  ctx.fillRect(x + holeX + holeWidth, y, width - (holeX + holeWidth), height)
  ctx.fillRect(x, y + holeY + holeHeight, width, height - (holeY + holeHeight))
}
<canvas id="canvas" width="300" height="300"><canvas>

Note that the hole's X and Y coordinates are relative to the rectangle