Ver código fonte

Implement rotate animation for shared element transition

Yogev Ben David 4 anos atrás
pai
commit
5d9e9100b7
Nenhuma conta vinculada ao e-mail do autor do commit

+ 2
- 0
lib/ios/ElementBaseTransition.h Ver arquivo

@@ -3,6 +3,8 @@
3 3
 #import "DisplayLinkAnimation.h"
4 4
 #import "RNNInterpolator.h"
5 5
 
6
+#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
7
+
6 8
 @interface ElementBaseTransition : NSObject <DisplayLinkAnimation>
7 9
 
8 10
 - (instancetype)initWithView:(UIView *)view startDelay:(NSTimeInterval)startDelay duration:(NSTimeInterval)duration interpolation:(Text *)interpolation;

+ 2
- 0
lib/ios/FloatTransition.h Ver arquivo

@@ -5,6 +5,8 @@
5 5
 
6 6
 - (instancetype)initWithView:(UIView *)view transitionDetails:(TransitionDetailsOptions *)transitionDetails;
7 7
 
8
+- (instancetype)initWithView:(UIView *)view fromFloat:(CGFloat)from toFloat:(CGFloat)to startDelay:(NSTimeInterval)startDelay duration:(NSTimeInterval)duration interpolation:(Text *)interpolation;
9
+
8 10
 @property (readonly) CGFloat initialValue;
9 11
 @property (nonatomic) CGFloat from;
10 12
 @property (nonatomic) CGFloat to;

+ 7
- 0
lib/ios/FloatTransition.m Ver arquivo

@@ -12,6 +12,13 @@
12 12
     return self;
13 13
 }
14 14
 
15
+- (instancetype)initWithView:(UIView *)view fromFloat:(CGFloat)from toFloat:(CGFloat)to startDelay:(NSTimeInterval)startDelay duration:(NSTimeInterval)duration interpolation:(Text *)interpolation {
16
+    self = [super initWithView:view startDelay:startDelay duration:duration interpolation:interpolation];
17
+    self.from = from;
18
+    self.to = to;
19
+    return self;
20
+}
21
+
15 22
 - (instancetype)initWithView:(UIView *)view from:(Double*)from to:(Double*)to startDelay:(NSTimeInterval)startDelay duration:(NSTimeInterval)duration interpolation:(Text *)interpolation {
16 23
     self = [super initWithView:view startDelay:startDelay duration:duration interpolation:interpolation];
17 24
     _initialValue = self.initialValue;

+ 2
- 0
lib/ios/RNNViewLocation.h Ver arquivo

@@ -4,6 +4,8 @@
4 4
 
5 5
 @property (nonatomic) CGRect fromFrame;
6 6
 @property (nonatomic) CGRect toFrame;
7
+@property (nonatomic) CGFloat fromAngle;
8
+@property (nonatomic) CGFloat toAngle;
7 9
 
8 10
 - (instancetype)initWithFromElement:(UIView*)fromElement toElement:(UIView*)toElement;
9 11
 

+ 10
- 3
lib/ios/RNNViewLocation.m Ver arquivo

@@ -8,18 +8,25 @@
8 8
 	self = [super init];
9 9
     self.fromFrame = [self convertViewFrame:fromElement];
10 10
     self.toFrame = [self convertViewFrame:toElement];
11
+    self.fromAngle = [self getViewAngle:fromElement];
12
+    self.toAngle = [self getViewAngle:toElement];
11 13
 	return self;
12 14
 }
13 15
 
14 16
 - (CGRect)convertViewFrame:(UIView *)view {
15 17
     UIView* topMostView = [self topMostView:view];
16
-    CGRect frame = [view.superview convertRect:view.frame toView:nil];
18
+    CGPoint center = [view.superview convertPoint:view.center toView:nil];
17 19
     CGFloat safeAreaTopOffset = [self safeAreaOffsetForView:view inView:topMostView];
18
-    frame.origin.y += safeAreaTopOffset;
19
-
20
+    center.y += safeAreaTopOffset;
21
+    CGRect frame = CGRectMake(center.x - view.bounds.size.width / 2, center.y - view.bounds.size.height / 2, view.bounds.size.width, view.bounds.size.height);
20 22
     return frame;
21 23
 }
22 24
 
25
+- (CGFloat)getViewAngle:(UIView *)view {
26
+    CGFloat radians = atan2f(view.transform.b, view.transform.a);
27
+    return radians;
28
+}
29
+
23 30
  - (UIView *)topMostView:(UIView *)view {
24 31
     if ([view isKindOfClass:[RNNReactView class]]) {
25 32
         return view;

+ 8
- 0
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj Ver arquivo

@@ -235,6 +235,8 @@
235 235
 		50644A2120E11A720026709C /* Constants.m in Sources */ = {isa = PBXBuildFile; fileRef = 50644A1F20E11A720026709C /* Constants.m */; };
236 236
 		506A2B1420973DFD00F43A95 /* RNNErrorHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 506A2B1220973DFD00F43A95 /* RNNErrorHandler.h */; };
237 237
 		506A2B1520973DFD00F43A95 /* RNNErrorHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 506A2B1320973DFD00F43A95 /* RNNErrorHandler.m */; };
