{"version":3,"file":"objectTransforms.min.mjs","sources":["../../../../src/util/misc/objectTransforms.ts"],"sourcesContent":["import { Point } from '../../Point';\nimport { CENTER } from '../../constants';\nimport type { FabricObject } from '../../shapes/Object/Object';\nimport type { TMat2D } from '../../typedefs';\nimport { makeBoundingBoxFromPoints } from './boundingBoxFromPoints';\nimport {\n  invertTransform,\n  multiplyTransformMatrices,\n  qrDecompose,\n} from './matrix';\n\n/**\n * given an object and a transform, apply the inverse transform to the object,\n * this is equivalent to remove from that object that transformation, so that\n * added in a space with the removed transform, the object will be the same as before.\n * Removing from an object a transform that scale by 2 is like scaling it by 1/2.\n * Removing from an object a transform that rotate by 30deg is like rotating by 30deg\n * in the opposite direction.\n * This util is used to add objects inside transformed groups or nested groups.\n * @param {FabricObject} object the object you want to transform\n * @param {TMat2D} transform the destination transform\n */\nexport const removeTransformFromObject = (\n  object: FabricObject,\n  transform: TMat2D,\n) => {\n  const inverted = invertTransform(transform),\n    finalTransform = multiplyTransformMatrices(\n      inverted,\n      object.calcOwnMatrix(),\n    );\n  applyTransformToObject(object, finalTransform);\n};\n\n/**\n * given an object and a transform, apply the transform to the object.\n * this is equivalent to change the space where the object is drawn.\n * Adding to an object a transform that scale by 2 is like scaling it by 2.\n * This is used when removing an object from an active selection for example.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const addTransformToObject = (object: FabricObject, transform: TMat2D) =>\n  applyTransformToObject(\n    object,\n    multiplyTransformMatrices(transform, object.calcOwnMatrix()),\n  );\n\n/**\n * discard an object transform state and apply the one from the matrix.\n * @param {FabricObject} object the object you want to transform\n * @param {Array} transform the destination transform\n */\nexport const applyTransformToObject = (\n  object: FabricObject,\n  transform: TMat2D,\n) => {\n  const { translateX, translateY, scaleX, scaleY, ...otherOptions } =\n      qrDecompose(transform),\n    center = new Point(translateX, translateY);\n  object.flipX = false;\n  object.flipY = false;\n  Object.assign(object, otherOptions);\n  object.set({ scaleX, scaleY });\n  object.setPositionByOrigin(center, CENTER, CENTER);\n};\n/**\n * reset an object transform state to neutral. Top and left are not accounted for\n * @param  {FabricObject} target object to transform\n */\nexport const resetObjectTransform = (target: FabricObject) => {\n  target.scaleX = 1;\n  target.scaleY = 1;\n  target.skewX = 0;\n  target.skewY = 0;\n  target.flipX = false;\n  target.flipY = false;\n  target.rotate(0);\n};\n\n/**\n * Extract Object transform values\n * @param  {FabricObject} target object to read from\n * @return {Object} Components of transform\n */\nexport const saveObjectTransform = (target: FabricObject) => ({\n  scaleX: target.scaleX,\n  scaleY: target.scaleY,\n  skewX: target.skewX,\n  skewY: target.skewY,\n  angle: target.angle,\n  left: target.left,\n  flipX: target.flipX,\n  flipY: target.flipY,\n  top: target.top,\n});\n\n/**\n * given a width and height, return the size of the bounding box\n * that can contains the box with width/height with applied transform.\n * Use to calculate the boxes around objects for controls.\n * @param {Number} width\n * @param {Number} height\n * @param {TMat2D} t\n * @returns {Point} size\n */\nexport const sizeAfterTransform = (\n  width: number,\n  height: number,\n  t: TMat2D,\n) => {\n  const dimX = width / 2,\n    dimY = height / 2,\n    points = [\n      new Point(-dimX, -dimY),\n      new Point(dimX, -dimY),\n      new Point(-dimX, dimY),\n      new Point(dimX, dimY),\n    ].map((p) => p.transform(t)),\n    bbox = makeBoundingBoxFromPoints(points);\n  return new Point(bbox.width, bbox.height);\n};\n"],"names":["removeTransformFromObject","object","transform","inverted","invertTransform","finalTransform","multiplyTransformMatrices","calcOwnMatrix","applyTransformToObject","addTransformToObject","translateX","translateY","scaleX","scaleY","otherOptions","qrDecompose","center","Point","flipX","flipY","Object","assign","set","setPositionByOrigin","CENTER","resetObjectTransform","target","skewX","skewY","rotate","saveObjectTransform","angle","left","top","sizeAfterTransform","width","height","t","dimX","dimY","points","map","p","bbox","makeBoundingBoxFromPoints"],"mappings":"kRAsBaA,EAA4BA,CACvCC,EACAC,KAEA,MAAMC,EAAWC,EAAgBF,GAC/BG,EAAiBC,EACfH,EACAF,EAAOM,iBAEXC,EAAuBP,EAAQI,IAWpBI,EAAuBA,CAACR,EAAsBC,IACzDM,EACEP,EACAK,EAA0BJ,EAAWD,EAAOM,kBAQnCC,EAAyBA,CACpCP,EACAC,KAEA,MAAMQ,WAAEA,EAAUC,WAAEA,EAAUC,OAAEA,EAAMC,OAAEA,KAAWC,GAC/CC,EAAYb,GACdc,EAAS,IAAIC,EAAMP,EAAYC,GACjCV,EAAOiB,OAAQ,EACfjB,EAAOkB,OAAQ,EACfC,OAAOC,OAAOpB,EAAQa,GACtBb,EAAOqB,IAAI,CAAEV,SAAQC,WACrBZ,EAAOsB,oBAAoBP,EAAQQ,EAAQA,IAMhCC,EAAwBC,IACnCA,EAAOd,OAAS,EAChBc,EAAOb,OAAS,EAChBa,EAAOC,MAAQ,EACfD,EAAOE,MAAQ,EACfF,EAAOR,OAAQ,EACfQ,EAAOP,OAAQ,EACfO,EAAOG,OAAO,IAQHC,EAAuBJ,IAAoB,CACtDd,OAAQc,EAAOd,OACfC,OAAQa,EAAOb,OACfc,MAAOD,EAAOC,MACdC,MAAOF,EAAOE,MACdG,MAAOL,EAAOK,MACdC,KAAMN,EAAOM,KACbd,MAAOQ,EAAOR,MACdC,MAAOO,EAAOP,MACdc,IAAKP,EAAOO,MAYDC,EAAqBA,CAChCC,EACAC,EACAC,KAEA,MAAMC,EAAOH,EAAQ,EACnBI,EAAOH,EAAS,EAChBI,EAAS,CACP,IAAIvB,GAAOqB,GAAOC,GAClB,IAAItB,EAAMqB,GAAOC,GACjB,IAAItB,GAAOqB,EAAMC,GACjB,IAAItB,EAAMqB,EAAMC,IAChBE,IAAKC,GAAMA,EAAExC,UAAUmC,IACzBM,EAAOC,EAA0BJ,GACnC,OAAO,IAAIvB,EAAM0B,EAAKR,MAAOQ,EAAKP"}