I am trying to make a customize object just like in the tutorial http://fabricjs.com/fabric-intro-part-3 (the LabeledRect). The object needs to be cloned, so I would have to implement the fromObject
method.
I am using react with typescript and I am not sure how to implement the fromObject
method.
const addLabeledRect = (canv: fabric.Canvas | null) => {
var LabeledRect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function (options: { label?: any; }) {
options || (options = {});
this.callSuper('initialize', options);
this.set('label', options.label || '');
},
toObject: function () {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label')
});
},
_render: function (ctx: { font: string; fillStyle: string; fillText: (arg0: any, arg1: number, arg2: number) => void; }) {
this.callSuper('_render', ctx);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width / 2, -this.height / 2 + 20);
}
});
var labeledRect = new LabeledRect({
width: 100,
height: 50,
left: 100,
top: 100,
label: '1',
fill: '#fff'
});
labeledRect.set('data', {
first_item: 'Hello',
second_item: 'World',
next_itme: true
})
canv?.add(labeledRect);}
This code works just fine, the thing is when I want to copy and paste the object it doesn't work correctly.
How would I implement thefromObject
methode so I am able to copy and paste the object?
I did some research and I found a solution, so I figured I would post it, maybe it is helpfull to somone. This post helped me out a lot: Cloning selection of custom objects
I took me a while, but it turns out you have to assign the property to the fabric library for it to work:
fabric.LabeledRect = fabric.util.createClass(...)
and for typescript first you have to assign fabric to a variable of type any to bypass the type system and than it will work:
var Fabric: any = fabric;
Fabric.LabeledRect = fabric.util.createClass(...)
so I just had to assign fabric to a variable of type any and assign the property to the fabric library and add the fromObject
function.
Now I can copy and paste my the labeledRect.
Here is how I solved it:
const addLabeledRect = (canv: fabric.Canvas | null) => {
var Fabric: any = fabric;
Fabric.LabeledRect = fabric.util.createClass(fabric.Rect, {
type: 'labeledRect',
initialize: function (options: { label?: any; }) {
options || (options = {});
this.callSuper('initialize', options);
this.set('label', options.label || '');
},
toObject: function () {
return fabric.util.object.extend(this.callSuper('toObject'), {
label: this.get('label')
});
},
_render: function (ctx: { font: string; fillStyle: string; fillText: (arg0: any, arg1: number, arg2: number) => void; }) {
this.callSuper('_render', ctx);
ctx.font = '20px Helvetica';
ctx.fillStyle = '#333';
ctx.fillText(this.label, -this.width / 2, -this.height / 2 + 20);
}
}
);
//added this part
Fabric.LabeledRect.fromObject = function (object: any, callback: any) {
var labeledRect = new Fabric.LabeledRect(object);
callback && callback(labeledRect);
return labeledRect;
};
var labeledRect = new Fabric.LabeledRect({
width: 100,
height: 50,
left: 100,
top: 100,
label: '1',
fill: '#fff'
});
labeledRect.set('data', {
first_item: 'Hello',
second_item: 'World',
next_itme: true
})
canv?.add(labeledRect);}