Skip to content

Commit 599dd63

Browse files
Support color animation with native driver for iOS (#1513)
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 # Conflicts: # packages/rn-tester/Podfile.lock Co-authored-by: Genki Kondo <[email protected]>
1 parent c7f8f12 commit 599dd63

File tree

8 files changed

+72
-12
lines changed

8 files changed

+72
-12
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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 <React/RCTAnimatedNode.h>
9+
10+
@interface RCTColorAnimatedNode : RCTAnimatedNode
11+
12+
@property (nonatomic, assign) int32_t color;
13+
14+
@end
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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 <React/RCTColorAnimatedNode.h>
9+
#import <React/RCTValueAnimatedNode.h>
10+
11+
@implementation RCTColorAnimatedNode
12+
13+
- (void)performUpdate
14+
{
15+
[super performUpdate];
16+
17+
RCTValueAnimatedNode *rNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:self.config[@"r"]];
18+
RCTValueAnimatedNode *gNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:self.config[@"g"]];
19+
RCTValueAnimatedNode *bNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:self.config[@"b"]];
20+
RCTValueAnimatedNode *aNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:self.config[@"a"]];
21+
22+
_color = ((int)round(aNode.value * 255) & 0xff) << 24 |
23+
((int)round(rNode.value) & 0xff) << 16 |
24+
((int)round(gNode.value) & 0xff) << 8 |
25+
((int)round(bNode.value) & 0xff);
26+
27+
// TODO (T111179606): Support platform colors for color animations
28+
}
29+
30+
@end

Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#import <React/RCTStyleAnimatedNode.h>
1313
#import <React/RCTUIManager.h>
1414
#import <React/RCTValueAnimatedNode.h>
15+
#import <React/RCTColorAnimatedNode.h>
1516

