2012-07-04 14:00:52 +08:00
|
|
|
///////////////////////////////////////////////////////////////////////
|
|
|
|
// Type
|
|
|
|
///////////////////////////////////////////////////////////////////////
|
2012-07-04 13:08:59 +08:00
|
|
|
/*
|
|
|
|
* utilities that determine data type and transform
|
|
|
|
* one type into another
|
2012-03-07 13:45:48 +08:00
|
|
|
*/
|
2012-07-04 13:08:59 +08:00
|
|
|
Kinetic.Type = {
|
2012-04-29 08:45:13 +08:00
|
|
|
/*
|
2012-06-22 03:47:15 +08:00
|
|
|
* cherry-picked utilities from underscore.js
|
2012-04-29 08:45:13 +08:00
|
|
|
*/
|
2012-04-28 10:42:04 +08:00
|
|
|
_isElement: function(obj) {
|
|
|
|
return !!(obj && obj.nodeType == 1);
|
|
|
|
},
|
|
|
|
_isFunction: function(obj) {
|
|
|
|
return !!(obj && obj.constructor && obj.call && obj.apply);
|
2012-04-28 14:57:01 +08:00
|
|
|
},
|
2012-05-09 13:11:37 +08:00
|
|
|
_isArray: function(obj) {
|
2012-06-21 03:55:34 +08:00
|
|
|
return Object.prototype.toString.call(obj) == '[object Array]';
|
2012-05-09 13:11:37 +08:00
|
|
|
},
|
|
|
|
_isObject: function(obj) {
|
2012-06-23 04:15:29 +08:00
|
|
|
return (!!obj && obj.constructor == Object);
|
2012-05-09 13:11:37 +08:00
|
|
|
},
|
2012-05-26 11:18:05 +08:00
|
|
|
_isNumber: function(obj) {
|
2012-05-29 14:46:40 +08:00
|
|
|
return Object.prototype.toString.call(obj) == '[object Number]';
|
2012-05-26 11:18:05 +08:00
|
|
|
},
|
2012-06-23 04:15:29 +08:00
|
|
|
/*
|
|
|
|
* other utils
|
|
|
|
*/
|
2012-05-27 09:31:13 +08:00
|
|
|
_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
|
|
|
/*
|
2012-05-26 11:18:05 +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) {
|
2012-05-26 11:18:05 +08:00
|
|
|
if(this._isNumber(arg)) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return {
|
2012-05-26 11:18:05 +08:00
|
|
|
x: arg,
|
|
|
|
y: arg
|
2012-05-20 12:14:04 +08:00
|
|
|
};
|
2012-05-13 09:37:07 +08:00
|
|
|
}
|
2012-05-26 11:18:05 +08:00
|
|
|
else if(this._isArray(arg)) {
|
|
|
|
// if arg is an array of one element
|
2012-05-20 12:14:04 +08:00
|
|
|
if(arg.length === 1) {
|
|
|
|
var val = arg[0];
|
2012-05-26 11:18:05 +08:00
|
|
|
// 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)) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return {
|
|
|
|
x: val[0],
|
|
|
|
y: val[1]
|
|
|
|
};
|
|
|
|
}
|
2012-05-26 11:18:05 +08:00
|
|
|
// if arg is an array of one element which is an object
|
|
|
|
else if(this._isObject(val)) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return val;
|
|
|
|
}
|
2012-05-13 09:37:07 +08:00
|
|
|
}
|
2012-05-26 11:18:05 +08:00
|
|
|
// if arg is an array of two or more elements
|
2012-05-27 07:37:37 +08:00
|
|
|
else if(arg.length >= 2) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return {
|
|
|
|
x: arg[0],
|
|
|
|
y: arg[1]
|
|
|
|
};
|
2012-05-13 09:37:07 +08:00
|
|
|
}
|
|
|
|
}
|
2012-05-26 11:18:05 +08:00
|
|
|
// if arg is an object return the object
|
|
|
|
else if(this._isObject(arg)) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return arg;
|
|
|
|
}
|
2012-05-27 07:37:37 +08:00
|
|
|
|
|
|
|
// default
|
|
|
|
return {
|
|
|
|
x: 0,
|
|
|
|
y: 0
|
|
|
|
};
|
2012-05-13 09:37:07 +08:00
|
|
|
},
|
2012-05-14 02:58:40 +08:00
|
|
|
/*
|
2012-05-27 07:37:37 +08:00
|
|
|
* 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
|
2012-05-14 02:58:40 +08:00
|
|
|
*/
|
2012-05-20 12:14:04 +08:00
|
|
|
_getSize: function(arg) {
|
2012-05-27 07:37:37 +08:00
|
|
|
if(this._isNumber(arg)) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return {
|
2012-05-27 07:37:37 +08:00
|
|
|
width: arg,
|
|
|
|
height: arg
|
2012-05-20 12:14:04 +08:00
|
|
|
};
|
2012-05-13 09:37:07 +08:00
|
|
|
}
|
2012-05-27 07:37:37 +08:00
|
|
|
else if(this._isArray(arg)) {
|
|
|
|
// if arg is an array of one element
|
2012-05-20 12:14:04 +08:00
|
|
|
if(arg.length === 1) {
|
|
|
|
var val = arg[0];
|
2012-05-27 07:37:37 +08:00
|
|
|
// 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) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return {
|
2012-05-27 07:37:37 +08:00
|
|
|
width: val[2],
|
|
|
|
height: val[3]
|
2012-05-20 12:14:04 +08:00
|
|
|
};
|
|
|
|
}
|
2012-05-27 07:37:37 +08:00
|
|
|
/*
|
|
|
|
* if arg is an array of one element which is an
|
|
|
|
* array of two elements
|
|
|
|
*/
|
|
|
|
else if(val.length >= 2) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return {
|
2012-05-27 07:37:37 +08:00
|
|
|
width: val[0],
|
|
|
|
height: val[1]
|
2012-05-20 12:14:04 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
2012-05-27 07:37:37 +08:00
|
|
|
// if arg is an array of one element which is an object
|
|
|
|
else if(this._isObject(val)) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return val;
|
|
|
|
}
|
|
|
|
}
|
2012-05-27 07:37:37 +08:00
|
|
|
// if arg is an array of four elements
|
|
|
|
else if(arg.length >= 4) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return {
|
2012-05-27 07:37:37 +08:00
|
|
|
width: arg[2],
|
|
|
|
height: arg[3]
|
2012-05-20 12:14:04 +08:00
|
|
|
};
|
2012-05-13 09:37:07 +08:00
|
|
|
}
|
2012-05-27 07:37:37 +08:00
|
|
|
// if arg is an array of two elements
|
|
|
|
else if(arg.length >= 2) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return {
|
2012-05-27 07:37:37 +08:00
|
|
|
width: arg[0],
|
|
|
|
height: arg[1]
|
2012-05-20 12:14:04 +08:00
|
|
|
};
|
2012-05-13 09:37:07 +08:00
|
|
|
}
|
|
|
|
}
|
2012-05-27 07:37:37 +08:00
|
|
|
// if arg is an object return the object
|
|
|
|
else if(this._isObject(arg)) {
|
2012-05-20 12:14:04 +08:00
|
|
|
return arg;
|
|
|
|
}
|
2012-05-27 07:37:37 +08:00
|
|
|
|
|
|
|
// default
|
|
|
|
return {
|
|
|
|
width: 0,
|
|
|
|
height: 0
|
|
|
|
};
|
2012-05-14 02:58:40 +08:00
|
|
|
},
|
|
|
|
/*
|
2012-05-20 12:14:04 +08:00
|
|
|
* arg will be an array of numbers or
|
2012-05-14 02:58:40 +08:00
|
|
|
* an array of point objects
|
|
|
|
*/
|
2012-05-20 12:14:04 +08:00
|
|
|
_getPoints: function(arg) {
|
|
|
|
if(arg === undefined) {
|
|
|
|
return [];
|
2012-05-14 02:58:40 +08:00
|
|
|
}
|
2012-05-20 12:14:04 +08:00
|
|
|
|
|
|
|
// an array of objects
|
|
|
|
if(this._isObject(arg[0])) {
|
|
|
|
return arg;
|
|
|
|
}
|
|
|
|
// an array of integers
|
2012-05-14 02:58:40 +08:00
|
|
|
else {
|
|
|
|
/*
|
|
|
|
* convert array of numbers into an array
|
|
|
|
* of objects containing x, y
|
|
|
|
*/
|
|
|
|
var arr = [];
|
2012-05-20 12:14:04 +08:00
|
|
|
for(var n = 0; n < arg.length; n += 2) {
|
2012-05-14 02:58:40 +08:00
|
|
|
arr.push({
|
2012-05-20 12:14:04 +08:00
|
|
|
x: arg[n],
|
|
|
|
y: arg[n + 1]
|
2012-05-14 02:58:40 +08:00
|
|
|
});
|
|
|
|
}
|
2012-05-20 12:14:04 +08:00
|
|
|
|
|
|
|
return arr;
|
2012-05-14 02:58:40 +08:00
|
|
|
}
|
2012-07-15 07:25:56 +08:00
|
|
|
},
|
|
|
|
/*
|
|
|
|
* arg can be an image object or image data
|
|
|
|
*/
|
|
|
|
_getImage: function(arg) {
|
|
|
|
// if arg is already an image object, just return it
|
|
|
|
if(this._isElement(arg)) {
|
|
|
|
return arg;
|
|
|
|
}
|
|
|
|
|
|
|
|
//if arg is image data, then convert it
|
|
|
|
if(arg.data) {
|
|
|
|
var canvas = document.createElement('canvas');
|
|
|
|
canvas.width = arg.width;
|
|
|
|
canvas.height = arg.height;
|
|
|
|
var context = canvas.getContext('2d');
|
|
|
|
context.putImageData(arg, 0, 0);
|
|
|
|
var dataUrl = canvas.toDataURL();
|
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
|
|
|
var imageObj = new Image();
|
|
|
|
imageObj.src = dataUrl;
|
|
|
|
return imageObj;
|
2012-07-15 07:25:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// default
|
|
|
|
return null;
|
2012-03-07 13:45:48 +08:00
|
|
|
}
|
|
|
|
};
|