238
+		506C2532244F0C6B00820F5B /* RotationTransition.h in Headers */ = {isa = PBXBuildFile; fileRef = 506C2530244F0C6B00820F5B /* RotationTransition.h */; };
239
+		506C2533244F0C6B00820F5B /* RotationTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = 506C2531244F0C6B00820F5B /* RotationTransition.m */; };
238 240
 		506F630D216A599300AD0D0A /* RNNTabBarControllerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 506F630C216A599300AD0D0A /* RNNTabBarControllerTest.m */; };
239 241
 		506F630F216A5AD700AD0D0A /* RNNComponentPresenterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 506F630E216A5AD700AD0D0A /* RNNComponentPresenterTest.m */; };
240 242
 		50706E6D20CE7CA5003345C3 /* UIImage+tint.h in Headers */ = {isa = PBXBuildFile; fileRef = 50706E6B20CE7CA5003345C3 /* UIImage+tint.h */; };
@@ -721,6 +723,8 @@
721 723
 		50644A1F20E11A720026709C /* Constants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Constants.m; sourceTree = "<group>"; };
722 724
 		506A2B1220973DFD00F43A95 /* RNNErrorHandler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNErrorHandler.h; sourceTree = "<group>"; };
723 725
 		506A2B1320973DFD00F43A95 /* RNNErrorHandler.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNErrorHandler.m; sourceTree = "<group>"; };
726
+		506C2530244F0C6B00820F5B /* RotationTransition.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RotationTransition.h; sourceTree = "<group>"; };
727
+		506C2531244F0C6B00820F5B /* RotationTransition.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RotationTransition.m; sourceTree = "<group>"; };
724 728
 		506F630C216A599300AD0D0A /* RNNTabBarControllerTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTabBarControllerTest.m; sourceTree = "<group>"; };
725 729
 		506F630E216A5AD700AD0D0A /* RNNComponentPresenterTest.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNComponentPresenterTest.m; sourceTree = "<group>"; };
726 730
 		50706E6B20CE7CA5003345C3 /* UIImage+tint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIImage+tint.h"; sourceTree = "<group>"; };
@@ -1320,6 +1324,8 @@
1320 1324
 				50AD288723CDB71C00FF3134 /* ElementHorizontalTransition.m */,
1321 1325
 				5082CC3123CDC3B800FD2B6A /* HorizontalTranslationTransition.h */,
1322 1326
 				5082CC3223CDC3B800FD2B6A /* HorizontalTranslationTransition.m */,
1327
+				506C2530244F0C6B00820F5B /* RotationTransition.h */,
1328
+				506C2531244F0C6B00820F5B /* RotationTransition.m */,
1323 1329
 				5061B6C523D48449008B9827 /* VerticalRotationTransition.h */,
1324 1330
 				5061B6C623D48449008B9827 /* VerticalRotationTransition.m */,
1325 1331
 				5096709923D49B35002224F9 /* DisplayLinkAnimatorDelegate.h */,
@@ -1812,6 +1818,7 @@
1812 1818
 				390AD477200F499D00A8250D /* RNNSwizzles.h in Headers */,
1813 1819
 				5022EDC924054C8A00852BA6 /* BottomTabsPresenterCreator.h in Headers */,
1814 1820
 				263905B11E4C6F440023D7D3 /* MMDrawerController.h in Headers */,
1821
+				506C2532244F0C6B00820F5B /* RotationTransition.h in Headers */,
1815 1822
 				263905B31E4C6F440023D7D3 /* MMDrawerVisualState.h in Headers */,
1816 1823
 				50451D092042E20600695F00 /* RNNAnimationsOptions.h in Headers */,
1817 1824
 				50EA541A23AEE1C6006F881A /* AnimatedReactView.h in Headers */,
@@ -2182,6 +2189,7 @@
2182 2189
 				50EA541B23AEE1C6006F881A /* AnimatedReactView.m in Sources */,
2183 2190
 				5095BB732416A3B900C4CD41 /* RNNConvert.m in Sources */,
2184 2191
 				7BC9346E1E26886E00EFA125 /* RNNControllerFactory.m in Sources */,
2192
+				506C2533244F0C6B00820F5B /* RotationTransition.m in Sources */,
2185 2193
 				507F43F91FF525B500D9425B /* RNNSegmentedControl.m in Sources */,
2186 2194
 				5038A3B2216DF41B009280BC /* UIViewController+RNNOptions.m in Sources */,
2187 2195
 				50D031352005149000386B3D /* RNNOverlayManager.m in Sources */,

+ 5
- 0
lib/ios/RotationTransition.h Ver arquivo

