[BACK_INCOMPAT] fabric.Path.fromObject is now async. fabric.Canvas#loadFromDatalessJSON is deprecated.

This commit is contained in:
kangax 2013-07-12 22:38:21 +02:00
parent 53f1368438
commit c8cab03aac
9 changed files with 97 additions and 285 deletions

View file

@ -1,6 +1,6 @@
/*! Fabric.js Copyright 2008-2013, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: "1.2.1" };
var fabric = fabric || { version: "1.2.2" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;

181
dist/all.js vendored
View file

@ -1,7 +1,7 @@
/* build: `node build.js modules=ALL exclude=gestures` */
/*! Fabric.js Copyright 2008-2013, Printio (Juriy Zaytsev, Maxim Chernyak) */
var fabric = fabric || { version: "1.2.1" };
var fabric = fabric || { version: "1.2.2" };
if (typeof exports !== 'undefined') {
exports.fabric = fabric;
@ -9854,6 +9854,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
/**
* Populates canvas with data from the specified dataless JSON
* JSON format must conform to the one of `fabric.Canvas#toDatalessJSON`
* @deprecated since 1.2.2
* @param {String|Object} json JSON string or object
* @param {Function} callback Callback, invoked when json is parsed
* and corresponding objects (e.g: fabric.Image)
@ -9862,138 +9863,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* @chainable
*/
loadFromDatalessJSON: function (json, callback) {
if (!json) return;
// serialize if it wasn't already
var serialized = (typeof json === 'string')
? JSON.parse(json)
: json;
if (!serialized) return;
if (!serialized.objects) {
serialized.objects = [];
}
this.clear();
var _this = this;
this._enlivenDatalessObjects(serialized.objects, function() {
_this._setBgOverlayImages(serialized, callback);
});
},
/**
* @private
* @param {Array} objects
* @param {Function} callback
*/
_enlivenDatalessObjects: function (objects, callback) {
var _this = this,
numLoadedObjects = 0,
numTotalObjects = objects.length;
/** @ignore */
function onObjectLoaded(object, index) {
_this.insertAt(object, index, true);
object.setCoords();
if (++numLoadedObjects === numTotalObjects) {
callback && callback();
}
}
/** @ignore */
function loadObject(obj, index) {
var pathProp = obj.paths ? 'paths' : 'path';
var path = obj[pathProp];
delete obj[pathProp];
if (typeof path !== 'string') {
if (obj.type === 'image' || obj.type === 'group') {
fabric[fabric.util.string.capitalize(obj.type)].fromObject(obj, function (o) {
onObjectLoaded(o, index);
});
}
else {
var klass = fabric[fabric.util.string.camelize(fabric.util.string.capitalize(obj.type))];
if (!klass || !klass.fromObject) return;
// restore path
if (path) {
obj[pathProp] = path;
}
onObjectLoaded(klass.fromObject(obj), index);
}
}
else {
if (obj.type === 'image') {
fabric.util.loadImage(path, function (image) {
var oImg = new fabric.Image(image);
oImg.setSourcePath(path);
fabric.util.object.extend(oImg, obj);
oImg.setAngle(obj.angle);
onObjectLoaded(oImg, index);
});
}
else if (obj.type === 'text') {
if (obj.useNative) {
onObjectLoaded(fabric.Text.fromObject(obj), index);
}
else {
obj.path = path;
var object = fabric.Text.fromObject(obj);
/** @ignore */
var onscriptload = function () {
// TODO (kangax): find out why Opera refuses to work without this timeout
if (Object.prototype.toString.call(fabric.window.opera) === '[object Opera]') {
setTimeout(function () {
onObjectLoaded(object, index);
}, 500);
}
else {
onObjectLoaded(object, index);
}
};
fabric.util.getScript(path, onscriptload);
}
}
else {
fabric.loadSVGFromURL(path, function (elements) {
var object = fabric.util.groupSVGElements(elements, obj, path);
// copy parameters from serialied json to object (left, top, scaleX, scaleY, etc.)
// skip this step if an object is a PathGroup, since we already passed it options object before
if (!(object instanceof fabric.PathGroup)) {
fabric.util.object.extend(object, obj);
if (typeof obj.angle !== 'undefined') {
object.setAngle(obj.angle);
}
}
onObjectLoaded(object, index);
});
}
}
}
if (numTotalObjects === 0 && callback) {
callback();
}
try {
objects.forEach(loadObject, this);
}
catch(e) {
fabric.log(e);
}
return this.loadFromJSON(json, callback);
},
/**
@ -10014,6 +9884,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
? JSON.parse(json)
: json;
this.clear();
var _this = this;
this._enlivenObjects(serialized.objects, function () {
_this._setBgOverlayImages(serialized, callback);
@ -10097,6 +9969,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
enlivenedObjects.forEach(function(obj, index) {
_this.insertAt(obj, index, true);
obj.setCoords();
});
callback && callback();
});
@ -14527,8 +14400,17 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* @static
* @return {fabric.Path} Instance of fabric.Path
*/
fabric.Path.fromObject = function(object) {
return new fabric.Path(object.path, object);
fabric.Path.fromObject = function(object, callback) {
if (typeof object.path === 'string') {
fabric.loadSVGFromURL(object.path, function (elements) {
var path = fabric.util.groupSVGElements(elements, object, object.path);
// fabric.util.object.extend(path, object);
callback(path);
});
}
else {
callback(new fabric.Path(object.path, object));
}
};
/* _FROM_SVG_START_ */
@ -14552,6 +14434,13 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
};
/* _FROM_SVG_END_ */
/**
* Indicates that instances of this type are async
* @static
* @type Boolean
*/
fabric.Path.async = true;
})(typeof exports !== 'undefined' ? exports : this);
@ -14783,11 +14672,27 @@ fabric.util.object.extend(fabric.Object.prototype, /** @lends fabric.Object.prot
* @param {Object} object
* @return {fabric.PathGroup}
*/
fabric.PathGroup.fromObject = function(object) {
var paths = instantiatePaths(object.paths);
return new fabric.PathGroup(paths, object);
fabric.PathGroup.fromObject = function(object, callback) {
if (typeof object.paths === 'string') {
fabric.loadSVGFromURL(object.paths, function (elements) {
delete object.paths;
var pathGroup = fabric.util.groupSVGElements(elements, object, object.paths);
callback(pathGroup);
});
}
else {
var paths = instantiatePaths(object.paths);
callback(new fabric.PathGroup(paths, object));
}
};
/**
* Indicates that instances of this type are async
* @static
* @type Boolean
*/
fabric.PathGroup.async = true;
})(typeof exports !== 'undefined' ? exports : this);

