Question

My code is

canvas.clipTo = function (ctx) {

    ctx.beginPath();
    for (var i = 0; i < totalPrintArea; i++) {
        ctx.save();
        ctx.fillStyle = 'rgba(51,51,51,0)';
        ctx.rect(clipLft[i], clipTp[i], clipW[i], clipH[i], 'rgba(51,51,51,1)', clipRtn[i]);
        ctx.stroke();
        ctx.restore();
    }

    ctx.closePath();
    ctx.clip();
    canvas.calcOffset();
};
canvas.renderAll();

I am taking values from the red dotted box and apply to clip where multiple masks are generating.

My issue is its taking all properties but not rotation for all.

I want to rotate all the rectangles.

I just get some code to change the rotation for the clip like ctx.rotate(50); but will not work as I want to make all rotate with their own values

Please guide me for the same.

no description

Was it helpful?

Solution

On the original fabricJS github project I saw the comment: https://github.com/kangax/fabric.js/issues/932#issuecomment-27223912

and decided that I need to prevent making ctx.beginPath all the time:

canvas.clipTo = function(ctx) { 
var skip = false;
// Workaround to make possible 
// making clipTo with 
// fabric.Group 
var oldBeginPath = ctx.beginPath;
ctx.beginPath = function() {
if (!skip) {
  oldBeginPath.apply(this, arguments);
  skip = true;
  setTimeout(function() {
    skip = false;
  }, 0);
}
}
group.render(ctx)
};

You can see my workaround to the problem described: https://jsfiddle.net/freelast/6o0o07p7/

The workaround is not perfect, but hope it will help somebody.

OTHER TIPS

I have tried using the Andrey's answer, but althouth there some interesting points, it didn't work.

If you try to clip the canvas to a single object (e.g. a circle or a rectangle), you can simply do this:

canvas.clipTo = function(ctx) {
    shape.render(ctx); //shape is a circle, for instance
}

However, as explained by Kienz and butch2k in the aforementioned comment on GitHub, the problem is that you cannot use this solution with groups. In particular, if you use the following snippet:

canvas.clipTo = function(ctx) {
    group.render(ctx);
}

you will only see one object of the group to be used for clipping.

The issue is due to the render method, which calls the ctx.beginPath() and ctx.closePath() for each object in the group. And because only the last couple of beginPath-closePath calls will affect the clipping, you need some workaround.

So in my solution, I have temporarily redefined the ctx.closePath and ctx.beginPath methods (after storing them in other two temporary variables, named oldBeginPath and oldClosePath) so that they do nothing. Then I call oldBeginPath at the beginning, and after rendering all the objects in the group I call the oldClosePath.

And now, here is the (working) snippet:

canvas.clipTo = function(ctx) {
    var oldBeginPath = ctx.beginPath;
    var oldClosePath = ctx.closePath;

    ctx.beginPath = function() {}
    ctx.closePath = function() {}

    oldBeginPath.apply(ctx);
    group.forEachObject(function(shape){
        shape.render(ctx);
    });
    oldClosePath.apply(ctx);

    ctx.beginPath = oldBeginPath;
    ctx.closePath = oldClosePath;
};

Hope this will save someone's spare time in the future.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top