konva/src/GlobalObject.js

354 lines
10 KiB
JavaScript
Raw Normal View History

///////////////////////////////////////////////////////////////////////
// Global Object
///////////////////////////////////////////////////////////////////////
/**
* Kinetic Namespace
* @namespace
*/
var Kinetic = {};
/**
* Kinetic Global Object
* @property {Object} GlobalObjet
*/
Kinetic.GlobalObject = {
stages: [],
idCounter: 0,
tempNodes: [],
animations: [],
animIdCounter: 0,
animRunning: false,
maxDragTimeInterval: 20,
frame: {
time: 0,
timeDiff: 0,
lastTime: 0
},
drag: {
moving: false,
node: undefined,
offset: {
x: 0,
y: 0
},
lastDrawTime: 0
},
extend: function(obj1, obj2) {
for(var key in obj2.prototype) {
if(obj2.prototype.hasOwnProperty(key) && obj1.prototype[key] === undefined) {
obj1.prototype[key] = obj2.prototype[key];
}
}
},
addSetters: function(constructor, arr) {
for(var n = 0; n < arr.length; n++) {
var attr = arr[n];
this._addSetter(constructor, attr);
}
},
addGetters: function(constructor, arr) {
for(var n = 0; n < arr.length; n++) {
var attr = arr[n];
this._addGetter(constructor, attr);
}
},
_pullNodes: function(stage) {
2012-04-29 02:41:58 +08:00
var tempNodes = this.tempNodes;
for(var n = 0; n < tempNodes.length; n++) {
var node = tempNodes[n];
if(node.getStage() !== undefined && node.getStage()._id === stage._id) {
stage._addId(node);
stage._addName(node);
2012-04-29 02:41:58 +08:00
this.tempNodes.splice(n, 1);
n -= 1;
}
}
},
/*
* animation support
*/
_addAnimation: function(anim) {
anim.id = this.animIdCounter++;
this.animations.push(anim);
},
_removeAnimation: function(anim) {
var id = anim.id;
var animations = this.animations;
for(var n = 0; n < animations.length; n++) {
if(animations[n].id === id) {
this.animations.splice(n, 1);
return false;
}
}
},
_runFrames: function() {
var nodes = {};
for(var n = 0; n < this.animations.length; n++) {
var anim = this.animations[n];
if(anim.node && anim.node._id !== undefined) {
nodes[anim.node._id] = anim.node;
}
anim.func(this.frame);
}
for(var key in nodes) {
nodes[key].draw();
}
},
_updateFrameObject: function() {
var date = new Date();
var time = date.getTime();
if(this.frame.lastTime === 0) {
this.frame.lastTime = time;
}
else {
this.frame.timeDiff = time - this.frame.lastTime;
this.frame.lastTime = time;
this.frame.time += this.frame.timeDiff;
}
},
_animationLoop: function() {
if(this.animations.length > 0) {
this._updateFrameObject();
this._runFrames();
var that = this;
requestAnimFrame(function() {
that._animationLoop();
});
}
else {
this.animRunning = false;
this.frame.lastTime = 0;
}
},
_handleAnimation: function() {
var that = this;
if(!this.animRunning) {
this.animRunning = true;
that._animationLoop();
}
else {
this.frame.lastTime = 0;
}
},
/*
* cherry-picked and modified utilities from underscore.js
*/
_isElement: function(obj) {
return !!(obj && obj.nodeType == 1);
},
_isFunction: function(obj) {
return !!(obj && obj.constructor && obj.call && obj.apply);
},
_isArray: function(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
},
_isObject: function(obj) {
return (obj !== undefined && obj.constructor == Object);
},
_isNumber: function(obj) {
return Object.prototype.toString.call(obj) == '[object Number]';
},
_hasMethods: function(obj) {
var names = [];
for(var key in obj) {
if(this._isFunction(obj[key]))
names.push(key);
}
return names.length > 0;
},
2012-05-14 01:46:49 +08:00
/*
* The argument can be:
* - an integer (will be applied to both x and y)
* - an array of one integer (will be applied to both x and y)
* - an array of two integers (contains x and y)
* - an array of four integers (contains x, y, width, and height)
* - an object with x and y properties
* - an array of one element which is an array of integers
* - an array of one element of an object
2012-05-14 01:46:49 +08:00
*/
_getXY: function(arg) {
if(this._isNumber(arg)) {
return {
x: arg,
y: arg
};
}
else if(this._isArray(arg)) {
// if arg is an array of one element
if(arg.length === 1) {
var val = arg[0];
// if arg is an array of one element which is a number
if(this._isNumber(val)) {
return {
x: val,
y: val
};
}
// if arg is an array of one element which is an array
else if(this._isArray(val)) {
return {
x: val[0],
y: val[1]
};
}
// if arg is an array of one element which is an object
else if(this._isObject(val)) {
return val;
}
}
// if arg is an array of two or more elements
else if(arg.length >= 2) {
return {
x: arg[0],
y: arg[1]
};
}
}
// if arg is an object return the object
else if(this._isObject(arg)) {
return arg;
}
// default
return {
x: 0,
y: 0
};
},
/*
* The argument can be:
* - an integer (will be applied to both width and height)
* - an array of one integer (will be applied to both width and height)
* - an array of two integers (contains width and height)
* - an array of four integers (contains x, y, width, and height)
* - an object with width and height properties
* - an array of one element which is an array of integers
* - an array of one element of an object
*/
_getSize: function(arg) {
if(this._isNumber(arg)) {
return {
width: arg,
height: arg
};
}
else if(this._isArray(arg)) {
// if arg is an array of one element
if(arg.length === 1) {
var val = arg[0];
// if arg is an array of one element which is a number
if(this._isNumber(val)) {
return {
width: val,
height: val
};
}
// if arg is an array of one element which is an array
else if(this._isArray(val)) {
/*
* if arg is an array of one element which is an
* array of four elements
*/
if(val.length >= 4) {
return {
width: val[2],
height: val[3]
};
}
/*
* if arg is an array of one element which is an
* array of two elements
*/
else if(val.length >= 2) {
return {
width: val[0],
height: val[1]
};
}
}
// if arg is an array of one element which is an object
else if(this._isObject(val)) {
return val;
}
}
// if arg is an array of four elements
else if(arg.length >= 4) {
return {
width: arg[2],
height: arg[3]
};
}
// if arg is an array of two elements
else if(arg.length >= 2) {
return {
width: arg[0],
height: arg[1]
};
}
}
// if arg is an object return the object
else if(this._isObject(arg)) {
return arg;
}
// default
return {
width: 0,
height: 0
};
},
/*
* arg will be an array of numbers or
* an array of point objects
*/
_getPoints: function(arg) {
if(arg === undefined) {
return [];
}
// an array of objects
if(this._isObject(arg[0])) {
return arg;
}
// an array of integers
else {
/*
* convert array of numbers into an array
* of objects containing x, y
*/
var arr = [];
for(var n = 0; n < arg.length; n += 2) {
arr.push({
x: arg[n],
y: arg[n + 1]
});
}
return arr;
}
},
_addSetter: function(constructor, attr) {
var that = this;
var method = 'set' + attr.charAt(0).toUpperCase() + attr.slice(1);
constructor.prototype[method] = function(arg) {
var obj = {};
obj[attr] = arg;
this.setAttrs(obj);
};
},
_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];
};
}
};
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();