Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Fabric.js how do I modify the object class so all sub-classes will have a new custom attribute?

I am looking for a way to extend the base fabric.Object class with a custom attribute I can save to JSON and load from JSON that would propagate all the way into the various sub classes.

Specifically i want to store a depth attribute so when i load the objects from the JSON i will be able to add the appropriate parallax to the object.

I imagine the solution would include modifying the fabric.Object.prototype. But i am still learning how to work with prototypes.

Here is some examples of what i have tried: http://www.sitepoint.com/fabric-js-advanced/

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

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

This does a great job at giving the specific object 'rect' the attribute desired, as well as making it available in the toJSON() method. But it fails to make it available for all objects and when i use loadFromJSON() it does not contain the new attribute.

Any help would be appreciated!

Other resources that got me closer to a solution:

Fabric.js - how to save canvas on server with custom attributes
 - Creates a subclass with the custom attributes but nothing inherits from it.

https://github.com/kangax/fabric.js/wiki/Adding-additional-object-properties-to-serialized-JSON
 - completely rewrites the methods needed in order to include custom attributes (I would prefer not to modify the core of fabricjs)

like image 846
payne8 Avatar asked Oct 18 '13 07:10

payne8


1 Answers

The simplest way would be to just specify which properties you'd like included when calling toJSON:

canvas.toJSON([ 'selectable', 'lockMovementX' ]);

But if you want to really-really add them to the output, you can monkey-patch fabric.Object.prototype.toObject the same way it's done with rectangle:

fabric.Object.prototype.toObject = (function (toObject) {
    return function () {
        return fabric.util.object.extend(toObject.call(this), {
            foobar: 123
        });
    };
})(fabric.Object.prototype.toObject);
like image 137
kangax Avatar answered Nov 03 '22 20:11

kangax