re-integrated simple serialization and deserialization with new attrs structure

This commit is contained in:
Eric Rowell
2012-04-07 14:39:31 -07:00
parent ff896a4946
commit 58eb778e9a
10 changed files with 82 additions and 118 deletions

61
dist/kinetic-core.js vendored
View File

@@ -56,22 +56,6 @@ Kinetic.GlobalObject = {
y: 0 y: 0
} }
}, },
jsonProps: function(props) {
if(this.jsonProps === undefined) {
this.jsonProps = props;
}
else {
this.jsonProps = this.jsonProps.concat(props);
}
},
arrayHas: function(arr, key) {
for(var n = 0; n < arr.length; n++) {
if(arr[n] === key) {
return true;
}
}
return false;
},
extend: function(obj1, obj2) { extend: function(obj1, obj2) {
for(var key in obj2.prototype) { for(var key in obj2.prototype) {
if(obj2.prototype.hasOwnProperty(key) && obj1.prototype[key] === undefined) { if(obj2.prototype.hasOwnProperty(key) && obj1.prototype[key] === undefined) {
@@ -190,6 +174,10 @@ Kinetic.Node = function(config) {
for(var key in config) { for(var key in config) {
// handle special keys // handle special keys
switch (key) { switch (key) {
/*
* config properties that require a method to
* be set
*/
case 'draggable': case 'draggable':
this.draggable(config[key]); this.draggable(config[key]);
break; break;
@@ -199,10 +187,15 @@ Kinetic.Node = function(config) {
case 'rotationDeg': case 'rotationDeg':
this.attrs.rotation = config[key] * Math.PI / 180; this.attrs.rotation = config[key] * Math.PI / 180;
break; break;
/*
* config objects that we don't want in attrs
*/
case 'drawFunc': case 'drawFunc':
break; break;
case 'image': case 'image':
break; break;
case 'container':
break;
default: default:
this.attrs[key] = config[key]; this.attrs[key] = config[key];
break; break;
@@ -836,9 +829,6 @@ Kinetic.Node.prototype = {
Kinetic.Container = function() { Kinetic.Container = function() {
this.children = []; this.children = [];
this.childrenNames = {}; this.childrenNames = {};
// used for serialization
Kinetic.GlobalObject.jsonProps.call(this, []);
}; };
/* /*
* Container methods * Container methods
@@ -958,6 +948,7 @@ Kinetic.Stage = function(config) {
} }
this.attrs.width = 400; this.attrs.width = 400;
this.attrs.height = 200; this.attrs.height = 200;
this.nodeType = 'Stage';
/* /*
* if container is a string, assume it's an id for * if container is a string, assume it's an id for
@@ -971,7 +962,6 @@ Kinetic.Stage = function(config) {
Kinetic.Container.apply(this, []); Kinetic.Container.apply(this, []);
Kinetic.Node.apply(this, [config]); Kinetic.Node.apply(this, [config]);
this.nodeType = 'Stage';
this.container = config.container; this.container = config.container;
this.content = document.createElement('div'); this.content = document.createElement('div');
this.dblClickWindow = 400; this.dblClickWindow = 400;
@@ -1130,14 +1120,9 @@ Kinetic.Stage.prototype = {
function addNode(node) { function addNode(node) {
var obj = {}; var obj = {};
obj.attrs = {}; obj.attrs = node.attrs;
obj.nodeType = node.nodeType;
// copy attrs obj.shapeType = node.shapeType;
for(var key in node) {
if(node.hasOwnProperty(key) && go.arrayHas(node.jsonProps, key)) {
obj.attrs[key.replace('_', '')] = node[key];
}
}
if(node.nodeType !== 'Shape') { if(node.nodeType !== 'Shape') {
obj.children = []; obj.children = [];
@@ -1160,7 +1145,7 @@ Kinetic.Stage.prototype = {
function loadNode(node, obj) { function loadNode(node, obj) {
// if custom shape then set draw function // if custom shape then set draw function
if(obj.nodeType === 'Shape' && obj.shapeType === undefined) { if(obj.nodeType === 'Shape' && obj.shapeType === undefined) {
node.drawFunc = drawFuncs[obj.attrs.drawFuncName]; node.drawFunc = drawFuncs[obj.drawFuncName];
} }
var children = obj.children; var children = obj.children;
@@ -1170,18 +1155,18 @@ Kinetic.Stage.prototype = {
var type; var type;
// determine type // determine type
if(child.attrs.nodeType === 'Shape') { if(child.nodeType === 'Shape') {
// add custom shape // add custom shape
if(child.attrs.shapeType === undefined) { if(child.shapeType === undefined) {
type = 'Shape'; type = 'Shape';
} }
// add standard shape // add standard shape
else { else {
type = child.attrs.shapeType; type = child.shapeType;
} }
} }
else { else {
type = child.attrs.nodeType; type = child.nodeType;
} }
var no = new Kinetic[type](child.attrs); var no = new Kinetic[type](child.attrs);
@@ -1193,9 +1178,7 @@ Kinetic.Stage.prototype = {
var obj = JSON.parse(json); var obj = JSON.parse(json);
// copy over stage properties // copy over stage properties
for(var key in obj.attrs) { this.attrs = obj.attrs;
this[key] = obj.attrs[key];
}
loadNode(this, obj); loadNode(this, obj);
this.draw(); this.draw();
@@ -1796,6 +1779,7 @@ Kinetic.GlobalObject.extend(Kinetic.Stage, Kinetic.Node);
*/ */
Kinetic.Layer = function(config) { Kinetic.Layer = function(config) {
this.nodeType = 'Layer'; this.nodeType = 'Layer';
this.canvas = document.createElement('canvas'); this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext('2d'); this.context = this.canvas.getContext('2d');
this.canvas.style.position = 'absolute'; this.canvas.style.position = 'absolute';
@@ -1879,7 +1863,7 @@ Kinetic.GlobalObject.extend(Kinetic.Layer, Kinetic.Node);
* @param {Object} config * @param {Object} config
*/ */
Kinetic.Group = function(config) { Kinetic.Group = function(config) {
this.nodeType = 'Group'; this.nodeType = 'Group';;
// call super constructors // call super constructors
Kinetic.Container.apply(this, []); Kinetic.Container.apply(this, []);
@@ -1949,8 +1933,8 @@ Kinetic.Shape = function(config) {
// special // special
this.drawFunc = config.drawFunc; this.drawFunc = config.drawFunc;
this.nodeType = 'Shape';
this.data = []; this.data = [];
this.nodeType = 'Shape';
// defaults // defaults
if(config.stroke !== undefined || config.strokeWidth !== undefined) { if(config.stroke !== undefined || config.strokeWidth !== undefined) {
@@ -2250,7 +2234,6 @@ Kinetic.Circle = function(config) {
this.attrs = {}; this.attrs = {};
} }
this.attrs.radius = 0; this.attrs.radius = 0;
this.shapeType = "Circle"; this.shapeType = "Circle";
config.drawFunc = function() { config.drawFunc = function() {

View File

@@ -9,9 +9,6 @@
Kinetic.Container = function() { Kinetic.Container = function() {
this.children = []; this.children = [];
this.childrenNames = {}; this.childrenNames = {};
// used for serialization
Kinetic.GlobalObject.jsonProps.call(this, []);
}; };
/* /*
* Container methods * Container methods

View File

@@ -28,22 +28,6 @@ Kinetic.GlobalObject = {
y: 0 y: 0
} }
}, },
jsonProps: function(props) {
if(this.jsonProps === undefined) {
this.jsonProps = props;
}
else {
this.jsonProps = this.jsonProps.concat(props);
}
},
arrayHas: function(arr, key) {
for(var n = 0; n < arr.length; n++) {
if(arr[n] === key) {
return true;
}
}
return false;
},
extend: function(obj1, obj2) { extend: function(obj1, obj2) {
for(var key in obj2.prototype) { for(var key in obj2.prototype) {
if(obj2.prototype.hasOwnProperty(key) && obj1.prototype[key] === undefined) { if(obj2.prototype.hasOwnProperty(key) && obj1.prototype[key] === undefined) {

View File

@@ -10,7 +10,7 @@
* @param {Object} config * @param {Object} config
*/ */
Kinetic.Group = function(config) { Kinetic.Group = function(config) {
this.nodeType = 'Group'; this.nodeType = 'Group';;
// call super constructors // call super constructors
Kinetic.Container.apply(this, []); Kinetic.Container.apply(this, []);

View File

@@ -11,6 +11,7 @@
*/ */
Kinetic.Layer = function(config) { Kinetic.Layer = function(config) {
this.nodeType = 'Layer'; this.nodeType = 'Layer';
this.canvas = document.createElement('canvas'); this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext('2d'); this.context = this.canvas.getContext('2d');
this.canvas.style.position = 'absolute'; this.canvas.style.position = 'absolute';

View File

@@ -39,6 +39,10 @@ Kinetic.Node = function(config) {
for(var key in config) { for(var key in config) {
// handle special keys // handle special keys
switch (key) { switch (key) {
/*
* config properties that require a method to
* be set
*/
case 'draggable': case 'draggable':
this.draggable(config[key]); this.draggable(config[key]);
break; break;
@@ -48,10 +52,15 @@ Kinetic.Node = function(config) {
case 'rotationDeg': case 'rotationDeg':
this.attrs.rotation = config[key] * Math.PI / 180; this.attrs.rotation = config[key] * Math.PI / 180;
break; break;
/*
* config objects that we don't want in attrs
*/
case 'drawFunc': case 'drawFunc':
break; break;
case 'image': case 'image':
break; break;
case 'container':
break;
default: default:
this.attrs[key] = config[key]; this.attrs[key] = config[key];
break; break;

View File

@@ -30,8 +30,8 @@ Kinetic.Shape = function(config) {
// special // special
this.drawFunc = config.drawFunc; this.drawFunc = config.drawFunc;
this.nodeType = 'Shape';
this.data = []; this.data = [];
this.nodeType = 'Shape';
// defaults // defaults
if(config.stroke !== undefined || config.strokeWidth !== undefined) { if(config.stroke !== undefined || config.strokeWidth !== undefined) {

View File

@@ -18,6 +18,7 @@ Kinetic.Stage = function(config) {
} }
this.attrs.width = 400; this.attrs.width = 400;
this.attrs.height = 200; this.attrs.height = 200;
this.nodeType = 'Stage';
/* /*
* if container is a string, assume it's an id for * if container is a string, assume it's an id for
@@ -31,7 +32,6 @@ Kinetic.Stage = function(config) {
Kinetic.Container.apply(this, []); Kinetic.Container.apply(this, []);
Kinetic.Node.apply(this, [config]); Kinetic.Node.apply(this, [config]);
this.nodeType = 'Stage';
this.container = config.container; this.container = config.container;
this.content = document.createElement('div'); this.content = document.createElement('div');
this.dblClickWindow = 400; this.dblClickWindow = 400;
@@ -190,14 +190,9 @@ Kinetic.Stage.prototype = {
function addNode(node) { function addNode(node) {
var obj = {}; var obj = {};
obj.attrs = {}; obj.attrs = node.attrs;
obj.nodeType = node.nodeType;
// copy attrs obj.shapeType = node.shapeType;
for(var key in node) {
if(node.hasOwnProperty(key) && go.arrayHas(node.jsonProps, key)) {
obj.attrs[key.replace('_', '')] = node[key];
}
}
if(node.nodeType !== 'Shape') { if(node.nodeType !== 'Shape') {
obj.children = []; obj.children = [];
@@ -220,7 +215,7 @@ Kinetic.Stage.prototype = {
function loadNode(node, obj) { function loadNode(node, obj) {
// if custom shape then set draw function // if custom shape then set draw function
if(obj.nodeType === 'Shape' && obj.shapeType === undefined) { if(obj.nodeType === 'Shape' && obj.shapeType === undefined) {
node.drawFunc = drawFuncs[obj.attrs.drawFuncName]; node.drawFunc = drawFuncs[obj.drawFuncName];
} }
var children = obj.children; var children = obj.children;
@@ -230,18 +225,18 @@ Kinetic.Stage.prototype = {
var type; var type;
// determine type // determine type
if(child.attrs.nodeType === 'Shape') { if(child.nodeType === 'Shape') {
// add custom shape // add custom shape
if(child.attrs.shapeType === undefined) { if(child.shapeType === undefined) {
type = 'Shape'; type = 'Shape';
} }
// add standard shape // add standard shape
else { else {
type = child.attrs.shapeType; type = child.shapeType;
} }
} }
else { else {
type = child.attrs.nodeType; type = child.nodeType;
} }
var no = new Kinetic[type](child.attrs); var no = new Kinetic[type](child.attrs);
@@ -253,9 +248,7 @@ Kinetic.Stage.prototype = {
var obj = JSON.parse(json); var obj = JSON.parse(json);
// copy over stage properties // copy over stage properties
for(var key in obj.attrs) { this.attrs = obj.attrs;
this[key] = obj.attrs[key];
}
loadNode(this, obj); loadNode(this, obj);
this.draw(); this.draw();

View File

@@ -13,7 +13,6 @@ Kinetic.Circle = function(config) {
this.attrs = {}; this.attrs = {};
} }
this.attrs.radius = 0; this.attrs.radius = 0;
this.shapeType = "Circle"; this.shapeType = "Circle";
config.drawFunc = function() { config.drawFunc = function() {

View File

@@ -65,49 +65,47 @@ Test.prototype.tests = {
group.add(circle); group.add(circle);
layer.draw(); layer.draw();
}, },
/* 'STAGE - serialize stage': function(containerId) {
'STAGE - serialize stage': function(containerId) { var stage = new Kinetic.Stage({
var stage = new Kinetic.Stage({ container: containerId,
container: containerId, width: 578,
width: 578, height: 200
height: 200 });
}); var layer = new Kinetic.Layer();
var layer = new Kinetic.Layer(); var group = new Kinetic.Group();
var group = new Kinetic.Group(); var circle = new Kinetic.Circle({
var circle = new Kinetic.Circle({ x: stage.getWidth() / 2,
x: stage.getWidth() / 2, y: stage.getHeight() / 2,
y: stage.getHeight() / 2, radius: 70,
radius: 70, fill: 'green',
fill: 'green', stroke: 'black',
stroke: 'black', strokeWidth: 4,
strokeWidth: 4, name: 'myCircle',
name: 'myCircle', draggable: true
draggable: true });
});
stage.add(layer); stage.add(layer);
layer.add(group); layer.add(group);
group.add(circle); group.add(circle);
layer.draw(); layer.draw();
console.log(stage.toJSON()) //console.log(stage.toJSON())
var expectedJson = '{"attrs":{"nodeType":"Stage","width":578,"height":200,"scale":{"x":1,"y":1},"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"children":[{"attrs":{"nodeType":"Layer","visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"children":[{"attrs":{"nodeType":"Group","visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"children":[{"attrs":{"shapeType":"Circle","nodeType":"Shape","detectionType":"path","visible":true,"listening":true,"name":"myCircle","alpha":1,"x":289,"y":100,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":true,"radius":70,"fill":"green","stroke":"black","strokeWidth":4}}]}]}]}'; var expectedJson = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Group","children":[{"attrs":{"radius":70,"fill":"green","stroke":"black","strokeWidth":4,"detectionType":"path","visible":true,"listening":true,"name":"myCircle","alpha":1,"x":289,"y":100,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":true},"nodeType":"Shape","shapeType":"Circle"}]}]}]}';
test(stage.toJSON() === expectedJson, 'problem with serialization'); test(stage.toJSON() === expectedJson, 'problem with serialization');
}, },
'STAGE - load stage with json': function(containerId) { 'STAGE - load stage with json': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({
container: containerId, container: containerId,
width: 578, width: 578,
height: 200 height: 200
}); });
var json = '{"attrs":{"nodeType":"Stage","width":578,"height":200,"scale":{"x":1,"y":1},"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"children":[{"attrs":{"nodeType":"Layer","visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"children":[{"attrs":{"nodeType":"Group","visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"children":[{"attrs":{"shapeType":"Circle","nodeType":"Shape","detectionType":"path","visible":true,"listening":true,"name":"myCircle","alpha":1,"x":289,"y":100,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":true,"radius":70,"fill":"green","stroke":"black","strokeWidth":4}}]}]}]}'; var json = '{"attrs":{"width":578,"height":200,"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Stage","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Layer","children":[{"attrs":{"visible":true,"listening":true,"alpha":1,"x":0,"y":0,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":false},"nodeType":"Group","children":[{"attrs":{"radius":70,"fill":"green","stroke":"black","strokeWidth":4,"detectionType":"path","visible":true,"listening":true,"name":"myCircle","alpha":1,"x":289,"y":100,"scale":{"x":1,"y":1},"rotation":0,"centerOffset":{"x":0,"y":0},"dragConstraint":"none","dragBounds":{},"draggable":true},"nodeType":"Shape","shapeType":"Circle"}]}]}]}';
stage.load(json); stage.load(json);
test(stage.toJSON() === json, "serialized stage is incorrect"); test(stage.toJSON() === json, "serialized stage is incorrect");
}, },
*/
/* /*
'STAGE - serialize stage with custom shape': function(containerId) { 'STAGE - serialize stage with custom shape': function(containerId) {
var stage = new Kinetic.Stage({ var stage = new Kinetic.Stage({