diff --git a/packages/react-native/Libraries/NativeAnimation/Nodes/RCTObjectAnimatedNode.h b/packages/react-native/Libraries/NativeAnimation/Nodes/RCTObjectAnimatedNode.h new file mode 100644 index 00000000000000..9ceeb1ec023c81 --- /dev/null +++ b/packages/react-native/Libraries/NativeAnimation/Nodes/RCTObjectAnimatedNode.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 "RCTAnimatedNode.h" + +@interface RCTObjectAnimatedNode : RCTAnimatedNode + +@property (nonatomic, strong, readonly) id value; + +@end diff --git a/packages/react-native/Libraries/NativeAnimation/Nodes/RCTObjectAnimatedNode.m b/packages/react-native/Libraries/NativeAnimation/Nodes/RCTObjectAnimatedNode.m new file mode 100644 index 00000000000000..81b9ef37a8b660 --- /dev/null +++ b/packages/react-native/Libraries/NativeAnimation/Nodes/RCTObjectAnimatedNode.m @@ -0,0 +1,66 @@ +/* + * 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 "RCTObjectAnimatedNode.h" +#import "RCTValueAnimatedNode.h" + +NSString *const VALUE_KEY = @"value"; +NSString *const NODE_TAG_KEY = @"nodeTag"; + +@implementation RCTObjectAnimatedNode + +- (void)performUpdate +{ + [super performUpdate]; + + id value = self.config[VALUE_KEY]; + if ([value isKindOfClass:[NSDictionary class]]) { + _value = [self _performUpdateHelperDictionary:(NSDictionary *)value]; + } else if ([value isKindOfClass:[NSArray class]]) { + _value = [self _performUpdateHelperArray:(NSArray *)value]; + } +} + +- (NSDictionary *)_performUpdateHelperDictionary:(NSDictionary *)source +{ + NSMutableDictionary *result = [NSMutableDictionary new]; + for (NSString *key in source) { + result[key] = [self _convertValue:source[key]]; + } + return result; +} + +- (NSArray *)_performUpdateHelperArray:(NSArray *)source +{ + NSMutableArray *result = [NSMutableArray array]; + for (id value in source) { + [result addObject:[self _convertValue:value]]; + } + return result; +} + +- (id)_convertValue:(id)value +{ + if ([value isKindOfClass:[NSDictionary class]]) { + NSDictionary *dict = (NSDictionary *)value; + id nodeTag = [dict objectForKey:NODE_TAG_KEY]; + if (nodeTag && [nodeTag isKindOfClass:[NSNumber class]]) { + RCTAnimatedNode *node = [self.parentNodes objectForKey:(NSNumber *)nodeTag]; + if ([node isKindOfClass:[RCTValueAnimatedNode class]]) { + RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)node; + return @(valueNode.value); + } + } + return [self _performUpdateHelperDictionary:dict]; + } else if ([value isKindOfClass:[NSArray class]]) { + return [self _performUpdateHelperArray:(NSArray *)value]; + } else { + return value; + } +} + +@end diff --git a/packages/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m b/packages/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m index fdc5f88d1020d5..2d8c6494c16139 100644 --- a/packages/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m +++ b/packages/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m @@ -9,7 +9,7 @@ #import #import -#import +#import #import #import #import @@ -131,6 +131,10 @@ - (void)performUpdate RCTColorAnimatedNode *colorAnimatedNode = (RCTColorAnimatedNode *)parentNode; NSString *property = [self propertyNameForParentTag:parentTag]; _propsDictionary[property] = @(colorAnimatedNode.color); + } else if ([parentNode isKindOfClass:[RCTObjectAnimatedNode class]]) { + RCTObjectAnimatedNode *objectAnimatedNode = (RCTObjectAnimatedNode *)parentNode; + NSString *property = [self propertyNameForParentTag:parentTag]; + _propsDictionary[property] = objectAnimatedNode.value; } } diff --git a/packages/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m b/packages/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m index 180b2b1e7848a4..7673db6323e41a 100644 --- a/packages/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m +++ b/packages/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m @@ -7,6 +7,7 @@ #import #import +#import #import #import #import @@ -50,6 +51,9 @@ - (void)performUpdate } else if ([node isKindOfClass:[RCTColorAnimatedNode class]]) { RCTColorAnimatedNode *colorAnimatedNode = (RCTColorAnimatedNode *)node; _propsDictionary[property] = @(colorAnimatedNode.color); + } else if ([node isKindOfClass:[RCTObjectAnimatedNode class]]) { + RCTObjectAnimatedNode *objectAnimatedNode = (RCTObjectAnimatedNode *)node; + _propsDictionary[property] = objectAnimatedNode.value; } } }]; diff --git a/packages/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m b/packages/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m index e5007d2e8c1c5c..a272dcc8ded6d0 100644 --- a/packages/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m +++ b/packages/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m @@ -21,6 +21,7 @@ #import #import #import +#import #import #import #import @@ -97,7 +98,8 @@ - (void)createAnimatedNode:(NSNumber *)tag config:(NSDictionary @"modulus" : [RCTModuloAnimatedNode class], @"subtraction" : [RCTSubtractionAnimatedNode class], @"transform" : [RCTTransformAnimatedNode class], - @"tracking" : [RCTTrackingAnimatedNode class] + @"tracking" : [RCTTrackingAnimatedNode class], + @"object" : [RCTObjectAnimatedNode class], }; });