Skip to content

Commit fa28c77

Browse files
committed
Use yoga values for transform origin
1 parent 60803e0 commit fa28c77

File tree

4 files changed

+58
-38
lines changed

4 files changed

+58
-38
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
#import <Foundation/Foundation.h>
9+
#import <yoga/Yoga.h>
10+
11+
typedef struct {
12+
YGValue x;
13+
YGValue y;
14+
CGFloat z;
15+
} RCTTransformOrigin;

packages/react-native/React/Views/RCTViewManager.m

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#import "RCTConvert.h"
1616
#import "RCTLog.h"
1717
#import "RCTShadowView.h"
18+
#import "RCTTransformOrigin.h"
1819
#import "RCTUIManager.h"
1920
#import "RCTUIManagerUtils.h"
2021
#import "RCTUtils.h"
@@ -121,27 +122,13 @@ @implementation RCTConvert (UIAccessibilityTraits)
121122
UIAccessibilityTraitNone,
122123
unsignedLongLongValue)
123124

124-
+ (CATransform3D)transformOrigin:(id)json
125+
+ (RCTTransformOrigin)RCTTransformOrigin:(id)json
125126
{
126-
CATransform3D transformOrigin = CATransform3DMakeScale(0, 0, 0);
127-
id anchorPointX = json[0];
128-
id anchorPointY = json[1];
129-
id anchorPointZ = json[2];
130-
131-
if ([anchorPointX isKindOfClass:NSString.class] && [(NSString *)anchorPointX hasSuffix:@"%"]) {
132-
transformOrigin.m11 = [anchorPointX doubleValue] / 100;
133-
} else {
134-
transformOrigin.m14 = [RCTConvert CGFloat:anchorPointX];
135-
}
136-
137-
if ([anchorPointY isKindOfClass:NSString.class] && [(NSString *)anchorPointY hasSuffix:@"%"]) {
138-
transformOrigin.m22 = [anchorPointY doubleValue] / 100;
139-
} else {
140-
transformOrigin.m24 = [RCTConvert CGFloat:anchorPointY];
141-
}
142-
143-
transformOrigin.m34 = [RCTConvert CGFloat:anchorPointZ];
144-
127+
RCTTransformOrigin transformOrigin = {
128+
[RCTConvert YGValue:json[0]],
129+
[RCTConvert YGValue:json[1]],
130+
[RCTConvert CGFloat:json[2]]
131+
};
145132
return transformOrigin;
146133
}
147134

@@ -242,13 +229,13 @@ - (RCTShadowView *)shadowView
242229

243230
RCT_CUSTOM_VIEW_PROPERTY(transform, CATransform3D, RCTView)
244231
{
245-
CATransform3D transform = json ? [RCTConvert CATransform3D:json] : defaultView.reactTransformOrigin;
232+
CATransform3D transform = json ? [RCTConvert CATransform3D:json] : defaultView.reactTransform;
246233
[view setReactTransform:transform];
247234
}
248235

249-
RCT_CUSTOM_VIEW_PROPERTY(transformOrigin, NSArray, RCTView)
236+
RCT_CUSTOM_VIEW_PROPERTY(transformOrigin, RCTTransformOrigin, RCTView)
250237
{
251-
CATransform3D transformOrigin = json ? [RCTConvert transformOrigin:json] : defaultView.reactTransformOrigin;
238+
RCTTransformOrigin transformOrigin = json ? [RCTConvert RCTTransformOrigin:json] : defaultView.reactTransformOrigin;
252239
[view setReactTransformOrigin:transformOrigin];
253240
}
254241

packages/react-native/React/Views/UIView+React.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#import <UIKit/UIKit.h>
99

1010
#import <React/RCTComponent.h>
11+
#import <React/RCTTransformOrigin.h>
1112
#import <yoga/YGEnums.h>
1213

1314
@class RCTShadowView;
@@ -105,11 +106,7 @@
105106
@property (nonatomic, readonly) CGRect reactContentFrame;
106107

107108
@property (nonatomic, assign) CATransform3D reactTransform;
108-
/**
109-
* Matrix form of transform-origin.
110-
* Vector form is calculated by multiplying matrix with the vector `[width, height, 0]`.
111-
*/
112-
@property (nonatomic, assign) CATransform3D reactTransformOrigin;
109+
@property (nonatomic, assign) RCTTransformOrigin reactTransformOrigin;
113110

114111
/**
115112
* The (sub)view which represents this view in terms of accessibility.

packages/react-native/React/Views/UIView+React.m

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -222,29 +222,50 @@ - (void)setReactTransform:(CATransform3D)reactTransform
222222
[self updateTransform];
223223
}
224224

225-
- (CATransform3D)reactTransformOrigin
225+
- (RCTTransformOrigin)reactTransformOrigin
226226
{
227+
RCTTransformOrigin transformOrigin = {
228+
(YGValue){50, YGUnitPercent},
229+
(YGValue){50, YGUnitPercent},
230+
0
231+
};
227232
id obj = objc_getAssociatedObject(self, _cmd);
228-
return obj != nil ? [obj CATransform3DValue] : CATransform3DMakeScale(0.5, 0.5, 0);
233+
if (obj != nil) {
234+
[obj getValue:&transformOrigin];
235+
}
236+
return transformOrigin;
229237
}
230238

231-
- (void)setReactTransformOrigin:(CATransform3D)reactTransformOrigin
239+
- (void)setReactTransformOrigin:(RCTTransformOrigin)reactTransformOrigin
232240
{
241+
id obj = [NSValue value:&reactTransformOrigin withObjCType:@encode(RCTTransformOrigin)];
233242
objc_setAssociatedObject(
234-
self, @selector(reactTransformOrigin), @(reactTransformOrigin), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
243+
self, @selector(reactTransformOrigin), obj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
235244
[self updateTransform];
236245
}
237246

238247
- (void)updateTransform
239248
{
240249
CGSize size = self.bounds.size;
241-
CATransform3D transformOrigin = self.reactTransformOrigin;
250+
RCTTransformOrigin transformOrigin = self.reactTransformOrigin;
251+
252+
CGFloat anchorPointX = 0;
253+
CGFloat anchorPointY = 0;
254+
CGFloat anchorPointZ = 0;
255+
256+
if (transformOrigin.x.unit == YGUnitPoint) {
257+
anchorPointX = transformOrigin.x.value - size.width * 0.5;
258+
} else if (transformOrigin.x.unit == YGUnitPercent) {
259+
anchorPointX = (transformOrigin.x.value * 0.01 - 0.5) * size.width;
260+
}
261+
262+
if (transformOrigin.y.unit == YGUnitPoint) {
263+
anchorPointY = transformOrigin.y.value - size.height * 0.5;
264+
} else if (transformOrigin.y.unit == YGUnitPercent) {
265+
anchorPointY = (transformOrigin.y.value * 0.01 - 0.5) * size.height;
266+
}
242267

243-
// There's no 3D vector type in CoreAnimation, so we'll have to do the matrix multiplication manually
244-
// Note we only compute the elements we know might be set
245-
CGFloat anchorPointX = transformOrigin.m11 * size.width + transformOrigin.m14 - size.width / 2;
246-
CGFloat anchorPointY = transformOrigin.m22 * size.height + transformOrigin.m24 - size.height / 2;
247-
CGFloat anchorPointZ = transformOrigin.m34;
268+
anchorPointZ = transformOrigin.z;
248269

249270
CATransform3D transform = CATransform3DMakeTranslation(anchorPointX, anchorPointY, anchorPointZ);
250271
transform = CATransform3DConcat(self.reactTransform, transform);

0 commit comments

Comments
 (0)