text: 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;
  