Skip to content

Commit

Permalink
chore(TS) convert more utils (#8180)
Browse files Browse the repository at this point in the history
Co-authored-by: ShaMan123 <shacharnen@gmail.com>
  • Loading branch information
asturur and ShaMan123 committed Aug 26, 2022
1 parent f52f1c4 commit d2571c9
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 129 deletions.
2 changes: 1 addition & 1 deletion src/point.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ export class Point {
* @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied
* @return {Point} The transformed point
*/
transform(t: TMat2D, ignoreOffset: boolean): Point {
transform(t: TMat2D, ignoreOffset = false): Point {
return new Point(
t[0] * this.x + t[2] * this.y + (ignoreOffset ? 0 : t[4]),
t[1] * this.x + t[3] * this.y + (ignoreOffset ? 0 : t[5])
Expand Down
2 changes: 2 additions & 0 deletions src/util/lang_object.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//@ts-nocheck

import { fabric } from "../../HEADER";

/**
* Copies all enumerable properties of one js object to another
* this does not and cannot compete with generic utils.
Expand Down
35 changes: 35 additions & 0 deletions src/util/misc/boundingBoxFromPoints.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Point } from '../../point.class';
import { TMat2D } from '../../typedefs';
import { transformPoint } from './matrix';

/**
* Returns coordinates of points's bounding rectangle (left, top, width, height)
* This function does not make sense.
* - it mutates the input in case transform is present
* - is used in 2 instances of the app one with the transform one without
* @static
* @memberOf fabric.util
* @param {Point[]} points 4 points array
* @param {TMat2D} [transform] an array of 6 numbers representing a 2x3 transform matrix
* @return {Object} Object with left, top, width, height properties
*/
export const makeBoundingBoxFromPoints = (points: Point[], transform: TMat2D) => {
if (transform) {
for (let i = 0; i < points.length; i++) {
points[i] = transformPoint(points[i], transform);
}
}
const left = Math.min(points[0].x, points[1].x, points[2].x, points[3].x),
right = Math.max(points[0].x, points[1].x, points[2].x, points[3].x),
width = right - left,
top = Math.min(points[0].y, points[1].y, points[2].y, points[3].y),
bottom = Math.max(points[0].y, points[1].y, points[2].y, points[3].y),
height = bottom - top;

return {
left,
top,
width,
height,
};
};
6 changes: 3 additions & 3 deletions src/util/misc/matrix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type TScaleMatrixArgs = {
skewY?: TDegree;
}

type TComposeMatrixArgs = TTranslateMatrixArgs & TRotateMatrixArgs & TScaleMatrixArgs;
export type TComposeMatrixArgs = TTranslateMatrixArgs & TRotateMatrixArgs & TScaleMatrixArgs;
/**
* Apply transform t to point p
* @static
Expand All @@ -33,7 +33,7 @@ type TComposeMatrixArgs = TTranslateMatrixArgs & TRotateMatrixArgs & TScaleMatri
* @param {Boolean} [ignoreOffset] Indicates that the offset should not be applied
* @return {Point} The transformed point
*/
export const transformPoint = (p: Point | IPoint, t: TMat2D, ignoreOffset: boolean): Point => new Point(p).transform(t, ignoreOffset);
export const transformPoint = (p: Point | IPoint, t: TMat2D, ignoreOffset?: boolean): Point => new Point(p).transform(t, ignoreOffset);

/**
* Invert transformation t
Expand Down Expand Up @@ -76,7 +76,7 @@ export const multiplyTransformMatrices = (a: TMat2D, b: TMat2D, is2x2?: boolean)
* @param {TMat2D} a transformMatrix
* @return {Object} Components of transform
*/
export const qrDecompose = (a: TMat2D): TComposeMatrixArgs => {
export const qrDecompose = (a: TMat2D): Required<Omit<TComposeMatrixArgs, 'flipX' | 'flipY'>> => {
const angle = Math.atan2(a[1], a[0]),
denom = Math.pow(a[0], 2) + Math.pow(a[1], 2),
scaleX = Math.sqrt(denom),
Expand Down
139 changes: 14 additions & 125 deletions src/util/misc/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@ import {
} from './svgParsing';
import { findScaleToFit, findScaleToCover } from './findScaleTo';
import { capValue } from './capValue';

/**
* @typedef {[number,number,number,number,number,number]} Matrix
*/
import {
saveObjectTransform,
resetObjectTransform,
addTransformToObject,
applyTransformToObject,
removeTransformFromObject,
} from './objectTransforms';
import { makeBoundingBoxFromPoints } from './boundingBoxFromPoints';

/**
* @namespace fabric.util
Expand Down Expand Up @@ -82,6 +86,12 @@ import { capValue } from './capValue';
findScaleToFit,
findScaleToCover,
capValue,
saveObjectTransform,
resetObjectTransform,
addTransformToObject,
applyTransformToObject,
removeTransformFromObject,
makeBoundingBoxFromPoints,
/**
* Sends a point from the source coordinate plane to the destination coordinate plane.\
* From the canvas/viewer's perspective the point remains unchanged.
Expand Down Expand Up @@ -142,37 +152,6 @@ import { capValue } from './capValue';
return fabric.util.transformPoint(point, relationAfter === 'child' ? fabric.util.invertTransform(t) : t);
},

/**
* Returns coordinates of points's bounding rectangle (left, top, width, height)
* @static
* @memberOf fabric.util
* @param {Array} points 4 points array
* @param {Array} [transform] an array of 6 numbers representing a 2x3 transform matrix
* @return {Object} Object with left, top, width, height properties
*/
makeBoundingBoxFromPoints: function(points, transform) {
if (transform) {
for (var i = 0; i < points.length; i++) {
points[i] = fabric.util.transformPoint(points[i], transform);
}
}
var xPoints = [points[0].x, points[1].x, points[2].x, points[3].x],
minX = fabric.util.array.min(xPoints),
maxX = fabric.util.array.max(xPoints),
width = maxX - minX,
yPoints = [points[0].y, points[1].y, points[2].y, points[3].y],
minY = fabric.util.array.min(yPoints),
maxY = fabric.util.array.max(yPoints),
height = maxY - minY;

return {
left: minX,
top: minY,
width: width,
height: height
};
},

/**
* Returns klass "Class" object of given namespace
* @memberOf fabric.util
Expand Down Expand Up @@ -343,43 +322,6 @@ import { capValue } from './capValue';
}
},

/**
* reset an object transform state to neutral. Top and left are not accounted for
* @static
* @memberOf fabric.util
* @param {fabric.Object} target object to transform
*/
resetObjectTransform: function (target) {
target.scaleX = 1;
target.scaleY = 1;
target.skewX = 0;
target.skewY = 0;
target.flipX = false;
target.flipY = false;
target.rotate(0);
},

/**
* Extract Object transform values
* @static
* @memberOf fabric.util
* @param {fabric.Object} target object to read from
* @return {Object} Components of transform
*/
saveObjectTransform: function (target) {
return {
scaleX: target.scaleX,
scaleY: target.scaleY,
skewX: target.skewX,
skewY: target.skewY,
angle: target.angle,
left: target.left,
flipX: target.flipX,
flipY: target.flipY,
top: target.top
};
},

/**
* Returns true if context has transparent pixel
* at specified location (taking tolerance into account)
Expand Down Expand Up @@ -462,59 +404,6 @@ import { capValue } from './capValue';
return { x: Math.floor(roughWidth), y: perfLimitSizeY };
},

/**
* given an object and a transform, apply the inverse transform to the object,
* this is equivalent to remove from that object that transformation, so that
* added in a space with the removed transform, the object will be the same as before.
* Removing from an object a transform that scale by 2 is like scaling it by 1/2.
* Removing from an object a transform that rotate by 30deg is like rotating by 30deg
* in the opposite direction.
* This util is used to add objects inside transformed groups or nested groups.
* @memberOf fabric.util
* @param {fabric.Object} object the object you want to transform
* @param {Array} transform the destination transform
*/
removeTransformFromObject: function(object, transform) {
var inverted = fabric.util.invertTransform(transform),
finalTransform = fabric.util.multiplyTransformMatrices(inverted, object.calcOwnMatrix());
fabric.util.applyTransformToObject(object, finalTransform);
},

/**
* given an object and a transform, apply the transform to the object.
* this is equivalent to change the space where the object is drawn.
* Adding to an object a transform that scale by 2 is like scaling it by 2.
* This is used when removing an object from an active selection for example.
* @memberOf fabric.util
* @param {fabric.Object} object the object you want to transform
* @param {Array} transform the destination transform
*/
addTransformToObject: function(object, transform) {
fabric.util.applyTransformToObject(
object,
fabric.util.multiplyTransformMatrices(transform, object.calcOwnMatrix())
);
},

/**
* discard an object transform state and apply the one from the matrix.
* @memberOf fabric.util
* @param {fabric.Object} object the object you want to transform
* @param {Array} transform the destination transform
*/
applyTransformToObject: function(object, transform) {
var options = fabric.util.qrDecompose(transform),
center = new Point(options.translateX, options.translateY);
object.flipX = false;
object.flipY = false;
object.set('scaleX', options.scaleX);
object.set('scaleY', options.scaleY);
object.skewX = options.skewX;
object.skewY = options.skewY;
object.angle = options.angle;
object.setPositionByOrigin(center, 'center', 'center');
},

/**
*
* A util that abstracts applying transform to objects.\
Expand Down
91 changes: 91 additions & 0 deletions src/util/misc/objectTransforms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import { Point } from "../../point.class";
import { TMat2D } from "../../typedefs";
import { invertTransform, multiplyTransformMatrices, qrDecompose } from "./matrix";
import type { TComposeMatrixArgs } from './matrix';

type FabricObject = any;

/**
* given an object and a transform, apply the inverse transform to the object,
* this is equivalent to remove from that object that transformation, so that
* added in a space with the removed transform, the object will be the same as before.
* Removing from an object a transform that scale by 2 is like scaling it by 1/2.
* Removing from an object a transform that rotate by 30deg is like rotating by 30deg
* in the opposite direction.
* This util is used to add objects inside transformed groups or nested groups.
* @memberOf fabric.util
* @param {fabric.Object} object the object you want to transform
* @param {Array} transform the destination transform
*/
export const removeTransformFromObject = (object: FabricObject, transform: TMat2D) => {
const inverted = invertTransform(transform),
finalTransform = multiplyTransformMatrices(inverted, object.calcOwnMatrix());
applyTransformToObject(object, finalTransform);
};

/**
* given an object and a transform, apply the transform to the object.
* this is equivalent to change the space where the object is drawn.
* Adding to an object a transform that scale by 2 is like scaling it by 2.
* This is used when removing an object from an active selection for example.
* @memberOf fabric.util
* @param {fabric.Object} object the object you want to transform
* @param {Array} transform the destination transform
*/
export const addTransformToObject = (object: FabricObject, transform: TMat2D) =>
applyTransformToObject(
object,
multiplyTransformMatrices(transform, object.calcOwnMatrix())
);

/**
* discard an object transform state and apply the one from the matrix.
* @memberOf fabric.util
* @param {fabric.Object} object the object you want to transform
* @param {Array} transform the destination transform
*/
export const applyTransformToObject = (object: FabricObject, transform: TMat2D) => {
const { translateX, translateY, scaleX, scaleY, ...otherOptions } = qrDecompose(transform),
center = new Point(translateX, translateY);
object.flipX = false;
object.flipY = false;
Object.assign(object, otherOptions);
object.set({ scaleX, scaleY });
object.setPositionByOrigin(center, 'center', 'center');
};
/**
* reset an object transform state to neutral. Top and left are not accounted for
* @static
* @memberOf fabric.util
* @param {fabric.Object} target object to transform
*/
export const resetObjectTransform = (target: FabricObject) => {
target.scaleX = 1;
target.scaleY = 1;
target.skewX = 0;
target.skewY = 0;
target.flipX = false;
target.flipY = false;
target.rotate(0);
};

/**
* Extract Object transform values
* @static
* @memberOf fabric.util
* @param {fabric.Object} target object to read from
* @return {Object} Components of transform
*/
export const saveObjectTransform = (
target: FabricObject
): TComposeMatrixArgs & { left: number, top: number } =>({
scaleX: target.scaleX,
scaleY: target.scaleY,
skewX: target.skewX,
skewY: target.skewY,
angle: target.angle,
left: target.left,
flipX: target.flipX,
flipY: target.flipY,
top: target.top
});

0 comments on commit d2571c9

Please sign in to comment.