带变换的Fabricjs遮罩对象

带变换的Fabricjs遮罩对象,fabricjs,Fabricjs,我正在尝试使用Fabric.js免费画笔遮罩对象。如果对象处于其默认位置且没有任何变换,则可以正常工作。但一旦我向对象添加了变换,遮罩就会被放置在错误的位置。我不知道如何解决这个问题。有人能看一下吗 我希望能够应用任何变换,在掩码之前或之后,而不会弄乱掩码 let canvas = new fabric.Canvas("canvas", { backgroundColor: "lightgray", width: 1280, height: 720, preser

我正在尝试使用
Fabric.js
免费画笔遮罩对象。如果对象处于其默认位置且没有任何变换,则可以正常工作。但一旦我向对象添加了变换,遮罩就会被放置在错误的位置。我不知道如何解决这个问题。有人能看一下吗

我希望能够应用任何变换,在掩码之前或之后,而不会弄乱掩码

let canvas = new fabric.Canvas("canvas", {
    backgroundColor: "lightgray",
    width: 1280,
    height: 720,
    preserveObjectStacking: true,
    selection: false,
    stateful: true
});

canvas.isDrawingMode = true;
canvas.freeDrawingBrush.color = "black";
canvas.freeDrawingBrush.width = 2;

canvas.on("path:created", function(options) {
    clip(options.path);
});

function clip(path) {
    canvas.isDrawingMode = false;
    canvas.remove(path);

    let mask = new fabric.Path(path.path, {
        top: object.top,
        left: object.left,
        objectCaching: false,
        strokeWidth: 0,
        pathOffset: {
            x: 0,
            y: 0
        }
    });

    let originalObjLeft = object.left,
        originalObjTop = object.top;

    object.set({
        clipTo: function(ctx) {
            mask.set({
                left: -object.width / 2 - mask.width / 2 - originalObjLeft,
                top: -object.height / 2 - mask.height / 2 - originalObjTop,
                objectCaching: false
            });
            mask.render(ctx);
        }
    });

    canvas.requestRenderAll();
}

// image

let image = new Image();
let object;

image.onload = function() {
    object = new fabric.Image(image, {
        width: 500,
        height: 500,
        //scaleX: 0.8,
        //scaleY: 0.8,
        //angle: 45,
        top: 50,
        left: 300
    });

    canvas.add(object);
};

image.src = "http://i.imgur.com/8rmMZI3.jpg";

我实现了一个带有一些转换的示例(
scaleX
scaleY
left
top
)。 当初始对象的角度不同于0时,我很难找到解决方案。对于当前解决方案,我需要它将
遮罩
比例与
对象
比例分开,并调整位置

let canvas=new fabric.canvas(“canvas”{
背景颜色:“浅灰色”,
宽度:1280,
身高:720,
对,对,
选择:假,
有状态的:正确的
});
canvas.isDrawingMode=true;
canvas.freedrawingprush.color=“黑色”;
canvas.freeDrawingBrush.width=2;
canvas.on(“路径:已创建”),函数(选项){
剪辑(options.path);
});
功能剪辑(路径){
canvas.isDrawingMode=false;
canvas.remove(路径);
让mask=new fabric.Path(Path.Path{
top:object.top,
左:object.left,
objectCaching:false,
冲程宽度:0,
scaleX:1/object.scaleX,
scaleY:1/object.scaleY,
补偿:{
x:0,,
y:0
}
});
让originalObjLeft=object.left,
originalObjTop=object.top,
originalMaskScaleX=mask.scaleX,
originalMaskScaleY=mask.scaleY,
originalObjScaleX=object.scaleX,
originalObjScaleY=object.scaleY;
object.set({
clipTo:功能(ctx){
掩码集({
左:-object.width/2-(mask.width/2*originalMaskScaleX)-originalObjLeft/originalObjScaleX,
顶部:-object.height/2-(mask.height/2*originalMaskScaleY)-originalObjTop/originalObjScaleY,
objectCaching:false
});
蒙版渲染(ctx);
}
});
canvas.requestRenderal();
}
//形象
让图像=新图像();
image.onload=函数(){
对象=新结构。图像(图像{
宽度:500,
身高:500,
scaleX:0.8,
斯卡利:0.8,
//角度:45,
前50名,
左:100
});
canvas.add(对象);
};
image.src=”http://i.imgur.com/8rmMZI3.jpg";

基本上,无论何时设置角度,您的上下文矩阵都已转换。为了正确地屏蔽,您需要返回到变换矩阵的初始状态。Fabricjs处理具有对象中心点的第一个矩阵(计算具有或不具有角度的对象的中心)。第二个矩阵是旋转矩阵,第三个是缩放矩阵。 要显示设置为对象的所有选项的图像,需要将所有矩阵相乘:

(First Matrix * Second Matrix) * Third Matrix
因此,裁剪的思想将是旋转上下文和矩阵乘法的反向工程: 不旋转的规则对象的中心点与旋转的同一对象的中心点之间的差异。然后取减法的结果,除以原始对象比例值

let canvas=new fabric.canvas(“canvas”{
背景颜色:“浅灰色”,
宽度:1280,
身高:720,
对,对,
选择:假,
有状态的:正确的
});
常数角=45;
让objecthasnrotated=false;
canvas.isDrawingMode=true;
canvas.freedrawingprush.color=“黑色”;
canvas.freeDrawingBrush.width=2;
canvas.on(“路径:已创建”),函数(选项){
剪辑(options.path);
});
功能剪辑(路径){
canvas.isDrawingMode=false;
canvas.remove(路径);
让mask=new fabric.Path(Path.Path{
排名:0,
左:0,,
objectCaching:false,
冲程宽度:0,
scaleX:1/object.scaleX,
scaleY:1/object.scaleY,
补偿:{
x:0,,
y:0,
}
});
让originalObjLeft=object.left,
originalObjTop=object.top,
originalMaskScaleX=mask.scaleX,
originalMaskScaleY=mask.scaleY,
originalObjScaleX=object.scaleX,
originalObjScaleY=object.scaleY,
transformedTranslate=object.translateToGivenOrigin({
x:object.left,
y:object.top
},object.originX,object.originY,'center','center',
OriginalTransferMLEFT=transformedTranslate.x-object.getCenterPoint().x,
originalTransformTop=transformedTranslate.y-object.getCenterPoint().y;
object.set({
clipTo:功能(ctx){
ctx.save();
ctx.旋转(-angle*Math.PI/180);
ctx.translate(原始传输MLEFT/originalObjScaleX,原始传输MTOP/originalObjScaleY)
掩码集({
左:-object.width/2-(mask.width/2*originalMaskScaleX)-originalObjLeft/originalObjScaleX,
顶部:-object.height/2-(mask.height/2*originalMaskScaleY)-originalObjTop/originalObjScaleY,
objectCaching:false
});
蒙版渲染(ctx);
ctx.restore();
}
});
canvas.requestRenderal();
}
//形象
让图像=新图像();
image.onload=函数(){
对象=新结构。图像(图像{
宽度:500,
身高:500,
scaleX:0.8,
斯卡利:0.8,
角度:角度,,
前50名,
左:300,,
id:'帕格'
});
canvas.add(对象);
};
image.src=”http://i.imgur.com/8rmMZI3.jpg";


我认为这不能正常工作。放置遮罩后,调整对象大小会弄乱遮罩。谢谢你的帮助。@marius我对图案也有一个问题。在保存和编辑它们之后,我在它们上面得到了黑色的覆盖。你能帮帮我吗?我在视网膜上,可能是因为这个原因,它从这里不起作用。现在面具放好了,但当旋转物体时,它弄乱了面具的位置。@lolol,ple