| import * as matrix from './matrix.js'; | 
| import * as vector from './vector.js'; | 
| var mIdentity = matrix.identity; | 
| var EPSILON = 5e-5; | 
| function isNotAroundZero(val) { | 
|     return val > EPSILON || val < -EPSILON; | 
| } | 
| var scaleTmp = []; | 
| var tmpTransform = []; | 
| var originTransform = matrix.create(); | 
| var abs = Math.abs; | 
| var Transformable = (function () { | 
|     function Transformable() { | 
|     } | 
|     Transformable.prototype.getLocalTransform = function (m) { | 
|         return Transformable.getLocalTransform(this, m); | 
|     }; | 
|     Transformable.prototype.setPosition = function (arr) { | 
|         this.x = arr[0]; | 
|         this.y = arr[1]; | 
|     }; | 
|     Transformable.prototype.setScale = function (arr) { | 
|         this.scaleX = arr[0]; | 
|         this.scaleY = arr[1]; | 
|     }; | 
|     Transformable.prototype.setSkew = function (arr) { | 
|         this.skewX = arr[0]; | 
|         this.skewY = arr[1]; | 
|     }; | 
|     Transformable.prototype.setOrigin = function (arr) { | 
|         this.originX = arr[0]; | 
|         this.originY = arr[1]; | 
|     }; | 
|     Transformable.prototype.needLocalTransform = function () { | 
|         return isNotAroundZero(this.rotation) | 
|             || isNotAroundZero(this.x) | 
|             || isNotAroundZero(this.y) | 
|             || isNotAroundZero(this.scaleX - 1) | 
|             || isNotAroundZero(this.scaleY - 1) | 
|             || isNotAroundZero(this.skewX) | 
|             || isNotAroundZero(this.skewY); | 
|     }; | 
|     Transformable.prototype.updateTransform = function () { | 
|         var parentTransform = this.parent && this.parent.transform; | 
|         var needLocalTransform = this.needLocalTransform(); | 
|         var m = this.transform; | 
|         if (!(needLocalTransform || parentTransform)) { | 
|             m && mIdentity(m); | 
|             return; | 
|         } | 
|         m = m || matrix.create(); | 
|         if (needLocalTransform) { | 
|             this.getLocalTransform(m); | 
|         } | 
|         else { | 
|             mIdentity(m); | 
|         } | 
|         if (parentTransform) { | 
|             if (needLocalTransform) { | 
|                 matrix.mul(m, parentTransform, m); | 
|             } | 
|             else { | 
|                 matrix.copy(m, parentTransform); | 
|             } | 
|         } | 
|         this.transform = m; | 
|         this._resolveGlobalScaleRatio(m); | 
|     }; | 
|     Transformable.prototype._resolveGlobalScaleRatio = function (m) { | 
|         var globalScaleRatio = this.globalScaleRatio; | 
|         if (globalScaleRatio != null && globalScaleRatio !== 1) { | 
|             this.getGlobalScale(scaleTmp); | 
|             var relX = scaleTmp[0] < 0 ? -1 : 1; | 
|             var relY = scaleTmp[1] < 0 ? -1 : 1; | 
|             var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0; | 
|             var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0; | 
|             m[0] *= sx; | 
|             m[1] *= sx; | 
|             m[2] *= sy; | 
|             m[3] *= sy; | 
|         } | 
|         this.invTransform = this.invTransform || matrix.create(); | 
|         matrix.invert(this.invTransform, m); | 
|     }; | 
|     Transformable.prototype.getComputedTransform = function () { | 
|         var transformNode = this; | 
|         var ancestors = []; | 
|         while (transformNode) { | 
|             ancestors.push(transformNode); | 
|             transformNode = transformNode.parent; | 
|         } | 
|         while (transformNode = ancestors.pop()) { | 
|             transformNode.updateTransform(); | 
|         } | 
|         return this.transform; | 
|     }; | 
|     Transformable.prototype.setLocalTransform = function (m) { | 
|         if (!m) { | 
|             return; | 
|         } | 
|         var sx = m[0] * m[0] + m[1] * m[1]; | 
|         var sy = m[2] * m[2] + m[3] * m[3]; | 
|         var rotation = Math.atan2(m[1], m[0]); | 
|         var shearX = Math.PI / 2 + rotation - Math.atan2(m[3], m[2]); | 
|         sy = Math.sqrt(sy) * Math.cos(shearX); | 
|         sx = Math.sqrt(sx); | 
|         this.skewX = shearX; | 
|         this.skewY = 0; | 
|         this.rotation = -rotation; | 
|         this.x = +m[4]; | 
|         this.y = +m[5]; | 
|         this.scaleX = sx; | 
|         this.scaleY = sy; | 
|         this.originX = 0; | 
|         this.originY = 0; | 
|     }; | 
|     Transformable.prototype.decomposeTransform = function () { | 
|         if (!this.transform) { | 
|             return; | 
|         } | 
|         var parent = this.parent; | 
|         var m = this.transform; | 
|         if (parent && parent.transform) { | 
|             matrix.mul(tmpTransform, parent.invTransform, m); | 
|             m = tmpTransform; | 
|         } | 
|         var ox = this.originX; | 
|         var oy = this.originY; | 
|         if (ox || oy) { | 
|             originTransform[4] = ox; | 
|             originTransform[5] = oy; | 
|             matrix.mul(tmpTransform, m, originTransform); | 
|             tmpTransform[4] -= ox; | 
|             tmpTransform[5] -= oy; | 
|             m = tmpTransform; | 
|         } | 
|         this.setLocalTransform(m); | 
|     }; | 
|     Transformable.prototype.getGlobalScale = function (out) { | 
|         var m = this.transform; | 
|         out = out || []; | 
|         if (!m) { | 
|             out[0] = 1; | 
|             out[1] = 1; | 
|             return out; | 
|         } | 
|         out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]); | 
|         out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]); | 
|         if (m[0] < 0) { | 
|             out[0] = -out[0]; | 
|         } | 
|         if (m[3] < 0) { | 
|             out[1] = -out[1]; | 
|         } | 
|         return out; | 
|     }; | 
|     Transformable.prototype.transformCoordToLocal = function (x, y) { | 
|         var v2 = [x, y]; | 
|         var invTransform = this.invTransform; | 
|         if (invTransform) { | 
|             vector.applyTransform(v2, v2, invTransform); | 
|         } | 
|         return v2; | 
|     }; | 
|     Transformable.prototype.transformCoordToGlobal = function (x, y) { | 
|         var v2 = [x, y]; | 
|         var transform = this.transform; | 
|         if (transform) { | 
|             vector.applyTransform(v2, v2, transform); | 
|         } | 
|         return v2; | 
|     }; | 
|     Transformable.prototype.getLineScale = function () { | 
|         var m = this.transform; | 
|         return m && abs(m[0] - 1) > 1e-10 && abs(m[3] - 1) > 1e-10 | 
|             ? Math.sqrt(abs(m[0] * m[3] - m[2] * m[1])) | 
|             : 1; | 
|     }; | 
|     Transformable.prototype.copyTransform = function (source) { | 
|         copyTransform(this, source); | 
|     }; | 
|     Transformable.getLocalTransform = function (target, m) { | 
|         m = m || []; | 
|         var ox = target.originX || 0; | 
|         var oy = target.originY || 0; | 
|         var sx = target.scaleX; | 
|         var sy = target.scaleY; | 
|         var ax = target.anchorX; | 
|         var ay = target.anchorY; | 
|         var rotation = target.rotation || 0; | 
|         var x = target.x; | 
|         var y = target.y; | 
|         var skewX = target.skewX ? Math.tan(target.skewX) : 0; | 
|         var skewY = target.skewY ? Math.tan(-target.skewY) : 0; | 
|         if (ox || oy || ax || ay) { | 
|             var dx = ox + ax; | 
|             var dy = oy + ay; | 
|             m[4] = -dx * sx - skewX * dy * sy; | 
|             m[5] = -dy * sy - skewY * dx * sx; | 
|         } | 
|         else { | 
|             m[4] = m[5] = 0; | 
|         } | 
|         m[0] = sx; | 
|         m[3] = sy; | 
|         m[1] = skewY * sx; | 
|         m[2] = skewX * sy; | 
|         rotation && matrix.rotate(m, m, rotation); | 
|         m[4] += ox + x; | 
|         m[5] += oy + y; | 
|         return m; | 
|     }; | 
|     Transformable.initDefaultProps = (function () { | 
|         var proto = Transformable.prototype; | 
|         proto.scaleX = | 
|             proto.scaleY = | 
|                 proto.globalScaleRatio = 1; | 
|         proto.x = | 
|             proto.y = | 
|                 proto.originX = | 
|                     proto.originY = | 
|                         proto.skewX = | 
|                             proto.skewY = | 
|                                 proto.rotation = | 
|                                     proto.anchorX = | 
|                                         proto.anchorY = 0; | 
|     })(); | 
|     return Transformable; | 
| }()); | 
| ; | 
| export var TRANSFORMABLE_PROPS = [ | 
|     'x', 'y', 'originX', 'originY', 'anchorX', 'anchorY', 'rotation', 'scaleX', 'scaleY', 'skewX', 'skewY' | 
| ]; | 
| export function copyTransform(target, source) { | 
|     for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) { | 
|         var propName = TRANSFORMABLE_PROPS[i]; | 
|         target[propName] = source[propName]; | 
|     } | 
| } | 
| export default Transformable; |