-
Notifications
You must be signed in to change notification settings - Fork 25.1k
feat: ios fabric transform origin #38559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: ios fabric transform origin #38559
Conversation
Base commit: a0a544f |
packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm
Show resolved
Hide resolved
packages/react-native/ReactCommon/react/renderer/components/view/ViewProps.cpp
Outdated
Show resolved
Hide resolved
packages/react-native/ReactCommon/react/renderer/components/view/conversions.h
Outdated
Show resolved
Hide resolved
packages/react-native/ReactCommon/react/renderer/graphics/Transform.h
Outdated
Show resolved
Hide resolved
packages/react-native/ReactCommon/react/renderer/components/view/conversions.h
Show resolved
Hide resolved
|
Getting this error on test_android CI 🤔 |
|
@rozele has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
javache
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for splitting these up into multiple PR's!
packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.cpp
Outdated
Show resolved
Hide resolved
packages/react-native/Libraries/StyleSheet/private/_TransformStyle.js
Outdated
Show resolved
Hide resolved
packages/react-native/ReactCommon/react/renderer/components/view/conversions.h
Outdated
Show resolved
Hide resolved
| opacity?: AnimatableNumericValue, | ||
| elevation?: number, | ||
| pointerEvents?: 'auto' | 'none' | 'box-none' | 'box-only', | ||
| transformOrigin?: string, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this required? transformOrigin should be included via ____TransformStyle_Internal already.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My bad. Updated!
| namespace { | ||
|
|
||
| std::array<float, 3> getTranslateForTransformOrigin(float viewWidth, float viewHeight, facebook::react::TransformOrigin transformOrigin) { | ||
| float viewCenterX = viewWidth / 2; | ||
| float viewCenterY = viewHeight / 2; | ||
|
|
||
| std::array<float, 3> origin = {viewCenterX, viewCenterY, transformOrigin.z}; | ||
|
|
||
| for (size_t i = 0; i < 2; ++i) { | ||
| auto& currentOrigin = transformOrigin.xy[i]; | ||
| if (currentOrigin.unit == YGUnitPoint) { | ||
| origin[i] = currentOrigin.value; | ||
| } else if (currentOrigin.unit == YGUnitPercent) { | ||
| origin[i] = ((i == 0) ? viewWidth : viewHeight) * currentOrigin.value / 100.0f; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| float newTranslateX = -viewCenterX + origin[0]; | ||
| float newTranslateY = -viewCenterY + origin[1]; | ||
| float newTranslateZ = origin[2]; | ||
|
|
||
| return std::array{newTranslateX, newTranslateY, newTranslateZ}; | ||
| } | ||
|
|
||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: move inside the namespace facebook::react below (and remove the extra facebook::react prefixes)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!
| TransformOrigin transformOrigin; | ||
|
|
||
| for (size_t i = 0; i < 2; i++) { | ||
| const auto& origin = origins[i]; | ||
| if (origin.hasType<Float>()) { | ||
| transformOrigin.xy[i] = yogaStyleValueFromFloat((Float)origin); | ||
| } else if (origin.hasType<std::string>()) { | ||
| const auto stringValue = (std::string)origin; | ||
|
|
||
| if (stringValue.back() == '%') { | ||
| auto tryValue = folly::tryTo<float>( | ||
| std::string_view(stringValue).substr(0, stringValue.length() - 1)); | ||
| if (tryValue.hasValue()) { | ||
| transformOrigin.xy[i] = YGValue{tryValue.value(), YGUnitPercent}; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (origins[2].hasType<Float>()) { | ||
| transformOrigin.z = (Float)origins[2]; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You do need to check now that the indices you're accessing are not exceeding the vector bounds.
| TransformOrigin transformOrigin; | |
| for (size_t i = 0; i < 2; i++) { | |
| const auto& origin = origins[i]; | |
| if (origin.hasType<Float>()) { | |
| transformOrigin.xy[i] = yogaStyleValueFromFloat((Float)origin); | |
| } else if (origin.hasType<std::string>()) { | |
| const auto stringValue = (std::string)origin; | |
| if (stringValue.back() == '%') { | |
| auto tryValue = folly::tryTo<float>( | |
| std::string_view(stringValue).substr(0, stringValue.length() - 1)); | |
| if (tryValue.hasValue()) { | |
| transformOrigin.xy[i] = YGValue{tryValue.value(), YGUnitPercent}; | |
| } | |
| } | |
| } | |
| } | |
| if (origins[2].hasType<Float>()) { | |
| transformOrigin.z = (Float)origins[2]; | |
| } | |
| TransformOrigin transformOrigin; | |
| for (size_t i = 0; i < std::min(origins.size(), 2); i++) { | |
| const auto& origin = origins[i]; | |
| if (origin.hasType<Float>()) { | |
| transformOrigin.xy[i] = yogaStyleValueFromFloat((Float)origin); | |
| } else if (origin.hasType<std::string>()) { | |
| const auto stringValue = (std::string)origin; | |
| if (stringValue.back() == '%') { | |
| auto tryValue = folly::tryTo<float>( | |
| std::string_view(stringValue).substr(0, stringValue.length() - 1)); | |
| if (tryValue.hasValue()) { | |
| transformOrigin.xy[i] = YGValue{tryValue.value(), YGUnitPercent}; | |
| } | |
| } | |
| } | |
| } | |
| if (origin.size() >= 3 && origins[2].hasType<Float>()) { | |
| transformOrigin.z = (Float)origins[2]; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!
| }; | ||
|
|
||
| struct TransformOrigin { | ||
| std::array<YGValue, 2> xy; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per @NickGerleman feedback on another PR, using YGValue is an undesired dependency. Let's introduce a custom struct for this in another PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a PR for struct - #39150. I have tested it replacing YGValue and it works, kept it simple. let me know!
std::array<YGValue, 2> xy; -> std::array<ValueUnit, 2> xy;
cc - @jacobp100 we can also use it here - #38626
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will try and get to it later this weekend
Co-authored-by: Nick Gerleman <nick@nickgerleman.com>
|
|
||
| namespace facebook::react { | ||
|
|
||
| enum class UnitType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need undefined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To represent initial/undefined value? Also useful to check the value is set. Check isSet in TransformOrigin struct.
|
@javache has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
|
This is now ready to ship internally so should be pushed soon. Please also submit a PR to https://github.com/facebook/react-native-website to add documentation for this. |
|
@javache Sorry - I never found time to do the iOS old arch - do you still need help with that? |
I think the plan was to remove the dependency on Yoga in this - 5f40f08#diff-6654f56131a3cc2c701d1ca11fbdd2c4c41854136153eaceba4a103413e81809R11-R15 So make our own struct that stores the float value, and whether it was a percent or pixel value |
I think we're ok as-is, as we've been able to cleanup the dependency in the new arch version. |
Summary:
This PR adds transform-origin support for iOS fabric. This PR also incorporates feedback/changes suggested by @javache in the original PR.
Changelog:
[IOS] [ADDED] - Fabric Transform origin
Test Plan:
Run iOS RNTester app in old architecture and test transform-origin example in
TransformExample.js.