2012-11-27 12:42:01 +08:00
|
|
|
(function() {
|
2013-03-24 13:56:22 +08:00
|
|
|
// CONSTANTS
|
|
|
|
var SPACE = ' ',
|
|
|
|
EMPTY_STRING = '',
|
|
|
|
DOT = '.',
|
|
|
|
GET = 'get',
|
|
|
|
SET = 'set',
|
|
|
|
SHAPE = 'Shape',
|
|
|
|
STAGE = 'Stage',
|
|
|
|
X = 'x',
|
|
|
|
Y = 'y',
|
2013-04-28 11:50:42 +08:00
|
|
|
UPPER_X = 'X',
|
|
|
|
UPPER_Y = 'Y',
|
2013-03-24 13:56:22 +08:00
|
|
|
KINETIC = 'kinetic',
|
|
|
|
BEFORE = 'before',
|
|
|
|
CHANGE = 'Change',
|
|
|
|
ID = 'id',
|
|
|
|
NAME = 'name',
|
|
|
|
MOUSEENTER = 'mouseenter',
|
|
|
|
MOUSELEAVE = 'mouseleave',
|
|
|
|
DEG = 'Deg',
|
|
|
|
ON = 'on',
|
2013-03-24 16:05:37 +08:00
|
|
|
OFF = 'off',
|
|
|
|
BEFORE_DRAW = 'beforeDraw',
|
2013-04-30 14:12:28 +08:00
|
|
|
DRAW = 'draw',
|
|
|
|
BLACK = 'black',
|
|
|
|
RGB = 'RGB',
|
|
|
|
R = 'r',
|
|
|
|
G = 'g',
|
2013-05-04 12:13:26 +08:00
|
|
|
B = 'b',
|
|
|
|
UPPER_R = 'R',
|
|
|
|
UPPER_G = 'G',
|
|
|
|
UPPER_B = 'B',
|
|
|
|
HASH = '#';
|
2013-03-24 13:56:22 +08:00
|
|
|
|
2013-05-08 14:51:02 +08:00
|
|
|
Kinetic.Util.addMethods(Kinetic.Node, {
|
2012-11-14 15:22:56 +08:00
|
|
|
_nodeInit: function(config) {
|
2013-01-13 14:01:12 +08:00
|
|
|
this._id = Kinetic.Global.idCounter++;
|
2012-11-14 15:22:56 +08:00
|
|
|
this.eventListeners = {};
|
|
|
|
this.setAttrs(config);
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* bind events to the node. KineticJS supports mouseover, mousemove,
|
|
|
|
* mouseout, mouseenter, mouseleave, mousedown, mouseup, click, dblclick, touchstart, touchmove,
|
|
|
|
* touchend, tap, dbltap, dragstart, dragmove, and dragend events. Pass in a string
|
|
|
|
* of events delimmited by a space to bind multiple events at once
|
|
|
|
* such as 'mousedown mouseup mousemove'. Include a namespace to bind an
|
2012-11-14 15:22:56 +08:00
|
|
|
* event by name such as 'click.foobar'.
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-27 11:12:02 +08:00
|
|
|
* @param {String} typesStr e.g. 'click', 'mousedown touchstart', 'mousedown.foo touchstart.foo'
|
|
|
|
* @param {Function} handler The handler function is passed an event object
|
2013-05-16 00:27:22 +08:00
|
|
|
* @example
|
|
|
|
* node.on('click', function() {<br>
|
|
|
|
* console.log('you clicked me!');<br>
|
|
|
|
* }
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
on: function(typesStr, handler) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var types = typesStr.split(SPACE),
|
|
|
|
len = types.length,
|
|
|
|
n, type, event, parts, baseEvent, name;
|
|
|
|
|
|
|
|
/*
|
2012-11-14 15:22:56 +08:00
|
|
|
* loop through types and attach event listeners to
|
|
|
|
* each one. eg. 'click mouseover.namespace mouseout'
|
|
|
|
* will create three event bindings
|
|
|
|
*/
|
2013-03-24 13:56:22 +08:00
|
|
|
for(n = 0; n < len; n++) {
|
|
|
|
type = types[n];
|
|
|
|
event = type;
|
|
|
|
parts = event.split(DOT);
|
|
|
|
baseEvent = parts[0];
|
|
|
|
name = parts.length > 1 ? parts[1] : EMPTY_STRING;
|
2012-11-14 15:22:56 +08:00
|
|
|
|
|
|
|
if(!this.eventListeners[baseEvent]) {
|
|
|
|
this.eventListeners[baseEvent] = [];
|
|
|
|
}
|
2012-08-26 13:26:25 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
this.eventListeners[baseEvent].push({
|
|
|
|
name: name,
|
|
|
|
handler: handler
|
|
|
|
});
|
2012-07-14 12:24:38 +08:00
|
|
|
}
|
2013-03-15 06:07:35 +08:00
|
|
|
return this;
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* remove event bindings from the node. Pass in a string of
|
2012-11-14 15:22:56 +08:00
|
|
|
* event types delimmited by a space to remove multiple event
|
|
|
|
* bindings at once such as 'mousedown mouseup mousemove'.
|
|
|
|
* include a namespace to remove an event binding by name
|
|
|
|
* such as 'click.foobar'. If you only give a name like '.foobar',
|
|
|
|
* all events in that namespace will be removed.
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-27 11:12:02 +08:00
|
|
|
* @param {String} typesStr e.g. 'click', 'mousedown touchstart', '.foobar'
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
off: function(typesStr) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var types = typesStr.split(SPACE),
|
|
|
|
len = types.length,
|
|
|
|
n, type, event, parts, baseEvent;
|
|
|
|
|
|
|
|
for(n = 0; n < len; n++) {
|
|
|
|
type = types[n];
|
|
|
|
event = type;
|
|
|
|
parts = event.split(DOT);
|
|
|
|
baseEvent = parts[0];
|
2012-11-14 15:22:56 +08:00
|
|
|
|
|
|
|
if(parts.length > 1) {
|
|
|
|
if(baseEvent) {
|
|
|
|
if(this.eventListeners[baseEvent]) {
|
|
|
|
this._off(baseEvent, parts[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for(var type in this.eventListeners) {
|
|
|
|
this._off(type, parts[1]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
delete this.eventListeners[baseEvent];
|
|
|
|
}
|
2012-07-14 12:24:38 +08:00
|
|
|
}
|
2013-03-15 06:07:35 +08:00
|
|
|
return this;
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
2013-01-13 14:01:12 +08:00
|
|
|
* remove child from container, but don't destroy it
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-03-07 13:45:48 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
remove: function() {
|
|
|
|
var parent = this.getParent();
|
2013-03-24 13:56:22 +08:00
|
|
|
|
2013-01-13 14:01:12 +08:00
|
|
|
if(parent && parent.children) {
|
2012-11-14 15:22:56 +08:00
|
|
|
parent.children.splice(this.index, 1);
|
|
|
|
parent._setChildrenIndices();
|
2013-01-13 14:01:12 +08:00
|
|
|
}
|
|
|
|
delete this.parent;
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* remove and destroy node
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-13 14:01:12 +08:00
|
|
|
*/
|
|
|
|
destroy: function() {
|
2013-03-24 13:56:22 +08:00
|
|
|
var parent = this.getParent(),
|
|
|
|
stage = this.getStage(),
|
|
|
|
dd = Kinetic.DD,
|
|
|
|
go = Kinetic.Global;
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2013-01-14 03:10:49 +08:00
|
|
|
// destroy children
|
|
|
|
while(this.children && this.children.length > 0) {
|
|
|
|
this.children[0].destroy();
|
2013-01-13 14:01:12 +08:00
|
|
|
}
|
|
|
|
|
2013-01-14 03:10:49 +08:00
|
|
|
// remove from ids and names hashes
|
|
|
|
go._removeId(this.getId());
|
|
|
|
go._removeName(this.getName(), this._id);
|
2013-01-13 14:01:12 +08:00
|
|
|
|
2013-04-29 05:14:45 +08:00
|
|
|
// TODO: stop transitions
|
|
|
|
|
2013-01-14 11:59:35 +08:00
|
|
|
this.remove();
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
2013-03-15 23:33:05 +08:00
|
|
|
/**
|
|
|
|
* get attr
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-03-16 07:19:12 +08:00
|
|
|
* @param {String} attr
|
2013-03-15 23:33:05 +08:00
|
|
|
*/
|
|
|
|
getAttr: function(attr) {
|
2013-05-08 14:51:02 +08:00
|
|
|
var method = GET + Kinetic.Util._capitalize(attr);
|
|
|
|
if(Kinetic.Util._isFunction(this[method])) {
|
2013-04-28 11:50:42 +08:00
|
|
|
return this[method]();
|
|
|
|
}
|
|
|
|
// otherwise get directly
|
|
|
|
else {
|
|
|
|
return this.attrs[attr];
|
|
|
|
}
|
2013-03-15 23:33:05 +08:00
|
|
|
},
|
2013-05-15 13:37:33 +08:00
|
|
|
/**
|
|
|
|
* set attr
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-15 13:37:33 +08:00
|
|
|
* @param {String} attr
|
|
|
|
* #param {*} val
|
|
|
|
*/
|
|
|
|
setAttr: function() {
|
|
|
|
var args = Array.prototype.slice.call(arguments),
|
|
|
|
attr = args[0],
|
|
|
|
method = SET + Kinetic.Util._capitalize(attr),
|
|
|
|
func = this[method];
|
|
|
|
|
|
|
|
args.shift();
|
|
|
|
if(Kinetic.Util._isFunction(func)) {
|
|
|
|
func.apply(this, args);
|
|
|
|
}
|
|
|
|
// otherwise get directly
|
|
|
|
else {
|
|
|
|
this.attrs[attr] = args[0];
|
|
|
|
}
|
|
|
|
},
|
2012-11-14 15:22:56 +08:00
|
|
|
/**
|
|
|
|
* get attrs
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getAttrs: function() {
|
2013-03-15 23:33:05 +08:00
|
|
|
return this.attrs || {};
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
2013-03-15 23:33:05 +08:00
|
|
|
createAttrs: function() {
|
2012-11-14 15:22:56 +08:00
|
|
|
if(this.attrs === undefined) {
|
|
|
|
this.attrs = {};
|
2012-03-07 13:45:48 +08:00
|
|
|
}
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
2013-03-15 23:33:05 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
/**
|
|
|
|
* set attrs
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-27 11:12:02 +08:00
|
|
|
* @param {Object} config object containing key value pairs
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
setAttrs: function(config) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var key, method;
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
if(config) {
|
2013-03-24 13:56:22 +08:00
|
|
|
for(key in config) {
|
2013-05-08 14:51:02 +08:00
|
|
|
method = SET + Kinetic.Util._capitalize(key);
|
2012-11-14 15:22:56 +08:00
|
|
|
// use setter if available
|
2013-05-08 14:51:02 +08:00
|
|
|
if(Kinetic.Util._isFunction(this[method])) {
|
2012-11-14 15:22:56 +08:00
|
|
|
this[method](config[key]);
|
|
|
|
}
|
|
|
|
// otherwise set directly
|
|
|
|
else {
|
2013-05-15 13:37:33 +08:00
|
|
|
this._setAttr(key, config[key]);
|
2012-03-07 13:45:48 +08:00
|
|
|
}
|
|
|
|
}
|
2012-03-14 12:16:25 +08:00
|
|
|
}
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* determine if node is visible or not. Node is visible only
|
|
|
|
* if it's visible and all of its ancestors are visible. If an ancestor
|
|
|
|
* is invisible, this means that the node is also invisible
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getVisible: function() {
|
2013-03-15 23:33:05 +08:00
|
|
|
var visible = this.attrs.visible,
|
|
|
|
parent = this.getParent();
|
|
|
|
|
|
|
|
// default
|
|
|
|
if (visible === undefined) {
|
|
|
|
visible = true;
|
|
|
|
}
|
|
|
|
|
2012-11-14 16:07:59 +08:00
|
|
|
if(visible && parent && !parent.getVisible()) {
|
2012-11-14 15:22:56 +08:00
|
|
|
return false;
|
2012-03-07 13:45:48 +08:00
|
|
|
}
|
2012-11-14 16:07:59 +08:00
|
|
|
return visible;
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* determine if node is listening or not. Node is listening only
|
|
|
|
* if it's listening and all of its ancestors are listening. If an ancestor
|
|
|
|
* is not listening, this means that the node is also not listening
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getListening: function() {
|
2013-03-15 23:33:05 +08:00
|
|
|
var listening = this.attrs.listening,
|
|
|
|
parent = this.getParent();
|
|
|
|
|
|
|
|
// default
|
|
|
|
if (listening === undefined) {
|
|
|
|
listening = true;
|
|
|
|
}
|
|
|
|
|
2012-11-14 16:07:59 +08:00
|
|
|
if(listening && parent && !parent.getListening()) {
|
2012-11-14 15:22:56 +08:00
|
|
|
return false;
|
|
|
|
}
|
2012-11-14 16:07:59 +08:00
|
|
|
return listening;
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* show node
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
show: function() {
|
|
|
|
this.setVisible(true);
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* hide node. Hidden nodes are no longer detectable
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
hide: function() {
|
|
|
|
this.setVisible(false);
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* get zIndex relative to the node's siblings who share the same parent
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getZIndex: function() {
|
2013-03-15 23:33:05 +08:00
|
|
|
return this.index || 0;
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* get absolute z-index which takes into account sibling
|
2012-11-27 11:12:02 +08:00
|
|
|
* and ancestor indices
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getAbsoluteZIndex: function() {
|
2013-03-24 13:56:22 +08:00
|
|
|
var level = this.getLevel(),
|
|
|
|
stage = this.getStage(),
|
|
|
|
that = this,
|
|
|
|
index = 0,
|
|
|
|
nodes, len, n, child;
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
function addChildren(children) {
|
2013-03-24 13:56:22 +08:00
|
|
|
nodes = [];
|
|
|
|
len = children.length;
|
|
|
|
for(n = 0; n < len; n++) {
|
|
|
|
child = children[n];
|
2012-11-14 15:22:56 +08:00
|
|
|
index++;
|
|
|
|
|
2013-03-24 13:56:22 +08:00
|
|
|
if(child.nodeType !== SHAPE) {
|
2012-11-14 15:22:56 +08:00
|
|
|
nodes = nodes.concat(child.getChildren());
|
|
|
|
}
|
|
|
|
|
|
|
|
if(child._id === that._id) {
|
|
|
|
n = len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(nodes.length > 0 && nodes[0].getLevel() <= level) {
|
|
|
|
addChildren(nodes);
|
|
|
|
}
|
|
|
|
}
|
2013-03-24 13:56:22 +08:00
|
|
|
if(that.nodeType !== STAGE) {
|
2012-11-14 15:22:56 +08:00
|
|
|
addChildren(that.getStage().getChildren());
|
|
|
|
}
|
|
|
|
|
|
|
|
return index;
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* get node level in node tree. Returns an integer.<br><br>
|
2012-11-30 12:15:01 +08:00
|
|
|
* e.g. Stage level will always be 0. Layers will always be 1. Groups and Shapes will always
|
2012-11-27 11:12:02 +08:00
|
|
|
* be >= 2
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getLevel: function() {
|
2013-03-24 13:56:22 +08:00
|
|
|
var level = 0,
|
|
|
|
parent = this.parent;
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
while(parent) {
|
|
|
|
level++;
|
|
|
|
parent = parent.parent;
|
|
|
|
}
|
|
|
|
return level;
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* set node position relative to parent
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Number} x
|
|
|
|
* @param {Number} y
|
|
|
|
*/
|
|
|
|
setPosition: function() {
|
2013-05-08 14:51:02 +08:00
|
|
|
var pos = Kinetic.Util._getXY([].slice.call(arguments));
|
2013-05-08 15:18:29 +08:00
|
|
|
this.setX(pos.x);
|
|
|
|
this.setY(pos.y);
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* get node position relative to parent
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getPosition: function() {
|
|
|
|
return {
|
2013-03-15 23:33:05 +08:00
|
|
|
x: this.getX(),
|
|
|
|
y: this.getY()
|
2012-11-14 15:22:56 +08:00
|
|
|
};
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* get absolute position relative to the top left corner of the stage container div
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getAbsolutePosition: function() {
|
2013-03-24 13:56:22 +08:00
|
|
|
var trans = this.getAbsoluteTransform(),
|
|
|
|
o = this.getOffset();
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
trans.translate(o.x, o.y);
|
|
|
|
return trans.getTranslation();
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* set absolute position
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-27 11:12:02 +08:00
|
|
|
* @param {Number} x
|
|
|
|
* @param {Number} y
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
setAbsolutePosition: function() {
|
2013-05-08 14:51:02 +08:00
|
|
|
var pos = Kinetic.Util._getXY([].slice.call(arguments)),
|
2013-03-24 13:56:22 +08:00
|
|
|
trans = this._clearTransform(),
|
|
|
|
it;
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
// don't clear translation
|
|
|
|
this.attrs.x = trans.x;
|
|
|
|
this.attrs.y = trans.y;
|
|
|
|
delete trans.x;
|
|
|
|
delete trans.y;
|
|
|
|
|
|
|
|
// unravel transform
|
2013-03-24 13:56:22 +08:00
|
|
|
it = this.getAbsoluteTransform();
|
2012-11-14 15:22:56 +08:00
|
|
|
|
|
|
|
it.invert();
|
|
|
|
it.translate(pos.x, pos.y);
|
|
|
|
pos = {
|
|
|
|
x: this.attrs.x + it.getTranslation().x,
|
|
|
|
y: this.attrs.y + it.getTranslation().y
|
|
|
|
};
|
|
|
|
|
|
|
|
this.setPosition(pos.x, pos.y);
|
|
|
|
this._setTransform(trans);
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* move node by an amount relative to its current position
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Number} x
|
|
|
|
* @param {Number} y
|
|
|
|
*/
|
|
|
|
move: function() {
|
2013-05-08 14:51:02 +08:00
|
|
|
var pos = Kinetic.Util._getXY([].slice.call(arguments)),
|
2013-03-24 13:56:22 +08:00
|
|
|
x = this.getX(),
|
|
|
|
y = this.getY();
|
2012-11-14 15:22:56 +08:00
|
|
|
|
|
|
|
if(pos.x !== undefined) {
|
|
|
|
x += pos.x;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(pos.y !== undefined) {
|
|
|
|
y += pos.y;
|
2012-09-27 03:50:08 +08:00
|
|
|
}
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
this.setPosition(x, y);
|
|
|
|
},
|
2012-12-31 17:47:49 +08:00
|
|
|
_eachAncestorReverse: function(func, includeSelf) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var family = [],
|
|
|
|
parent = this.getParent(),
|
|
|
|
len, n;
|
2012-12-31 15:14:23 +08:00
|
|
|
|
|
|
|
// build family by traversing ancestors
|
2012-12-31 17:47:49 +08:00
|
|
|
if(includeSelf) {
|
|
|
|
family.unshift(this);
|
|
|
|
}
|
2012-12-31 15:14:23 +08:00
|
|
|
while(parent) {
|
|
|
|
family.unshift(parent);
|
|
|
|
parent = parent.parent;
|
|
|
|
}
|
|
|
|
|
2013-03-24 13:56:22 +08:00
|
|
|
len = family.length;
|
|
|
|
for(n = 0; n < len; n++) {
|
2012-12-31 15:48:46 +08:00
|
|
|
func(family[n]);
|
2012-12-31 15:14:23 +08:00
|
|
|
}
|
|
|
|
},
|
2012-11-14 15:22:56 +08:00
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* rotate node by an amount in radians relative to its current rotation
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Number} theta
|
|
|
|
*/
|
|
|
|
rotate: function(theta) {
|
|
|
|
this.setRotation(this.getRotation() + theta);
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* rotate node by an amount in degrees relative to its current rotation
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Number} deg
|
|
|
|
*/
|
|
|
|
rotateDeg: function(deg) {
|
2013-05-08 14:51:02 +08:00
|
|
|
this.setRotation(this.getRotation() + Kinetic.Util._degToRad(deg));
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* move node to the top of its siblings
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
moveToTop: function() {
|
|
|
|
var index = this.index;
|
|
|
|
this.parent.children.splice(index, 1);
|
|
|
|
this.parent.children.push(this);
|
|
|
|
this.parent._setChildrenIndices();
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* move node up
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
moveUp: function() {
|
2013-03-24 13:56:22 +08:00
|
|
|
var index = this.index,
|
|
|
|
len = this.parent.getChildren().length;
|
2012-11-14 15:22:56 +08:00
|
|
|
if(index < len - 1) {
|
|
|
|
this.parent.children.splice(index, 1);
|
|
|
|
this.parent.children.splice(index + 1, 0, this);
|
|
|
|
this.parent._setChildrenIndices();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* move node down
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
moveDown: function() {
|
|
|
|
var index = this.index;
|
|
|
|
if(index > 0) {
|
|
|
|
this.parent.children.splice(index, 1);
|
|
|
|
this.parent.children.splice(index - 1, 0, this);
|
|
|
|
this.parent._setChildrenIndices();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* move node to the bottom of its siblings
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
moveToBottom: function() {
|
|
|
|
var index = this.index;
|
|
|
|
if(index > 0) {
|
|
|
|
this.parent.children.splice(index, 1);
|
|
|
|
this.parent.children.unshift(this);
|
|
|
|
this.parent._setChildrenIndices();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* set zIndex relative to siblings
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Integer} zIndex
|
|
|
|
*/
|
|
|
|
setZIndex: function(zIndex) {
|
|
|
|
var index = this.index;
|
|
|
|
this.parent.children.splice(index, 1);
|
|
|
|
this.parent.children.splice(zIndex, 0, this);
|
|
|
|
this.parent._setChildrenIndices();
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* get absolute opacity
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getAbsoluteOpacity: function() {
|
|
|
|
var absOpacity = this.getOpacity();
|
|
|
|
if(this.getParent()) {
|
|
|
|
absOpacity *= this.getParent().getAbsoluteOpacity();
|
|
|
|
}
|
|
|
|
return absOpacity;
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* move node to another container
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Container} newContainer
|
|
|
|
*/
|
|
|
|
moveTo: function(newContainer) {
|
2013-01-14 03:10:49 +08:00
|
|
|
Kinetic.Node.prototype.remove.call(this);
|
|
|
|
newContainer.add(this);
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* convert Node into an object for serialization. Returns an object.
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
toObject: function() {
|
2013-05-08 14:51:02 +08:00
|
|
|
var type = Kinetic.Util,
|
2013-03-24 13:56:22 +08:00
|
|
|
obj = {},
|
|
|
|
attrs = this.getAttrs(),
|
|
|
|
key, val;
|
2012-04-29 03:55:18 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
obj.attrs = {};
|
|
|
|
|
|
|
|
// serialize only attributes that are not function, image, DOM, or objects with methods
|
2013-03-24 13:56:22 +08:00
|
|
|
for(key in attrs) {
|
|
|
|
val = attrs[key];
|
2012-11-14 16:07:59 +08:00
|
|
|
if(!type._isFunction(val) && !type._isElement(val) && !(type._isObject(val) && type._hasMethods(val))) {
|
2012-11-14 15:22:56 +08:00
|
|
|
obj.attrs[key] = val;
|
2012-05-13 06:15:42 +08:00
|
|
|
}
|
2012-04-29 03:55:18 +08:00
|
|
|
}
|
2012-11-14 15:22:56 +08:00
|
|
|
|
|
|
|
obj.nodeType = this.nodeType;
|
|
|
|
obj.shapeType = this.shapeType;
|
|
|
|
|
|
|
|
return obj;
|
|
|
|
},
|
2012-11-27 11:12:02 +08:00
|
|
|
/**
|
|
|
|
* convert Node into a JSON string. Returns a JSON string.
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-27 11:12:02 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
toJSON: function() {
|
|
|
|
return JSON.stringify(this.toObject());
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* get parent container
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getParent: function() {
|
|
|
|
return this.parent;
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* get layer ancestor
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getLayer: function() {
|
|
|
|
return this.getParent().getLayer();
|
|
|
|
},
|
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* get stage ancestor
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getStage: function() {
|
|
|
|
if(this.getParent()) {
|
|
|
|
return this.getParent().getStage();
|
2012-09-26 04:38:36 +08:00
|
|
|
}
|
2012-11-14 15:22:56 +08:00
|
|
|
else {
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
/**
|
2013-03-22 10:43:17 +08:00
|
|
|
* fire event
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-03-22 10:43:17 +08:00
|
|
|
* @param {String} eventType event type. can be a regular event, like click, mouseover, or mouseout, or it can be a custom event, like myCustomEvent
|
|
|
|
* @param {EventObject} evt event object
|
2013-05-13 23:56:09 +08:00
|
|
|
* @param {Boolean} bubble setting the value to false, or leaving it undefined, will result in the event
|
|
|
|
* not bubbling. Setting the value to true will result in the event bubbling.
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
2013-05-13 23:56:09 +08:00
|
|
|
fire: function(eventType, evt, bubble) {
|
2013-03-22 10:43:17 +08:00
|
|
|
// bubble
|
2013-05-13 23:56:09 +08:00
|
|
|
if (bubble) {
|
|
|
|
this._fireAndBubble(eventType, evt || {});
|
|
|
|
}
|
|
|
|
// no bubble
|
2013-03-22 10:43:17 +08:00
|
|
|
else {
|
2013-05-13 23:56:09 +08:00
|
|
|
this._fire(eventType, evt || {});
|
2013-03-22 10:43:17 +08:00
|
|
|
}
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* get absolute transform of the node which takes into
|
2012-11-27 11:12:02 +08:00
|
|
|
* account its ancestor transforms
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getAbsoluteTransform: function() {
|
|
|
|
// absolute transform
|
2013-03-24 13:56:22 +08:00
|
|
|
var am = new Kinetic.Transform(),
|
|
|
|
m;
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2012-12-31 17:47:49 +08:00
|
|
|
this._eachAncestorReverse(function(node) {
|
2013-03-24 13:56:22 +08:00
|
|
|
m = node.getTransform();
|
2012-11-14 15:22:56 +08:00
|
|
|
am.multiply(m);
|
2012-12-31 17:47:49 +08:00
|
|
|
}, true);
|
2012-11-14 15:22:56 +08:00
|
|
|
return am;
|
|
|
|
},
|
2013-04-22 13:42:25 +08:00
|
|
|
_getAndCacheTransform: function() {
|
2013-02-12 16:20:24 +08:00
|
|
|
var m = new Kinetic.Transform(),
|
2013-03-15 23:33:05 +08:00
|
|
|
x = this.getX(),
|
|
|
|
y = this.getY(),
|
|
|
|
rotation = this.getRotation(),
|
2013-05-02 01:56:01 +08:00
|
|
|
scaleX = this.getScaleX(),
|
|
|
|
scaleY = this.getScaleY(),
|
|
|
|
skewX = this.getSkewX(),
|
|
|
|
skewY = this.getSkewY(),
|
|
|
|
offsetX = this.getOffsetX(),
|
|
|
|
offsetY = this.getOffsetY();
|
2013-02-12 16:20:24 +08:00
|
|
|
|
2012-11-14 16:07:59 +08:00
|
|
|
if(x !== 0 || y !== 0) {
|
|
|
|
m.translate(x, y);
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
2012-11-14 16:07:59 +08:00
|
|
|
if(rotation !== 0) {
|
|
|
|
m.rotate(rotation);
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
2013-05-02 01:56:01 +08:00
|
|
|
if(skewX !== 0 || skewY !== 0) {
|
|
|
|
m.skew(skewX, skewY);
|
|
|
|
}
|
2012-11-14 16:07:59 +08:00
|
|
|
if(scaleX !== 1 || scaleY !== 1) {
|
|
|
|
m.scale(scaleX, scaleY);
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
2012-11-14 16:07:59 +08:00
|
|
|
if(offsetX !== 0 || offsetY !== 0) {
|
|
|
|
m.translate(-1 * offsetX, -1 * offsetY);
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
2013-04-22 13:42:25 +08:00
|
|
|
|
|
|
|
// cache result
|
|
|
|
this.cachedTransform = m;
|
2012-11-14 15:22:56 +08:00
|
|
|
return m;
|
|
|
|
},
|
2013-04-22 13:42:25 +08:00
|
|
|
/**
|
|
|
|
* get transform of the node
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-04-22 13:42:25 +08:00
|
|
|
*/
|
|
|
|
getTransform: function(useCache) {
|
|
|
|
var cachedTransform = this.cachedTransform;
|
|
|
|
if (useCache && cachedTransform) {
|
|
|
|
return cachedTransform;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return this._getAndCacheTransform();
|
|
|
|
}
|
|
|
|
},
|
2012-11-14 15:22:56 +08:00
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* clone node. Returns a new Node instance with identical attributes
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Object} attrs override attrs
|
|
|
|
*/
|
|
|
|
clone: function(obj) {
|
|
|
|
// instantiate new node
|
2013-03-24 13:56:22 +08:00
|
|
|
var classType = this.shapeType || this.nodeType,
|
|
|
|
node = new Kinetic[classType](this.attrs),
|
|
|
|
key, allListeners, len, n, listener;
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2013-03-24 11:15:49 +08:00
|
|
|
// copy over listeners
|
2013-03-24 13:56:22 +08:00
|
|
|
for(key in this.eventListeners) {
|
|
|
|
allListeners = this.eventListeners[key];
|
|
|
|
len = allListeners.length;
|
|
|
|
for(n = 0; n < len; n++) {
|
|
|
|
listener = allListeners[n];
|
2012-11-14 15:22:56 +08:00
|
|
|
/*
|
|
|
|
* don't include kinetic namespaced listeners because
|
|
|
|
* these are generated by the constructors
|
|
|
|
*/
|
2013-03-24 13:56:22 +08:00
|
|
|
if(listener.name.indexOf(KINETIC) < 0) {
|
2012-11-14 15:22:56 +08:00
|
|
|
// if listeners array doesn't exist, then create it
|
|
|
|
if(!node.eventListeners[key]) {
|
|
|
|
node.eventListeners[key] = [];
|
|
|
|
}
|
|
|
|
node.eventListeners[key].push(listener);
|
|
|
|
}
|
2012-04-01 06:17:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
// apply attr overrides
|
|
|
|
node.setAttrs(obj);
|
|
|
|
return node;
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* Creates a composite data URL. If MIME type is not
|
|
|
|
* specified, then "image/png" will result. For "image/jpeg", specify a quality
|
|
|
|
* level as quality (range 0.0 - 1.0)
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Object} config
|
2012-12-17 12:52:07 +08:00
|
|
|
* @param {Function} config.callback function executed when the composite has completed
|
|
|
|
* @param {String} [config.mimeType] can be "image/png" or "image/jpeg".
|
2012-11-14 15:22:56 +08:00
|
|
|
* "image/png" is the default
|
2012-12-17 12:52:07 +08:00
|
|
|
* @param {Number} [config.x] x position of canvas section
|
|
|
|
* @param {Number} [config.y] y position of canvas section
|
|
|
|
* @param {Number} [config.width] width of canvas section
|
|
|
|
* @param {Number} [config.height] height of canvas section
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
|
|
|
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
|
|
|
* is very high quality
|
|
|
|
*/
|
|
|
|
toDataURL: function(config) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var config = config || {},
|
|
|
|
mimeType = config.mimeType || null,
|
|
|
|
quality = config.quality || null,
|
2013-04-15 00:41:59 +08:00
|
|
|
stage = this.getStage(),
|
2013-03-24 13:56:22 +08:00
|
|
|
x = config.x || 0,
|
|
|
|
y = config.y || 0,
|
2013-03-22 15:46:41 +08:00
|
|
|
canvas = new Kinetic.SceneCanvas({
|
2013-04-15 00:41:59 +08:00
|
|
|
width: config.width || stage.getWidth(),
|
|
|
|
height: config.height || stage.getHeight(),
|
|
|
|
pixelRatio: 1
|
|
|
|
}),
|
|
|
|
context = canvas.getContext();
|
|
|
|
|
2012-12-11 16:08:59 +08:00
|
|
|
context.save();
|
2012-12-31 15:14:23 +08:00
|
|
|
|
2012-12-11 16:08:59 +08:00
|
|
|
if(x || y) {
|
|
|
|
context.translate(-1 * x, -1 * y);
|
|
|
|
}
|
2013-04-15 00:41:59 +08:00
|
|
|
|
2012-12-11 16:08:59 +08:00
|
|
|
this.drawScene(canvas);
|
|
|
|
context.restore();
|
2012-04-01 06:17:36 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
return canvas.toDataURL(mimeType, quality);
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* converts node into an image. Since the toImage
|
2012-11-27 11:12:02 +08:00
|
|
|
* method is asynchronous, a callback is required. toImage is most commonly used
|
|
|
|
* to cache complex drawings as an image so that they don't have to constantly be redrawn
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Object} config
|
2012-12-17 12:52:07 +08:00
|
|
|
* @param {Function} config.callback function executed when the composite has completed
|
|
|
|
* @param {String} [config.mimeType] can be "image/png" or "image/jpeg".
|
2012-11-14 15:22:56 +08:00
|
|
|
* "image/png" is the default
|
2012-12-17 12:52:07 +08:00
|
|
|
* @param {Number} [config.x] x position of canvas section
|
|
|
|
* @param {Number} [config.y] y position of canvas section
|
|
|
|
* @param {Number} [config.width] width of canvas section
|
|
|
|
* @param {Number} [config.height] height of canvas section
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Number} [config.quality] jpeg quality. If using an "image/jpeg" mimeType,
|
|
|
|
* you can specify the quality from 0 to 1, where 0 is very poor quality and 1
|
|
|
|
* is very high quality
|
|
|
|
*/
|
|
|
|
toImage: function(config) {
|
2013-05-08 14:51:02 +08:00
|
|
|
Kinetic.Util._getImage(this.toDataURL(config), function(img) {
|
2012-11-14 15:22:56 +08:00
|
|
|
config.callback(img);
|
|
|
|
});
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* set size
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Number} width
|
|
|
|
* @param {Number} height
|
|
|
|
*/
|
|
|
|
setSize: function() {
|
|
|
|
// set stage dimensions
|
2013-05-08 14:51:02 +08:00
|
|
|
var size = Kinetic.Util._getSize(Array.prototype.slice.call(arguments));
|
2012-11-14 15:22:56 +08:00
|
|
|
this.setWidth(size.width);
|
|
|
|
this.setHeight(size.height);
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* get size
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getSize: function() {
|
|
|
|
return {
|
|
|
|
width: this.getWidth(),
|
|
|
|
height: this.getHeight()
|
|
|
|
};
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* get width
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getWidth: function() {
|
|
|
|
return this.attrs.width || 0;
|
|
|
|
},
|
|
|
|
/**
|
|
|
|
* get height
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
|
|
|
getHeight: function() {
|
|
|
|
return this.attrs.height || 0;
|
|
|
|
},
|
|
|
|
_get: function(selector) {
|
|
|
|
return this.nodeType === selector ? [this] : [];
|
|
|
|
},
|
|
|
|
_off: function(type, name) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var evtListeners = this.eventListeners[type],
|
|
|
|
i;
|
|
|
|
|
|
|
|
for(i = 0; i < evtListeners.length; i++) {
|
|
|
|
if(evtListeners[i].name === name) {
|
|
|
|
evtListeners.splice(i, 1);
|
|
|
|
if(evtListeners.length === 0) {
|
2012-11-14 15:22:56 +08:00
|
|
|
delete this.eventListeners[type];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_clearTransform: function() {
|
2013-05-03 01:22:21 +08:00
|
|
|
|
2013-05-02 01:56:01 +08:00
|
|
|
var trans = {
|
|
|
|
x: this.getX(),
|
|
|
|
y: this.getY(),
|
|
|
|
rotation: this.getRotation(),
|
|
|
|
scaleX: this.getScaleX(),
|
|
|
|
scaleY: this.getScaleY(),
|
|
|
|
offsetX: this.getOffsetX(),
|
|
|
|
offsetY: this.getOffsetY(),
|
|
|
|
skewX: this.getSkewX(),
|
|
|
|
skewY: this.getSkewY()
|
|
|
|
};
|
2012-06-10 06:31:25 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
this.attrs.x = 0;
|
|
|
|
this.attrs.y = 0;
|
|
|
|
this.attrs.rotation = 0;
|
2013-05-02 01:56:01 +08:00
|
|
|
this.attrs.scaleX = 1;
|
|
|
|
this.attrs.scaleY = 1;
|
2013-05-03 01:22:21 +08:00
|
|
|
this.attrs.offsetX = 0;
|
|
|
|
this.attrs.offsetY = 0;
|
2013-05-02 01:56:01 +08:00
|
|
|
this.attrs.skewX = 0;
|
|
|
|
this.attrs.skewY = 0;
|
2012-06-10 06:31:25 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
return trans;
|
|
|
|
},
|
|
|
|
_setTransform: function(trans) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var key;
|
|
|
|
|
|
|
|
for(key in trans) {
|
2012-11-14 15:22:56 +08:00
|
|
|
this.attrs[key] = trans[key];
|
|
|
|
}
|
2013-05-03 01:22:21 +08:00
|
|
|
|
|
|
|
this.cachedTransform = null;
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
_fireBeforeChangeEvent: function(attr, oldVal, newVal) {
|
2013-05-13 23:56:09 +08:00
|
|
|
this._fire(BEFORE + Kinetic.Util._capitalize(attr) + CHANGE, {
|
2012-11-14 15:22:56 +08:00
|
|
|
oldVal: oldVal,
|
|
|
|
newVal: newVal
|
2013-05-13 23:56:09 +08:00
|
|
|
});
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
|
|
|
_fireChangeEvent: function(attr, oldVal, newVal) {
|
2013-05-13 23:56:09 +08:00
|
|
|
this._fire(attr + CHANGE, {
|
2012-11-14 15:22:56 +08:00
|
|
|
oldVal: oldVal,
|
|
|
|
newVal: newVal
|
2013-05-13 23:56:09 +08:00
|
|
|
});
|
2012-11-14 15:22:56 +08:00
|
|
|
},
|
2013-01-14 03:10:49 +08:00
|
|
|
/**
|
|
|
|
* set id
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-14 03:10:49 +08:00
|
|
|
* @param {String} id
|
|
|
|
*/
|
|
|
|
setId: function(id) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var oldId = this.getId(),
|
|
|
|
stage = this.getStage(),
|
|
|
|
go = Kinetic.Global;
|
|
|
|
|
2013-01-14 03:10:49 +08:00
|
|
|
go._removeId(oldId);
|
|
|
|
go._addId(this, id);
|
2013-05-15 13:37:33 +08:00
|
|
|
this._setAttr(ID, id);
|
2013-01-14 03:10:49 +08:00
|
|
|
},
|
|
|
|
/**
|
|
|
|
* set name
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-14 03:10:49 +08:00
|
|
|
* @param {String} name
|
|
|
|
*/
|
|
|
|
setName: function(name) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var oldName = this.getName(),
|
|
|
|
stage = this.getStage(),
|
|
|
|
go = Kinetic.Global;
|
|
|
|
|
2013-01-14 03:10:49 +08:00
|
|
|
go._removeName(oldName, this._id);
|
|
|
|
go._addName(this, name);
|
2013-05-15 13:37:33 +08:00
|
|
|
this._setAttr(NAME, name);
|
2013-01-14 03:10:49 +08:00
|
|
|
},
|
2013-03-24 15:14:42 +08:00
|
|
|
/**
|
|
|
|
* get node type. Returns 'Stage', 'Layer', 'Group', or 'Shape'
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-03-24 15:14:42 +08:00
|
|
|
*/
|
|
|
|
getNodeType: function() {
|
|
|
|
return this.nodeType;
|
|
|
|
},
|
2013-05-15 13:37:33 +08:00
|
|
|
_setAttr: function(key, val) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var oldVal;
|
2012-11-14 15:22:56 +08:00
|
|
|
if(val !== undefined) {
|
2013-03-24 13:56:22 +08:00
|
|
|
oldVal = this.attrs[key];
|
2012-11-14 15:22:56 +08:00
|
|
|
this._fireBeforeChangeEvent(key, oldVal, val);
|
|
|
|
this.attrs[key] = val;
|
|
|
|
this._fireChangeEvent(key, oldVal, val);
|
|
|
|
}
|
|
|
|
},
|
2013-05-13 23:56:09 +08:00
|
|
|
_fireAndBubble: function(eventType, evt, compareShape) {
|
2013-03-24 13:56:22 +08:00
|
|
|
if(evt && this.nodeType === SHAPE) {
|
2013-03-25 01:38:05 +08:00
|
|
|
evt.targetNode = this;
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
|
|
|
var stage = this.getStage();
|
|
|
|
var el = this.eventListeners;
|
|
|
|
var okayToRun = true;
|
|
|
|
|
2013-03-24 13:56:22 +08:00
|
|
|
if(eventType === MOUSEENTER && compareShape && this._id === compareShape._id) {
|
2012-11-14 15:22:56 +08:00
|
|
|
okayToRun = false;
|
|
|
|
}
|
2013-03-24 13:56:22 +08:00
|
|
|
else if(eventType === MOUSELEAVE && compareShape && this._id === compareShape._id) {
|
2012-11-14 15:22:56 +08:00
|
|
|
okayToRun = false;
|
|
|
|
}
|
2012-06-10 06:31:25 +08:00
|
|
|
|
2013-03-22 15:46:41 +08:00
|
|
|
if(okayToRun) {
|
2013-05-13 23:56:09 +08:00
|
|
|
this._fire(eventType, evt);
|
2012-11-14 15:22:56 +08:00
|
|
|
|
|
|
|
// simulate event bubbling
|
|
|
|
if(evt && !evt.cancelBubble && this.parent) {
|
|
|
|
if(compareShape && compareShape.parent) {
|
2013-05-13 23:56:09 +08:00
|
|
|
this._fireAndBubble.call(this.parent, eventType, evt, compareShape.parent);
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
|
|
|
else {
|
2013-05-13 23:56:09 +08:00
|
|
|
this._fireAndBubble.call(this.parent, eventType, evt);
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2013-05-13 23:56:09 +08:00
|
|
|
_fire: function(eventType, evt) {
|
2013-03-22 10:43:17 +08:00
|
|
|
var events = this.eventListeners[eventType],
|
|
|
|
len, i;
|
|
|
|
|
|
|
|
if (events) {
|
|
|
|
len = events.length;
|
|
|
|
for(i = 0; i < len; i++) {
|
2013-05-15 13:37:33 +08:00
|
|
|
events[i].handler.call(this, evt);
|
2013-03-22 10:43:17 +08:00
|
|
|
}
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
2013-03-22 15:46:41 +08:00
|
|
|
},
|
|
|
|
/*
|
2013-03-24 11:02:11 +08:00
|
|
|
* draw both scene and hit graphs. If the node being drawn is the stage, all of the layers will be cleared and redra
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-03-22 15:46:41 +08:00
|
|
|
* the scene renderer
|
|
|
|
*/
|
|
|
|
draw: function() {
|
2013-04-05 14:17:20 +08:00
|
|
|
var evt = {
|
2013-05-08 14:17:57 +08:00
|
|
|
node: this
|
|
|
|
};
|
2013-03-22 15:46:41 +08:00
|
|
|
|
2013-05-13 23:56:09 +08:00
|
|
|
this._fire(BEFORE_DRAW, evt);
|
2013-03-22 15:46:41 +08:00
|
|
|
this.drawScene();
|
|
|
|
this.drawHit();
|
2013-05-13 23:56:09 +08:00
|
|
|
this._fire(DRAW, evt);
|
2013-03-24 11:02:11 +08:00
|
|
|
},
|
2013-03-24 13:56:22 +08:00
|
|
|
shouldDrawHit: function() {
|
2013-03-24 14:19:24 +08:00
|
|
|
return this.isVisible() && this.isListening() && !Kinetic.Global.isDragging();
|
2012-06-10 06:31:25 +08:00
|
|
|
}
|
2013-05-08 14:17:57 +08:00
|
|
|
});
|
2012-06-10 06:31:25 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
// add getter and setter methods
|
2013-04-28 11:50:42 +08:00
|
|
|
Kinetic.Node.addGetterSetter = function(constructor, attr, def, isTransform) {
|
|
|
|
this.addGetter(constructor, attr, def);
|
|
|
|
this.addSetter(constructor, attr, isTransform);
|
2012-11-14 15:22:56 +08:00
|
|
|
};
|
2013-04-28 11:50:42 +08:00
|
|
|
Kinetic.Node.addPointGetterSetter = function(constructor, attr, def, isTransform) {
|
|
|
|
this.addPointGetter(constructor, attr);
|
|
|
|
this.addPointSetter(constructor, attr);
|
|
|
|
|
|
|
|
// add invdividual component getters and setters
|
2013-05-03 01:22:21 +08:00
|
|
|
this.addGetter(constructor, attr + UPPER_X, def);
|
|
|
|
this.addGetter(constructor, attr + UPPER_Y, def);
|
2013-04-28 11:50:42 +08:00
|
|
|
this.addSetter(constructor, attr + UPPER_X, isTransform);
|
|
|
|
this.addSetter(constructor, attr + UPPER_Y, isTransform);
|
2013-01-02 15:54:02 +08:00
|
|
|
};
|
2013-04-28 11:50:42 +08:00
|
|
|
Kinetic.Node.addRotationGetterSetter = function(constructor, attr, def, isTransform) {
|
|
|
|
this.addRotationGetter(constructor, attr, def);
|
|
|
|
this.addRotationSetter(constructor, attr, isTransform);
|
2013-01-02 15:54:02 +08:00
|
|
|
};
|
2013-04-30 14:12:28 +08:00
|
|
|
Kinetic.Node.addColorGetterSetter = function(constructor, attr) {
|
|
|
|
this.addGetter(constructor, attr);
|
|
|
|
this.addSetter(constructor, attr);
|
|
|
|
|
2013-05-04 12:13:26 +08:00
|
|
|
// component getters
|
2013-04-30 14:12:28 +08:00
|
|
|
this.addColorRGBGetter(constructor, attr);
|
|
|
|
this.addColorComponentGetter(constructor, attr, R);
|
|
|
|
this.addColorComponentGetter(constructor, attr, G);
|
|
|
|
this.addColorComponentGetter(constructor, attr, B);
|
2013-05-04 12:13:26 +08:00
|
|
|
|
|
|
|
// component setters
|
|
|
|
this.addColorRGBSetter(constructor, attr);
|
|
|
|
this.addColorComponentSetter(constructor, attr, R);
|
|
|
|
this.addColorComponentSetter(constructor, attr, G);
|
|
|
|
this.addColorComponentSetter(constructor, attr, B);
|
2013-04-30 14:12:28 +08:00
|
|
|
};
|
|
|
|
Kinetic.Node.addColorRGBGetter = function(constructor, attr) {
|
2013-05-08 14:51:02 +08:00
|
|
|
var method = GET + Kinetic.Util._capitalize(attr) + RGB;
|
2013-04-30 14:12:28 +08:00
|
|
|
constructor.prototype[method] = function() {
|
2013-05-08 14:51:02 +08:00
|
|
|
return Kinetic.Util.getRGB(this.attrs[attr]);
|
2013-04-30 14:12:28 +08:00
|
|
|
};
|
|
|
|
};
|
2013-05-04 12:13:26 +08:00
|
|
|
Kinetic.Node.addColorRGBSetter = function(constructor, attr) {
|
2013-05-08 14:51:02 +08:00
|
|
|
var method = SET + Kinetic.Util._capitalize(attr) + RGB;
|
2013-05-04 12:13:26 +08:00
|
|
|
|
|
|
|
constructor.prototype[method] = function(obj) {
|
|
|
|
var r = obj && obj.r !== undefined ? obj.r | 0 : this.getAttr(attr + UPPER_R),
|
|
|
|
g = obj && obj.g !== undefined ? obj.g | 0 : this.getAttr(attr + UPPER_G),
|
|
|
|
b = obj && obj.b !== undefined ? obj.b | 0 : this.getAttr(attr + UPPER_B);
|
|
|
|
|
2013-05-15 13:37:33 +08:00
|
|
|
this._setAttr(attr, HASH + Kinetic.Util._rgbToHex(r, g, b));
|
2013-05-04 12:13:26 +08:00
|
|
|
};
|
|
|
|
};
|
2013-04-30 14:12:28 +08:00
|
|
|
Kinetic.Node.addColorComponentGetter = function(constructor, attr, c) {
|
2013-05-08 14:51:02 +08:00
|
|
|
var prefix = GET + Kinetic.Util._capitalize(attr),
|
|
|
|
method = prefix + Kinetic.Util._capitalize(c);
|
2013-04-30 14:12:28 +08:00
|
|
|
constructor.prototype[method] = function() {
|
2013-05-04 12:13:26 +08:00
|
|
|
return this[prefix + RGB]()[c];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
Kinetic.Node.addColorComponentSetter = function(constructor, attr, c) {
|
2013-05-08 14:51:02 +08:00
|
|
|
var prefix = SET + Kinetic.Util._capitalize(attr),
|
|
|
|
method = prefix + Kinetic.Util._capitalize(c);
|
2013-05-04 12:13:26 +08:00
|
|
|
constructor.prototype[method] = function(val) {
|
|
|
|
var obj = {};
|
|
|
|
obj[c] = val;
|
|
|
|
this[prefix + RGB](obj);
|
2013-04-30 14:12:28 +08:00
|
|
|
};
|
|
|
|
};
|
2013-04-22 13:42:25 +08:00
|
|
|
Kinetic.Node.addSetter = function(constructor, attr, isTransform) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var that = this,
|
2013-05-08 14:51:02 +08:00
|
|
|
method = SET + Kinetic.Util._capitalize(attr);
|
2013-03-24 13:56:22 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
constructor.prototype[method] = function(val) {
|
2013-05-15 13:37:33 +08:00
|
|
|
this._setAttr(attr, val);
|
2013-04-22 13:42:25 +08:00
|
|
|
if (isTransform) {
|
|
|
|
this.cachedTransform = null;
|
|
|
|
}
|
2012-11-14 15:22:56 +08:00
|
|
|
};
|
|
|
|
};
|
2013-04-28 11:50:42 +08:00
|
|
|
Kinetic.Node.addPointSetter = function(constructor, attr) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var that = this,
|
2013-05-08 14:51:02 +08:00
|
|
|
baseMethod = SET + Kinetic.Util._capitalize(attr);
|
2013-03-15 23:33:05 +08:00
|
|
|
|
2013-04-28 11:50:42 +08:00
|
|
|
constructor.prototype[baseMethod] = function() {
|
2013-05-08 14:51:02 +08:00
|
|
|
var pos = Kinetic.Util._getXY([].slice.call(arguments)),
|
2013-04-28 11:50:42 +08:00
|
|
|
oldVal = this.attrs[attr];
|
|
|
|
x = 0,
|
|
|
|
y = 0;
|
2013-04-22 13:42:25 +08:00
|
|
|
|
2013-04-28 11:50:42 +08:00
|
|
|
if (pos) {
|
|
|
|
x = pos.x;
|
|
|
|
y = pos.y;
|
|
|
|
|
|
|
|
this._fireBeforeChangeEvent(attr, oldVal, pos);
|
|
|
|
if (x !== undefined) {
|
|
|
|
this[baseMethod + UPPER_X](x);
|
|
|
|
}
|
|
|
|
if (y !== undefined) {
|
|
|
|
this[baseMethod + UPPER_Y](y);
|
|
|
|
}
|
|
|
|
this._fireChangeEvent(attr, oldVal, pos);
|
|
|
|
}
|
2013-01-02 15:54:02 +08:00
|
|
|
};
|
|
|
|
};
|
2013-04-22 13:42:25 +08:00
|
|
|
Kinetic.Node.addRotationSetter = function(constructor, attr, isTransform) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var that = this,
|
2013-05-08 14:51:02 +08:00
|
|
|
method = SET + Kinetic.Util._capitalize(attr);
|
2013-03-24 13:56:22 +08:00
|
|
|
|
2013-01-02 15:54:02 +08:00
|
|
|
// radians
|
|
|
|
constructor.prototype[method] = function(val) {
|
2013-05-15 13:37:33 +08:00
|
|
|
this._setAttr(attr, val);
|
2013-04-22 13:42:25 +08:00
|
|
|
if (isTransform) {
|
|
|
|
this.cachedTransform = null;
|
|
|
|
}
|
2013-01-02 15:54:02 +08:00
|
|
|
};
|
|
|
|
// degrees
|
2013-03-24 13:56:22 +08:00
|
|
|
constructor.prototype[method + DEG] = function(deg) {
|
2013-05-15 13:37:33 +08:00
|
|
|
this._setAttr(attr, Kinetic.Util._degToRad(deg));
|
2013-04-22 13:42:25 +08:00
|
|
|
if (isTransform) {
|
|
|
|
this.cachedTransform = null;
|
|
|
|
}
|
2013-01-02 15:54:02 +08:00
|
|
|
};
|
|
|
|
};
|
2013-03-15 23:33:05 +08:00
|
|
|
Kinetic.Node.addGetter = function(constructor, attr, def) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var that = this,
|
2013-05-08 14:51:02 +08:00
|
|
|
method = GET + Kinetic.Util._capitalize(attr);
|
2013-04-28 11:50:42 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
constructor.prototype[method] = function(arg) {
|
2013-03-15 23:33:05 +08:00
|
|
|
var val = this.attrs[attr];
|
|
|
|
if (val === undefined) {
|
|
|
|
val = def;
|
|
|
|
}
|
2013-04-28 11:50:42 +08:00
|
|
|
|
2013-03-15 23:33:05 +08:00
|
|
|
return val;
|
2012-11-14 15:22:56 +08:00
|
|
|
};
|
|
|
|
};
|
2013-04-28 11:50:42 +08:00
|
|
|
Kinetic.Node.addPointGetter = function(constructor, attr) {
|
|
|
|
var that = this,
|
2013-05-08 14:51:02 +08:00
|
|
|
baseMethod = GET + Kinetic.Util._capitalize(attr);
|
2013-04-28 11:50:42 +08:00
|
|
|
|
|
|
|
constructor.prototype[baseMethod] = function(arg) {
|
|
|
|
var that = this;
|
|
|
|
return {
|
|
|
|
x: that[baseMethod + UPPER_X](),
|
|
|
|
y: that[baseMethod + UPPER_Y]()
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
2013-03-15 23:33:05 +08:00
|
|
|
Kinetic.Node.addRotationGetter = function(constructor, attr, def) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var that = this,
|
2013-05-08 14:51:02 +08:00
|
|
|
method = GET + Kinetic.Util._capitalize(attr);
|
2013-03-24 13:56:22 +08:00
|
|
|
|
2013-01-02 15:54:02 +08:00
|
|
|
// radians
|
|
|
|
constructor.prototype[method] = function() {
|
2013-03-15 23:33:05 +08:00
|
|
|
var val = this.attrs[attr];
|
|
|
|
if (val === undefined) {
|
|
|
|
val = def;
|
|
|
|
}
|
|
|
|
return val;
|
2013-01-02 15:54:02 +08:00
|
|
|
};
|
|
|
|
// degrees
|
2013-03-24 13:56:22 +08:00
|
|
|
constructor.prototype[method + DEG] = function() {
|
2013-03-15 23:33:05 +08:00
|
|
|
var val = this.attrs[attr];
|
|
|
|
if (val === undefined) {
|
|
|
|
val = def;
|
|
|
|
}
|
2013-05-08 14:51:02 +08:00
|
|
|
return Kinetic.Util._radToDeg(val);
|
2013-01-02 15:54:02 +08:00
|
|
|
};
|
|
|
|
};
|
2012-03-07 13:45:48 +08:00
|
|
|
/**
|
2012-11-14 15:22:56 +08:00
|
|
|
* 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
|
|
|
|
* event handlers (it probably does), then you need to select the appropriate
|
|
|
|
* shapes after loading the stage and set these properties via on(), setDrawFunc(),
|
2012-11-27 11:12:02 +08:00
|
|
|
* and setImage() methods
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {String} JSON string
|
2012-11-30 12:15:01 +08:00
|
|
|
* @param {DomElement} [container] optional container dom element used only if you're
|
2012-11-27 11:12:02 +08:00
|
|
|
* creating a stage node
|
2012-03-07 13:45:48 +08:00
|
|
|
*/
|
2012-11-27 12:42:01 +08:00
|
|
|
Kinetic.Node.create = function(json, container) {
|
2012-11-14 15:22:56 +08:00
|
|
|
return this._createNode(JSON.parse(json), container);
|
|
|
|
};
|
2012-11-27 12:42:01 +08:00
|
|
|
Kinetic.Node._createNode = function(obj, container) {
|
2013-03-24 13:56:22 +08:00
|
|
|
var type, no, len, n;
|
2012-11-14 15:22:56 +08:00
|
|
|
|
|
|
|
// determine type
|
2013-03-24 13:56:22 +08:00
|
|
|
if(obj.nodeType === SHAPE) {
|
2012-11-14 15:22:56 +08:00
|
|
|
// add custom shape
|
|
|
|
if(obj.shapeType === undefined) {
|
2013-03-24 13:56:22 +08:00
|
|
|
type = SHAPE;
|
2012-11-14 15:22:56 +08:00
|
|
|
}
|
|
|
|
// add standard shape
|
|
|
|
else {
|
|
|
|
type = obj.shapeType;
|
|
|
|
}
|
2012-08-26 13:26:25 +08:00
|
|
|
}
|
2012-11-14 15:22:56 +08:00
|
|
|
else {
|
|
|
|
type = obj.nodeType;
|
2012-03-07 13:45:48 +08:00
|
|
|
}
|
2012-10-04 10:38:12 +08:00
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
// if container was passed in, add it to attrs
|
|
|
|
if(container) {
|
|
|
|
obj.attrs.container = container;
|
|
|
|
}
|
2012-10-04 10:38:12 +08:00
|
|
|
|
2013-03-24 13:56:22 +08:00
|
|
|
no = new Kinetic[type](obj.attrs);
|
2012-11-14 15:22:56 +08:00
|
|
|
if(obj.children) {
|
2013-03-24 13:56:22 +08:00
|
|
|
len = obj.children.length;
|
|
|
|
for(n = 0; n < len; n++) {
|
2012-11-14 15:22:56 +08:00
|
|
|
no.add(this._createNode(obj.children[n]));
|
2012-10-04 10:38:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
return no;
|
|
|
|
};
|
|
|
|
// add getters setters
|
2013-04-22 13:42:25 +08:00
|
|
|
Kinetic.Node.addGetterSetter(Kinetic.Node, 'x', 0, true);
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2012-03-07 13:45:48 +08:00
|
|
|
/**
|
2012-11-27 11:12:02 +08:00
|
|
|
* set x position
|
2012-11-14 15:22:56 +08:00
|
|
|
* @name setX
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
* @param {Number} x
|
2012-03-07 13:45:48 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2012-06-02 15:21:49 +08:00
|
|
|
/**
|
2013-05-02 01:56:01 +08:00
|
|
|
* get x position
|
|
|
|
* @name getX
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-06-02 15:21:49 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2013-05-02 01:56:01 +08:00
|
|
|
Kinetic.Node.addGetterSetter(Kinetic.Node, 'y', 0, true);
|
|
|
|
|
2012-03-24 14:39:54 +08:00
|
|
|
/**
|
2013-05-02 01:56:01 +08:00
|
|
|
* set y position
|
|
|
|
* @name setY
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-02 01:56:01 +08:00
|
|
|
* @param {Number} y
|
2012-03-24 14:39:54 +08:00
|
|
|
*/
|
|
|
|
|
2012-11-27 11:12:02 +08:00
|
|
|
/**
|
2013-05-02 01:56:01 +08:00
|
|
|
* get y position
|
|
|
|
* @name getY
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-27 11:12:02 +08:00
|
|
|
*/
|
2012-11-30 12:15:01 +08:00
|
|
|
|
2013-05-02 01:56:01 +08:00
|
|
|
Kinetic.Node.addGetterSetter(Kinetic.Node, 'opacity', 1);
|
|
|
|
|
2012-11-27 11:12:02 +08:00
|
|
|
/**
|
2013-05-02 01:56:01 +08:00
|
|
|
* 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
|
|
|
|
* @name setOpacity
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-02 01:56:01 +08:00
|
|
|
* @param {Object} opacity
|
2012-11-27 11:12:02 +08:00
|
|
|
*/
|
2012-07-08 05:43:12 +08:00
|
|
|
|
toDataURL() is now synchronous, and works with all nodes, including the stage, layers, groups, and shapes. This also sets things up nicely for node caching. You can now cache anything, including the whole stage, layers, groups, or shapes, manifested as Kinetic Images that were instantiated with data urls
2012-07-15 09:10:37 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* get opacity.
|
|
|
|
* @name getOpacity
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
toDataURL() is now synchronous, and works with all nodes, including the stage, layers, groups, and shapes. This also sets things up nicely for node caching. You can now cache anything, including the whole stage, layers, groups, or shapes, manifested as Kinetic Images that were instantiated with data urls
2012-07-15 09:10:37 +08:00
|
|
|
*/
|
2012-07-22 06:38:25 +08:00
|
|
|
|
2013-03-15 23:33:05 +08:00
|
|
|
Kinetic.Node.addGetter(Kinetic.Node, 'name');
|
2013-01-14 03:10:49 +08:00
|
|
|
|
2013-05-02 01:56:01 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* get name
|
|
|
|
* @name getName
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-07-15 14:41:16 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2013-05-02 01:56:01 +08:00
|
|
|
Kinetic.Node.addGetter(Kinetic.Node, 'id');
|
|
|
|
|
2012-09-25 11:34:23 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* get id
|
|
|
|
* @name getId
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-09-26 04:38:36 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2013-04-22 13:42:25 +08:00
|
|
|
Kinetic.Node.addRotationGetterSetter(Kinetic.Node, 'rotation', 0, true);
|
2013-01-03 13:35:51 +08:00
|
|
|
|
2012-09-25 11:34:23 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* set rotation in radians
|
|
|
|
* @name setRotation
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
* @param {Number} theta
|
2012-09-26 04:38:36 +08:00
|
|
|
*/
|
|
|
|
|
2012-10-11 09:48:08 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* set rotation in degrees
|
|
|
|
* @name setRotationDeg
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
* @param {Number} deg
|
2012-10-11 09:48:08 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2012-10-11 09:48:08 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* get rotation in degrees
|
|
|
|
* @name getRotationDeg
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-10-11 09:48:08 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2012-10-11 09:48:08 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* get rotation in radians
|
|
|
|
* @name getRotation
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-10-11 09:48:08 +08:00
|
|
|
*/
|
2012-11-14 15:22:56 +08:00
|
|
|
|
2013-05-03 01:22:21 +08:00
|
|
|
Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'scale', 1, true);
|
2013-01-03 13:35:51 +08:00
|
|
|
|
2012-10-11 09:48:08 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* set scale
|
|
|
|
* @name setScale
|
|
|
|
* @param {Number} x
|
|
|
|
* @param {Number} y
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
*/
|
|
|
|
|
2013-05-08 01:19:54 +08:00
|
|
|
/**
|
|
|
|
* set scale x
|
|
|
|
* @name setScaleX
|
|
|
|
* @param {Number} x
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set scale y
|
|
|
|
* @name setScaleY
|
|
|
|
* @param {Number} y
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
2013-01-03 13:35:51 +08:00
|
|
|
/**
|
2013-05-02 01:56:01 +08:00
|
|
|
* get scale
|
|
|
|
* @name getScale
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-02 01:56:01 +08:00
|
|
|
*/
|
|
|
|
|
2013-05-08 01:19:54 +08:00
|
|
|
/**
|
|
|
|
* get scale x
|
|
|
|
* @name getScaleX
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get scale y
|
|
|
|
* @name getScaleY
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
2013-05-03 01:22:21 +08:00
|
|
|
Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'skew', 0, true);
|
2013-05-02 01:56:01 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* set skew
|
|
|
|
* @name setSkew
|
2013-01-03 13:35:51 +08:00
|
|
|
* @param {Number} x
|
|
|
|
* @param {Number} y
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-10-11 09:48:08 +08:00
|
|
|
*/
|
2012-07-20 14:30:59 +08:00
|
|
|
|
2013-05-08 01:19:54 +08:00
|
|
|
/**
|
|
|
|
* set skew x
|
|
|
|
* @name setSkewX
|
|
|
|
* @param {Number} x
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set skew y
|
|
|
|
* @name setSkewY
|
|
|
|
* @param {Number} y
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
2012-03-07 13:45:48 +08:00
|
|
|
/**
|
2013-05-02 01:56:01 +08:00
|
|
|
* get skew
|
|
|
|
* @name getSkew
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-03-07 13:45:48 +08:00
|
|
|
*/
|
2012-10-11 09:48:08 +08:00
|
|
|
|
2013-05-08 01:19:54 +08:00
|
|
|
/**
|
|
|
|
* get skew x
|
|
|
|
* @name getSkewX
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get skew y
|
|
|
|
* @name getSkewY
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
2013-05-03 01:22:21 +08:00
|
|
|
Kinetic.Node.addPointGetterSetter(Kinetic.Node, 'offset', 0, true);
|
2013-05-02 01:56:01 +08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* set offset. A node's offset defines the position and rotation point
|
|
|
|
* @name setOffset
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-02 01:56:01 +08:00
|
|
|
* @param {Number} x
|
|
|
|
* @param {Number} y
|
|
|
|
*/
|
|
|
|
|
2013-05-08 01:19:54 +08:00
|
|
|
/**
|
|
|
|
* set offset x
|
|
|
|
* @name setOffsetX
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
* @param {Number} x
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* set offset y
|
|
|
|
* @name setOffsetY
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
* @param {Number} y
|
|
|
|
*/
|
|
|
|
|
2012-11-14 15:22:56 +08:00
|
|
|
/**
|
|
|
|
* get offset
|
|
|
|
* @name getOffset
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2012-11-14 15:22:56 +08:00
|
|
|
*/
|
2013-01-02 15:54:02 +08:00
|
|
|
|
2013-05-08 01:19:54 +08:00
|
|
|
/**
|
|
|
|
* get offset x
|
|
|
|
* @name getOffsetX
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* get offset y
|
|
|
|
* @name getOffsetY
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-05-08 01:19:54 +08:00
|
|
|
*/
|
|
|
|
|
2013-03-15 23:33:05 +08:00
|
|
|
Kinetic.Node.addSetter(Kinetic.Node, 'width');
|
2013-01-03 13:35:51 +08:00
|
|
|
|
2013-01-02 15:54:02 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* set width
|
|
|
|
* @name setWidth
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
* @param {Number} width
|
2013-01-02 15:54:02 +08:00
|
|
|
*/
|
|
|
|
|
2013-05-02 01:56:01 +08:00
|
|
|
Kinetic.Node.addSetter(Kinetic.Node, 'height');
|
|
|
|
|
2013-01-02 15:54:02 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* set height
|
|
|
|
* @name setHeight
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
* @param {Number} height
|
2013-01-02 15:54:02 +08:00
|
|
|
*/
|
|
|
|
|
2013-05-02 01:56:01 +08:00
|
|
|
Kinetic.Node.addSetter(Kinetic.Node, 'listening');
|
|
|
|
|
2013-01-02 15:54:02 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* listen or don't listen to events
|
|
|
|
* @name setListening
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
* @param {Boolean} listening
|
2013-01-02 15:54:02 +08:00
|
|
|
*/
|
|
|
|
|
2013-05-02 01:56:01 +08:00
|
|
|
Kinetic.Node.addSetter(Kinetic.Node, 'visible');
|
|
|
|
|
2013-01-02 15:54:02 +08:00
|
|
|
/**
|
2013-01-03 13:35:51 +08:00
|
|
|
* set visible
|
|
|
|
* @name setVisible
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
* @param {Boolean} visible
|
2013-01-02 15:54:02 +08:00
|
|
|
*/
|
2013-01-03 13:35:51 +08:00
|
|
|
|
|
|
|
// aliases
|
|
|
|
/**
|
|
|
|
* Alias of getListening()
|
|
|
|
* @name isListening
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
*/
|
|
|
|
Kinetic.Node.prototype.isListening = Kinetic.Node.prototype.getListening;
|
|
|
|
/**
|
|
|
|
* Alias of getVisible()
|
|
|
|
* @name isVisible
|
2013-05-16 00:27:22 +08:00
|
|
|
* @method
|
|
|
|
* @memberof Kinetic.Node.prototype
|
2013-01-03 13:35:51 +08:00
|
|
|
*/
|
|
|
|
Kinetic.Node.prototype.isVisible = Kinetic.Node.prototype.getVisible;
|
2013-03-26 13:43:35 +08:00
|
|
|
|
|
|
|
Kinetic.Collection.mapMethods(['on', 'off']);
|
2012-09-26 04:38:36 +08:00
|
|
|
})();
|