Skip to content

Commit e2c923e

Browse files
committed
🔧
1 parent 9241bea commit e2c923e

File tree

12 files changed

+80
-106
lines changed

12 files changed

+80
-106
lines changed

package/cpp/rnskia/dom/props/TransformProp.h

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ namespace RNSkia {
1010

1111
static PropId PropNameTranslateX = JsiPropId::get("translateX");
1212
static PropId PropNameTranslateY = JsiPropId::get("translateY");
13+
static PropId PropNameTranslateZ = JsiPropId::get("translateZ");
14+
static PropId PropNameTranslate = JsiPropId::get("translate");
1315
static PropId PropNameScale = JsiPropId::get("scale");
1416
static PropId PropNameScaleX = JsiPropId::get("scaleX");
1517
static PropId PropNameScaleY = JsiPropId::get("scaleY");
@@ -18,6 +20,13 @@ static PropId PropNameSkewY = JsiPropId::get("skewY");
1820
static PropId PropNameRotate = JsiPropId::get("rotate");
1921
static PropId PropNameRotateZ = JsiPropId::get("rotateZ");
2022

23+
/*
24+
| "perspective"
25+
| "rotateX"
26+
| "rotateY"
27+
| "matrix"
28+
*/
29+
2130
class TransformProp : public DerivedProp<SkMatrix> {
2231
public:
2332
explicit TransformProp(PropId name,
@@ -34,6 +43,7 @@ class TransformProp : public DerivedProp<SkMatrix> {
3443
"Expected array for transform property, got " +
3544
JsiValue::getTypeAsString(_transformProp->value().getType()));
3645
} else {
46+
SkM44 m4;
3747
auto m = std::make_shared<SkMatrix>(SkMatrix());
3848
for (auto &el : _transformProp->value().getAsArray()) {
3949
auto keys = el.getKeys();
@@ -44,23 +54,43 @@ class TransformProp : public DerivedProp<SkMatrix> {
4454
"scaleX, scaleY, skewX, skewY, rotate or rotateZ.");
4555
}
4656
auto key = el.getKeys().at(0);
47-
auto value = el.getValue(key).getAsNumber();
4857
if (key == PropNameTranslateX) {
49-
m->preTranslate(value, 0);
58+
auto x = el.getValue(key).getAsNumber();
59+
SkM44 trX(1, 0, 0, x, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
60+
m4.preConcat(trX);
5061
} else if (key == PropNameTranslateY) {
51-
m->preTranslate(0, value);
62+
auto y = el.getValue(key).getAsNumber();
63+
SkM44 trY(1, 0, 0, 0, 0, 1, 0, y, 0, 0, 1, 0, 0, 0, 0, 1);
64+
m4.preConcat(trY);
65+
} else if (key == PropNameTranslateZ) {
66+
auto z = el.getValue(key).getAsNumber();
67+
SkM44 trZ(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, z, 0, 0, 0, 1);
68+
m4.preConcat(trZ);
5269
} else if (key == PropNameScale) {
53-
m->preScale(value, value);
70+
auto s = el.getValue(key).getAsNumber();
71+
SkM44 scale(s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
72+
m4.preConcat(scale);
5473
} else if (key == PropNameScaleX) {
55-
m->preScale(value, 1);
74+
auto s = el.getValue(key).getAsNumber();
75+
SkM44 scale(s, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
76+
m4.preConcat(scale);
5677
} else if (key == PropNameScaleY) {
57-
m->preScale(1, value);
78+
auto s = el.getValue(key).getAsNumber();
79+
SkM44 scale(1, 0, 0, 0, 0, s, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
80+
m4.preConcat(scale);
5881
} else if (key == PropNameSkewX) {
59-
m->preSkew(value, 0);
82+
auto angle = el.getValue(key).getAsNumber();
83+
SkM44 skewX(1, 0, 0, 0, std::tan(angle), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
84+
m4.preConcat(skewX);
6085
} else if (key == PropNameSkewY) {
61-
m->preSkew(0, value);
86+
auto angle = el.getValue(key).getAsNumber();
87+
SkM44 skewY(1, std::tan(angle), 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
88+
m4.preConcat(skewY);
6289
} else if (key == PropNameRotate || key == PropNameRotateZ) {
63-
m->preRotate(SkRadiansToDegrees(value));
90+
auto angle = el.getValue(key).getAsNumber();
91+
SkM44 rotate;
92+
rotate.setRotateUnit({ 0, 0, 1}, angle);
93+
m4.preConcat(rotate);
6494
} else {
6595
throw std::runtime_error(
6696
"Unknown key in transform. Expected translateX, translateY, "
@@ -69,6 +99,7 @@ class TransformProp : public DerivedProp<SkMatrix> {
6999
std::string(key) + ".");
70100
}
71101
}
102+
m->preConcat(m4.asM33());
72103
setDerivedValue(m);
73104
}
74105
}
1.38 KB
Loading
-2.03 KB
Loading

package/src/dom/nodes/datatypes/Fitting.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,20 @@ export interface Size {
99

1010
export const size = (width = 0, height = 0) => ({ width, height });
1111

12-
export const rect2rect = (src: SkRect, dst: SkRect) => {
12+
export const rect2rect = (
13+
src: SkRect,
14+
dst: SkRect
15+
): [
16+
{ translateX: number },
17+
{ translateY: number },
18+
{ scaleX: number },
19+
{ scaleY: number }
20+
] => {
1321
const scaleX = dst.width / src.width;
1422
const scaleY = dst.height / src.height;
1523
const translateX = dst.x - src.x * scaleX;
1624
const translateY = dst.y - src.y * scaleY;
17-
return [{ translateX }, { translateY }, { scaleX }, { scaleY }] as const;
25+
return [{ translateX }, { translateY }, { scaleX }, { scaleY }];
1826
};
1927

2028
export const fitRects = (

package/src/dom/nodes/datatypes/Gradient.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { Skia, SkRect, Transforms2d, Vector } from "../../../skia/types";
1+
import type { Skia, SkRect, Transforms3d, Vector } from "../../../skia/types";
22
import { TileMode } from "../../../skia/types";
33
import type { GradientProps, ImageShaderProps } from "../../types";
44

55
import { enumKey } from "./Enum";
66
import { processTransformProps } from "./Transform";
77

8-
export const transformOrigin = (origin: Vector, transform: Transforms2d) => [
8+
export const transformOrigin = (origin: Vector, transform: Transforms3d) => [
99
{ translateX: origin.x },
1010
{ translateY: origin.y },
1111
...transform,

package/src/dom/types/Common.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type {
1111
SkRRect,
1212
StrokeCap,
1313
StrokeJoin,
14-
Transforms2d,
14+
Transforms3d,
1515
Vector,
1616
} from "../../skia/types";
1717

@@ -64,7 +64,7 @@ export interface ScalarCircleDef {
6464
export type CircleDef = PointCircleDef | ScalarCircleDef;
6565

6666
export interface TransformProps {
67-
transform?: Transforms2d;
67+
transform?: Transforms3d;
6868
origin?: Vector;
6969
matrix?: SkMatrix | number[];
7070
}

package/src/skia/core/Matrix.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Skia } from "../Skia";
2-
import type { Transforms2d } from "../types";
2+
import type { Transforms3d } from "../types";
33
import { processTransform } from "../types";
44

5-
export const processTransform2d = (transforms: Transforms2d) =>
5+
export const processTransform2d = (transforms: Transforms3d) =>
66
processTransform(Skia.Matrix(), transforms);

package/src/skia/core/Vector.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ export const dist = (a: Vector, b: Vector) => {
2222
"worklet";
2323
return Math.hypot(a.x - b.x, a.y - b.y);
2424
};
25-
export const translate = ({ x, y }: Vector) => {
25+
export const translate = ({
26+
x,
27+
y,
28+
}: Vector): [{ translateX: number }, { translateY: number }] => {
2629
"worklet";
27-
return [{ translateX: x }, { translateY: y }] as const;
30+
return [{ translateX: x }, { translateY: y }];
2831
};

package/src/skia/types/Canvas.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,7 @@ export interface SkCanvas {
485485
* Replaces current matrix with m premultiplied with the existing matrix.
486486
* @param m
487487
*/
488-
concat(m: SkMatrix): void;
488+
concat(m: SkMatrix | number[]): void;
489489

490490
/**
491491
* Draws the given picture using the current clip, current matrix, and the provided paint.

package/src/skia/types/Matrix.ts

Lines changed: 6 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import type { SkJSIInstance } from "./JsiInstance";
22
import type { SkCanvas } from "./Canvas";
3+
import type { Transforms3d } from "./Matrix4";
4+
import { processTransform3d } from "./Matrix4";
35
export enum MatrixIndex {
46
ScaleX = 0,
57
SkewX = 1,
@@ -29,88 +31,19 @@ export interface SkMatrix extends SkJSIInstance<"Matrix"> {
2931
get: () => number[];
3032
}
3133

32-
type Transform2dName =
33-
| "translateX"
34-
| "translateY"
35-
| "scale"
36-
| "skewX"
37-
| "skewY"
38-
| "scaleX"
39-
| "scaleY"
40-
| "rotateZ"
41-
| "rotate";
42-
43-
type Transformations = {
44-
readonly [Name in Transform2dName]: number;
45-
};
46-
47-
export type Transforms2d = readonly (
48-
| Pick<Transformations, "translateX">
49-
| Pick<Transformations, "translateY">
50-
| Pick<Transformations, "scale">
51-
| Pick<Transformations, "scaleX">
52-
| Pick<Transformations, "scaleY">
53-
| Pick<Transformations, "skewX">
54-
| Pick<Transformations, "skewY">
55-
| Pick<Transformations, "rotate">
56-
)[];
57-
5834
export interface TransformProp {
59-
transform?: Transforms2d;
35+
transform?: Transforms3d;
6036
}
6137

6238
export const processTransform = <T extends SkMatrix | SkCanvas>(
6339
m: T,
64-
transforms: Transforms2d
40+
transforms: Transforms3d
6541
) => {
66-
for (const transform of transforms) {
67-
const key = Object.keys(transform)[0] as Transform2dName;
68-
const value = (transform as Pick<Transformations, typeof key>)[key];
69-
if (key === "translateX") {
70-
m.translate(value, 0);
71-
continue;
72-
}
73-
if (key === "translateY") {
74-
m.translate(0, value);
75-
continue;
76-
}
77-
if (key === "scale") {
78-
m.scale(value, value);
79-
continue;
80-
}
81-
if (key === "scaleX") {
82-
m.scale(value, 1);
83-
continue;
84-
}
85-
if (key === "scaleY") {
86-
m.scale(1, value);
87-
continue;
88-
}
89-
if (key === "skewX") {
90-
m.skew(value, 0);
91-
continue;
92-
}
93-
if (key === "skewY") {
94-
m.skew(0, value);
95-
continue;
96-
}
97-
if (key === "rotate" || key === "rotateZ") {
98-
if (isMatrix(m)) {
99-
m.rotate(value);
100-
} else {
101-
m.rotate(toDegrees(value), 0, 0);
102-
}
103-
continue;
104-
}
105-
exhaustiveCheck(key);
106-
}
42+
const m3 = processTransform3d(transforms);
43+
m.concat(m3);
10744
return m;
10845
};
10946

110-
const exhaustiveCheck = (a: never): never => {
111-
throw new Error(`Unknown transformation: ${a}`);
112-
};
113-
11447
export const toDegrees = (rad: number) => {
11548
return (rad * 180) / Math.PI;
11649
};

0 commit comments

Comments
 (0)