1617
@implementation RCTPropsAnimatedNode
1718
{
@@ -118,17 +119,21 @@ - (void)performUpdate
118119
for (NSNumber *parentTag in self.parentNodes.keyEnumerator) {
119120
RCTAnimatedNode *parentNode = [self.parentNodes objectForKey:parentTag];
120121
if ([parentNode isKindOfClass:[RCTStyleAnimatedNode class]]) {
121-
[self->_propsDictionary addEntriesFromDictionary:[(RCTStyleAnimatedNode *)parentNode propsDictionary]];
122-
122+
RCTStyleAnimatedNode *styleAnimatedNode = (RCTStyleAnimatedNode *)parentNode;
123+
[_propsDictionary addEntriesFromDictionary:styleAnimatedNode.propsDictionary];
123124
} else if ([parentNode isKindOfClass:[RCTValueAnimatedNode class]]) {
125+
RCTValueAnimatedNode *valueAnimatedNode = (RCTValueAnimatedNode *)parentNode;
124126
NSString *property = [self propertyNameForParentTag:parentTag];
125-
id animatedObject = [(RCTValueAnimatedNode *)parentNode animatedObject];
127+
id animatedObject = valueAnimatedNode.animatedObject;
126128
if (animatedObject) {
127-
self->_propsDictionary[property] = animatedObject;
129+
_propsDictionary[property] = animatedObject;
128130
} else {
129-
CGFloat value = [(RCTValueAnimatedNode *)parentNode value];
130-
self->_propsDictionary[property] = @(value);
131+
_propsDictionary[property] = @(valueAnimatedNode.value);
131132
}
133+
} else if ([parentNode isKindOfClass:[RCTColorAnimatedNode class]]) {
134+
RCTColorAnimatedNode *colorAnimatedNode = (RCTColorAnimatedNode *)parentNode;
135+
NSString *property = [self propertyNameForParentTag:parentTag];
136+
_propsDictionary[property] = @(colorAnimatedNode.color);
132137
}
133138
}
134139

Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#import <React/RCTAnimationUtils.h>
1010
#import <React/RCTValueAnimatedNode.h>
1111
#import <React/RCTTransformAnimatedNode.h>
12+
#import <React/RCTColorAnimatedNode.h>
1213

1314
@implementation RCTStyleAnimatedNode
1415
{
@@ -38,11 +39,14 @@ - (void)performUpdate
3839
RCTAnimatedNode *node = [self.parentNodes objectForKey:nodeTag];
3940
if (node) {
4041
if ([node isKindOfClass:[RCTValueAnimatedNode class]]) {
41-
RCTValueAnimatedNode *parentNode = (RCTValueAnimatedNode *)node;
42-
[self->_propsDictionary setObject:@(parentNode.value) forKey:property];
42+
RCTValueAnimatedNode *valueAnimatedNode = (RCTValueAnimatedNode *)node;
43+
_propsDictionary[property] = @(valueAnimatedNode.value);
4344
} else if ([node isKindOfClass:[RCTTransformAnimatedNode class]]) {
44-
RCTTransformAnimatedNode *parentNode = (RCTTransformAnimatedNode *)node;
45-
[self->_propsDictionary addEntriesFromDictionary:parentNode.propsDictionary];
45+
RCTTransformAnimatedNode *transformAnimatedNode = (RCTTransformAnimatedNode *)node;
46+
[_propsDictionary addEntriesFromDictionary:transformAnimatedNode.propsDictionary];
47+
} else if ([node isKindOfClass:[RCTColorAnimatedNode class]]) {
48+
RCTColorAnimatedNode *colorAnimatedNode = (RCTColorAnimatedNode *)node;
49+
_propsDictionary[property] = @(colorAnimatedNode.color);
4650
}
4751
}
4852
}];

Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#import <React/RCTAdditionAnimatedNode.h>
1313
#import <React/RCTAnimatedNode.h>
1414
#import <React/RCTAnimationDriver.h>
15+
#import <React/RCTColorAnimatedNode.h>
1516
#import <React/RCTDiffClampAnimatedNode.h>
1617
#import <React/RCTDivisionAnimatedNode.h>
1718
#import <React/RCTEventAnimation.h>
@@ -86,6 +87,7 @@ - (void)createAnimatedNode:(NSNumber *)tag
8687
dispatch_once(&mapToken, ^{
8788
map = @{@"style" : [RCTStyleAnimatedNode class],
8889
@"value" : [RCTValueAnimatedNode class],
90+
@"color" : [RCTColorAnimatedNode class],
8991
@"props" : [RCTPropsAnimatedNode class],
9092
@"interpolation" : [RCTInterpolationAnimatedNode class],
9193
@"addition" : [RCTAdditionAnimatedNode class],

Libraries/NativeAnimation/React-RCTAnimation.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Pod::Spec.new do |s|
2929
s.platforms = { :ios => "11.0", :osx => "10.15" } # TODO(macOS GH#214)
3030
s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness'
3131
s.source = source
32-
s.source_files = "{Drivers/*,Nodes/*,*}.{m,mm}"
32+
s.source_files = "**/*.{h,m,mm}"
3333
s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs"
3434
s.header_dir = "RCTAnimation"
3535
s.pod_target_xcconfig = {

React/Fabric/Mounting/RCTMountingManager.mm

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#import <React/RCTFollyConvert.h>
1616
#import <React/RCTLog.h>
1717
#import <React/RCTUtils.h>
18+
#import <react/config/ReactNativeConfig.h>
1819
#import <react/renderer/components/root/RootShadowNode.h>
1920
#import <react/renderer/core/LayoutableShadowNode.h>
2021
#import <react/renderer/core/RawProps.h>
@@ -318,6 +319,11 @@ - (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag
318319
if (props[@"opacity"] && componentView.layer.opacity != (float)newViewProps.opacity) {
319320
componentView.layer.opacity = newViewProps.opacity;
320321
}
322+
323+
auto reactNativeConfig = _contextContainer->at<std::shared_ptr<ReactNativeConfig const>>("ReactNativeConfig");
324+
if (reactNativeConfig && reactNativeConfig->getBool("react_fabric:finalize_updates_on_synchronous_update_view_ios")) {
325+
[componentView finalizeUpdates:RNComponentViewUpdateMaskProps];
326+
}
321327
}
322328

323329
- (void)synchronouslyDispatchCommandOnUIThread:(ReactTag)reactTag

ReactCommon/react/renderer/graphics/platform/ios/Color.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
#pragma once
99

10-
#include <butter/optional.h>
1110
#include <cmath>
1211
#include <optional>
1312

0 commit comments

Comments
 (0)