Yeak
Yeak

Reputation: 2538

adding custom attributes to fabricjs object

Im trying to add a custom attribute to a fabric js object that i have:

var trimLine = new fabric.Rect({
    width: Math.round(obj.box_dimensions.box.width,2),
    height: Math.round(obj.box_dimensions.box.height,2),
    strokeWidth: 1,
    stroke: 'rgb(255,2,2)',
    fill: '',
    selectable: false
});

so thats my rectangle im trying to add and i want to pass a name or id in it to be able to identify it later when i get the canvas object and convert it to a json.

I have tried doing

var trimLine = new fabric.Rect({
    width: Math.round(obj.box_dimensions.box.width,2),
    height: Math.round(obj.box_dimensions.box.height,2),
    strokeWidth: 1,
    stroke: 'rgb(255,2,2)',
    fill: '',
    selectable: false,
    name: trimLine
});

canvas.add(trimLine);
canvas.renderAll();

and it did not work i also tried to do

 trimline.name = 'trimLine'

Upvotes: 8

Views: 18463

Answers (6)

Harsh Patel
Harsh Patel

Reputation: 1344

If You use Fabric.js v5 (v5.3) with TypeScript or Angular, and you wish to store custom attributes in Fabric.js Drawing Object, you can achieve it as follows:

// Create a rectangle
const rect = new fabric.Rect({
  left: 100,
  top: 100,
  width: 100,
  height: 100,
  fill: 'red'
});

rect.toObject = function(this: fabric.Rect, propertiesToInclude) {
  return fabric.util.object.extend(fabric.Rect.prototype.toObject.call(this, propertiesToInclude), {
    name: 'some name'
  });
};

this.canvas.add(rect);

// If you wish to add custom attributes using a separate method, you can do it as follows:

/**
 * Adds a custom attribute to a Fabric.js object when serializing to JSON.
 *
 * @param fabricObject - The Fabric.js object to which the custom attribute should be added.
 * @param attributeName - The name of the custom attribute.
 * @param attributeValue - The value of the custom attribute.
 * @returns The Fabric.js object with the custom attribute added.
 */
addCustomAttribute(fabricObject: fabric.Object, attributeName: string, attributeValue: string) {
    /* fabricObject.toObject = function(this: fabric.Rect, propertiesToInclude) {
      return fabric.util.object.extend(fabric.Rect.prototype.toObject.call(this, propertiesToInclude), {
        [attributeName]: attributeValue
      });
    }; */  

  fabricObject.toObject = (function (originalToObject) {
    return function (this: fabric.Object, propertiesToInclude) {
      const customAttributes = {
        [attributeName]: attributeValue
      };
      return fabric.util.object.extend(originalToObject.call(this, propertiesToInclude), customAttributes);
    };
  })(fabricObject.toObject);

  return fabricObject;
}

Additionally, you can export saved data as JSON data by using the toJSON() method. In Fabric.js v5.3, it exports custom attributes in the object. However, if you're not getting custom attributes in the exported JSON object, you can pass the custom attribute names as an array to the toJSON() method:

canvas.toJSON(['myCustomAttr', 'name', 'ownType']);

This will include the specified custom attributes in the exported JSON data.

for more reference

  1. fabric.js - Adding custom properties to a shape
  2. https://github.com/fabricjs/fabric.js/issues/6917#issuecomment-792463545

I hope this helps!

Upvotes: 0

Shashank Bhatt
Shashank Bhatt

Reputation: 857

As per fabric js latest documentation, we can extend object representation with our own property along with it's already existing properties.

var rect = new fabric.Rect();

rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);

canvas.add(rect);

rect.name = 'trololo';

console.log(JSON.stringify(canvas));

Source - http://fabricjs.com/fabric-intro-part-3

Upvotes: 1

Michel
Michel

Reputation: 1153

Found a simple solution if your custom attribute is inside a variable,

var oText = new fabric.IText(text, { 
    left: 100, 
    top: 100 ,
    transparentCorners: false
    });

var attribute = 'my_attribute';
var value = 'first_name';

oText[attribute] = value;

canvas.add(oText);
canvas.renderAll();

Upvotes: 5

Zulander
Zulander

Reputation: 824

I know it's old but this works on version 2.2.3

var trimLine = new fabric.Rect({
                width: Math.round(obj.box_dimensions.trimbox.width,2),
                height: Math.round(obj.box_dimensions.trimbox.height,2),
                strokeWidth: 1,
                stroke: 'rgb(255,2,2)',
                fill: '',
                selectable: false
            });

let obj={hello:'World'};
trimLine.set('helloworld',obj);

then you can get the object

  var myObj = e.target.get('helloworld');

Upvotes: 0

Yeak
Yeak

Reputation: 2538

For those that run into the same issue the way i solved this is by doing the following:

            var trimLine = new fabric.Rect({
                width: Math.round(obj.box_dimensions.trimbox.width,2),
                height: Math.round(obj.box_dimensions.trimbox.height,2),
                strokeWidth: 1,
                stroke: 'rgb(255,2,2)',
                fill: '',
                selectable: false
            });

right below it i added this code:

           trimLine.toObject = function() {
                return {
                    name: 'trimline'
                };
            };

      canvas.add(trimLine);
      canvas.renderAll();

So now when i convert the canvas to a json the trimline object only returns the name which is all i need. Of course you can also add any other info you need as well.

Upvotes: 6

markE
markE

Reputation: 105035

name:trimLine should be name:"trimLine" unless you have previously declared a var trimLine='myTrimLineName'.

FabricJS has many attached properties, including the name property.

To avoid overwriting these native properties, add a sub-property to indicate these are your own custom properties:

// example: using .my to hold your own custom properties
trimLine.my.name='trimLine';
trimLine.my.id='myOwnID15';
trimLine.my.sayName=function(){alert(this.my.name);}

Upvotes: 7

Related Questions