Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
126
rated 0 times [  133] [ 7]  / answers: 1 / hits: 20981  / 13 Years ago, sun, july 31, 2011, 12:00:00

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!


More From » json

 Answers
8

fabric.Canvas#toJSON actually 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 about JSON.stringify is that it supports custom serialization; all you need to do is pass an object that has toJSON method. And this is exactly what I did in fabric — fabric.Canvas has toJSON method, which is essentially an alias to toObject method.



This allows us to serialize canvas by doing something as simple as:



JSON.stringify(canvas);


.. where canvas is a reference to fabric.Canvas instance.



The difference between toObject and toDatalessObject (as well as toJSON and toDatalessJSON) is that toDatalessObject returns 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:



{ angle : 3,
fill : #00274D,
flipX : false,
flipY : false,
height : 115,
left : 353,
opacity : 1,
overlayFill : null,
path : [ [ M,
67.390000000000001,
22.390000000000001
],
[ c,
2.5899999999999999,
-0.42999999999999999,
5.1100000000000003,
1.4399999999999999,
5.54,
4.1799999999999997
],
[ c,
0.42999999999999999,
2.6600000000000001,
-1.3,
5.2599999999999998,
-3.8900000000000001,
5.6900000000000004
],
[ c,
-1.8,
0.28999999999999998,
-3.6000000000000001,
-0.57999999999999996,
-4.6100000000000003,
-2.02
],
[ L,
44.5,
34.560000000000002
],
[ l,
10.869999999999999,
59.619999999999997
],
[ c,
17.420000000000002,
-4.46,
26.059999999999999,
-14.18,
27.5,
-29.02
],
[ l,
-10.01,
-0.71999999999999997
],
[ L,
88.700000000000003,
51.909999999999997
],
[ l,
9.4299999999999997,
21.239999999999998
],
[ c,
-3.3799999999999999,
-1.95,
-5.9000000000000004,
-5.1100000000000003,
-9.2899999999999991,
-7.0599999999999996
],
[ c,
-0.28999999999999998,
25.059999999999999,
-27.140000000000001,
32.759999999999998,
-33.770000000000003,
47.950000000000003
],
[ C,
44.420000000000002,
100.08,
26.5,
114.77,
6.9100000000000001,
82.799999999999997
],
[ L,
0,
92.450000000000003
],
[ l,
1.51,
-21.600000000000001
],
[ l,
19.66,
4.6799999999999997
],
[ l,
-9.4299999999999997,
3.6699999999999999
],
[ c,
7.4900000000000002,
11.59,
17.57,
19.870000000000001,
36.43,
16.420000000000002
],
[ L,
36.219999999999999,
36.57
],
[ l,
-18.649999999999999,
2.3799999999999999
],
[ c,
-0.14000000000000001,
2.1600000000000001,
-1.73,
4.0300000000000002,
-3.8900000000000001,
4.3899999999999997
],
[ c,
-2.5899999999999999,
0.42999999999999999,
-5.04,
-1.4399999999999999,
-5.54,
-4.0999999999999996
],
[ c,
-0.42999999999999999,
-2.7400000000000002,
1.3,
-5.2599999999999998,
3.8900000000000001,
-5.6900000000000004
],
[ c,
1.9399999999999999,
-0.35999999999999999,
3.8900000000000001,
0.65000000000000002,
4.9000000000000004,
2.2999999999999998
],
[ l,
17.93,
-4.8200000000000003
],
[ l,
-1.3700000000000001,
-6.8399999999999999
],
[ c,
-4.8200000000000003,
-0.79000000000000004,
-8.9299999999999997,
-4.75,
-9.7899999999999991,
-10.08
],
[ c,
-1.1499999999999999,
-6.6200000000000001,
3.1000000000000001,
-12.890000000000001,
9.4299999999999997,
-13.970000000000001
],
[ c,
6.4100000000000001,
-1.01,
12.460000000000001,
3.46,
13.539999999999999,
10.08
],
[ c,
0.85999999999999999,
5.1799999999999997,
-1.5800000000000001,
10.15,
-5.6900000000000004,
12.6
],
[ l,
1.8700000000000001,
6.1200000000000001
],
[ l,
20.739999999999998,
-2.8799999999999999
],
[ C,
64.010000000000005,
24.260000000000002,
65.519999999999996,
22.75,
67.390000000000001,
22.390000000000001
],
[ L,
67.390000000000001,
22.390000000000001
],
[ z ],
[ M,
33.909999999999997,
5.1799999999999997
],
[ c,
-3.46,
0.57999999999999996,
-5.7599999999999998,
3.96,
-5.1100000000000003,
7.5599999999999996
],
[ c,
0.57999999999999996,
3.6000000000000001,
3.8900000000000001,
6.0499999999999998,
7.2699999999999996,
5.4699999999999998
],
[ c,
3.46,
-0.57999999999999996,
5.7599999999999998,
-3.96,
5.1799999999999997,
-7.5599999999999996
],
[ C,
40.609999999999999,
7.0499999999999998,
37.369999999999997,
4.6100000000000003,
33.909999999999997,
5.1799999999999997
],
[ z ]
],
scaleX : 3.0299999999999998,
scaleY : 3.0299999999999998,
selectable : true,
stroke : null,
strokeWidth : 1,
top : 220,
type : path,
width : 99
}


you would have this:



{ angle : 3,
fill : #00274D,
flipX : false,
flipY : false,
height : 115,
left : 353,
opacity : 1,
overlayFill : null,
path : http://example.com,
scaleX : 3.0299999999999998,
scaleY : 3.0299999999999998,
selectable : true,
stroke : null,
strokeWidth : 1,
top : 220,
type : path,
width : 99
}


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 setSourcePath method before calling toDatalessObject/toDatalessJSON on it (sourcePath is internally copied to path).



Hope this clears things up a little.


[#90905] Friday, July 29, 2011, 13 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
jonrened

Total Points: 627
Total Questions: 114
Total Answers: 99

Location: Zimbabwe
Member since Thu, Jul 21, 2022
2 Years ago
;