mirror of
https://github.com/Hopiu/fabric.js.git
synced 2026-05-19 02:51:07 +00:00
Merge pull request #839 from Kienz/patch-1
Add reviver function to `fabric.Canvas.loadFromJSON` (and loadFromDatalessJSON). Closes #722
This commit is contained in:
commit
1627e67b48
3 changed files with 114 additions and 55 deletions
|
|
@ -8,11 +8,12 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
* @param {Function} callback Callback, invoked when json is parsed
|
||||
* and corresponding objects (e.g: fabric.Image)
|
||||
* are initialized
|
||||
* @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.
|
||||
* @return {fabric.Canvas} instance
|
||||
* @chainable
|
||||
*/
|
||||
loadFromDatalessJSON: function (json, callback) {
|
||||
return this.loadFromJSON(json, callback);
|
||||
loadFromDatalessJSON: function (json, callback, reviver) {
|
||||
return this.loadFromJSON(json, callback, reviver);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
@ -22,10 +23,11 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
* @param {Function} callback Callback, invoked when json is parsed
|
||||
* and corresponding objects (e.g: fabric.Image)
|
||||
* are initialized
|
||||
* @param {Function} [reviver] Method for further parsing of JSON elements, called after each fabric object created.
|
||||
* @return {fabric.Canvas} instance
|
||||
* @chainable
|
||||
*/
|
||||
loadFromJSON: function (json, callback) {
|
||||
loadFromJSON: function (json, callback, reviver) {
|
||||
if (!json) return;
|
||||
|
||||
// serialize if it wasn't already
|
||||
|
|
@ -38,7 +40,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
var _this = this;
|
||||
this._enlivenObjects(serialized.objects, function () {
|
||||
_this._setBgOverlayImages(serialized, callback);
|
||||
});
|
||||
}, reviver);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
|
@ -109,8 +111,9 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
* @private
|
||||
* @param {Array} objects
|
||||
* @param {Function} callback
|
||||
* @param {Function} [reviver]
|
||||
*/
|
||||
_enlivenObjects: function (objects, callback) {
|
||||
_enlivenObjects: function (objects, callback, reviver) {
|
||||
var _this = this;
|
||||
|
||||
if (objects.length === 0) {
|
||||
|
|
@ -127,7 +130,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
|
|||
|
||||
_this.renderOnAddRemove = renderOnAddRemove;
|
||||
callback && callback();
|
||||
});
|
||||
}, null, reviver);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -163,8 +163,9 @@
|
|||
* @memberOf fabric.util
|
||||
* @param {Array} objects Objects to enliven
|
||||
* @param {Function} callback Callback to invoke when all objects are created
|
||||
* @param {Function} [reviver] Method for further parsing of object elements, called after each fabric object created.
|
||||
*/
|
||||
function enlivenObjects(objects, callback, namespace) {
|
||||
function enlivenObjects(objects, callback, namespace, reviver) {
|
||||
|
||||
function onLoaded() {
|
||||
if (++numLoadedObjects === numTotalObjects) {
|
||||
|
|
@ -184,15 +185,17 @@
|
|||
}
|
||||
var klass = fabric.util.getKlass(o.type, namespace);
|
||||
if (klass.async) {
|
||||
klass.fromObject(o, function (o, error) {
|
||||
klass.fromObject(o, function (obj, error) {
|
||||
if (!error) {
|
||||
enlivenedObjects[index] = o;
|
||||
enlivenedObjects[index] = obj;
|
||||
reviver && reviver(o, enlivenedObjects[index]);
|
||||
}
|
||||
onLoaded();
|
||||
});
|
||||
}
|
||||
else {
|
||||
enlivenedObjects[index] = klass.fromObject(o);
|
||||
reviver && reviver(o, enlivenedObjects[index]);
|
||||
onLoaded();
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,6 +21,23 @@
|
|||
'["c", 0.877, -9.979, 2.893, -12.905, 4.942, -15.621], ["C", 17.878, 21.775, 18.713, 17.397, 18.511, '+
|
||||
'13.99], ["z", null]]}], "background": "#ff5555"}';
|
||||
|
||||
var PATH_OBJ_JSON = '{"type": "path", "originX": "center", "originY": "center", "left": 268, "top": 266, "width": 51, "height": 49,'+
|
||||
' "fill": "rgb(0,0,0)", "overlayFill": null, "stroke": null, "strokeWidth": 1, "scaleX": 1, "scaleY": 1, '+
|
||||
'"angle": 0, "flipX": false, "flipY": false, "opacity": 1, "path": [["M", 18.511, 13.99],'+
|
||||
' ["c", 0, 0, -2.269, -4.487, -12.643, 4.411], ["c", 0, 0, 4.824, -14.161, 19.222, -9.059],'+
|
||||
' ["l", 0.379, -2.1], ["c", -0.759, -0.405, -1.375, -1.139, -1.645, -2.117], ["c", -0.531, '+
|
||||
'-1.864, 0.371, -3.854, 1.999, -4.453], ["c", 0.312, -0.118, 0.633, -0.169, 0.953, -0.169], '+
|
||||
'["c", 1.299, 0, 2.514, 0.953, 2.936, 2.455], ["c", 0.522, 1.864, -0.372, 3.854, -1.999, '+
|
||||
'4.453], ["c", -0.229, 0.084, -0.464, 0.127, -0.692, 0.152], ["l", -0.379, 2.37], ["c", '+
|
||||
'1.146, 0.625, 2.024, 1.569, 2.674, 2.758], ["c", 3.213, 2.514, 8.561, 4.184, 11.774, -8.232],'+
|
||||
' ["c", 0, 0, 0.86, 16.059, -12.424, 14.533], ["c", 0.008, 2.859, 0.615, 5.364, -0.076, 8.224],'+
|
||||
' ["c", 8.679, 3.146, 15.376, 14.389, 17.897, 18.168], ["l", 2.497, -2.151], ["l", 1.206, 1.839],'+
|
||||
' ["l", -3.889, 3.458], ["C", 46.286, 48.503, 31.036, 32.225, 22.72, 35.81], ["c", -1.307, 2.851,'+
|
||||
' -3.56, 6.891, -7.481, 8.848], ["c", -4.689, 2.336, -9.084, -0.802, -11.277, -2.868], ["l",'+
|
||||
' -1.948, 3.104], ["l", -1.628, -1.333], ["l", 3.138, -4.689], ["c", 0.025, 0, 9, 1.932, 9, 1.932], '+
|
||||
'["c", 0.877, -9.979, 2.893, -12.905, 4.942, -15.621], ["C", 17.878, 21.775, 18.713, 17.397, 18.511, '+
|
||||
'13.99], ["z", null]]}';
|
||||
|
||||
var PATH_DATALESS_JSON = '{"objects":[{"type":"path","originX":"center","originY":"center","left":200,"top":200,"width":200,"height":200,"fill":"rgb(0,0,0)",'+
|
||||
'"overlayFill":null,"stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeLineJoin":"miter","strokeMiterLimit":10,'+
|
||||
'"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,'+
|
||||
|
|
@ -346,6 +363,42 @@
|
|||
});
|
||||
});
|
||||
|
||||
test('loadFromJSON with reviver function', function() {
|
||||
ok(typeof canvas.loadFromJSON == 'function');
|
||||
|
||||
function reviver(obj, instance) {
|
||||
deepEqual(obj, JSON.parse(PATH_OBJ_JSON));
|
||||
|
||||
if (instance.type === 'path') {
|
||||
instance.customID = 'fabric_1';
|
||||
}
|
||||
}
|
||||
|
||||
canvas.loadFromJSON(JSON.parse(PATH_JSON), function(){
|
||||
var obj = canvas.item(0);
|
||||
|
||||
ok(!canvas.isEmpty(), 'canvas is not empty');
|
||||
equal(obj.type, 'path', 'first object is a path object');
|
||||
equal(canvas.backgroundColor, '#ff5555', 'backgroundColor is populated properly');
|
||||
|
||||
equal(obj.get('left'), 268);
|
||||
equal(obj.get('top'), 266);
|
||||
equal(obj.get('width'), 51);
|
||||
equal(obj.get('height'), 49);
|
||||
equal(obj.get('fill'), 'rgb(0,0,0)');
|
||||
equal(obj.get('stroke'), null);
|
||||
equal(obj.get('strokeWidth'), 1);
|
||||
equal(obj.get('scaleX'), 1);
|
||||
equal(obj.get('scaleY'), 1);
|
||||
equal(obj.get('angle'), 0);
|
||||
equal(obj.get('flipX'), false);
|
||||
equal(obj.get('flipY'), false);
|
||||
equal(obj.get('opacity'), 1);
|
||||
equal(obj.get('customID'), 'fabric_1');
|
||||
ok(obj.get('path').length > 0);
|
||||
}, reviver);
|
||||
});
|
||||
|
||||
asyncTest('loadFromJSON with no objects', function() {
|
||||
var c1 = new fabric.Canvas('c1', { backgroundColor: 'green' }),
|
||||
c2 = new fabric.Canvas('c2', { backgroundColor: 'red' });
|
||||
|
|
@ -363,6 +416,52 @@
|
|||
}, 500);
|
||||
});
|
||||
|
||||
asyncTest('loadFromJSON with async content', function() {
|
||||
var group = new fabric.Group([
|
||||
new fabric.Rect({ width: 10, height: 20 }),
|
||||
new fabric.Circle({ radius: 10 })
|
||||
]);
|
||||
var rect = new fabric.Rect({ width: 20, height: 10 });
|
||||
var circle = new fabric.Circle({ radius: 25 });
|
||||
|
||||
canvas.add(group, rect, circle);
|
||||
var json = JSON.stringify(canvas);
|
||||
canvas.clear();
|
||||
|
||||
equal(0, canvas.getObjects().length);
|
||||
|
||||
canvas.loadFromJSON(json, function() {
|
||||
equal(3, canvas.getObjects().length);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('loadFromDatalessJSON with async content', function() {
|
||||
|
||||
var circ1 = new fabric.Circle({ radius: 30, fill: '#55f', top: 0, left: 0 });
|
||||
var circ2 = new fabric.Circle({ radius: 30, fill: '#f55', top: 50, left: 50 });
|
||||
var circ3 = new fabric.Circle({ radius: 30, fill: '#5f5', top: 50, left: 50 });
|
||||
|
||||
var arr = [circ1, circ2];
|
||||
var group = new fabric.Group(arr, { top: 150, left: 150 });
|
||||
|
||||
canvas.add(circ3);
|
||||
canvas.add(group);
|
||||
canvas.renderAll();
|
||||
|
||||
canvas.deactivateAll();
|
||||
var json = JSON.stringify( canvas.toDatalessJSON() );
|
||||
canvas.clear();
|
||||
canvas.loadFromDatalessJSON(json, function() {
|
||||
|
||||
equal(2, canvas.getObjects().length);
|
||||
equal('group', canvas.getObjects()[1].type);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
// asyncTest('loadFromJSON with backgroundImage', function() {
|
||||
// canvas.setBackgroundImage('../../assets/pug.jpg');
|
||||
// var anotherCanvas = new fabric.Canvas();
|
||||
|
|
@ -901,52 +1000,6 @@
|
|||
// equal(isFired, true, 'removing active object should fire "selection:cleared"');
|
||||
});
|
||||
|
||||
asyncTest('loadFromJSON with async content', function() {
|
||||
var group = new fabric.Group([
|
||||
new fabric.Rect({ width: 10, height: 20 }),
|
||||
new fabric.Circle({ radius: 10 })
|
||||
]);
|
||||
var rect = new fabric.Rect({ width: 20, height: 10 });
|
||||
var circle = new fabric.Circle({ radius: 25 });
|
||||
|
||||
canvas.add(group, rect, circle);
|
||||
var json = JSON.stringify(canvas);
|
||||
canvas.clear();
|
||||
|
||||
equal(0, canvas.getObjects().length);
|
||||
|
||||
canvas.loadFromJSON(json, function() {
|
||||
equal(3, canvas.getObjects().length);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
asyncTest('loadFromDatalessJSON with async content', function() {
|
||||
|
||||
var circ1 = new fabric.Circle({ radius: 30, fill: '#55f', top: 0, left: 0 });
|
||||
var circ2 = new fabric.Circle({ radius: 30, fill: '#f55', top: 50, left: 50 });
|
||||
var circ3 = new fabric.Circle({ radius: 30, fill: '#5f5', top: 50, left: 50 });
|
||||
|
||||
var arr = [circ1, circ2];
|
||||
var group = new fabric.Group(arr, { top: 150, left: 150 });
|
||||
|
||||
canvas.add(circ3);
|
||||
canvas.add(group);
|
||||
canvas.renderAll();
|
||||
|
||||
canvas.deactivateAll();
|
||||
var json = JSON.stringify( canvas.toDatalessJSON() );
|
||||
canvas.clear();
|
||||
canvas.loadFromDatalessJSON(json, function() {
|
||||
|
||||
equal(2, canvas.getObjects().length);
|
||||
equal('group', canvas.getObjects()[1].type);
|
||||
|
||||
start();
|
||||
});
|
||||
});
|
||||
|
||||
test('clipTo', function() {
|
||||
canvas.clipTo = function(ctx) {
|
||||
ctx.arc(0, 0, 10, 0, Math.PI * 2, false);
|
||||
|
|
|
|||
Loading…
Reference in a new issue