Canvas/Fabric.js .loadFromJSON() replaces entire c

2019-06-04 08:01发布

问题:

I have 2 JSON objects:

  • jSONObject1

    {"type":"group","originX":"left","originY":"top","left":0,"top":0,"objects": [{"type":"line","stroke":"grey","x1":430,"x2":20.0,"y1":430,"y2":430}, {"type":"line","stroke":"grey","x1":430,"x2":20.0,"y1":20.0,"y2":20.0}, {"type":"line","stroke":"grey","x1":430,"x2":430,"y1":20.0,"y2":430}, {"type":"line","stroke":"grey","x1":20.0,"x2":20.0,"y1":430,"y2":20.0}]}

contains an array of lines to be drawn on the canvas that make up a building floorplan

  • jSONObject2

    {"type":"group","originX":"left","originY":"top","left":0,"top":0, "objects":[{"type":"rect","originX":"left","originY":"top","left":45,"top":-405,"width":60,"height":60,"fill":"red"}, {"type":"rect","originX":"left","originY":"top","left":105,"top":-405.0,"width":60,"height":60,"fill":"red"}, {"type":"rect","originX":"left","originY":"top","left":165,"top":-405.0,"width":60,"height":60,"fill":"blue"}, {"type":"rect","originX":"left","originY":"top","left":225,"top":-405.0,"width":60,"height":60,"fill":"blue"}]}

contains an array of rectangles to be drawn on the canvas that show metrics for different points in the floorplan.

I am using .loadFromJSON(...) to render the desired lines/rectangles on the canvas. The problem is that every time this function gets called, it completely replaces everything on the canvas instead of overlaying the floor plan metric rectangles over the floorplan.

What is the best way to render 2 separate JSON objects onto a Canvas element without one overwriting the other?

I have looked at this GitHub issue which suggests using the fromObject() method to add objects from JSON without clearing the entire canvas. In theory this sounds like a decent idea... This page also leads to 2 jsfiddle "examples" of how to use this fromObject method, one of which doesn't even work and the other of which seems to be working but is very unclear.

Trying to use loadFromJSON() (Overwrites):

Canvas canvas = document.getElementById("myCanvas");
canvas.loadFromJSON(JSON.stringify(jSONObject1))
canvas.loadFromJSON(JSON.stringify(jSONObject2))
canvas.renderAll();

Trying to use fromObject() (Doesn't work)

var jSONObjects = jSONObject1.concat(jSONObject2);
for (var i = 0; i < jSONObjects.length; i++) {
    var klass = fabric.util.getKlass(jSONObjects[i].type);
    var obj = klass.fromObject(jSONObjects[i]);
    canvas.add(obj);
}
canvas.renderAll();

Thanks in advance.

回答1:

I've never tried the fromObject() method.

I'd try merging the two JSON objects first using concat, then use loadFromJson().

var finalFloorPlan = jSONObject1.concat(jSONObject2);


回答2:

If you look at the code for loadFromJSON, the canvas is cleared each time.

loadFromJSON: function (json, callback, reviver) {
if (!json) {
  return;
}

// serialize if it wasn't already
var serialized = (typeof json === 'string')
  ? JSON.parse(json)
  : json;

this.clear();

var _this = this;
this._enlivenObjects(serialized.objects, function () {
  _this._setBgOverlay(serialized, callback);
}, reviver);

return this;
},

You will need to concat your two JSON objects.