Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions Examples/UIExplorer/js/NativeAnimationsExample.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -30,8 +30,11 @@ const {
Animated,
StyleSheet,
TouchableWithoutFeedback,
Slider,
} = ReactNative;

var AnimatedSlider = Animated.createAnimatedComponent(Slider);

class Tester extends React.Component {
state = {
native: new Animated.Value(0),
Expand DownExpand Up@@ -228,7 +231,6 @@ exports.description = 'Test out Native Animations';
exports.examples = [
{
title: 'Multistage With Multiply and rotation',
description: 'description',
render: function() {
return (
<Tester
Expand DownExpand Up@@ -278,7 +280,6 @@ exports.examples = [
},
{
title: 'Multistage With Multiply',
description: 'description',
render: function() {
return (
<Tester
Expand DownExpand Up@@ -322,7 +323,6 @@ exports.examples = [
},
{
title: 'Scale interpolation with clamping',
description: 'description',
render: function() {
return (
<Tester
Expand DownExpand Up@@ -352,7 +352,6 @@ exports.examples = [
},
{
title: 'Opacity without interpolation',
description: 'description',
render: function() {
return (
<Tester
Expand All@@ -374,7 +373,6 @@ exports.examples = [
},
{
title: 'Rotate interpolation',
description: 'description',
render: function() {
return (
<Tester
Expand DownExpand Up@@ -403,7 +401,6 @@ exports.examples = [
},
{
title: 'translateX => Animated.spring',
description: 'description',
render: function() {
return (
<Tester
Expand DownExpand Up@@ -454,6 +451,19 @@ exports.examples = [
</Tester>
);
},
},{
title: 'Drive custom property',
render: function() {
return (
<Tester
type="timing"
config={{ duration: 1000 }}>
{anim => (
<AnimatedSlider style={{}} value={anim} />
)}
</Tester>
);
},
},
{
title: 'Animated value listener',
Expand Down
1 change: 0 additions & 1 deletion Libraries/Animated/src/AnimatedImplementation.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -1676,7 +1676,6 @@ class AnimatedProps extends Animated {
propsConfig[propKey] = value.__getNativeTag();
}
}
NativeAnimatedHelper.validateProps(propsConfig);
return {
type: 'props',
props: propsConfig,
Expand Down
33 changes: 10 additions & 23 deletions Libraries/Animated/src/NativeAnimatedHelper.js
Original file line numberDiff line numberDiff line change
Expand Up@@ -100,22 +100,19 @@ const API = {
};

/**
* Properties allowed by the native animated implementation.
* Styles allowed by the native animated implementation.
*
* In general native animated implementation should support any numeric property that doesn't need
* to be updated through the shadow view hierarchy (all non-layout properties). This list is limited
* to the properties that will perform best when animated off the JS thread.
* to be updated through the shadow view hierarchy (all non-layout properties).
*/
const PROPS_WHITELIST = {
style: {
opacity: true,
transform: true,
/* legacy android transform properties */
scaleX: true,
scaleY: true,
translateX: true,
translateY: true,
},
const STYLES_WHITELIST = {
opacity: true,
transform: true,
/* legacy android transform properties */
scaleX: true,
scaleY: true,
translateX: true,
translateY: true,
};

const TRANSFORM_WHITELIST = {
Expand All@@ -130,14 +127,6 @@ const TRANSFORM_WHITELIST = {
perspective: true,
};

function validateProps(params: Object): void {
for (var key in params) {
if (!PROPS_WHITELIST.hasOwnProperty(key)) {
throw new Error(`Property '${key}' is not supported by native animated module`);
}
}
}

function validateTransform(configs: Array<Object>): void {
configs.forEach((config) => {
if (!TRANSFORM_WHITELIST.hasOwnProperty(config.property)) {
Expand All@@ -147,7 +136,6 @@ function validateTransform(configs: Array<Object>): void {
}

function validateStyles(styles: Object): void {
var STYLES_WHITELIST = PROPS_WHITELIST.style || {};
for (var key in styles) {
if (!STYLES_WHITELIST.hasOwnProperty(key)) {
throw new Error(`Style property '${key}' is not supported by native animated module`);
Expand DownExpand Up@@ -188,7 +176,6 @@ function isNativeAnimatedAvailable(): boolean {

module.exports = {
API,
validateProps,
validateStyles,
validateTransform,
validateInterpolation,
Expand Down
7 changes: 3 additions & 4 deletions Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,11 +14,10 @@

@interface RCTPropsAnimatedNode : RCTAnimatedNode

@property (nonatomic, readonly) RCTViewPropertyMapper *propertyMapper;
- (void)connectToView:(NSNumber *)viewTag
viewName:(NSString *)viewName
uiManager:(RCTUIManager *)uiManager;

- (void)connectToView:(NSNumber *)viewTag uiManager:(RCTUIManager *)uiManager;
- (void)disconnectFromView:(NSNumber *)viewTag;

- (void)performViewUpdatesIfNecessary;

@end
41 changes: 28 additions & 13 deletions Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,27 +9,33 @@

#import "RCTPropsAnimatedNode.h"

#import <React/RCTLog.h>
#import <React/RCTUIManager.h>

#import "RCTAnimationUtils.h"
#import "RCTStyleAnimatedNode.h"
#import "RCTValueAnimatedNode.h"
#import "RCTViewPropertyMapper.h"

@implementation RCTPropsAnimatedNode

- (void)connectToView:(NSNumber *)viewTag uiManager:(RCTUIManager *)uiManager
{
_propertyMapper = [[RCTViewPropertyMapper alloc] initWithViewTag:viewTag uiManager:uiManager];
@implementation RCTPropsAnimatedNode {
NSNumber *_connectedViewTag;
NSString *_connectedViewName;
RCTUIManager *_uiManager;
}

- (void)disconnectFromView:(NSNumber *)viewTag
- (void)connectToView:(NSNumber *)viewTag
viewName:(NSString *)viewName
uiManager:(RCTUIManager *)uiManager
{
_propertyMapper = nil;
_connectedViewTag = viewTag;
_connectedViewName = viewName;
_uiManager = uiManager;
}

- (void)performUpdate
- (void)disconnectFromView:(NSNumber *)viewTag
{
[super performUpdate];
[self performViewUpdatesIfNecessary];
_connectedViewTag = nil;
_connectedViewName = nil;
_uiManager = nil;
}

- (NSString *)propertyNameForParentTag:(NSNumber *)parentTag
Expand All@@ -44,8 +50,15 @@ - (NSString *)propertyNameForParentTag:(NSNumber *)parentTag
return propertyName;
}

- (void)performViewUpdatesIfNecessary
- (void)performUpdate
{
[super performUpdate];

if (!_connectedViewTag) {
RCTLogError(@"Node has not been attached to a view");
return;
}

NSMutableDictionary *props = [NSMutableDictionary dictionary];
[self.parentNodes enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull parentTag, RCTAnimatedNode * _Nonnull parentNode, BOOL * _Nonnull stop) {

Expand All@@ -61,7 +74,9 @@ - (void)performViewUpdatesIfNecessary
}];

if (props.count) {
[_propertyMapper updateViewWithDictionary:props];
[_uiManager synchronouslyUpdateViewOnUIThread:_connectedViewTag
viewName:_connectedViewName
props:props];
}
}

Expand Down
41 changes: 6 additions & 35 deletions Libraries/NativeAnimation/Nodes/RCTTransformAnimatedNode.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -33,56 +33,27 @@ - (void)performUpdate
{
[super performUpdate];

CATransform3D transform = CATransform3DIdentity;

NSArray<NSDictionary *> *transformConfigs = self.config[@"transforms"];
NSMutableArray<NSDictionary *> *transform = [NSMutableArray arrayWithCapacity:transformConfigs.count];
for (NSDictionary *transformConfig in transformConfigs) {
NSString *type = transformConfig[@"type"];
NSString *property = transformConfig[@"property"];

CGFloat value;
NSNumber *value;
if ([type isEqualToString: @"animated"]) {
NSNumber *nodeTag = transformConfig[@"nodeTag"];
RCTAnimatedNode *node = self.parentNodes[nodeTag];
if (![node isKindOfClass:[RCTValueAnimatedNode class]]) {
continue;
}
RCTValueAnimatedNode *parentNode = (RCTValueAnimatedNode *)node;
value = parentNode.value;
value = @(parentNode.value);
} else {
value = [transformConfig[@"value"] floatValue];
}

if ([property isEqualToString:@"scale"]) {
transform = CATransform3DScale(transform, value, value, 1);

} else if ([property isEqualToString:@"scaleX"]) {
transform = CATransform3DScale(transform, value, 1, 1);

} else if ([property isEqualToString:@"scaleY"]) {
transform = CATransform3DScale(transform, 1, value, 1);

} else if ([property isEqualToString:@"translateX"]) {
transform = CATransform3DTranslate(transform, value, 0, 0);

} else if ([property isEqualToString:@"translateY"]) {
transform = CATransform3DTranslate(transform, 0, value, 0);

} else if ([property isEqualToString:@"rotate"]) {
transform = CATransform3DRotate(transform, value, 0, 0, 1);

} else if ([property isEqualToString:@"rotateX"]) {
transform = CATransform3DRotate(transform, value, 1, 0, 0);

} else if ([property isEqualToString:@"rotateY"]) {
transform = CATransform3DRotate(transform, value, 0, 1, 0);

} else if ([property isEqualToString:@"perspective"]) {
transform.m34 = 1.0 / -value;
value = transformConfig[@"value"];
}
[transform addObject:@{property: value}];
}

_propsDictionary[@"transform"] = [NSValue valueWithCATransform3D:transform];
_propsDictionary[@"transform"] = transform;
}

@end
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,6 @@
/* Begin PBXBuildFile section */
13E501CC1D07A644005F35D8 /* RCTAnimationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501B81D07A644005F35D8 /* RCTAnimationUtils.m */; };
13E501CF1D07A644005F35D8 /* RCTNativeAnimatedModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501BE1D07A644005F35D8 /* RCTNativeAnimatedModule.m */; };
13E501D41D07A644005F35D8 /* RCTViewPropertyMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501C81D07A644005F35D8 /* RCTViewPropertyMapper.m */; };
13E501E81D07A6C9005F35D8 /* RCTAdditionAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501D71D07A6C9005F35D8 /* RCTAdditionAnimatedNode.m */; };
13E501E91D07A6C9005F35D8 /* RCTAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501D91D07A6C9005F35D8 /* RCTAnimatedNode.m */; };
13E501EB1D07A6C9005F35D8 /* RCTInterpolationAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501DD1D07A6C9005F35D8 /* RCTInterpolationAnimatedNode.m */; };
Expand All@@ -22,7 +21,6 @@
19F00F221DC8847500113FEE /* RCTEventAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 19F00F211DC8847500113FEE /* RCTEventAnimation.m */; };
19F00F231DC8848E00113FEE /* RCTEventAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 19F00F211DC8847500113FEE /* RCTEventAnimation.m */; };
2D3B5EF21D9B0B3100451313 /* RCTAnimationUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501B81D07A644005F35D8 /* RCTAnimationUtils.m */; };
2D3B5EF31D9B0B3400451313 /* RCTViewPropertyMapper.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501C81D07A644005F35D8 /* RCTViewPropertyMapper.m */; };
2D3B5EF41D9B0B3700451313 /* RCTNativeAnimatedModule.m in Sources */ = {isa = PBXBuildFile; fileRef = 13E501BE1D07A644005F35D8 /* RCTNativeAnimatedModule.m */; };
2D3B5EF51D9B0B4800451313 /* RCTDivisionAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 5C9894941D999639008027DB /* RCTDivisionAnimatedNode.m */; };
2D3B5EF61D9B0B4800451313 /* RCTDiffClampAnimatedNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 193F64F31D776EC6004D1CAA /* RCTDiffClampAnimatedNode.m */; };
Expand DownExpand Up@@ -51,9 +49,7 @@
13E501B81D07A644005F35D8 /* RCTAnimationUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAnimationUtils.m; sourceTree = "<group>"; };
13E501BD1D07A644005F35D8 /* RCTNativeAnimatedModule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTNativeAnimatedModule.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
13E501BE1D07A644005F35D8 /* RCTNativeAnimatedModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTNativeAnimatedModule.m; sourceTree = "<group>"; };
13E501C71D07A644005F35D8 /* RCTViewPropertyMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTViewPropertyMapper.h; sourceTree = "<group>"; };
13E501C81D07A644005F35D8 /* RCTViewPropertyMapper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTViewPropertyMapper.m; sourceTree = "<group>"; };
13E501D61D07A6C9005F35D8 /* RCTAdditionAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = RCTAdditionAnimatedNode.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
13E501D61D07A6C9005F35D8 /* RCTAdditionAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAdditionAnimatedNode.h; sourceTree = "<group>"; };
13E501D71D07A6C9005F35D8 /* RCTAdditionAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAdditionAnimatedNode.m; sourceTree = "<group>"; };
13E501D81D07A6C9005F35D8 /* RCTAnimatedNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAnimatedNode.h; sourceTree = "<group>"; };
13E501D91D07A6C9005F35D8 /* RCTAnimatedNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAnimatedNode.m; sourceTree = "<group>"; };
Expand DownExpand Up@@ -130,8 +126,6 @@
children = (
13E501B71D07A644005F35D8 /* RCTAnimationUtils.h */,
13E501B81D07A644005F35D8 /* RCTAnimationUtils.m */,
13E501C71D07A644005F35D8 /* RCTViewPropertyMapper.h */,
13E501C81D07A644005F35D8 /* RCTViewPropertyMapper.m */,
13E501BD1D07A644005F35D8 /* RCTNativeAnimatedModule.h */,
13E501BE1D07A644005F35D8 /* RCTNativeAnimatedModule.m */,
94DA09161DC7971C00AEA8C9 /* RCTNativeAnimatedNodesManager.h */,
Expand DownExpand Up@@ -245,7 +239,6 @@
2D3B5EFF1D9B0B4800451313 /* RCTTransformAnimatedNode.m in Sources */,
2D3B5EFC1D9B0B4800451313 /* RCTMultiplicationAnimatedNode.m in Sources */,
2D3B5EFD1D9B0B4800451313 /* RCTPropsAnimatedNode.m in Sources */,
2D3B5EF31D9B0B3400451313 /* RCTViewPropertyMapper.m in Sources */,
944244D01DB962DA0032A02B /* RCTFrameAnimation.m in Sources */,
944244D11DB962DC0032A02B /* RCTSpringAnimation.m in Sources */,
9476E8EC1DC9232D005D5CD1 /* RCTNativeAnimatedNodesManager.m in Sources */,
Expand DownExpand Up@@ -273,7 +266,6 @@
13E501E81D07A6C9005F35D8 /* RCTAdditionAnimatedNode.m in Sources */,
5C9894951D999639008027DB /* RCTDivisionAnimatedNode.m in Sources */,
13E501EF1D07A6C9005F35D8 /* RCTTransformAnimatedNode.m in Sources */,
13E501D41D07A644005F35D8 /* RCTViewPropertyMapper.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
3 changes: 2 additions & 1 deletion Libraries/NativeAnimation/RCTNativeAnimatedModule.m
Original file line numberDiff line numberDiff line change
Expand Up@@ -121,8 +121,9 @@ - (void)setBridge:(RCTBridge *)bridge
RCT_EXPORT_METHOD(connectAnimatedNodeToView:(nonnull NSNumber *)nodeTag
viewTag:(nonnull NSNumber *)viewTag)
{
NSString *viewName = [self.bridge.uiManager viewNameForReactTag:viewTag];
[_operations addObject:^(RCTNativeAnimatedNodesManager *nodesManager) {
[nodesManager connectAnimatedNodeToView:nodeTag viewTag:viewTag];
[nodesManager connectAnimatedNodeToView:nodeTag viewTag:viewTag viewName:viewName];
}];
}

Expand Down
3 changes: 2 additions & 1 deletion Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,7 +32,8 @@
childTag:(nonnull NSNumber *)childTag;

- (void)connectAnimatedNodeToView:(nonnull NSNumber *)nodeTag
viewTag:(nonnull NSNumber *)viewTag;
viewTag:(nonnull NSNumber *)viewTag
viewName:(nonnull NSString *)viewName;

- (void)disconnectAnimatedNodeFromView:(nonnull NSNumber *)nodeTag
viewTag:(nonnull NSNumber *)viewTag;
Expand Down
Loading