8
dist/all.min.js vendored

File diff suppressed because one or more lines are too long

BIN
dist/all.min.js.gz vendored

Binary file not shown.

View file

@ -1,7 +1,7 @@
{
"name": "fabric",
"description": "Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.",
"version": "1.2.1",
"version": "1.2.2",
"author": "Juriy Zaytsev <kangax@gmail.com>",
"keywords": ["canvas", "graphic", "graphics", "SVG", "node-canvas", "parser", "HTML5", "object model"],
"repository": "git://github.com/kangax/fabric.js",

View file

@ -3,6 +3,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
/**
* Populates canvas with data from the specified dataless JSON
* JSON format must conform to the one of `fabric.Canvas#toDatalessJSON`
* @deprecated since 1.2.2
* @param {String|Object} json JSON string or object
* @param {Function} callback Callback, invoked when json is parsed
* and corresponding objects (e.g: fabric.Image)
@ -11,138 +12,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
* @chainable
*/
loadFromDatalessJSON: function (json, callback) {
if (!json) return;
// serialize if it wasn't already
var serialized = (typeof json === 'string')
? JSON.parse(json)
: json;
if (!serialized) return;
if (!serialized.objects) {
serialized.objects = [];
}
this.clear();
var _this = this;
this._enlivenDatalessObjects(serialized.objects, function() {
_this._setBgOverlayImages(serialized, callback);
});
},
/**
* @private
* @param {Array} objects
* @param {Function} callback
*/
_enlivenDatalessObjects: function (objects, callback) {
var _this = this,
numLoadedObjects = 0,
numTotalObjects = objects.length;
/** @ignore */
function onObjectLoaded(object, index) {
_this.insertAt(object, index, true);
object.setCoords();
if (++numLoadedObjects === numTotalObjects) {
callback && callback();
}
}
/** @ignore */
function loadObject(obj, index) {
var pathProp = obj.paths ? 'paths' : 'path';
var path = obj[pathProp];
delete obj[pathProp];
if (typeof path !== 'string') {
if (obj.type === 'image' || obj.type === 'group') {
fabric[fabric.util.string.capitalize(obj.type)].fromObject(obj, function (o) {
onObjectLoaded(o, index);
});
}
else {
var klass = fabric[fabric.util.string.camelize(fabric.util.string.capitalize(obj.type))];
if (!klass || !klass.fromObject) return;
// restore path
if (path) {
obj[pathProp] = path;
}
onObjectLoaded(klass.fromObject(obj), index);
}
}
else {
if (obj.type === 'image') {
fabric.util.loadImage(path, function (image) {
var oImg = new fabric.Image(image);
oImg.setSourcePath(path);
fabric.util.object.extend(oImg, obj);
oImg.setAngle(obj.angle);
onObjectLoaded(oImg, index);
});
}
else if (obj.type === 'text') {
if (obj.useNative) {
onObjectLoaded(fabric.Text.fromObject(obj), index);
}
else {
obj.path = path;
var object = fabric.Text.fromObject(obj);
/** @ignore */
var onscriptload = function () {
// TODO (kangax): find out why Opera refuses to work without this timeout
if (Object.prototype.toString.call(fabric.window.opera) === '[object Opera]') {
setTimeout(function () {
onObjectLoaded(object, index);
}, 500);
}
else {
onObjectLoaded(object, index);
}
};
fabric.util.getScript(path, onscriptload);
}
}
else {
fabric.loadSVGFromURL(path, function (elements) {
var object = fabric.util.groupSVGElements(elements, obj, path);
// copy parameters from serialied json to object (left, top, scaleX, scaleY, etc.)
// skip this step if an object is a PathGroup, since we already passed it options object before
if (!(object instanceof fabric.PathGroup)) {
fabric.util.object.extend(object, obj);
if (typeof obj.angle !== 'undefined') {
object.setAngle(obj.angle);
}
}
onObjectLoaded(object, index);
});
}
}
}
if (numTotalObjects === 0 && callback) {
callback();
}
try {
objects.forEach(loadObject, this);
}
catch(e) {
fabric.log(e);
}
return this.loadFromJSON(json, callback);
},
/**
@ -163,6 +33,8 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
? JSON.parse(json)
: json;
this.clear();
var _this = this;
this._enlivenObjects(serialized.objects, function () {
_this._setBgOverlayImages(serialized, callback);
@ -246,6 +118,7 @@ fabric.util.object.extend(fabric.StaticCanvas.prototype, /** @lends fabric.Stati
fabric.util.enlivenObjects(objects, function(enlivenedObjects) {
enlivenedObjects.forEach(function(obj, index) {
_this.insertAt(obj, index, true);
obj.setCoords();
});
callback && callback();
});

View file

@ -681,8 +681,17 @@
* @static
* @return {fabric.Path} Instance of fabric.Path
*/
fabric.Path.fromObject = function(object) {
return new fabric.Path(object.path, object);
fabric.Path.fromObject = function(object, callback) {
if (typeof object.path === 'string') {
fabric.loadSVGFromURL(object.path, function (elements) {
var path = fabric.util.groupSVGElements(elements, object, object.path);
// fabric.util.object.extend(path, object);
callback(path);
});
}
else {
callback(new fabric.Path(object.path, object));
}
};
/* _FROM_SVG_START_ */
@ -706,4 +715,11 @@
};
/* _FROM_SVG_END_ */
/**
* Indicates that instances of this type are async
* @static
* @type Boolean
*/
fabric.Path.async = true;
})(typeof exports !== 'undefined' ? exports : this);

