3

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 thefromObjectmethode so I am able to copy and paste the object?

Nick Vu
  • 14,512
  • 4
  • 21
  • 31
JadeDuck
  • 51
  • 5

1 Answers1

0

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);}
JadeDuck
  • 51
  • 5