diff --git a/Libraries/LayoutAnimation/LayoutAnimation.js b/Libraries/LayoutAnimation/LayoutAnimation.js index fe4a2cc2b84328..f04feca9331afb 100644 --- a/Libraries/LayoutAnimation/LayoutAnimation.js +++ b/Libraries/LayoutAnimation/LayoutAnimation.js @@ -32,6 +32,8 @@ const Types = keyMirror(TypesEnum); const PropertiesEnum = { opacity: true, + scaleX: true, + scaleY: true, scaleXY: true, }; const Properties = keyMirror(PropertiesEnum); diff --git a/React/Modules/RCTUIManager.m b/React/Modules/RCTUIManager.m index 5dcce46588ba58..49b0f774e3cdab 100644 --- a/React/Modules/RCTUIManager.m +++ b/React/Modules/RCTUIManager.m @@ -595,6 +595,10 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * NSString *property = creatingLayoutAnimation.property; if ([property isEqualToString:@"scaleXY"]) { view.layer.transform = CATransform3DMakeScale(0, 0, 0); + } else if ([property isEqualToString:@"scaleX"]) { + view.layer.transform = CATransform3DMakeScale(0, 1, 0); + } else if ([property isEqualToString:@"scaleY"]) { + view.layer.transform = CATransform3DMakeScale(1, 0, 0); } else if ([property isEqualToString:@"opacity"]) { view.layer.opacity = 0.0; } else { @@ -603,7 +607,11 @@ - (RCTViewManagerUIBlock)uiBlockWithLayoutUpdateForRootView:(RCTRootShadowView * } [creatingLayoutAnimation performAnimations:^{ - if ([property isEqualToString:@"scaleXY"]) { + if ( + [property isEqualToString:@"scaleX"] || + [property isEqualToString:@"scaleY"] || + [property isEqualToString:@"scaleXY"] + ) { view.layer.transform = finalTransform; } else if ([property isEqualToString:@"opacity"]) { view.layer.opacity = finalOpacity; @@ -738,6 +746,10 @@ - (void)_removeChildren:(NSArray *)children [deletingLayoutAnimation performAnimations:^{ if ([property isEqualToString:@"scaleXY"]) { removedChild.layer.transform = CATransform3DMakeScale(0.001, 0.001, 0.001); + } else if ([property isEqualToString:@"scaleX"]) { + removedChild.layer.transform = CATransform3DMakeScale(0.001, 1, 0.001); + } else if ([property isEqualToString:@"scaleY"]) { + removedChild.layer.transform = CATransform3DMakeScale(1, 0.001, 0.001); } else if ([property isEqualToString:@"opacity"]) { removedChild.layer.opacity = 0.0; } else { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AnimatedPropertyType.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AnimatedPropertyType.java index 51a9d246c061bb..b979799747ca7a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AnimatedPropertyType.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/AnimatedPropertyType.java @@ -8,6 +8,8 @@ */ /* package */ enum AnimatedPropertyType { OPACITY("opacity"), + SCALE_X("scaleX"), + SCALE_Y("scaleY"), SCALE_XY("scaleXY"); private final String mName; diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/BaseLayoutAnimation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/BaseLayoutAnimation.java index f4fa2ea5cd4254..be06aedbc195f8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/BaseLayoutAnimation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/layoutanimation/BaseLayoutAnimation.java @@ -42,6 +42,32 @@ Animation createAnimationImpl(View view, int x, int y, int width, int height) { Animation.RELATIVE_TO_SELF, .5f); } + case SCALE_X: { + float fromValue = isReverse() ? 1.0f : 0.0f; + float toValue = isReverse() ? 0.0f : 1.0f; + return new ScaleAnimation( + fromValue, + toValue, + 1f, + 1f, + Animation.RELATIVE_TO_SELF, + .5f, + Animation.RELATIVE_TO_SELF, + 0f); + } + case SCALE_Y: { + float fromValue = isReverse() ? 1.0f : 0.0f; + float toValue = isReverse() ? 0.0f : 1.0f; + return new ScaleAnimation( + 1f, + 1f, + fromValue, + toValue, + Animation.RELATIVE_TO_SELF, + 0f, + Animation.RELATIVE_TO_SELF, + .5f); + } default: throw new IllegalViewOperationException( "Missing animation for property : " + mAnimatedProperty);