View file

@ -226,9 +226,25 @@
* @param {Object} object
* @return {fabric.PathGroup}
*/
fabric.PathGroup.fromObject = function(object) {
var paths = instantiatePaths(object.paths);
return new fabric.PathGroup(paths, object);
fabric.PathGroup.fromObject = function(object, callback) {
if (typeof object.paths === 'string') {
fabric.loadSVGFromURL(object.paths, function (elements) {
delete object.paths;
var pathGroup = fabric.util.groupSVGElements(elements, object, object.paths);
callback(pathGroup);
});
}
else {
var paths = instantiatePaths(object.paths);
callback(new fabric.PathGroup(paths, object));
}
};
/**
* Indicates that instances of this type are async
* @static
* @type Boolean
*/
fabric.PathGroup.async = true;
})(typeof exports !== 'undefined' ? exports : this);

View file

@ -106,11 +106,13 @@
ok(typeof path.complexity == 'function');
});
test('fromObject', function() {
asyncTest('fromObject', function() {
ok(typeof fabric.Path.fromObject == 'function');
var path = fabric.Path.fromObject(REFERENCE_PATH_OBJECT);
ok(path instanceof fabric.Path);
deepEqual(path.toObject(), REFERENCE_PATH_OBJECT);
fabric.Path.fromObject(REFERENCE_PATH_OBJECT, function(path) {
ok(path instanceof fabric.Path);
deepEqual(path.toObject(), REFERENCE_PATH_OBJECT);
start();
});
});
test('fromElement', function() {