2012-03-07 13:45:48 +08:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
// Container
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
2012-07-09 12:56:52 +08:00
|
|
|
/**
|
|
|
|
* Container constructor. Containers are used to contain nodes or other containers
|
|
|
|
* @constructor
|
|
|
|
* @augments Kinetic.Node
|
|
|
|
* @param {Object} config
|
|
|
|
*/
|
2012-07-04 03:07:27 +08:00
|
|
|
Kinetic.Container = Kinetic.Node.extend({
|
|
|
|
init: function(config) {
|
|
|
|
this.children = [];
|
|
|
|
this._super(config);
|
|
|
|
},
|
2012-03-07 13:45:48 +08:00
|
|
|
/**
|
|
|
|
* get children
|
2012-07-09 12:56:52 +08:00
|
|
|
* @name getChildren
|
|
|
|
* @methodOf Kinetic.Container.prototype
|
2012-03-07 13:45:48 +08:00
|
|
|
*/
|
|
|
|
getChildren: function() {
|
|
|
|
return this.children;
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* remove all children
|
2012-07-09 12:56:52 +08:00
|
|
|
* @name removeChildren
|
|
|
|
* @methodOf Kinetic.Container.prototype
|
2012-03-07 13:45:48 +08:00
|
|
|
*/
|
|
|
|
removeChildren: function() {
|
|
|
|
while(this.children.length > 0) {
|
|
|
|
this.remove(this.children[0]);
|
|
|
|
}
|
|
|
|
},
|
2012-05-27 07:49:58 +08:00
|
|
|
/**
|
|
|
|
* add node to container
|
2012-07-09 12:56:52 +08:00
|
|
|
* @name add
|
|
|
|
* @methodOf Kinetic.Container.prototype
|
2012-05-27 07:49:58 +08:00
|
|
|
* @param {Node} child
|
|
|
|
*/
|
|
|
|
add: function(child) {
|
2012-07-04 13:08:59 +08:00
|
|
|
child._id = Kinetic.Global.idCounter++;
|
2012-05-27 07:49:58 +08:00
|
|
|
child.index = this.children.length;
|
|
|
|
child.parent = this;
|
|
|
|
|
|
|
|
this.children.push(child);
|
|
|
|
|
|
|
|
var stage = child.getStage();
|
|
|
|
if(stage === undefined) {
|
2012-07-04 13:08:59 +08:00
|
|
|
var go = Kinetic.Global;
|
2012-05-27 07:49:58 +08:00
|
|
|
go.tempNodes.push(child);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
stage._addId(child);
|
|
|
|
stage._addName(child);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* pull in other nodes that are now linked
|
|
|
|
* to a stage
|
|
|
|
*/
|
2012-07-04 13:08:59 +08:00
|
|
|
var go = Kinetic.Global;
|
2012-05-27 07:49:58 +08:00
|
|
|
go._pullNodes(stage);
|
|
|
|
}
|
|
|
|
|
|
|
|
// do extra stuff if needed
|
|
|
|
if(this._add !== undefined) {
|
|
|
|
this._add(child);
|
|
|
|
}
|
|
|
|
|
|
|
|
// chainable
|
|
|
|
return this;
|
|
|
|
},
|
2012-03-07 13:45:48 +08:00
|
|
|
/**
|
|
|
|
* remove child from container
|
2012-07-09 12:56:52 +08:00
|
|
|
* @name remove
|
|
|
|
* @methodOf Kinetic.Container.prototype
|
2012-03-07 13:45:48 +08:00
|
|
|
* @param {Node} child
|
2012-05-27 07:49:58 +08:00
|
|
|
*/
|
|
|
|
remove: function(child) {
|
2012-06-02 14:56:01 +08:00
|
|
|
if(child && child.index !== undefined && this.children[child.index]._id == child._id) {
|
2012-04-09 08:37:49 +08:00
|
|
|
var stage = this.getStage();
|
2012-04-09 08:50:46 +08:00
|
|
|
if(stage !== undefined) {
|
2012-07-14 12:24:38 +08:00
|
|
|
stage._removeId(child.getId());
|
|
|
|
stage._removeName(child.getName(), child._id);
|
2012-04-09 08:50:46 +08:00
|
|
|
}
|
2012-04-09 08:37:49 +08:00
|
|
|
|
2012-07-04 13:08:59 +08:00
|
|
|
var go = Kinetic.Global;
|
2012-04-09 08:37:49 +08:00
|
|
|
for(var n = 0; n < go.tempNodes.length; n++) {
|
|
|
|
var node = go.tempNodes[n];
|
|
|
|
if(node._id === child._id) {
|
|
|
|
go.tempNodes.splice(n, 1);
|
2012-06-02 14:56:01 +08:00
|
|
|
break;
|
2012-04-09 08:37:49 +08:00
|
|
|
}
|
|
|
|
}
|
2012-04-02 01:29:16 +08:00
|
|
|
|
|
|
|
this.children.splice(child.index, 1);
|
|
|
|
this._setChildrenIndices();
|
2012-05-27 07:49:58 +08:00
|
|
|
|
2012-06-02 14:56:01 +08:00
|
|
|
// remove children
|
2012-07-05 13:04:03 +08:00
|
|
|
while(child.children && child.children.length > 0) {
|
|
|
|
child.remove(child.children[0]);
|
2012-06-02 14:56:01 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// do extra stuff if needed
|
|
|
|
if(this._remove !== undefined) {
|
|
|
|
this._remove(child);
|
|
|
|
}
|
2012-05-27 07:49:58 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// chainable
|
|
|
|
return this;
|
2012-03-07 13:45:48 +08:00
|
|
|
},
|
2012-04-09 12:26:13 +08:00
|
|
|
/**
|
2012-04-09 12:37:10 +08:00
|
|
|
* return an array of nodes that match the selector. Use '#' for id selections
|
|
|
|
* and '.' for name selections
|
2012-04-09 12:26:13 +08:00
|
|
|
* ex:
|
|
|
|
* var node = stage.get('#foo'); // selects node with id foo
|
|
|
|
* var nodes = layer.get('.bar'); // selects nodes with name bar inside layer
|
2012-07-09 12:56:52 +08:00
|
|
|
* @name get
|
|
|
|
* @methodOf Kinetic.Container.prototype
|
2012-04-09 12:26:13 +08:00
|
|
|
* @param {String} selector
|
|
|
|
*/
|
|
|
|
get: function(selector) {
|
|
|
|
var stage = this.getStage();
|
|
|
|
var arr;
|
|
|
|
var key = selector.slice(1);
|
|
|
|
if(selector.charAt(0) === '#') {
|
|
|
|
arr = stage.ids[key] !== undefined ? [stage.ids[key]] : [];
|
|
|
|
}
|
|
|
|
else if(selector.charAt(0) === '.') {
|
|
|
|
arr = stage.names[key] !== undefined ? stage.names[key] : [];
|
|
|
|
}
|
2012-04-28 13:54:39 +08:00
|
|
|
else if(selector === 'Shape' || selector === 'Group' || selector === 'Layer') {
|
|
|
|
return this._getNodes(selector);
|
|
|
|
}
|
2012-04-09 12:26:13 +08:00
|
|
|
else {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
var retArr = [];
|
|
|
|
for(var n = 0; n < arr.length; n++) {
|
|
|
|
var node = arr[n];
|
|
|
|
if(this.isAncestorOf(node)) {
|
|
|
|
retArr.push(node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return retArr;
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* determine if node is an ancestor
|
|
|
|
* of descendant
|
2012-07-09 12:56:52 +08:00
|
|
|
* @name isAncestorOf
|
|
|
|
* @methodOf Kinetic.Container.prototype
|
2012-04-09 12:26:13 +08:00
|
|
|
* @param {Kinetic.Node} node
|
|
|
|
*/
|
|
|
|
isAncestorOf: function(node) {
|
|
|
|
if(this.nodeType === 'Stage') {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
var parent = node.getParent();
|
|
|
|
while(parent) {
|
|
|
|
if(parent._id === this._id) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
parent = parent.getParent();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
},
|
2012-07-07 12:45:18 +08:00
|
|
|
/**
|
|
|
|
* get shapes that intersect a point
|
2012-07-09 12:56:52 +08:00
|
|
|
* @name getIntersections
|
|
|
|
* @methodOf Kinetic.Container.prototype
|
2012-07-07 12:45:18 +08:00
|
|
|
* @param {Object} point
|
|
|
|
*/
|
|
|
|
getIntersections: function() {
|
|
|
|
var pos = Kinetic.Type._getXY(Array.prototype.slice.call(arguments));
|
|
|
|
var arr = [];
|
|
|
|
var shapes = this.get('Shape');
|
|
|
|
|
|
|
|
for(var n = 0; n < shapes.length; n++) {
|
|
|
|
var shape = shapes[n];
|
|
|
|
if(shape.isVisible() && shape.intersects(pos)) {
|
|
|
|
arr.push(shape);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return arr;
|
|
|
|
},
|
2012-04-28 13:54:39 +08:00
|
|
|
/**
|
|
|
|
* get all shapes inside container
|
|
|
|
*/
|
|
|
|
_getNodes: function(sel) {
|
|
|
|
var arr = [];
|
|
|
|
function traverse(cont) {
|
|
|
|
var children = cont.getChildren();
|
|
|
|
for(var n = 0; n < children.length; n++) {
|
|
|
|
var child = children[n];
|
|
|
|
if(child.nodeType === sel) {
|
|
|
|
arr.push(child);
|
|
|
|
}
|
|
|
|
else if(child.nodeType !== 'Shape') {
|
|
|
|
traverse(child);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
traverse(this);
|
|
|
|
|
|
|
|
return arr;
|
|
|
|
},
|
2012-03-07 13:45:48 +08:00
|
|
|
/**
|
|
|
|
* draw children
|
|
|
|
*/
|
2012-07-19 14:28:45 +08:00
|
|
|
_drawChildren: function(canvas) {
|
2012-04-15 03:04:45 +08:00
|
|
|
var stage = this.getStage();
|
2012-03-07 13:45:48 +08:00
|
|
|
var children = this.children;
|
|
|
|
for(var n = 0; n < children.length; n++) {
|
|
|
|
var child = children[n];
|
2012-05-27 15:07:36 +08:00
|
|
|
if(child.nodeType === 'Shape') {
|
|
|
|
if(child.isVisible() && stage.isVisible()) {
|
2012-07-19 14:28:45 +08:00
|
|
|
child._draw(canvas);
|
2012-05-27 15:07:36 +08:00
|
|
|
}
|
2012-03-18 01:28:25 +08:00
|
|
|
}
|
|
|
|
else {
|
2012-07-19 14:28:45 +08:00
|
|
|
child.draw(canvas);
|
2012-03-07 13:45:48 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* set children indices
|
|
|
|
*/
|
|
|
|
_setChildrenIndices: function() {
|
|
|
|
for(var n = 0; n < this.children.length; n++) {
|
|
|
|
this.children[n].index = n;
|
|
|
|
}
|
|
|
|
}
|
2012-07-04 03:07:27 +08:00
|
|
|
});
|