Skip to content

Commit e5cde5a

Browse files
committed
Improve rotation in flutter, text-trim in html, and inline transform in flutter
1 parent afef362 commit e5cde5a

File tree

6 files changed

+54
-15
lines changed

6 files changed

+54
-15
lines changed

packages/backend/src/flutter/builderImpl/flutterBlend.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,35 @@ export const flutterVisibility = (node: SceneNode, child: string): string => {
3737
/**
3838
* https://api.flutter.dev/flutter/widgets/Transform-class.html
3939
* that's how you convert angles to clockwise radians: angle * -pi/180
40-
* using 3.14159 as Pi for enough precision and to avoid importing math lib.
4140
*/
4241
export const flutterRotation = (node: LayoutMixin, child: string): string => {
4342
if (
4443
node.rotation !== undefined &&
4544
child !== "" &&
4645
Math.round(node.rotation) !== 0
4746
) {
48-
return generateWidgetCode("Transform", {
49-
transform: `Matrix4.identity()..translate(0.0, 0.0)..rotateZ(${numberToFixedString(
50-
node.rotation * (-3.14159 / 180),
51-
)})`,
52-
child: child,
53-
});
47+
const matrix = generateRotationMatrix(node);
48+
if (matrix) {
49+
return generateWidgetCode("Transform", {
50+
transform: matrix,
51+
child: child,
52+
});
53+
}
5454
}
5555
return child;
5656
};
57+
58+
/**
59+
* Generates a rotation matrix string for Flutter transforms
60+
*/
61+
export const generateRotationMatrix = (node: LayoutMixin): string => {
62+
const rotation = (node.rotation || 0) + (node.cumulativeRotation || 0);
63+
64+
if (Math.round(rotation) === 0) {
65+
return "";
66+
}
67+
68+
return `Matrix4.identity()..translate(0.0, 0.0)..rotateZ(${numberToFixedString(
69+
rotation * (-Math.PI / 180),
70+
)})`;
71+
};

packages/backend/src/flutter/flutterContainer.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
import { numberToFixedString } from "../common/numToAutoFixed";
1414
import { getCommonRadius } from "../common/commonRadius";
1515
import { commonStroke } from "../common/commonStroke";
16+
import { generateRotationMatrix } from "./builderImpl/flutterBlend";
1617

1718
export const flutterContainer = (node: SceneNode, child: string): string => {
1819
// ignore the view when size is zero or less
@@ -42,6 +43,18 @@ export const flutterContainer = (node: SceneNode, child: string): string => {
4243
let result: string;
4344
const hasConstraints = constraints && Object.keys(constraints).length > 0;
4445

46+
const properties: Record<string, string> = {};
47+
48+
// If node has rotation, get the matrix for the transform property
49+
if ("rotation" in node) {
50+
const matrix = generateRotationMatrix(node);
51+
if (matrix) {
52+
properties.transform = matrix;
53+
}
54+
}
55+
56+
properties.child = child;
57+
4558
if (width || height || propBoxDecoration || clipBehavior) {
4659
const parsedDecoration = skipDefaultProperty(
4760
propBoxDecoration,
@@ -53,7 +66,7 @@ export const flutterContainer = (node: SceneNode, child: string): string => {
5366
padding: propPadding,
5467
clipBehavior: clipBehavior,
5568
decoration: clipBehavior ? propBoxDecoration : parsedDecoration,
56-
child: child,
69+
...properties,
5770
});
5871
} else if (propPadding) {
5972
// if there is just a padding, add Padding

packages/backend/src/flutter/flutterDefaultBuilder.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,25 @@ import { generateWidgetCode } from "../common/numToAutoFixed";
1313

1414
export class FlutterDefaultBuilder {
1515
child: string;
16+
rotationApplied: boolean = false;
1617

1718
constructor(optChild: string) {
1819
this.child = optChild;
1920
}
2021

2122
createContainer(node: SceneNode): this {
2223
this.child = flutterContainer(node, this.child);
24+
this.rotationApplied = true;
25+
2326
return this;
2427
}
2528

2629
blendAttr(node: SceneNode): this {
27-
console.log("rotation is", node.rotation);
28-
if ("rotation" in node) {
30+
// Only apply rotation via Transform if it wasn't already handled in the container
31+
if ("rotation" in node && !this.rotationApplied) {
2932
this.child = flutterRotation(node, this.child);
3033
}
34+
3135
if ("visible" in node) {
3236
this.child = flutterVisibility(node, this.child);
3337
} else if ("opacity" in node) {

packages/backend/src/html/htmlMain.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ const htmlGroup = async (
472472
const htmlText = (node: TextNode, settings: HTMLSettings): string => {
473473
let layoutBuilder = new HtmlTextBuilder(node, settings)
474474
.commonPositionStyles()
475+
.textTrim()
475476
.textAlignHorizontal()
476477
.textAlignVertical();
477478

packages/backend/src/html/htmlTextBuilder.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ export class HtmlTextBuilder extends HtmlDefaultBuilder {
134134
return this;
135135
}
136136

137+
textTrim(): this {
138+
if ("leadingTrim" in this.node && this.node.leadingTrim === "CAP_HEIGHT") {
139+
this.addStyles(formatWithJSX("text-box-trim", this.isJSX, "trim-both"));
140+
this.addStyles(formatWithJSX("text-box-edge", this.isJSX, "cap alphabetic"));
141+
}
142+
return this;
143+
}
144+
137145
textDecoration(textDecoration: TextDecoration): string {
138146
switch (textDecoration) {
139147
case "STRIKETHROUGH":

packages/backend/src/swiftui/builderImpl/swiftuiBlend.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,9 @@ export const swiftuiVisibility = (
3030
* https://developer.apple.com/documentation/swiftui/modifiedcontent/rotationeffect(_:anchor:)
3131
*/
3232
export const swiftuiRotation = (node: LayoutMixin): SwiftUIModifier | null => {
33-
if (node.rotation !== undefined && Math.round(node.rotation) !== 0) {
34-
return [
35-
"rotationEffect",
36-
`.degrees(${numberToFixedString(node.rotation)})`,
37-
];
33+
const rotation = (node.rotation || 0) + (node.cumulativeRotation || 0);
34+
if (Math.round(rotation) !== 0) {
35+
return ["rotationEffect", `.degrees(${numberToFixedString(rotation)})`];
3836
}
3937
return null;
4038
};

0 commit comments

Comments
 (0)