%PDF- %PDF-
Direktori : /home/jalalj2hb/www/ftm-admin/bower_components/kineticjs/src/ |
Current File : /home/jalalj2hb/www/ftm-admin/bower_components/kineticjs/src/Util.js |
(function() { /** * Collection constructor. Collection extends * Array. This class is used in conjunction with {@link Kinetic.Container#get} * @constructor * @memberof Kinetic */ Kinetic.Collection = function() { var args = [].slice.call(arguments), length = args.length, i = 0; this.length = length; for(; i < length; i++) { this[i] = args[i]; } return this; }; Kinetic.Collection.prototype = []; /** * iterate through node array and run a function for each node. * The node and index is passed into the function * @method * @memberof Kinetic.Collection.prototype * @param {Function} func * @example * // get all nodes with name foo inside layer, and set x to 10 for each * layer.get('.foo').each(function(shape, n) {<br> * shape.setX(10);<br> * }); */ Kinetic.Collection.prototype.each = function(func) { for(var n = 0; n < this.length; n++) { func(this[n], n); } }; /** * convert collection into an array * @method * @memberof Kinetic.Collection.prototype */ Kinetic.Collection.prototype.toArray = function() { var arr = [], len = this.length, n; for(n = 0; n < len; n++) { arr.push(this[n]); } return arr; }; /** * convert array into a collection * @method * @memberof Kinetic.Collection * @param {Array} arr */ Kinetic.Collection.toCollection = function(arr) { var collection = new Kinetic.Collection(), len = arr.length, n; for(n = 0; n < len; n++) { collection.push(arr[n]); } return collection; }; // map one method by it's name Kinetic.Collection._mapMethod = function(methodName) { Kinetic.Collection.prototype[methodName] = function() { var len = this.length, i; var args = [].slice.call(arguments); for(i = 0; i < len; i++) { this[i][methodName].apply(this[i], args); } return this; }; }; Kinetic.Collection.mapMethods = function(constructor) { var prot = constructor.prototype; for(var methodName in prot) { Kinetic.Collection._mapMethod(methodName); } }; /* * Last updated November 2011 * By Simon Sarris * www.simonsarris.com * sarris@acm.org * * Free to use and distribute at will * So long as you are nice to people, etc */ /* * The usage of this class was inspired by some of the work done by a forked * project, KineticJS-Ext by Wappworks, which is based on Simon's Transform * class. Modified by Eric Rowell */ /** * Transform constructor * @constructor * @param {Array} Optional six-element matrix * @memberof Kinetic */ Kinetic.Transform = function(m) { this.m = (m && m.slice()) || [1, 0, 0, 1, 0, 0]; }; Kinetic.Transform.prototype = { /** * Copy Kinetic.Transform object * @method * @memberof Kinetic.Transform.prototype * @returns {Kinetic.Transform} */ copy: function() { return new Kinetic.Transform(this.m); }, /** * Transform point * @method * @memberof Kinetic.Transform.prototype * @param {Object} 2D point(x, y) * @returns {Object} 2D point(x, y) */ point: function(p) { var m = this.m; return { x: m[0] * p.x + m[2] * p.y + m[4], y: m[1] * p.x + m[3] * p.y + m[5] }; }, /** * Apply translation * @method * @memberof Kinetic.Transform.prototype * @param {Number} x * @param {Number} y * @returns {Kinetic.Transform} */ translate: function(x, y) { this.m[4] += this.m[0] * x + this.m[2] * y; this.m[5] += this.m[1] * x + this.m[3] * y; return this; }, /** * Apply scale * @method * @memberof Kinetic.Transform.prototype * @param {Number} sx * @param {Number} sy * @returns {Kinetic.Transform} */ scale: function(sx, sy) { this.m[0] *= sx; this.m[1] *= sx; this.m[2] *= sy; this.m[3] *= sy; return this; }, /** * Apply rotation * @method * @memberof Kinetic.Transform.prototype * @param {Number} rad Angle in radians * @returns {Kinetic.Transform} */ rotate: function(rad) { var c = Math.cos(rad); var s = Math.sin(rad); var m11 = this.m[0] * c + this.m[2] * s; var m12 = this.m[1] * c + this.m[3] * s; var m21 = this.m[0] * -s + this.m[2] * c; var m22 = this.m[1] * -s + this.m[3] * c; this.m[0] = m11; this.m[1] = m12; this.m[2] = m21; this.m[3] = m22; return this; }, /** * Returns the translation * @method * @memberof Kinetic.Transform.prototype * @returns {Object} 2D point(x, y) */ getTranslation: function() { return { x: this.m[4], y: this.m[5] }; }, /** * Apply skew * @method * @memberof Kinetic.Transform.prototype * @param {Number} sx * @param {Number} sy * @returns {Kinetic.Transform} */ skew: function(sx, sy) { var m11 = this.m[0] + this.m[2] * sy; var m12 = this.m[1] + this.m[3] * sy; var m21 = this.m[2] + this.m[0] * sx; var m22 = this.m[3] + this.m[1] * sx; this.m[0] = m11; this.m[1] = m12; this.m[2] = m21; this.m[3] = m22; return this; }, /** * Transform multiplication * @method * @memberof Kinetic.Transform.prototype * @param {Kinetic.Transform} matrix * @returns {Kinetic.Transform} */ multiply: function(matrix) { var m11 = this.m[0] * matrix.m[0] + this.m[2] * matrix.m[1]; var m12 = this.m[1] * matrix.m[0] + this.m[3] * matrix.m[1]; var m21 = this.m[0] * matrix.m[2] + this.m[2] * matrix.m[3]; var m22 = this.m[1] * matrix.m[2] + this.m[3] * matrix.m[3]; var dx = this.m[0] * matrix.m[4] + this.m[2] * matrix.m[5] + this.m[4]; var dy = this.m[1] * matrix.m[4] + this.m[3] * matrix.m[5] + this.m[5]; this.m[0] = m11; this.m[1] = m12; this.m[2] = m21; this.m[3] = m22; this.m[4] = dx; this.m[5] = dy; return this; }, /** * Invert the matrix * @method * @memberof Kinetic.Transform.prototype * @returns {Kinetic.Transform} */ invert: function() { var d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]); var m0 = this.m[3] * d; var m1 = -this.m[1] * d; var m2 = -this.m[2] * d; var m3 = this.m[0] * d; var m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]); var m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]); this.m[0] = m0; this.m[1] = m1; this.m[2] = m2; this.m[3] = m3; this.m[4] = m4; this.m[5] = m5; return this; }, /** * return matrix * @method * @memberof Kinetic.Transform.prototype */ getMatrix: function() { return this.m; }, /** * set to absolute position via translation * @method * @memberof Kinetic.Transform.prototype * @returns {Kinetic.Transform} * @author ericdrowell */ setAbsolutePosition: function(x, y) { var m0 = this.m[0], m1 = this.m[1], m2 = this.m[2], m3 = this.m[3], m4 = this.m[4], m5 = this.m[5], yt = ((m0 * (y - m5)) - (m1 * (x - m4))) / ((m0 * m3) - (m1 * m2)), xt = (x - m4 - (m2 * yt)) / m0; return this.translate(xt, yt); } }; // CONSTANTS var CANVAS = 'canvas', CONTEXT_2D = '2d', OBJECT_ARRAY = '[object Array]', OBJECT_NUMBER = '[object Number]', OBJECT_STRING = '[object String]', PI_OVER_DEG180 = Math.PI / 180, DEG180_OVER_PI = 180 / Math.PI, HASH = '#', EMPTY_STRING = '', ZERO = '0', KINETIC_WARNING = 'Kinetic warning: ', KINETIC_ERROR = 'Kinetic error: ', RGB_PAREN = 'rgb(', COLORS = { aqua: [0,255,255], lime: [0,255,0], silver: [192,192,192], black: [0,0,0], maroon: [128,0,0], teal: [0,128,128], blue: [0,0,255], navy: [0,0,128], white: [255,255,255], fuchsia: [255,0,255], olive:[128,128,0], yellow: [255,255,0], orange: [255,165,0], gray: [128,128,128], purple: [128,0,128], green: [0,128,0], red: [255,0,0], pink: [255,192,203], cyan: [0,255,255], transparent: [255,255,255,0] }, RGB_REGEX = /rgb\((\d{1,3}),(\d{1,3}),(\d{1,3})\)/; /** * @namespace Util * @memberof Kinetic */ Kinetic.Util = { /* * cherry-picked utilities from underscore.js */ _isElement: function(obj) { return !!(obj && obj.nodeType == 1); }, _isFunction: function(obj) { return !!(obj && obj.constructor && obj.call && obj.apply); }, _isObject: function(obj) { return (!!obj && obj.constructor == Object); }, _isArray: function(obj) { return Object.prototype.toString.call(obj) == OBJECT_ARRAY; }, _isNumber: function(obj) { return Object.prototype.toString.call(obj) == OBJECT_NUMBER; }, _isString: function(obj) { return Object.prototype.toString.call(obj) == OBJECT_STRING; }, // Returns a function, that, when invoked, will only be triggered at most once // during a given window of time. Normally, the throttled function will run // as much as it can, without ever going more than once per `wait` duration; // but if you'd like to disable the execution on the leading edge, pass // `{leading: false}`. To disable execution on the trailing edge, ditto. _throttle: function(func, wait, options) { var context, args, result; var timeout = null; var previous = 0; options || (options = {}); var later = function() { previous = options.leading === false ? 0 : new Date().getTime(); timeout = null; result = func.apply(context, args); context = args = null; }; return function() { var now = new Date().getTime(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0) { clearTimeout(timeout); timeout = null; previous = now; result = func.apply(context, args); context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; }, /* * other utils */ _hasMethods: function(obj) { var names = [], key; for(key in obj) { if(this._isFunction(obj[key])) { names.push(key); } } return names.length > 0; }, createCanvasElement: function() { var canvas = Kinetic.document.createElement('canvas'); canvas.style = canvas.style || {}; return canvas; }, isBrowser: function() { return (typeof exports !== 'object'); }, _isInDocument: function(el) { while(el = el.parentNode) { if(el == Kinetic.document) { return true; } } return false; }, _simplifyArray: function(arr) { var retArr = [], len = arr.length, util = Kinetic.Util, n, val; for (n=0; n<len; n++) { val = arr[n]; if (util._isNumber(val)) { val = Math.round(val * 1000) / 1000; } else if (!util._isString(val)) { val = val.toString(); } retArr.push(val); } return retArr; }, /* * arg can be an image object or image data */ _getImage: function(arg, callback) { var imageObj, canvas; // if arg is null or undefined if(!arg) { callback(null); } // if arg is already an image object else if(this._isElement(arg)) { callback(arg); } // if arg is a string, then it's a data url else if(this._isString(arg)) { imageObj = new Kinetic.window.Image(); imageObj.onload = function() { callback(imageObj); }; imageObj.src = arg; } //if arg is an object that contains the data property, it's an image object else if(arg.data) { canvas = Kinetic.Util.createCanvasElement(); canvas.width = arg.width; canvas.height = arg.height; var _context = canvas.getContext(CONTEXT_2D); _context.putImageData(arg, 0, 0); this._getImage(canvas.toDataURL(), callback); } else { callback(null); } }, _getRGBAString: function(obj) { var red = obj.red || 0, green = obj.green || 0, blue = obj.blue || 0, alpha = obj.alpha || 1; return [ 'rgba(', red, ',', green, ',', blue, ',', alpha, ')' ].join(EMPTY_STRING); }, _rgbToHex: function(r, g, b) { return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); }, _hexToRgb: function(hex) { hex = hex.replace(HASH, EMPTY_STRING); var bigint = parseInt(hex, 16); return { r: (bigint >> 16) & 255, g: (bigint >> 8) & 255, b: bigint & 255 }; }, /** * return random hex color * @method * @memberof Kinetic.Util.prototype */ getRandomColor: function() { var randColor = (Math.random() * 0xFFFFFF << 0).toString(16); while (randColor.length < 6) { randColor = ZERO + randColor; } return HASH + randColor; }, /** * return value with default fallback * @method * @memberof Kinetic.Util.prototype */ get: function(val, def) { if (val === undefined) { return def; } else { return val; } }, /** * get RGB components of a color * @method * @memberof Kinetic.Util.prototype * @param {String} color * @example * // each of the following examples return {r:0, g:0, b:255}<br> * var rgb = Kinetic.Util.getRGB('blue');<br> * var rgb = Kinetic.Util.getRGB('#0000ff');<br> * var rgb = Kinetic.Util.getRGB('rgb(0,0,255)'); */ getRGB: function(color) { var rgb; // color string if (color in COLORS) { rgb = COLORS[color]; return { r: rgb[0], g: rgb[1], b: rgb[2] }; } // hex else if (color[0] === HASH) { return this._hexToRgb(color.substring(1)); } // rgb string else if (color.substr(0, 4) === RGB_PAREN) { rgb = RGB_REGEX.exec(color.replace(/ /g,'')); return { r: parseInt(rgb[1], 10), g: parseInt(rgb[2], 10), b: parseInt(rgb[3], 10) }; } // default else { return { r: 0, g: 0, b: 0 }; } }, // o1 takes precedence over o2 _merge: function(o1, o2) { var retObj = this._clone(o2); for(var key in o1) { if(this._isObject(o1[key])) { retObj[key] = this._merge(o1[key], retObj[key]); } else { retObj[key] = o1[key]; } } return retObj; }, cloneObject: function(obj) { var retObj = {}; for(var key in obj) { if(this._isObject(obj[key])) { retObj[key] = this.cloneObject(obj[key]); } else if (this._isArray(obj[key])) { retObj[key] = this.cloneArray(obj[key]); } else { retObj[key] = obj[key]; } } return retObj; }, cloneArray: function(arr) { return arr.slice(0); }, _degToRad: function(deg) { return deg * PI_OVER_DEG180; }, _radToDeg: function(rad) { return rad * DEG180_OVER_PI; }, _capitalize: function(str) { return str.charAt(0).toUpperCase() + str.slice(1); }, error: function(str) { throw new Error(KINETIC_ERROR + str); }, warn: function(str) { /* * IE9 on Windows7 64bit will throw a JS error * if we don't use window.console in the conditional */ if(Kinetic.root.console && console.warn) { console.warn(KINETIC_WARNING + str); } }, extend: function(c1, c2) { for(var key in c2.prototype) { if(!( key in c1.prototype)) { c1.prototype[key] = c2.prototype[key]; } } }, /** * adds methods to a constructor prototype * @method * @memberof Kinetic.Util.prototype * @param {Function} constructor * @param {Object} methods */ addMethods: function(constructor, methods) { var key; for (key in methods) { constructor.prototype[key] = methods[key]; } }, _getControlPoints: function(x0, y0, x1, y1, x2, y2, t) { var d01 = Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2)), d12 = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)), fa = t * d01 / (d01 + d12), fb = t * d12 / (d01 + d12), p1x = x1 - fa * (x2 - x0), p1y = y1 - fa * (y2 - y0), p2x = x1 + fb * (x2 - x0), p2y = y1 + fb * (y2 - y0); return [p1x ,p1y, p2x, p2y]; }, _expandPoints: function(p, tension) { var len = p.length, allPoints = [], n, cp; for (n=2; n<len-2; n+=2) { cp = Kinetic.Util._getControlPoints(p[n-2], p[n-1], p[n], p[n+1], p[n+2], p[n+3], tension); allPoints.push(cp[0]); allPoints.push(cp[1]); allPoints.push(p[n]); allPoints.push(p[n+1]); allPoints.push(cp[2]); allPoints.push(cp[3]); } return allPoints; }, _removeLastLetter: function(str) { return str.substring(0, str.length - 1); } }; })();