Fabric.js subclassing fabric.Group - Error: "Unable to read the" async "property from undefined" when loading from JSON

You have the following problem:

Attempting to subclass fabric.Group:

var CustomGroup = fabric.util.createClass(fabric.Group, { type : 'customGroup', initialize : function(objects, options) { options || ( options = { }); this.callSuper('initialize', objects, options); this.set('customAttribute', options.customAttribute || 'undefinedCustomAttribute'); }, toObject : function() { return fabric.util.object.extend(this.callSuper('toObject'), { customAttribute : this.get('customAttribute') }); }, _render : function(ctx) { this.callSuper('_render', ctx); } }); 

TestCase:

I create a red rectangle and add it to the user group:

 function drawTestRect() { // create a rectangle object var rect = new fabric.Rect({ left : 100, top : 100, fill : 'red', width : 20, height : 20 }); var cgroup = new CustomGroup([rect], { top : 50, left : 50, customAttribute : 'Hello World' }); canvas.add(cgroup); }; 

Problem: I want to get JSON on the canvas, and then I want to load the canvas from JSON.

drawTestRect ()

var savedCanvas = canvas.toJSON ();

canvas.clear ();

canvas.loadFromJSON (savedCanvas);

Everything works fine (Rect / Group is drawn, JSON is valid), but when I boot from JSON, I get the following error in the console:

TypeError: cannot read property asynchronous from undefined

What else have I tried:

  • I added " CustomGroup.async = false; ". But didn’t help
+6
source share
1 answer

The error "Unable to read the property" async "from undefined" occurs because "klass" was not found - https://github.com/kangax/fabric.js/blob/master/src/util/misc.js#L214-215 .

You must assign your custom object to the fabric object - otherwise canvas.loadFromJSON() does not work.

 var fabric.CustomGroup = fabric.util.createClass(fabric.Group, { type : 'customGroup', initialize : function(objects, options) { options || ( options = { }); this.callSuper('initialize', objects, options); this.set('customAttribute', options.customAttribute || 'undefinedCustomAttribute'); }, toObject : function() { return fabric.util.object.extend(this.callSuper('toObject'), { customAttribute : this.get('customAttribute') }); }, _render : function(ctx) { this.callSuper('_render', ctx); } }); 

In addition, you must declare a fromObject method - this is necessary for loadFromJSON . In this case, your object is synchronous with the load.

 fabric.CustomGroup.fromObject = function (object, callback) { var _enlivenedObjects; fabric.util.enlivenObjects(object.objects, function (enlivenedObjects) { delete object.objects; _enlivenedObjects = enlivenedObjects; }); return new fabric.CustomGroup(_enlivenedObjects, object); }; 

If your custom object is loaded async, you should do this:

 fabric.CustomGroup.fromObject = function (object, callback) { fabric.util.enlivenObjects(object.objects, function (enlivenedObjects) { delete object.objects; callback && callback(new fabric.CustomGroup(enlivenedObjects, object)); }); }; fabric.CustomGroup.async = true; 

I made a small jsfiddle test file: http://jsfiddle.net/Kienz/qPLY6/

+12
source

Source: https://habr.com/ru/post/971282/


All Articles