diff --git a/packages/rn-tester/js/examples/Transform/TransformExample.js b/packages/rn-tester/js/examples/Transform/TransformExample.js
index b8cd2fdbc191..87787a4c4904 100644
--- a/packages/rn-tester/js/examples/Transform/TransformExample.js
+++ b/packages/rn-tester/js/examples/Transform/TransformExample.js
@@ -99,6 +99,44 @@ function TransformOriginExample() {
);
}
+function TransformOriginParsingExample() {
+ const cases: ReadonlyArray<{
+ origin: string,
+ expected: [string | number, string | number, string | number],
+ }> = [
+ {origin: '52.9% 88.2%', expected: ['52.9%', '88.2%', 0]},
+ {origin: '12.5px 67.5px', expected: [12.5, 67.5, 0]},
+ {origin: '-25% 125%', expected: ['-25%', '125%', 0]},
+ {origin: '-12.5px -7.5px', expected: [-12.5, -7.5, 0]},
+ ];
+
+ return (
+
+ {cases.map(({origin, expected}) => (
+
+
+
+
+
+ {origin}
+
+ ))}
+
+ );
+}
+
function Flip() {
const [theta] = useState(new Animated.Value(45));
const animate = () => {
@@ -476,6 +514,39 @@ const styles = StyleSheet.create({
height: 100,
transformOrigin: 'top left',
},
+ transformOriginParsingGrid: {
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ justifyContent: 'space-around',
+ },
+ transformOriginParsingCell: {
+ alignItems: 'center',
+ marginBottom: 12,
+ },
+ transformOriginParsingStage: {
+ width: 140,
+ height: 170,
+ },
+ transformOriginParsingExpected: {
+ position: 'absolute',
+ top: 40,
+ left: 40,
+ width: 60,
+ height: 60,
+ borderWidth: 2,
+ borderStyle: 'dashed',
+ borderColor: 'black',
+ transform: [{rotate: '45deg'}],
+ },
+ transformOriginParsingActual: {
+ position: 'absolute',
+ top: 40,
+ left: 40,
+ width: 60,
+ height: 60,
+ backgroundColor: 'rgba(255, 105, 180, 0.6)',
+ transform: [{rotate: '45deg'}],
+ },
translatePercentageView: {
transform: 'translate(50%)',
padding: 50,
@@ -684,6 +755,15 @@ exports.examples = [
return ;
},
},
+ {
+ title: 'Transform origin with decimal and negative values',
+ name: 'transform-origin-decimal-negative',
+ description:
+ 'Each pink box sets transformOrigin as a string and should exactly cover the dashed outline, which sets the same origin as an array',
+ render(): React.Node {
+ return ;
+ },
+ },
{
title: 'Translate Percentage',
name: 'translate-percentage',
diff --git a/packages/rn-tester/visual-tests/config.json b/packages/rn-tester/visual-tests/config.json
index d6d45c7a70f6..6d10b56750eb 100644
--- a/packages/rn-tester/visual-tests/config.json
+++ b/packages/rn-tester/visual-tests/config.json
@@ -19,6 +19,11 @@
"threshold": 0.1,
"includeAA": false,
"maxDiffPixels": 100
+ },
+ "transform/origin-decimal-negative/default": {
+ "threshold": 0.1,
+ "includeAA": false,
+ "maxDiffPixels": 100
}
}
}
diff --git a/packages/rn-tester/visual-tests/flows/transform.yml b/packages/rn-tester/visual-tests/flows/transform.yml
index 3f76be6d858d..ed4ceeda0b8a 100644
--- a/packages/rn-tester/visual-tests/flows/transform.yml
+++ b/packages/rn-tester/visual-tests/flows/transform.yml
@@ -56,3 +56,17 @@ appId: ${APP_ID}
path: ${VISUAL_OUTPUT_DIR}/transform/string/default
cropOn:
id: 'transform-string'
+- runFlow:
+ file: ../helpers/open-example.yml
+ env:
+ EXAMPLE_URL: rntester://example/TransformExample/transform-origin-decimal-negative
+- extendedWaitUntil:
+ visible:
+ id: 'transform-origin-decimal-negative'
+ timeout: 15000
+- waitForAnimationToEnd:
+ timeout: 5000
+- takeScreenshot:
+ path: ${VISUAL_OUTPUT_DIR}/transform/origin-decimal-negative/default
+ cropOn:
+ id: 'transform-origin-decimal-negative'
diff --git a/packages/rn-tester/visual-tests/suites/transform.md b/packages/rn-tester/visual-tests/suites/transform.md
index eb3fef424b3f..3714df8c8c2d 100644
--- a/packages/rn-tester/visual-tests/suites/transform.md
+++ b/packages/rn-tester/visual-tests/suites/transform.md
@@ -6,5 +6,6 @@
| `rotate-scale` | Initial rendering |
| `translate-percentage` | Initial rendering |
| `string-transform` | Initial rendering |
+| `transform-origin-decimal-negative` | Initial rendering |
Screenshots use the existing RNTester example crops. Each example starts from a fresh app launch; captures wait for the target and for animations to settle.