Skip to content

Commit

Permalink
fix(🧮): Fix 2d transform type (#464)
Browse files Browse the repository at this point in the history
  • Loading branch information
wcandillon authored Aug 29, 2021
1 parent fd0b0dd commit 86e061a
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 33 deletions.
134 changes: 103 additions & 31 deletions src/Matrix3.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,22 @@ export type Vec3 = readonly [number, number, number];

export type Matrix3 = readonly [Vec3, Vec3, Vec3];

type Transform2dName =
| "translateX"
| "translateY"
| "scale"
| "skewX"
| "skewY"
| "scaleX"
| "scaleY"
| "rotateZ"
| "rotate";

export interface TransformProp {
transform: Transforms2d;
}

type Transformations = {
[Name in Transform2dName]: number;
translateX: number;
translateY: number;
scale: number;
skewX: string;
skewY: string;
scaleX: number;
scaleY: number;
rotateZ: string;
rotate: string;
};

export type Transforms2d = (
| Pick<Transformations, "translateX">
| Pick<Transformations, "translateY">
Expand All @@ -32,9 +30,82 @@ export type Transforms2d = (
| Pick<Transformations, "skewX">
| Pick<Transformations, "skewY">
| Pick<Transformations, "rotate">
| Pick<Transformations, "rotateZ">
)[];

export const parseAngle = (angle: string) => {
"worklet";
if (angle.endsWith("deg")) {
return parseFloat(angle) * (Math.PI / 180);
}
return parseFloat(angle);
};

export const isTranslateX = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "translateX"> => {
"worklet";
return Object.keys(transform).indexOf("translateX") !== -1;
};

export const isTranslateY = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "translateY"> => {
"worklet";
return Object.keys(transform).indexOf("translateY") !== -1;
};

export const isScale = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "scale"> => {
"worklet";
return Object.keys(transform).indexOf("scale") !== -1;
};

export const isScaleX = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "scaleX"> => {
"worklet";
return Object.keys(transform).indexOf("scaleX") !== -1;
};

export const isScaleY = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "scaleY"> => {
"worklet";
return Object.keys(transform).indexOf("scaleY") !== -1;
};

export const isSkewX = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "skewX"> => {
"worklet";
return Object.keys(transform).indexOf("skewX") !== -1;
};

export const isSkewY = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "skewY"> => {
"worklet";
return Object.keys(transform).indexOf("skewY") !== -1;
};

export const isRotate = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "rotate"> => {
"worklet";
return Object.keys(transform).indexOf("rotate") !== -1;
};

export const isRotateZ = (
transform: Transforms2d[0]
): transform is Pick<Transformations, "rotateZ"> => {
"worklet";
return Object.keys(transform).indexOf("rotateZ") !== -1;
};

const exhaustiveCheck = (a: never): never => {
"worklet";
throw new Error(`Unexhaustive handling for ${a}`);
};

Expand Down Expand Up @@ -151,33 +222,34 @@ export const serializeToSVGMatrix = (m: Matrix3) => {
export const processTransform2d = (transforms: Transforms2d) => {
"worklet";
return transforms.reduce((acc, transform) => {
const key = Object.keys(transform)[0] as Transform2dName;
const value = (transform as Pick<Transformations, typeof key>)[key];
if (key === "translateX") {
return multiply3(acc, translateXMatrix(value));
if (isTranslateX(transform)) {
return multiply3(acc, translateXMatrix(transform.translateX));
}
if (isTranslateY(transform)) {
return multiply3(acc, translateYMatrix(transform.translateY));
}
if (key === "translateY") {
return multiply3(acc, translateYMatrix(value));
if (isScale(transform)) {
return multiply3(acc, scaleMatrix(transform.scale));
}
if (key === "scale") {
return multiply3(acc, scaleMatrix(value));
if (isScaleX(transform)) {
return multiply3(acc, scaleXMatrix(transform.scaleX));
}
if (key === "scaleX") {
return multiply3(acc, scaleXMatrix(value));
if (isScaleY(transform)) {
return multiply3(acc, scaleYMatrix(transform.scaleY));
}
if (key === "scaleY") {
return multiply3(acc, scaleYMatrix(value));
if (isSkewX(transform)) {
return multiply3(acc, skewXMatrix(parseAngle(transform.skewX)));
}
if (key === "skewX") {
return multiply3(acc, skewXMatrix(value));
if (isSkewY(transform)) {
return multiply3(acc, skewYMatrix(parseAngle(transform.skewY)));
}
if (key === "skewY") {
return multiply3(acc, skewYMatrix(value));
if (isRotate(transform)) {
return multiply3(acc, rotateZMatrix(parseAngle(transform.rotate)));
}
if (key === "rotate" || key === "rotateZ") {
return multiply3(acc, rotateZMatrix(value));
if (isRotateZ(transform)) {
return multiply3(acc, rotateZMatrix(parseAngle(transform.rotateZ)));
}
return exhaustiveCheck(key);
return exhaustiveCheck(transform);
}, identityMatrix);
};

Expand Down
15 changes: 15 additions & 0 deletions src/Transforms.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { TransformsStyle } from "react-native";

import type { Vector } from "./Vectors";
import type { Transforms2d } from "./Matrix3";

type RNTransform = Exclude<TransformsStyle["transform"], undefined>;

Expand All @@ -17,3 +18,17 @@ export const transformOrigin = (
{ translateY: -y },
];
};

export const transformOrigin2d = (
{ x, y }: Vector,
transformations: Transforms2d
): Transforms2d => {
"worklet";
return [
{ translateX: x },
{ translateY: y },
...transformations,
{ translateX: -x },
{ translateY: -y },
];
};
2 changes: 1 addition & 1 deletion src/__tests__/Matrix3.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ test("processTransform3d()", () => {
processTransform2d([
{ translateX: width / 2 },
{ translateY: height / 2 },
{ rotate: Math.PI / 2 },
{ rotate: `${Math.PI / 2}rad` },
{ translateX: -width / 2 },
{ translateY: -height / 2 },
])
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es2017",
"target": "esnext",
"lib": ["es6"],
"jsx": "react-native",
"strict": true,
Expand Down

0 comments on commit 86e061a

Please sign in to comment.