From 49f3f47b1e9b840e4374d46b105604f4d2c22dd5 Mon Sep 17 00:00:00 2001 From: Genki Kondo Date: Thu, 10 Feb 2022 11:16:49 -0800 Subject: [PATCH] Support color animation with native driver for iOS Summary: Adds support for Animated.Color with native driver for iOS. Reads the native config for the rbga channel AnimatedNodes, and on update(), converts the values into a SharedColor. Followup changes will include support for platform colors. Ran update_pods: https://www.internalfb.com/intern/wiki/React_Native/Preparing_to_Ship/Open_Source_Pods/ Changelog: [iOS][Added] - Support running animations with AnimatedColor with native driver Reviewed By: sammy-SC Differential Revision: D33860583 fbshipit-source-id: 990ad0f754a21e3939f2cb233bcfa793ef12eb14 --- .../Nodes/RCTColorAnimatedNode.h | 14 +++++++++ .../Nodes/RCTColorAnimatedNode.m | 30 +++++++++++++++++++ .../Nodes/RCTPropsAnimatedNode.m | 17 +++++++---- .../Nodes/RCTStyleAnimatedNode.m | 12 +++++--- .../RCTNativeAnimatedNodesManager.m | 2 ++ .../React-RCTAnimation.podspec | 2 +- React/Fabric/Mounting/RCTMountingManager.mm | 6 ++++ .../renderer/graphics/platform/ios/Color.h | 1 - packages/rn-tester/Podfile.lock | 8 ++--- 9 files changed, 76 insertions(+), 16 deletions(-) create mode 100644 Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.h create mode 100644 Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.m diff --git a/Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.h b/Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.h new file mode 100644 index 00000000000000..ae1d132573445a --- /dev/null +++ b/Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import + +@interface RCTColorAnimatedNode : RCTAnimatedNode + +@property (nonatomic, assign) int32_t color; + +@end diff --git a/Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.m b/Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.m new file mode 100644 index 00000000000000..6c8d2a881116ba --- /dev/null +++ b/Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.m @@ -0,0 +1,30 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import +#import + +@implementation RCTColorAnimatedNode + +- (void)performUpdate +{ + [super performUpdate]; + + RCTValueAnimatedNode *rNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:self.config[@"r"]]; + RCTValueAnimatedNode *gNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:self.config[@"g"]]; + RCTValueAnimatedNode *bNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:self.config[@"b"]]; + RCTValueAnimatedNode *aNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:self.config[@"a"]]; + + _color = ((int)round(aNode.value * 255) & 0xff) << 24 | + ((int)round(rNode.value) & 0xff) << 16 | + ((int)round(gNode.value) & 0xff) << 8 | + ((int)round(bNode.value) & 0xff); + + // TODO (T111179606): Support platform colors for color animations +} + +@end diff --git a/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m b/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m index aac71b01efaf23..43e96a2eb2b6f5 100644 --- a/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m +++ b/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m @@ -12,6 +12,7 @@ #import #import #import +#import @implementation RCTPropsAnimatedNode { @@ -118,17 +119,21 @@ - (void)performUpdate for (NSNumber *parentTag in self.parentNodes.keyEnumerator) { RCTAnimatedNode *parentNode = [self.parentNodes objectForKey:parentTag]; if ([parentNode isKindOfClass:[RCTStyleAnimatedNode class]]) { - [self->_propsDictionary addEntriesFromDictionary:[(RCTStyleAnimatedNode *)parentNode propsDictionary]]; - + RCTStyleAnimatedNode *styleAnimatedNode = (RCTStyleAnimatedNode *)parentNode; + [_propsDictionary addEntriesFromDictionary:styleAnimatedNode.propsDictionary]; } else if ([parentNode isKindOfClass:[RCTValueAnimatedNode class]]) { + RCTValueAnimatedNode *valueAnimatedNode = (RCTValueAnimatedNode *)parentNode; NSString *property = [self propertyNameForParentTag:parentTag]; - id animatedObject = [(RCTValueAnimatedNode *)parentNode animatedObject]; + id animatedObject = valueAnimatedNode.animatedObject; if (animatedObject) { - self->_propsDictionary[property] = animatedObject; + _propsDictionary[property] = animatedObject; } else { - CGFloat value = [(RCTValueAnimatedNode *)parentNode value]; - self->_propsDictionary[property] = @(value); + _propsDictionary[property] = @(valueAnimatedNode.value); } + } else if ([parentNode isKindOfClass:[RCTColorAnimatedNode class]]) { + RCTColorAnimatedNode *colorAnimatedNode = (RCTColorAnimatedNode *)parentNode; + NSString *property = [self propertyNameForParentTag:parentTag]; + _propsDictionary[property] = @(colorAnimatedNode.color); } } diff --git a/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m b/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m index c6710d0582ea43..8dc81c9efbd3b1 100644 --- a/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m +++ b/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m @@ -9,6 +9,7 @@ #import #import #import +#import @implementation RCTStyleAnimatedNode { @@ -38,11 +39,14 @@ - (void)performUpdate RCTAnimatedNode *node = [self.parentNodes objectForKey:nodeTag]; if (node) { if ([node isKindOfClass:[RCTValueAnimatedNode class]]) { - RCTValueAnimatedNode *parentNode = (RCTValueAnimatedNode *)node; - [self->_propsDictionary setObject:@(parentNode.value) forKey:property]; + RCTValueAnimatedNode *valueAnimatedNode = (RCTValueAnimatedNode *)node; + _propsDictionary[property] = @(valueAnimatedNode.value); } else if ([node isKindOfClass:[RCTTransformAnimatedNode class]]) { - RCTTransformAnimatedNode *parentNode = (RCTTransformAnimatedNode *)node; - [self->_propsDictionary addEntriesFromDictionary:parentNode.propsDictionary]; + RCTTransformAnimatedNode *transformAnimatedNode = (RCTTransformAnimatedNode *)node; + [_propsDictionary addEntriesFromDictionary:transformAnimatedNode.propsDictionary]; + } else if ([node isKindOfClass:[RCTColorAnimatedNode class]]) { + RCTColorAnimatedNode *colorAnimatedNode = (RCTColorAnimatedNode *)node; + _propsDictionary[property] = @(colorAnimatedNode.color); } } }]; diff --git a/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m b/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m index 50356c65471427..a07d19ba6307d4 100644 --- a/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m +++ b/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m @@ -12,6 +12,7 @@ #import #import #import +#import #import #import #import @@ -86,6 +87,7 @@ - (void)createAnimatedNode:(NSNumber *)tag dispatch_once(&mapToken, ^{ map = @{@"style" : [RCTStyleAnimatedNode class], @"value" : [RCTValueAnimatedNode class], + @"color" : [RCTColorAnimatedNode class], @"props" : [RCTPropsAnimatedNode class], @"interpolation" : [RCTInterpolationAnimatedNode class], @"addition" : [RCTAdditionAnimatedNode class], diff --git a/Libraries/NativeAnimation/React-RCTAnimation.podspec b/Libraries/NativeAnimation/React-RCTAnimation.podspec index 94af81394604eb..06e317f98a72fa 100644 --- a/Libraries/NativeAnimation/React-RCTAnimation.podspec +++ b/Libraries/NativeAnimation/React-RCTAnimation.podspec @@ -29,7 +29,7 @@ Pod::Spec.new do |s| s.platforms = { :ios => "11.0" } s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness' s.source = source - s.source_files = "{Drivers/*,Nodes/*,*}.{m,mm}" + s.source_files = "**/*.{h,m,mm}" s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs" s.header_dir = "RCTAnimation" s.pod_target_xcconfig = { diff --git a/React/Fabric/Mounting/RCTMountingManager.mm b/React/Fabric/Mounting/RCTMountingManager.mm index 4f396bc72a57f7..fb18cf4e96d15b 100644 --- a/React/Fabric/Mounting/RCTMountingManager.mm +++ b/React/Fabric/Mounting/RCTMountingManager.mm @@ -14,6 +14,7 @@ #import #import #import +#import #import #import #import @@ -316,6 +317,11 @@ - (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag if (props[@"opacity"] && componentView.layer.opacity != (float)newViewProps.opacity) { componentView.layer.opacity = newViewProps.opacity; } + + auto reactNativeConfig = _contextContainer->at>("ReactNativeConfig"); + if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:finalize_updates_on_synchronous_update_view_ios")) { + [componentView finalizeUpdates:RNComponentViewUpdateMaskProps]; + } } - (void)synchronouslyDispatchCommandOnUIThread:(ReactTag)reactTag diff --git a/ReactCommon/react/renderer/graphics/platform/ios/Color.h b/ReactCommon/react/renderer/graphics/platform/ios/Color.h index 43086364751b80..2e62adb8fc2d6c 100644 --- a/ReactCommon/react/renderer/graphics/platform/ios/Color.h +++ b/ReactCommon/react/renderer/graphics/platform/ios/Color.h @@ -7,7 +7,6 @@ #pragma once -#include #include #include diff --git a/packages/rn-tester/Podfile.lock b/packages/rn-tester/Podfile.lock index ed15bf41011ca1..7e31588013f9be 100644 --- a/packages/rn-tester/Podfile.lock +++ b/packages/rn-tester/Podfile.lock @@ -884,7 +884,7 @@ SPEC CHECKSUMS: CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 FBLazyVector: b81a2b70c72d8b0aefb652cea22c11e9ffd02949 - FBReactNativeSpec: 8e730e8017b1ba644ba3c14f0c33a4cc96cce9f4 + FBReactNativeSpec: 277e2460e8a1a20883306c886d5d57a361e32a71 Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0 Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c Flipper-DoubleConversion: 57ffbe81ef95306cc9e69c4aa3aeeeeb58a6a28c @@ -915,7 +915,7 @@ SPEC CHECKSUMS: React-logger: 2009c0280c286a76200d6b7c5fe242fad51ddd7a React-perflogger: fe66bd6d8b17ebcfdf0159bf41fe28d8035ac20c React-RCTActionSheet: 3131a0b9280aa0e51bdf54b3d79aecd8503db62c - React-RCTAnimation: 70f2b9daaa1b45dea608be865cc5f2e1789dbc39 + React-RCTAnimation: 0c0a35cd27c5005cfddcda59b612994f4ebdaa43 React-RCTBlob: 48cae62d905ef96ab10c84ab16163643a3c872a7 React-RCTFabric: c126a269f6279896e19e133d6b1e019fa2f0f028 React-RCTImage: 2ce3f1f72de91798eb31c9001b30cab8d1c71c4e @@ -926,10 +926,10 @@ SPEC CHECKSUMS: React-RCTTest: 12bbd7fc2e72bd9920dc7286c5b8ef96639582b6 React-RCTText: e9146b2c0550a83d1335bfe2553760070a2d75c7 React-RCTVibration: 50be9c390f2da76045ef0dfdefa18b9cf9f35cfa - React-rncore: 7db29a115e312e9f0f280294d78fe8501f740d8d + React-rncore: 252dd9c510174ba718e358d332a43ad7056e9cb0 React-runtimeexecutor: 4b0c6eb341c7d3ceb5e2385cb0fdb9bf701024f3 ReactCommon: 7a2714d1128f965392b6f99a8b390e3aa38c9569 - ScreenshotManager: 1a419252584923755f7e7fd96ededcac2cf95521 + ScreenshotManager: 79ae4255728f14773097f05accaa53949bdd526c SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 Yoga: c0d06f5380d34e939f55420669a60fe08b79bd75 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a