removed ATTRS class level variable cache from Shape. added class level variable cache to Node. Made several low level optimizations.

This commit is contained in:
Eric Rowell
2012-11-13 23:22:56 -08:00
parent 429f28964a
commit 3c3351ec6f
2 changed files with 1139 additions and 1127 deletions

View File

@@ -1,4 +1,8 @@
/**
Kinetic.Node = (function() {
// variable cache
var TYPE = Kinetic.Type;
/**
* Node constructor.  Nodes are entities that can be transformed, layered,
* and have events bound to them. They are the building blocks of a KineticJS
* application
@@ -22,11 +26,11 @@
* @param {Boolean} [config.draggable]
* @param {Function} [config.dragBoundFunc] dragBoundFunc(pos, evt) should return new position
*/
Kinetic.Node = function(config) {
var Node = function(config) {
this._nodeInit(config);
};
};
Kinetic.Node.prototype = {
Node.prototype = {
_nodeInit: function(config) {
this.defaultNodeAttrs = {
visible: true,
@@ -87,7 +91,8 @@ Kinetic.Node.prototype = {
* each one. eg. 'click mouseover.namespace mouseout'
* will create three event bindings
*/
for(var n = 0; n < types.length; n++) {
var len = types.length;
for(var n = 0; n < len; n++) {
var type = types[n];
var event = type;
var parts = event.split('.');
@@ -117,8 +122,8 @@ Kinetic.Node.prototype = {
*/
off: function(typesStr) {
var types = typesStr.split(' ');
for(var n = 0; n < types.length; n++) {
var len = types.length;
for(var n = 0; n < len; n++) {
var type = types[n];
//var event = (type.indexOf('touch') === -1) ? 'on' + type : type;
var event = type;
@@ -218,7 +223,7 @@ Kinetic.Node.prototype = {
for(var key in config) {
var method = 'set' + key.charAt(0).toUpperCase() + key.slice(1);
// use setter if available
if(Kinetic.Type._isFunction(this[method])) {
if(TYPE._isFunction(this[method])) {
this[method](config[key]);
}
// otherwise set directly
@@ -291,7 +296,8 @@ Kinetic.Node.prototype = {
var index = 0;
function addChildren(children) {
var nodes = [];
for(var n = 0; n < children.length; n++) {
var len = children.length;
for(var n = 0; n < len; n++) {
var child = children[n];
index++;
@@ -300,7 +306,7 @@ Kinetic.Node.prototype = {
}
if(child._id === that._id) {
n = children.length;
n = len;
}
}
@@ -336,7 +342,7 @@ Kinetic.Node.prototype = {
* @param {Number} y
*/
setPosition: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
var pos = TYPE._getXY([].slice.call(arguments));
this.setAttr('x', pos.x);
this.setAttr('y', pos.y);
},
@@ -370,7 +376,7 @@ Kinetic.Node.prototype = {
* y property
*/
setAbsolutePosition: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
var pos = TYPE._getXY([].slice.call(arguments));
var trans = this._clearTransform();
// don't clear translation
this.attrs.x = trans.x;
@@ -399,7 +405,7 @@ Kinetic.Node.prototype = {
* @param {Number} y
*/
move: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
var pos = TYPE._getXY([].slice.call(arguments));
var x = this.getX();
var y = this.getY();
@@ -468,7 +474,8 @@ Kinetic.Node.prototype = {
*/
moveUp: function() {
var index = this.index;
if(index < this.parent.getChildren().length - 1) {
var len = this.parent.getChildren().length;
if(index < len - 1) {
this.parent.children.splice(index, 1);
this.parent.children.splice(index + 1, 0, this);
this.parent._setChildrenIndices();
@@ -552,14 +559,13 @@ Kinetic.Node.prototype = {
*/
toObject: function() {
var obj = {};
var type = Kinetic.Type;
obj.attrs = {};
// serialize only attributes that are not function, image, DOM, or objects with methods
for(var key in this.attrs) {
var val = this.attrs[key];
if(!type._isFunction(val) && !type._isElement(val) && !(type._isObject(val) && type._hasMethods(val))) {
if(!TYPE._isFunction(val) && !TYPE._isElement(val) && !(TYPE._isObject(val) && TYPE._hasMethods(val))) {
obj.attrs[key] = val;
}
}
@@ -640,7 +646,8 @@ Kinetic.Node.prototype = {
parent = parent.parent;
}
for(var n = 0; n < family.length; n++) {
var len = family.length;
for(var n = 0; n < len; n++) {
var node = family[n];
var m = node.getTransform();
am.multiply(m);
@@ -687,7 +694,8 @@ Kinetic.Node.prototype = {
*/
for(var key in this.eventListeners) {
var allListeners = this.eventListeners[key];
for(var n = 0; n < allListeners.length; n++) {
var len = allListeners.length;
for(var n = 0; n < len; n++) {
var listener = allListeners[n];
/*
* don't include kinetic namespaced listeners because
@@ -756,7 +764,7 @@ Kinetic.Node.prototype = {
* is very high quality
*/
toImage: function(config) {
Kinetic.Type._getImage(this.toDataURL(config), function(img) {
TYPE._getImage(this.toDataURL(config), function(img) {
config.callback(img);
});
},
@@ -768,7 +776,7 @@ Kinetic.Node.prototype = {
* @param {Number} y
*/
setOffset: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
var pos = TYPE._getXY([].slice.call(arguments));
if(pos.x === undefined) {
pos.x = this.getOffset().x;
}
@@ -785,7 +793,7 @@ Kinetic.Node.prototype = {
* @methodOf Kinetic.Node.prototype
*/
setScale: function() {
var pos = Kinetic.Type._getXY([].slice.call(arguments));
var pos = TYPE._getXY([].slice.call(arguments));
if(pos.x === undefined) {
pos.x = this.getScale().x;
@@ -805,7 +813,7 @@ Kinetic.Node.prototype = {
*/
setSize: function() {
// set stage dimensions
var size = Kinetic.Type._getSize(Array.prototype.slice.call(arguments));
var size = TYPE._getSize(Array.prototype.slice.call(arguments));
this.setWidth(size.width);
this.setHeight(size.height);
},
@@ -941,47 +949,50 @@ Kinetic.Node.prototype = {
},
_executeHandlers: function(eventType, evt) {
var events = this.eventListeners[eventType];
for(var i = 0; i < events.length; i++) {
var len = events.length;
for(var i = 0; i < len; i++) {
events[i].handler.apply(this, [evt]);
}
},
_shouldDraw: function(canvas) {
return (this.isVisible() && (!canvas || canvas.getContext().type === 'scene' || this.getListening()));
}
};
};
// add getter and setter methods
Kinetic.Node.addSetters = function(constructor, arr) {
for(var n = 0; n < arr.length; n++) {
// add getter and setter methods
Node.addSetters = function(constructor, arr) {
var len = arr.length;
for(var n = 0; n < len; n++) {
var attr = arr[n];
this._addSetter(constructor, attr);
}
};
Kinetic.Node.addGetters = function(constructor, arr) {
for(var n = 0; n < arr.length; n++) {
};
Node.addGetters = function(constructor, arr) {
var len = arr.length;
for(var n = 0; n < len; n++) {
var attr = arr[n];
this._addGetter(constructor, attr);
}
};
Kinetic.Node.addGettersSetters = function(constructor, arr) {
};
Node.addGettersSetters = function(constructor, arr) {
this.addSetters(constructor, arr);
this.addGetters(constructor, arr);
};
Kinetic.Node._addSetter = function(constructor, attr) {
};
Node._addSetter = function(constructor, attr) {
var that = this;
var method = 'set' + attr.charAt(0).toUpperCase() + attr.slice(1);
constructor.prototype[method] = function(val) {
this.setAttr(attr, val);
};
};
Kinetic.Node._addGetter = function(constructor, attr) {
};
Node._addGetter = function(constructor, attr) {
var that = this;
var method = 'get' + attr.charAt(0).toUpperCase() + attr.slice(1);
constructor.prototype[method] = function(arg) {
return this.attrs[attr];
};
};
/**
};
/**
* create node with JSON string. De-serializtion does not generate custom
* shape drawing functions, images, or event handlers (this would make the
* serialized object huge). If your app uses custom shapes, images, and
@@ -992,10 +1003,10 @@ Kinetic.Node._addGetter = function(constructor, attr) {
* @methodOf Kinetic.Node
* @param {String} JSON string
*/
Kinetic.Node.create = function(json, container) {
Node.create = function(json, container) {
return this._createNode(JSON.parse(json), container);
};
Kinetic.Node._createNode = function(obj, container) {
};
Node._createNode = function(obj, container) {
var type;
// determine type
@@ -1020,36 +1031,36 @@ Kinetic.Node._createNode = function(obj, container) {
var no = new Kinetic[type](obj.attrs);
if(obj.children) {
for(var n = 0; n < obj.children.length; n++) {
var len = obj.children.length;
for(var n = 0; n < len; n++) {
no.add(this._createNode(obj.children[n]));
}
}
return no;
};
// add getters setters
Kinetic.Node.addGettersSetters(Kinetic.Node, ['x', 'y', 'rotation', 'opacity', 'name', 'id']);
Kinetic.Node.addGetters(Kinetic.Node, ['scale', 'offset']);
Kinetic.Node.addSetters(Kinetic.Node, ['width', 'height', 'listening', 'visible']);
};
// add getters setters
Node.addGettersSetters(Node, ['x', 'y', 'rotation', 'opacity', 'name', 'id']);
Node.addGetters(Node, ['scale', 'offset']);
Node.addSetters(Node, ['width', 'height', 'listening', 'visible']);
// mappings
/**
// mappings
/**
* Alias of getListening()
* @name isListening
* @methodOf Kinetic.Node.prototype
*/
Kinetic.Node.prototype.isListening = Kinetic.Node.prototype.getListening;
/**
Node.prototype.isListening = Node.prototype.getListening;
/**
* Alias of getVisible()
* @name isVisible
* @methodOf Kinetic.Node.prototype
*/
Kinetic.Node.prototype.isVisible = Kinetic.Node.prototype.getVisible;
Node.prototype.isVisible = Node.prototype.getVisible;
// collection mappings
(function() {
// collection mappings
var collectionMappings = ['on', 'off'];
for(var n = 0; n < collectionMappings.length; n++) {
for(var n = 0; n < 2; n++) {
// induce scope
(function(i) {
var method = collectionMappings[i];
@@ -1060,30 +1071,29 @@ Kinetic.Node.prototype.isVisible = Kinetic.Node.prototype.getVisible;
};
})(n);
}
})();
/**
/**
* set node x position
* @name setX
* @methodOf Kinetic.Node.prototype
* @param {Number} x
*/
/**
/**
* set node y position
* @name setY
* @methodOf Kinetic.Node.prototype
* @param {Number} y
*/
/**
/**
* set node rotation in radians
* @name setRotation
* @methodOf Kinetic.Node.prototype
* @param {Number} theta
*/
/**
/**
* set opacity. Opacity values range from 0 to 1.
* A node with an opacity of 0 is fully transparent, and a node
* with an opacity of 1 is fully opaque
@@ -1092,78 +1102,81 @@ Kinetic.Node.prototype.isVisible = Kinetic.Node.prototype.getVisible;
* @param {Object} opacity
*/
/**
/**
* set name
* @name setName
* @methodOf Kinetic.Node.prototype
* @param {String} name
*/
/**
/**
* set id
* @name setId
* @methodOf Kinetic.Node.prototype
* @param {String} id
*/
/**
/**
* listen or don't listen to events
* @name setListening
* @methodOf Kinetic.Node.prototype
* @param {Boolean} listening
*/
/**
/**
* set visible
* @name setVisible
* @methodOf Kinetic.Node.prototype
* @param {Boolean} visible
*/
/**
/**
* get node x position
* @name getX
* @methodOf Kinetic.Node.prototype
*/
/**
/**
* get node y position
* @name getY
* @methodOf Kinetic.Node.prototype
*/
/**
/**
* get rotation in radians
* @name getRotation
* @methodOf Kinetic.Node.prototype
*/
/**
/**
* get opacity.
* @name getOpacity
* @methodOf Kinetic.Node.prototype
*/
/**
/**
* get name
* @name getName
* @methodOf Kinetic.Node.prototype
*/
/**
/**
* get id
* @name getId
* @methodOf Kinetic.Node.prototype
*/
/**
/**
* get scale
* @name getScale
* @methodOf Kinetic.Node.prototype
*/
/**
/**
* get offset
* @name getOffset
* @methodOf Kinetic.Node.prototype
*/
return Node;
})();

View File

@@ -1,6 +1,6 @@
Kinetic.Shape = (function() {
// variable cache
var ATTRS, TYPE = Kinetic.Type;
var TYPE = Kinetic.Type;
/**
* Shape constructor. Shapes are primitive objects such as rectangles,
@@ -83,7 +83,6 @@ Kinetic.Shape = (function() {
// call super constructor
Kinetic.Node.call(this, config);
ATTRS = this.attrs;
},
/**
* get canvas context tied to the layer
@@ -120,7 +119,7 @@ Kinetic.Shape = (function() {
var appliedShadow = false;
context.save();
if(ATTRS.shadow && !this.appliedShadow) {
if(this.attrs.shadow && !this.appliedShadow) {
appliedShadow = this._applyShadow(context);
}
@@ -181,7 +180,7 @@ Kinetic.Shape = (function() {
var appliedShadow = false, fill = this.getFill(), fillType = this._getFillType(fill);
if(fill) {
context.save();
if(ATTRS.shadow && !this.appliedShadow) {
if(this.attrs.shadow && !this.appliedShadow) {
appliedShadow = this._applyShadow(context);
}
@@ -260,7 +259,7 @@ Kinetic.Shape = (function() {
var a = Array.prototype.slice.call(arguments);
if(a.length === 6 || a.length === 10) {
if(ATTRS.shadow && !this.appliedShadow) {
if(this.attrs.shadow && !this.appliedShadow) {
appliedShadow = this._applyShadow(context);
}
@@ -291,8 +290,8 @@ Kinetic.Shape = (function() {
* @methodOf Kinetic.Shape.prototype
*/
applyLineJoin: function(context) {
if(ATTRS.lineJoin) {
context.lineJoin = ATTRS.lineJoin;
if(this.attrs.lineJoin) {
context.lineJoin = this.attrs.lineJoin;
}
},
/**
@@ -302,8 +301,8 @@ Kinetic.Shape = (function() {
* @methodOf Kinetic.Shape.prototype
*/
applyLineCap: function(context) {
if(ATTRS.lineCap) {
context.lineCap = ATTRS.lineCap;
if(this.attrs.lineCap) {
context.lineCap = this.attrs.lineCap;
}
},
/**
@@ -381,7 +380,7 @@ Kinetic.Shape = (function() {
* and false if it was not
*/
_applyShadow: function(context) {
var s = ATTRS.shadow;
var s = this.attrs.shadow;
if(s) {
var aa = this.getAbsoluteOpacity();
// defaults