I'm using fabric for a project and was previously faced with a situation where I needed to save some custom attributes along with a class instance (say, an object's database id or some reference to server-side state). These 1 or more attributes will continue to exist when calling toJSON() on a class to save the canvas' state on the server and load it back later on.
I previously asked this on SO and got a pretty good answer that worked well for me at the time.
Lately that solution proved difficult to maintain (I have to verify my custom extension every time I update fabric), and that got me thinking that perhaps there's another way to handle this. The example that comes to mind is the way Backbone.js' views save additional passed attributes inside a special "options" field.
For those of you not familiar with it, basically a Backbone.js view can be instantiated with several pre-defined attributes, and any other custom value that is passed will be stored inside this.options on that model. So, for example, I can define a view instance like this:
App.myView = new Backbone.View({
// model is a predefined attr
model: new Backbone.Model({ name: "Jim", age: 30 }),
// custom attribute
isAdmin: false
});
And then access its attributes later like so:
App.myView.model.get('name'); // "Jim"
App.myView.options.isAdmin; // false
This way one wouldn't have to extend a class or override its constructor just to persist data across server side save/load.
Thoughts?
(I should say that I skipped a few version bumps - so my apologies if something like this already exists and I somehow missed it)
Do you know about toJSON supporting inclusion of custom properties?
Yeah, and that works fine for saving on the server. However, I need that data to be restored when using loadFromJSON.
loadFromJSON respects any of the custom properties in data. Check it out:
canvas.item(0).foo = 'bar'; // custom property
var json = JSON.stringify(canvas.toJSON(['foo'])); // include that property in json
canvas.clear();
canvas.loadFromJSON(json);
canvas.item(0).foo; // "bar" <-- the property is preserved
Fantastic - thanks!
Hi,
I am to facing problem with custom attributes.
my scenario is :-
i am saving the canvas using adding custom attributes, it includes images and svg objects
i use the below method to add custom attributes to it
shape.toObject = (function (toObject) {
return function () {
return fabric.util.object.extend(toObject.call(this), {
name: 'stencil',
maxWidth: maxWidth,
maxHeight: maxHeight,
minWidth: minWidth,
minHeight: minHeight,
lockScalingFlip: true,
cornerColor: 'black',
cornerSize: 10,
scaleX: 2,
scaleY: 2,
transparentCorners: false,
mb: false,
ml: false,
mr: false,
mt: false,
//width: shape.getWidth(),
//height: shape.getHeight()
});
};
})(shape.toObject);
as you can see i use a some custom as well as some inbuilt attributes which the canvas does not save usually using canvas.toJson
the problem i am facing is when i load the objects, the images does seems to face any problems with position and the resizing, but with svg, they seem to to resize back to original svg, i am not sure i am doing something wrong when saving them, i am using scaleX and scaleY along with other things, and i cannot figure a way out to resolve it
I please request you let me know incase am doing something wrong, as for the code it is just as the one you mention aboves expect for the way am adding the custom attributes, in case you still require anything please let me know and thank you very much for your help
please make a fiddle that show the problem. Is not easy to help you in this way.
Hi @asturur,
below is the link for the jsfiddle
https://jsfiddle.net/stormbreakerz/go6fss55/20/
resize the circle, save the json, now load it back it is restored to its original size and not the updated size.
let me know incase you require anything else, thank you.
in the toObject function you are setting scaleX and scaleY fixed at 5. So it is restoring at 5.
Hi @asturur,
thank you very much for your help, after removing scaleX and scaleY from toObject function loadFromJSON is working fine :+1:
Most helpful comment
loadFromJSONrespects any of the custom properties in data. Check it out: