I am trying to save data in JSON and load it back into the canvas with fabric.js I keep getting errors likep with the following simple code:
canvas.add(new fabric.Rect({ width: 50, height: 50, fill: 'red', top: 100, left: 100 }));
var c = canvas.toJSON();
canvas.clear();
canvas.loadFromJSON(c);
I get:
SyntaxError: JSON.parse: unexpected character
[Break On This Error] var Cufon=(function(){var k=function()....Image.fromElement.async=true})(this);
When I use my own JSON, It validates well, but I still get errors when I use whatever was output by fabric’s method canvas.toJSON(). Anyone would have working examples of loading back into an empty canvas data saved from a previous canvas state in fabric.js? It would be greatly appreciated!
fabric.Canvas#toJSONactually returns an object, not a JSON string.Sorry, if this is confusing.
The reason this works like that is due to
JSON.stringify. The thing aboutJSON.stringifyis that it supports custom serialization; all you need to do is pass an object that hastoJSONmethod. And this is exactly what I did in fabric — fabric.Canvas hastoJSONmethod, which is essentially an alias totoObjectmethod.This allows us to serialize canvas by doing something as simple as:
.. where
canvasis a reference tofabric.Canvasinstance.The difference between
toObjectandtoDatalessObject(as well astoJSONandtoDatalessJSON) is thattoDatalessObjectreturns “url” instead of actual path data. This is done to save on size of canvas representation with shapes of large size. If you load large SVG shape, its path data could literally result in multi-million character string. If you later need to serialize this data (say, for saving purposes), it makes much more sense to replace path data with URL of svg shape. Just imagine having to upload/download such huge strings to the server back and forth.So, instead of this:
you would have this:
Notice how large that data is, and how relatively small it becomes by replacing path chunk with url.
And that’s a representation of a very simple shape.
The only requirement here is to set object’s “sourcePath” using
setSourcePathmethod before callingtoDatalessObject/toDatalessJSONon it (“sourcePath” is internally copied to “path”).Hope this clears things up a little.