@@ -0,0 +1,5 @@
1
+#import "FloatTransition.h"
2
+
3
+@interface RotationTransition : FloatTransition
4
+
5
+@end

+ 11
- 0
lib/ios/RotationTransition.m Ver arquivo

@@ -0,0 +1,11 @@
1
+#import "RotationTransition.h"
2
+
3
+@implementation RotationTransition
4
+
5
+- (CATransform3D)animateWithProgress:(CGFloat)p {
6
+    double degrees = [RNNInterpolator fromFloat:self.from toFloat:self.to precent:p interpolation:self.interpolation];
7
+    double rads = DEGREES_TO_RADIANS(degrees);
8
+    return CATransform3DMakeRotation(rads, 0, 0, 1);
9
+}
10
+
11
+@end

+ 2
- 1
lib/ios/SharedElementAnimator.m Ver arquivo

@@ -2,6 +2,7 @@
2 2
 #import "AnimatedViewFactory.h"
3 3
 #import "RectTransition.h"
4 4
 #import "TransformRectTransition.h"
5
+#import "RotationTransition.h"
5 6
 #import "ColorTransition.h"
6 7
 #import "AnimatedTextView.h"
7 8
 #import "TextStorageTransition.h"
@@ -43,7 +44,7 @@
43 44
         if ([self.view isKindOfClass:AnimatedTextView.class]) {
44 45
             [animations addObject:[[RectTransition alloc] initWithView:self.view from:self.view.location.fromFrame to:self.view.location.toFrame startDelay:startDelay duration:duration interpolation:interpolation]];
45 46
         } else {
46
-            [animations addObject:[[TransformRectTransition alloc] initWithView:self.view from:self.view.location.fromFrame to:self.view.location.toFrame startDelay:startDelay duration:duration interpolation:interpolation]];
47
+            [animations addObject:[[TransformRectTransition alloc] initWithView:self.view fromRect:self.view.location.fromFrame toRect:self.view.location.toFrame fromAngle:self.view.location.fromAngle toAngle:self.view.location.toAngle startDelay:startDelay duration:duration interpolation:interpolation]];
47 48
         }
48 49
     }
49 50
     

+ 5
- 0
lib/ios/TransformRectTransition.h Ver arquivo

@@ -3,4 +3,9 @@
3 3
 
4 4
 @interface TransformRectTransition : RectTransition
5 5
 
6
+- (instancetype)initWithView:(UIView *)view fromRect:(CGRect)fromRect toRect:(CGRect)toRect fromAngle:(CGFloat)fromAngle toAngle:(CGFloat)toAngle startDelay:(NSTimeInterval)startDelay duration:(NSTimeInterval)duration interpolation:(Text *)interpolation;
7
+
8
+@property (nonatomic, readonly) CGFloat fromAngle;
9
+@property (nonatomic, readonly) CGFloat toAngle;
10
+
6 11
 @end

+ 10
- 1
lib/ios/TransformRectTransition.m Ver arquivo

@@ -2,8 +2,16 @@
2 2
 
3 3
 @implementation TransformRectTransition
4 4
 
5
+- (instancetype)initWithView:(UIView *)view fromRect:(CGRect)fromRect toRect:(CGRect)toRect fromAngle:(CGFloat)fromAngle toAngle:(CGFloat)toAngle startDelay:(NSTimeInterval)startDelay duration:(NSTimeInterval)duration interpolation:(Text *)interpolation {
6
+    self = [super initWithView:view from:fromRect to:toRect startDelay:startDelay duration:duration interpolation:interpolation];
7
+    _fromAngle = fromAngle;
8
+    _toAngle = toAngle;
9
+    return self;
10
+}
11
+
5 12
 - (CATransform3D)animateWithProgress:(CGFloat)p {
6 13
     CGRect toFrame = [RNNInterpolator fromRect:self.from toRect:self.to precent:p interpolation:self.interpolation];
14
+    CGFloat toAngle = [RNNInterpolator fromFloat:self.fromAngle toFloat:self.toAngle precent:p interpolation:self.interpolation];
7 15
     
8 16
     CGFloat scaleX = toFrame.size.width / self.from.size.width;
9 17
     CGFloat scaleY = toFrame.size.height / self.from.size.height;
@@ -14,8 +22,9 @@
14 22
     
15 23
     CATransform3D translate = CATransform3DMakeTranslation(translateX, translateY, 0);
16 24
     CATransform3D scale = CATransform3DScale(translate, scaleX, scaleY, 0);
25
+    CATransform3D rotate = CATransform3DRotate(scale, toAngle, 0, 0, 1);
17 26
     
18
-    return scale;
27
+    return rotate;
19 28
 }
20 29
 
21 30
 @end

+ 0
- 1
lib/ios/VerticalRotationTransition.m Ver arquivo

@@ -1,5 +1,4 @@
1 1
 #import "VerticalRotationTransition.h"
2
-#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
3 2
 
4 3
 @implementation VerticalRotationTransition
5 4