yeet
This commit is contained in:
38
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTAnimationDriver.h
generated
vendored
Normal file
38
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTAnimationDriver.h
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTBridgeModule.h>
|
||||
|
||||
static CGFloat RCTSingleFrameInterval = (CGFloat)(1.0 / 60.0);
|
||||
|
||||
@class RCTValueAnimatedNode;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol RCTAnimationDriver <NSObject>
|
||||
|
||||
@property (nonatomic, readonly) NSNumber *animationId;
|
||||
@property (nonatomic, readonly) RCTValueAnimatedNode *valueNode;
|
||||
@property (nonatomic, readonly) BOOL animationHasBegun;
|
||||
@property (nonatomic, readonly) BOOL animationHasFinished;
|
||||
|
||||
- (instancetype)initWithId:(NSNumber *)animationId
|
||||
config:(NSDictionary *)config
|
||||
forNode:(RCTValueAnimatedNode *)valueNode
|
||||
callBack:(nullable RCTResponseSenderBlock)callback;
|
||||
|
||||
- (void)startAnimation;
|
||||
- (void)stepAnimationWithTime:(NSTimeInterval)currentTime;
|
||||
- (void)stopAnimation;
|
||||
- (void)resetAnimationConfig:(NSDictionary *)config;
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTAnimationDriver.h"
|
||||
|
||||
@interface RCTDecayAnimation : NSObject<RCTAnimationDriver>
|
||||
|
||||
@end
|
128
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.m
generated
vendored
Normal file
128
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.m
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTDecayAnimation.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import <React/RCTAnimationUtils.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
|
||||
@interface RCTDecayAnimation ()
|
||||
|
||||
@property (nonatomic, strong) NSNumber *animationId;
|
||||
@property (nonatomic, strong) RCTValueAnimatedNode *valueNode;
|
||||
@property (nonatomic, assign) BOOL animationHasBegun;
|
||||
@property (nonatomic, assign) BOOL animationHasFinished;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTDecayAnimation
|
||||
{
|
||||
CGFloat _velocity;
|
||||
CGFloat _deceleration;
|
||||
NSTimeInterval _frameStartTime;
|
||||
CGFloat _fromValue;
|
||||
CGFloat _lastValue;
|
||||
NSInteger _iterations;
|
||||
NSInteger _currentLoop;
|
||||
RCTResponseSenderBlock _callback;
|
||||
}
|
||||
|
||||
- (instancetype)initWithId:(NSNumber *)animationId
|
||||
config:(NSDictionary *)config
|
||||
forNode:(RCTValueAnimatedNode *)valueNode
|
||||
callBack:(nullable RCTResponseSenderBlock)callback
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_callback = [callback copy];
|
||||
_animationId = animationId;
|
||||
_valueNode = valueNode;
|
||||
_fromValue = 0;
|
||||
_lastValue = 0;
|
||||
_velocity = [RCTConvert CGFloat:config[@"velocity"]]; // initial velocity
|
||||
[self resetAnimationConfig:config];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)resetAnimationConfig:(NSDictionary *)config
|
||||
{
|
||||
NSNumber *iterations = [RCTConvert NSNumber:config[@"iterations"]] ?: @1;
|
||||
_fromValue = _lastValue;
|
||||
_deceleration = [RCTConvert CGFloat:config[@"deceleration"]];
|
||||
_iterations = iterations.integerValue;
|
||||
_currentLoop = 1;
|
||||
_animationHasFinished = iterations.integerValue == 0;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
- (void)startAnimation
|
||||
{
|
||||
_frameStartTime = -1;
|
||||
_animationHasBegun = YES;
|
||||
}
|
||||
|
||||
- (void)stopAnimation
|
||||
{
|
||||
_valueNode = nil;
|
||||
if (_callback) {
|
||||
_callback(@[@{
|
||||
@"finished": @(_animationHasFinished)
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stepAnimationWithTime:(NSTimeInterval)currentTime
|
||||
{
|
||||
if (!_animationHasBegun || _animationHasFinished) {
|
||||
// Animation has not begun or animation has already finished.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_frameStartTime == -1) {
|
||||
// Since this is the first animation step, consider the start to be on the previous frame.
|
||||
_frameStartTime = currentTime - RCTSingleFrameInterval;
|
||||
if (_fromValue == _lastValue) {
|
||||
// First iteration, assign _fromValue based on _valueNode.
|
||||
_fromValue = _valueNode.value;
|
||||
} else {
|
||||
// Not the first iteration, reset _valueNode based on _fromValue.
|
||||
[self updateValue:_fromValue];
|
||||
}
|
||||
_lastValue = _valueNode.value;
|
||||
}
|
||||
|
||||
CGFloat value = _fromValue +
|
||||
(_velocity / (1 - _deceleration)) *
|
||||
(1 - exp(-(1 - _deceleration) * (currentTime - _frameStartTime) * 1000.0 / RCTAnimationDragCoefficient()));
|
||||
|
||||
[self updateValue:value];
|
||||
|
||||
if (fabs(_lastValue - value) < 0.1) {
|
||||
if (_iterations == -1 || _currentLoop < _iterations) {
|
||||
// Set _frameStartTime to -1 to reset instance variables on the next runAnimationStep.
|
||||
_frameStartTime = -1;
|
||||
_currentLoop++;
|
||||
} else {
|
||||
_animationHasFinished = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
_lastValue = value;
|
||||
}
|
||||
|
||||
- (void)updateValue:(CGFloat)outputValue
|
||||
{
|
||||
_valueNode.value = outputValue;
|
||||
[_valueNode setNeedsUpdate];
|
||||
}
|
||||
|
||||
@end
|
21
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTEventAnimation.h
generated
vendored
Normal file
21
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTEventAnimation.h
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTEventAnimation : NSObject
|
||||
|
||||
@property (nonatomic, readonly, weak) RCTValueAnimatedNode *valueNode;
|
||||
|
||||
- (instancetype)initWithEventPath:(NSArray<NSString *> *)eventPath
|
||||
valueNode:(RCTValueAnimatedNode *)valueNode;
|
||||
|
||||
- (void)updateWithEvent:(id<RCTEvent>)event;
|
||||
|
||||
@end
|
38
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTEventAnimation.m
generated
vendored
Normal file
38
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTEventAnimation.m
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTEventAnimation.h>
|
||||
|
||||
@implementation RCTEventAnimation
|
||||
{
|
||||
NSArray<NSString *> *_eventPath;
|
||||
}
|
||||
|
||||
- (instancetype)initWithEventPath:(NSArray<NSString *> *)eventPath
|
||||
valueNode:(RCTValueAnimatedNode *)valueNode
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_eventPath = eventPath;
|
||||
_valueNode = valueNode;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateWithEvent:(id<RCTEvent>)event
|
||||
{
|
||||
NSArray *args = event.arguments;
|
||||
// Supported events args are in the following order: viewTag, eventName, eventData.
|
||||
id currentValue = args[2];
|
||||
for (NSString *key in _eventPath) {
|
||||
currentValue = [currentValue valueForKey:key];
|
||||
}
|
||||
|
||||
_valueNode.value = ((NSNumber *)currentValue).doubleValue;
|
||||
[_valueNode setNeedsUpdate];
|
||||
}
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTAnimationDriver.h"
|
||||
|
||||
@interface RCTFrameAnimation : NSObject<RCTAnimationDriver>
|
||||
|
||||
@end
|
158
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.m
generated
vendored
Normal file
158
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.m
generated
vendored
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTFrameAnimation.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
#import <React/RCTAnimationUtils.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
|
||||
@interface RCTFrameAnimation ()
|
||||
|
||||
@property (nonatomic, strong) NSNumber *animationId;
|
||||
@property (nonatomic, strong) RCTValueAnimatedNode *valueNode;
|
||||
@property (nonatomic, assign) BOOL animationHasBegun;
|
||||
@property (nonatomic, assign) BOOL animationHasFinished;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTFrameAnimation
|
||||
{
|
||||
NSArray<NSNumber *> *_frames;
|
||||
CGFloat _toValue;
|
||||
CGFloat _fromValue;
|
||||
CGFloat _lastPosition;
|
||||
NSTimeInterval _animationStartTime;
|
||||
NSTimeInterval _animationCurrentTime;
|
||||
RCTResponseSenderBlock _callback;
|
||||
NSInteger _iterations;
|
||||
NSInteger _currentLoop;
|
||||
}
|
||||
|
||||
- (instancetype)initWithId:(NSNumber *)animationId
|
||||
config:(NSDictionary *)config
|
||||
forNode:(RCTValueAnimatedNode *)valueNode
|
||||
callBack:(nullable RCTResponseSenderBlock)callback
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_animationId = animationId;
|
||||
_lastPosition = _fromValue = valueNode.value;
|
||||
_valueNode = valueNode;
|
||||
_callback = [callback copy];
|
||||
[self resetAnimationConfig:config];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)resetAnimationConfig:(NSDictionary *)config
|
||||
{
|
||||
NSNumber *toValue = [RCTConvert NSNumber:config[@"toValue"]] ?: @1;
|
||||
NSArray<NSNumber *> *frames = [RCTConvert NSNumberArray:config[@"frames"]];
|
||||
NSNumber *iterations = [RCTConvert NSNumber:config[@"iterations"]] ?: @1;
|
||||
|
||||
_fromValue = _lastPosition;
|
||||
_toValue = toValue.floatValue;
|
||||
_frames = [frames copy];
|
||||
_animationStartTime = _animationCurrentTime = -1;
|
||||
_animationHasFinished = iterations.integerValue == 0;
|
||||
_iterations = iterations.integerValue;
|
||||
_currentLoop = 1;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
- (void)startAnimation
|
||||
{
|
||||
_animationStartTime = _animationCurrentTime = -1;
|
||||
_animationHasBegun = YES;
|
||||
}
|
||||
|
||||
- (void)stopAnimation
|
||||
{
|
||||
_valueNode = nil;
|
||||
if (_callback) {
|
||||
_callback(@[@{
|
||||
@"finished": @(_animationHasFinished)
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stepAnimationWithTime:(NSTimeInterval)currentTime
|
||||
{
|
||||
if (!_animationHasBegun || _animationHasFinished || _frames.count == 0) {
|
||||
// Animation has not begun or animation has already finished.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_animationStartTime == -1) {
|
||||
_animationStartTime = _animationCurrentTime = currentTime;
|
||||
}
|
||||
|
||||
_animationCurrentTime = currentTime;
|
||||
NSTimeInterval currentDuration = (_animationCurrentTime - _animationStartTime) / RCTAnimationDragCoefficient();
|
||||
|
||||
// Determine how many frames have passed since last update.
|
||||
// Get index of frames that surround the current interval
|
||||
NSUInteger startIndex = floor(currentDuration / RCTSingleFrameInterval);
|
||||
NSUInteger nextIndex = startIndex + 1;
|
||||
|
||||
if (nextIndex >= _frames.count) {
|
||||
if (_iterations == -1 || _currentLoop < _iterations) {
|
||||
// Looping, reset to the first frame value.
|
||||
_animationStartTime = currentTime;
|
||||
_currentLoop++;
|
||||
NSNumber *firstValue = _frames.firstObject;
|
||||
[self updateOutputWithFrameOutput:firstValue.doubleValue];
|
||||
} else {
|
||||
_animationHasFinished = YES;
|
||||
// We are at the end of the animation
|
||||
// Update value and flag animation has ended.
|
||||
NSNumber *finalValue = _frames.lastObject;
|
||||
[self updateOutputWithFrameOutput:finalValue.doubleValue];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Do a linear remap of the two frames to safeguard against variable framerates
|
||||
NSNumber *fromFrameValue = _frames[startIndex];
|
||||
NSNumber *toFrameValue = _frames[nextIndex];
|
||||
NSTimeInterval fromInterval = startIndex * RCTSingleFrameInterval;
|
||||
NSTimeInterval toInterval = nextIndex * RCTSingleFrameInterval;
|
||||
|
||||
// Interpolate between the individual frames to ensure the animations are
|
||||
//smooth and of the proper duration regardless of the framerate.
|
||||
CGFloat frameOutput = RCTInterpolateValue(currentDuration,
|
||||
fromInterval,
|
||||
toInterval,
|
||||
fromFrameValue.doubleValue,
|
||||
toFrameValue.doubleValue,
|
||||
EXTRAPOLATE_TYPE_EXTEND,
|
||||
EXTRAPOLATE_TYPE_EXTEND);
|
||||
|
||||
[self updateOutputWithFrameOutput:frameOutput];
|
||||
}
|
||||
|
||||
- (void)updateOutputWithFrameOutput:(CGFloat)frameOutput
|
||||
{
|
||||
CGFloat outputValue = RCTInterpolateValue(frameOutput,
|
||||
0,
|
||||
1,
|
||||
_fromValue,
|
||||
_toValue,
|
||||
EXTRAPOLATE_TYPE_EXTEND,
|
||||
EXTRAPOLATE_TYPE_EXTEND);
|
||||
|
||||
_lastPosition = outputValue;
|
||||
_valueNode.value = outputValue;
|
||||
[_valueNode setNeedsUpdate];
|
||||
}
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTAnimationDriver.h"
|
||||
|
||||
@interface RCTSpringAnimation : NSObject<RCTAnimationDriver>
|
||||
|
||||
@end
|
214
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.m
generated
vendored
Normal file
214
node_modules/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.m
generated
vendored
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTSpringAnimation.h>
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
#import <React/RCTAnimationUtils.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
|
||||
@interface RCTSpringAnimation ()
|
||||
|
||||
@property (nonatomic, strong) NSNumber *animationId;
|
||||
@property (nonatomic, strong) RCTValueAnimatedNode *valueNode;
|
||||
@property (nonatomic, assign) BOOL animationHasBegun;
|
||||
@property (nonatomic, assign) BOOL animationHasFinished;
|
||||
|
||||
@end
|
||||
|
||||
const NSTimeInterval MAX_DELTA_TIME = 0.064;
|
||||
|
||||
@implementation RCTSpringAnimation
|
||||
{
|
||||
CGFloat _toValue;
|
||||
CGFloat _fromValue;
|
||||
BOOL _overshootClamping;
|
||||
CGFloat _restDisplacementThreshold;
|
||||
CGFloat _restSpeedThreshold;
|
||||
CGFloat _stiffness;
|
||||
CGFloat _damping;
|
||||
CGFloat _mass;
|
||||
CGFloat _initialVelocity;
|
||||
NSTimeInterval _animationStartTime;
|
||||
NSTimeInterval _animationCurrentTime;
|
||||
RCTResponseSenderBlock _callback;
|
||||
|
||||
CGFloat _lastPosition;
|
||||
CGFloat _lastVelocity;
|
||||
|
||||
NSInteger _iterations;
|
||||
NSInteger _currentLoop;
|
||||
|
||||
NSTimeInterval _t; // Current time (startTime + dt)
|
||||
}
|
||||
|
||||
- (instancetype)initWithId:(NSNumber *)animationId
|
||||
config:(NSDictionary *)config
|
||||
forNode:(RCTValueAnimatedNode *)valueNode
|
||||
callBack:(nullable RCTResponseSenderBlock)callback
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_animationId = animationId;
|
||||
_lastPosition = valueNode.value;
|
||||
_valueNode = valueNode;
|
||||
_lastVelocity = [RCTConvert CGFloat:config[@"initialVelocity"]];
|
||||
_callback = [callback copy];
|
||||
[self resetAnimationConfig:config];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)resetAnimationConfig:(NSDictionary *)config
|
||||
{
|
||||
NSNumber *iterations = [RCTConvert NSNumber:config[@"iterations"]] ?: @1;
|
||||
_toValue = [RCTConvert CGFloat:config[@"toValue"]];
|
||||
_overshootClamping = [RCTConvert BOOL:config[@"overshootClamping"]];
|
||||
_restDisplacementThreshold = [RCTConvert CGFloat:config[@"restDisplacementThreshold"]];
|
||||
_restSpeedThreshold = [RCTConvert CGFloat:config[@"restSpeedThreshold"]];
|
||||
_stiffness = [RCTConvert CGFloat:config[@"stiffness"]];
|
||||
_damping = [RCTConvert CGFloat:config[@"damping"]];
|
||||
_mass = [RCTConvert CGFloat:config[@"mass"]];
|
||||
_initialVelocity = _lastVelocity;
|
||||
_fromValue = _lastPosition;
|
||||
_fromValue = _lastPosition;
|
||||
_lastVelocity = _initialVelocity;
|
||||
_animationHasFinished = iterations.integerValue == 0;
|
||||
_iterations = iterations.integerValue;
|
||||
_currentLoop = 1;
|
||||
_animationStartTime = _animationCurrentTime = -1;
|
||||
_animationHasBegun = YES;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
- (void)startAnimation
|
||||
{
|
||||
_animationStartTime = _animationCurrentTime = -1;
|
||||
_animationHasBegun = YES;
|
||||
}
|
||||
|
||||
- (void)stopAnimation
|
||||
{
|
||||
_valueNode = nil;
|
||||
if (_callback) {
|
||||
_callback(@[@{
|
||||
@"finished": @(_animationHasFinished)
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stepAnimationWithTime:(NSTimeInterval)currentTime
|
||||
{
|
||||
if (!_animationHasBegun || _animationHasFinished) {
|
||||
// Animation has not begun or animation has already finished.
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate delta time
|
||||
if(_animationStartTime == -1) {
|
||||
_t = 0.0;
|
||||
_animationStartTime = currentTime;
|
||||
} else {
|
||||
// Handle frame drops, and only advance dt by a max of MAX_DELTA_TIME
|
||||
NSTimeInterval deltaTime = MIN(MAX_DELTA_TIME, currentTime - _animationCurrentTime);
|
||||
_t = _t + deltaTime / RCTAnimationDragCoefficient();
|
||||
}
|
||||
|
||||
// store the timestamp
|
||||
_animationCurrentTime = currentTime;
|
||||
|
||||
CGFloat c = _damping;
|
||||
CGFloat m = _mass;
|
||||
CGFloat k = _stiffness;
|
||||
CGFloat v0 = -_initialVelocity;
|
||||
|
||||
CGFloat zeta = c / (2 * sqrtf(k * m));
|
||||
CGFloat omega0 = sqrtf(k / m);
|
||||
CGFloat omega1 = omega0 * sqrtf(1.0 - (zeta * zeta));
|
||||
CGFloat x0 = _toValue - _fromValue;
|
||||
|
||||
CGFloat position;
|
||||
CGFloat velocity;
|
||||
if (zeta < 1) {
|
||||
// Under damped
|
||||
CGFloat envelope = expf(-zeta * omega0 * _t);
|
||||
position =
|
||||
_toValue -
|
||||
envelope *
|
||||
((v0 + zeta * omega0 * x0) / omega1 * sinf(omega1 * _t) +
|
||||
x0 * cosf(omega1 * _t));
|
||||
// This looks crazy -- it's actually just the derivative of the
|
||||
// oscillation function
|
||||
velocity =
|
||||
zeta *
|
||||
omega0 *
|
||||
envelope *
|
||||
(sinf(omega1 * _t) * (v0 + zeta * omega0 * x0) / omega1 +
|
||||
x0 * cosf(omega1 * _t)) -
|
||||
envelope *
|
||||
(cosf(omega1 * _t) * (v0 + zeta * omega0 * x0) -
|
||||
omega1 * x0 * sinf(omega1 * _t));
|
||||
} else {
|
||||
CGFloat envelope = expf(-omega0 * _t);
|
||||
position = _toValue - envelope * (x0 + (v0 + omega0 * x0) * _t);
|
||||
velocity =
|
||||
envelope * (v0 * (_t * omega0 - 1) + _t * x0 * (omega0 * omega0));
|
||||
}
|
||||
|
||||
_lastPosition = position;
|
||||
_lastVelocity = velocity;
|
||||
|
||||
[self onUpdate:position];
|
||||
|
||||
// Conditions for stopping the spring animation
|
||||
BOOL isOvershooting = NO;
|
||||
if (_overshootClamping && _stiffness != 0) {
|
||||
if (_fromValue < _toValue) {
|
||||
isOvershooting = position > _toValue;
|
||||
} else {
|
||||
isOvershooting = position < _toValue;
|
||||
}
|
||||
}
|
||||
BOOL isVelocity = ABS(velocity) <= _restSpeedThreshold;
|
||||
BOOL isDisplacement = YES;
|
||||
if (_stiffness != 0) {
|
||||
isDisplacement = ABS(_toValue - position) <= _restDisplacementThreshold;
|
||||
}
|
||||
|
||||
if (isOvershooting || (isVelocity && isDisplacement)) {
|
||||
if (_stiffness != 0) {
|
||||
// Ensure that we end up with a round value
|
||||
if (_animationHasFinished) {
|
||||
return;
|
||||
}
|
||||
[self onUpdate:_toValue];
|
||||
}
|
||||
|
||||
if (_iterations == -1 || _currentLoop < _iterations) {
|
||||
_lastPosition = _fromValue;
|
||||
_lastVelocity = _initialVelocity;
|
||||
// Set _animationStartTime to -1 to reset instance variables on the next animation step.
|
||||
_animationStartTime = -1;
|
||||
_currentLoop++;
|
||||
[self onUpdate:_fromValue];
|
||||
} else {
|
||||
_animationHasFinished = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onUpdate:(CGFloat)outputValue
|
||||
{
|
||||
_valueNode.value = outputValue;
|
||||
[_valueNode setNeedsUpdate];
|
||||
}
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTAdditionAnimatedNode.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTAdditionAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTAdditionAnimatedNode : RCTValueAnimatedNode
|
||||
|
||||
@end
|
26
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTAdditionAnimatedNode.m
generated
vendored
Normal file
26
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTAdditionAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTAdditionAnimatedNode.h>
|
||||
|
||||
@implementation RCTAdditionAnimatedNode
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
NSArray<NSNumber *> *inputNodes = self.config[@"input"];
|
||||
if (inputNodes.count > 1) {
|
||||
RCTValueAnimatedNode *parent1 = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNodes[0]];
|
||||
RCTValueAnimatedNode *parent2 = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNodes[1]];
|
||||
if ([parent1 isKindOfClass:[RCTValueAnimatedNode class]] &&
|
||||
[parent2 isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
self.value = parent1.value + parent2.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
51
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h
generated
vendored
Normal file
51
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@class RCTNativeAnimatedNodesManager;
|
||||
|
||||
@interface RCTAnimatedNode : NSObject
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
@property (nonatomic, readonly) NSNumber *nodeTag;
|
||||
@property (nonatomic, weak) RCTNativeAnimatedNodesManager *manager;
|
||||
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id> *config;
|
||||
|
||||
@property (nonatomic, copy, readonly) NSMapTable<NSNumber *, RCTAnimatedNode *> *childNodes;
|
||||
@property (nonatomic, copy, readonly) NSMapTable<NSNumber *, RCTAnimatedNode *> *parentNodes;
|
||||
|
||||
@property (nonatomic, readonly) BOOL needsUpdate;
|
||||
|
||||
-(BOOL)isManagedByFabric;
|
||||
|
||||
/**
|
||||
* Marks a node and its children as needing update.
|
||||
*/
|
||||
- (void)setNeedsUpdate NS_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* The node will update its value if necessary and only after its parents have updated.
|
||||
*/
|
||||
- (void)updateNodeIfNecessary NS_REQUIRES_SUPER;
|
||||
|
||||
/**
|
||||
* Where the actual update code lives. Called internally from updateNodeIfNecessary
|
||||
*/
|
||||
- (void)performUpdate NS_REQUIRES_SUPER;
|
||||
|
||||
- (void)addChild:(RCTAnimatedNode *)child NS_REQUIRES_SUPER;
|
||||
- (void)removeChild:(RCTAnimatedNode *)child NS_REQUIRES_SUPER;
|
||||
|
||||
- (void)onAttachedToNode:(RCTAnimatedNode *)parent NS_REQUIRES_SUPER;
|
||||
- (void)onDetachedFromNode:(RCTAnimatedNode *)parent NS_REQUIRES_SUPER;
|
||||
|
||||
- (void)detachNode NS_REQUIRES_SUPER;
|
||||
|
||||
@end
|
128
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.m
generated
vendored
Normal file
128
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTAnimatedNode.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
@implementation RCTAnimatedNode
|
||||
{
|
||||
NSMapTable<NSNumber *, RCTAnimatedNode *> *_childNodes;
|
||||
NSMapTable<NSNumber *, RCTAnimatedNode *> *_parentNodes;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_nodeTag = tag;
|
||||
_config = [config copy];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
||||
|
||||
- (NSMapTable<NSNumber *, RCTAnimatedNode *> *)childNodes
|
||||
{
|
||||
return _childNodes;
|
||||
}
|
||||
|
||||
- (NSMapTable<NSNumber *, RCTAnimatedNode *> *)parentNodes
|
||||
{
|
||||
return _parentNodes;
|
||||
}
|
||||
|
||||
- (void)addChild:(RCTAnimatedNode *)child
|
||||
{
|
||||
if (!_childNodes) {
|
||||
_childNodes = [NSMapTable strongToWeakObjectsMapTable];
|
||||
}
|
||||
if (child) {
|
||||
[_childNodes setObject:child forKey:child.nodeTag];
|
||||
[child onAttachedToNode:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeChild:(RCTAnimatedNode *)child
|
||||
{
|
||||
if (!_childNodes) {
|
||||
return;
|
||||
}
|
||||
if (child) {
|
||||
[_childNodes removeObjectForKey:child.nodeTag];
|
||||
[child onDetachedFromNode:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onAttachedToNode:(RCTAnimatedNode *)parent
|
||||
{
|
||||
if (!_parentNodes) {
|
||||
_parentNodes = [NSMapTable strongToWeakObjectsMapTable];
|
||||
}
|
||||
if (parent) {
|
||||
[_parentNodes setObject:parent forKey:parent.nodeTag];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onDetachedFromNode:(RCTAnimatedNode *)parent
|
||||
{
|
||||
if (!_parentNodes) {
|
||||
return;
|
||||
}
|
||||
if (parent) {
|
||||
[_parentNodes removeObjectForKey:parent.nodeTag];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)detachNode
|
||||
{
|
||||
for (RCTAnimatedNode *parent in _parentNodes.objectEnumerator) {
|
||||
[parent removeChild:self];
|
||||
}
|
||||
for (RCTAnimatedNode *child in _childNodes.objectEnumerator) {
|
||||
[self removeChild:child];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setNeedsUpdate
|
||||
{
|
||||
_needsUpdate = YES;
|
||||
for (RCTAnimatedNode *child in _childNodes.objectEnumerator) {
|
||||
[child setNeedsUpdate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)updateNodeIfNecessary
|
||||
{
|
||||
if (_needsUpdate) {
|
||||
for (RCTAnimatedNode *parent in _parentNodes.objectEnumerator) {
|
||||
[parent updateNodeIfNecessary];
|
||||
}
|
||||
[self performUpdate];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
_needsUpdate = NO;
|
||||
// To be overridden by subclasses
|
||||
// This method is called on a node only if it has been marked for update
|
||||
// during the current update loop
|
||||
}
|
||||
|
||||
- (BOOL)isManagedByFabric
|
||||
{
|
||||
for (RCTAnimatedNode *child in _childNodes.objectEnumerator) {
|
||||
if ([child isManagedByFabric]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTDiffClampAnimatedNode.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTDiffClampAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTDiffClampAnimatedNode : RCTValueAnimatedNode
|
||||
|
||||
@end
|
61
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTDiffClampAnimatedNode.m
generated
vendored
Normal file
61
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTDiffClampAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTDiffClampAnimatedNode.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
@implementation RCTDiffClampAnimatedNode
|
||||
{
|
||||
NSNumber *_inputNodeTag;
|
||||
CGFloat _min;
|
||||
CGFloat _max;
|
||||
CGFloat _lastValue;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
if (self = [super initWithTag:tag config:config]) {
|
||||
_inputNodeTag = config[@"input"];
|
||||
_min = [config[@"min"] floatValue];
|
||||
_max = [config[@"max"] floatValue];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)onAttachedToNode:(RCTAnimatedNode *)parent
|
||||
{
|
||||
[super onAttachedToNode:parent];
|
||||
|
||||
self.value = _lastValue = [self inputNodeValue];
|
||||
}
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
|
||||
CGFloat value = [self inputNodeValue];
|
||||
|
||||
CGFloat diff = value - _lastValue;
|
||||
_lastValue = value;
|
||||
self.value = MIN(MAX(self.value + diff, _min), _max);
|
||||
}
|
||||
|
||||
- (CGFloat)inputNodeValue
|
||||
{
|
||||
RCTValueAnimatedNode *inputNode = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:_inputNodeTag];
|
||||
if (![inputNode isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
RCTLogError(@"Illegal node ID set as an input for Animated.DiffClamp node");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return inputNode.value;
|
||||
}
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTDivisionAnimatedNode : RCTValueAnimatedNode
|
||||
|
||||
@end
|
33
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.m
generated
vendored
Normal file
33
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTDivisionAnimatedNode.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
@implementation RCTDivisionAnimatedNode
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
|
||||
NSArray<NSNumber *> *inputNodes = self.config[@"input"];
|
||||
if (inputNodes.count > 1) {
|
||||
RCTValueAnimatedNode *parent1 = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNodes[0]];
|
||||
RCTValueAnimatedNode *parent2 = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNodes[1]];
|
||||
if ([parent1 isKindOfClass:[RCTValueAnimatedNode class]] &&
|
||||
[parent2 isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
if (parent2.value == 0) {
|
||||
RCTLogError(@"Detected a division by zero in Animated.divide node");
|
||||
return;
|
||||
}
|
||||
self.value = parent1.value / parent2.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTInterpolationAnimatedNode.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTInterpolationAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTInterpolationAnimatedNode : RCTValueAnimatedNode
|
||||
|
||||
@end
|
171
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTInterpolationAnimatedNode.m
generated
vendored
Normal file
171
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTInterpolationAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTInterpolationAnimatedNode.h>
|
||||
|
||||
#import <React/RCTAnimationUtils.h>
|
||||
|
||||
static NSRegularExpression *regex;
|
||||
|
||||
@implementation RCTInterpolationAnimatedNode
|
||||
{
|
||||
__weak RCTValueAnimatedNode *_parentNode;
|
||||
NSArray<NSNumber *> *_inputRange;
|
||||
NSArray<NSNumber *> *_outputRange;
|
||||
NSArray<NSArray<NSNumber *> *> *_outputs;
|
||||
NSArray<NSString *> *_soutputRange;
|
||||
NSString *_extrapolateLeft;
|
||||
NSString *_extrapolateRight;
|
||||
NSUInteger _numVals;
|
||||
bool _hasStringOutput;
|
||||
bool _shouldRound;
|
||||
NSArray<NSTextCheckingResult*> *_matches;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
NSString *fpRegex = @"[+-]?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?";
|
||||
regex = [NSRegularExpression regularExpressionWithPattern:fpRegex options:NSRegularExpressionCaseInsensitive error:nil];
|
||||
});
|
||||
if ((self = [super initWithTag:tag config:config])) {
|
||||
_inputRange = [config[@"inputRange"] copy];
|
||||
NSMutableArray *outputRange = [NSMutableArray array];
|
||||
NSMutableArray *soutputRange = [NSMutableArray array];
|
||||
NSMutableArray<NSMutableArray<NSNumber *> *> *_outputRanges = [NSMutableArray array];
|
||||
|
||||
_hasStringOutput = NO;
|
||||
for (id value in config[@"outputRange"]) {
|
||||
if ([value isKindOfClass:[NSNumber class]]) {
|
||||
[outputRange addObject:value];
|
||||
} else if ([value isKindOfClass:[NSString class]]) {
|
||||
/**
|
||||
* Supports string shapes by extracting numbers so new values can be computed,
|
||||
* and recombines those values into new strings of the same shape. Supports
|
||||
* things like:
|
||||
*
|
||||
* rgba(123, 42, 99, 0.36) // colors
|
||||
* -45deg // values with units
|
||||
*/
|
||||
NSMutableArray *output = [NSMutableArray array];
|
||||
[_outputRanges addObject:output];
|
||||
[soutputRange addObject:value];
|
||||
|
||||
_matches = [regex matchesInString:value options:0 range:NSMakeRange(0, [value length])];
|
||||
for (NSTextCheckingResult *match in _matches) {
|
||||
NSString* strNumber = [value substringWithRange:match.range];
|
||||
[output addObject:[NSNumber numberWithDouble:strNumber.doubleValue]];
|
||||
}
|
||||
|
||||
_hasStringOutput = YES;
|
||||
[outputRange addObject:[output objectAtIndex:0]];
|
||||
}
|
||||
}
|
||||
if (_hasStringOutput) {
|
||||
// ['rgba(0, 100, 200, 0)', 'rgba(50, 150, 250, 0.5)']
|
||||
// ->
|
||||
// [
|
||||
// [0, 50],
|
||||
// [100, 150],
|
||||
// [200, 250],
|
||||
// [0, 0.5],
|
||||
// ]
|
||||
_numVals = [_matches count];
|
||||
NSString *value = [soutputRange objectAtIndex:0];
|
||||
_shouldRound = [value containsString:@"rgb"];
|
||||
_matches = [regex matchesInString:value options:0 range:NSMakeRange(0, [value length])];
|
||||
NSMutableArray<NSMutableArray<NSNumber *> *> *outputs = [NSMutableArray arrayWithCapacity:_numVals];
|
||||
NSUInteger size = [soutputRange count];
|
||||
for (NSUInteger j = 0; j < _numVals; j++) {
|
||||
NSMutableArray *output = [NSMutableArray arrayWithCapacity:size];
|
||||
[outputs addObject:output];
|
||||
for (int i = 0; i < size; i++) {
|
||||
[output addObject:[[_outputRanges objectAtIndex:i] objectAtIndex:j]];
|
||||
}
|
||||
}
|
||||
_outputs = [outputs copy];
|
||||
}
|
||||
_outputRange = [outputRange copy];
|
||||
_soutputRange = [soutputRange copy];
|
||||
_extrapolateLeft = config[@"extrapolateLeft"];
|
||||
_extrapolateRight = config[@"extrapolateRight"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)onAttachedToNode:(RCTAnimatedNode *)parent
|
||||
{
|
||||
[super onAttachedToNode:parent];
|
||||
if ([parent isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
_parentNode = (RCTValueAnimatedNode *)parent;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onDetachedFromNode:(RCTAnimatedNode *)parent
|
||||
{
|
||||
[super onDetachedFromNode:parent];
|
||||
if (_parentNode == parent) {
|
||||
_parentNode = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
if (!_parentNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGFloat inputValue = _parentNode.value;
|
||||
|
||||
CGFloat interpolated = RCTInterpolateValueInRange(inputValue,
|
||||
_inputRange,
|
||||
_outputRange,
|
||||
_extrapolateLeft,
|
||||
_extrapolateRight);
|
||||
self.value = interpolated;
|
||||
if (_hasStringOutput) {
|
||||
// 'rgba(0, 100, 200, 0)'
|
||||
// ->
|
||||
// 'rgba(${interpolations[0](input)}, ${interpolations[1](input)}, ...'
|
||||
if (_numVals > 1) {
|
||||
NSString *text = _soutputRange[0];
|
||||
NSMutableString *formattedText = [NSMutableString stringWithString:text];
|
||||
NSUInteger i = _numVals;
|
||||
for (NSTextCheckingResult *match in [_matches reverseObjectEnumerator]) {
|
||||
CGFloat val = RCTInterpolateValueInRange(inputValue,
|
||||
_inputRange,
|
||||
_outputs[--i],
|
||||
_extrapolateLeft,
|
||||
_extrapolateRight);
|
||||
NSString *str;
|
||||
if (_shouldRound) {
|
||||
// rgba requires that the r,g,b are integers.... so we want to round them, but we *dont* want to
|
||||
// round the opacity (4th column).
|
||||
bool isAlpha = i == 3;
|
||||
CGFloat rounded = isAlpha ? round(val * 1000) / 1000 : round(val);
|
||||
str = isAlpha ? [NSString stringWithFormat:@"%1.3f", rounded] : [NSString stringWithFormat:@"%1.0f", rounded];
|
||||
} else {
|
||||
NSNumber *numberValue = [NSNumber numberWithDouble:val];
|
||||
str = [numberValue stringValue];
|
||||
}
|
||||
|
||||
[formattedText replaceCharactersInRange:[match range] withString:str];
|
||||
}
|
||||
self.animatedObject = formattedText;
|
||||
} else {
|
||||
self.animatedObject = [regex stringByReplacingMatchesInString:_soutputRange[0]
|
||||
options:0
|
||||
range:NSMakeRange(0, _soutputRange[0].length)
|
||||
withTemplate:[NSString stringWithFormat:@"%1f", interpolated]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTModuloAnimatedNode.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTModuloAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTModuloAnimatedNode : RCTValueAnimatedNode
|
||||
|
||||
@end
|
22
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTModuloAnimatedNode.m
generated
vendored
Normal file
22
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTModuloAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTModuloAnimatedNode.h>
|
||||
|
||||
@implementation RCTModuloAnimatedNode
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
NSNumber *inputNode = self.config[@"input"];
|
||||
NSNumber *modulus = self.config[@"modulus"];
|
||||
RCTValueAnimatedNode *parent = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNode];
|
||||
const float m = modulus.floatValue;
|
||||
self.value = fmodf(fmodf(parent.value, m) + m, m);
|
||||
}
|
||||
|
||||
@end
|
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTMultiplicationAnimatedNode.h
generated
vendored
Normal file
12
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTMultiplicationAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTMultiplicationAnimatedNode : RCTValueAnimatedNode
|
||||
|
||||
@end
|
27
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTMultiplicationAnimatedNode.m
generated
vendored
Normal file
27
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTMultiplicationAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTMultiplicationAnimatedNode.h>
|
||||
|
||||
@implementation RCTMultiplicationAnimatedNode
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
|
||||
NSArray<NSNumber *> *inputNodes = self.config[@"input"];
|
||||
if (inputNodes.count > 1) {
|
||||
RCTValueAnimatedNode *parent1 = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNodes[0]];
|
||||
RCTValueAnimatedNode *parent2 = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNodes[1]];
|
||||
if ([parent1 isKindOfClass:[RCTValueAnimatedNode class]] &&
|
||||
[parent2 isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
self.value = parent1.value * parent2.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
23
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.h
generated
vendored
Normal file
23
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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"
|
||||
|
||||
@class RCTBridge;
|
||||
@class RCTViewPropertyMapper;
|
||||
|
||||
@interface RCTPropsAnimatedNode : RCTAnimatedNode
|
||||
|
||||
- (void)connectToView:(NSNumber *)viewTag
|
||||
viewName:(NSString *)viewName
|
||||
bridge:(RCTBridge *)bridge;
|
||||
|
||||
- (void)disconnectFromView:(NSNumber *)viewTag;
|
||||
|
||||
- (void)restoreDefaultValues;
|
||||
|
||||
@end
|
133
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m
generated
vendored
Normal file
133
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTPropsAnimatedNode.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
#import <React/RCTSurfacePresenterStub.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
|
||||
#import <React/RCTAnimationUtils.h>
|
||||
#import <React/RCTStyleAnimatedNode.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
|
||||
|
||||
|
||||
@implementation RCTPropsAnimatedNode
|
||||
{
|
||||
NSNumber *_connectedViewTag;
|
||||
NSNumber *_rootTag;
|
||||
NSString *_connectedViewName;
|
||||
__weak RCTBridge *_bridge;
|
||||
NSMutableDictionary<NSString *, NSObject *> *_propsDictionary; // TODO: use RawProps or folly::dynamic directly
|
||||
BOOL _managedByFabric;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
if (self = [super initWithTag:tag config:config]) {
|
||||
_propsDictionary = [NSMutableDictionary new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isManagedByFabric
|
||||
{
|
||||
return _managedByFabric;
|
||||
}
|
||||
|
||||
- (void)connectToView:(NSNumber *)viewTag
|
||||
viewName:(NSString *)viewName
|
||||
bridge:(RCTBridge *)bridge
|
||||
{
|
||||
_bridge = bridge;
|
||||
_connectedViewTag = viewTag;
|
||||
_connectedViewName = viewName;
|
||||
_managedByFabric = RCTUIManagerTypeForTagIsFabric(viewTag);
|
||||
_rootTag = nil;
|
||||
}
|
||||
|
||||
- (void)disconnectFromView:(NSNumber *)viewTag
|
||||
{
|
||||
_bridge = nil;
|
||||
_connectedViewTag = nil;
|
||||
_connectedViewName = nil;
|
||||
_managedByFabric = NO;
|
||||
_rootTag = nil;
|
||||
}
|
||||
|
||||
- (void)updateView
|
||||
{
|
||||
if (_managedByFabric) {
|
||||
[_bridge.surfacePresenter synchronouslyUpdateViewOnUIThread:_connectedViewTag
|
||||
props:_propsDictionary];
|
||||
} else {
|
||||
[_bridge.uiManager synchronouslyUpdateViewOnUIThread:_connectedViewTag
|
||||
viewName:_connectedViewName
|
||||
props:_propsDictionary];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)restoreDefaultValues
|
||||
{
|
||||
// Restore the default value for all props that were modified by this node.
|
||||
for (NSString *key in _propsDictionary.allKeys) {
|
||||
_propsDictionary[key] = [NSNull null];
|
||||
}
|
||||
|
||||
if (_propsDictionary.count) {
|
||||
[self updateView];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *)propertyNameForParentTag:(NSNumber *)parentTag
|
||||
{
|
||||
__block NSString *propertyName;
|
||||
[self.config[@"props"] enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull property, NSNumber *_Nonnull tag, BOOL *_Nonnull stop) {
|
||||
if ([tag isEqualToNumber:parentTag]) {
|
||||
propertyName = property;
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
return propertyName;
|
||||
}
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
|
||||
// Since we are updating nodes after detaching them from views there is a time where it's
|
||||
// possible that the view was disconnected and still receive an update, this is normal and we can
|
||||
// simply skip that update.
|
||||
if (!_connectedViewTag) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (NSNumber *parentTag in self.parentNodes.keyEnumerator) {
|
||||
RCTAnimatedNode *parentNode = [self.parentNodes objectForKey:parentTag];
|
||||
if ([parentNode isKindOfClass:[RCTStyleAnimatedNode class]]) {
|
||||
[self->_propsDictionary addEntriesFromDictionary:[(RCTStyleAnimatedNode *)parentNode propsDictionary]];
|
||||
|
||||
} else if ([parentNode isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
NSString *property = [self propertyNameForParentTag:parentTag];
|
||||
id animatedObject = [(RCTValueAnimatedNode *)parentNode animatedObject];
|
||||
if (animatedObject) {
|
||||
self->_propsDictionary[property] = animatedObject;
|
||||
} else {
|
||||
CGFloat value = [(RCTValueAnimatedNode *)parentNode value];
|
||||
self->_propsDictionary[property] = @(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_propsDictionary.count) {
|
||||
[self updateView];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
14
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.h
generated
vendored
Normal file
14
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 RCTStyleAnimatedNode : RCTAnimatedNode
|
||||
|
||||
- (NSDictionary<NSString *, NSObject *> *)propsDictionary;
|
||||
|
||||
@end
|
51
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m
generated
vendored
Normal file
51
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTStyleAnimatedNode.h>
|
||||
#import <React/RCTAnimationUtils.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
#import <React/RCTTransformAnimatedNode.h>
|
||||
|
||||
@implementation RCTStyleAnimatedNode
|
||||
{
|
||||
NSMutableDictionary<NSString *, NSObject *> *_propsDictionary;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
if ((self = [super initWithTag:tag config:config])) {
|
||||
_propsDictionary = [NSMutableDictionary new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)propsDictionary
|
||||
{
|
||||
return _propsDictionary;
|
||||
}
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
|
||||
NSDictionary<NSString *, NSNumber *> *style = self.config[@"style"];
|
||||
[style enumerateKeysAndObjectsUsingBlock:^(NSString *property, NSNumber *nodeTag, __unused BOOL *stop) {
|
||||
RCTAnimatedNode *node = [self.parentNodes objectForKey:nodeTag];
|
||||
if (node) {
|
||||
if ([node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
RCTValueAnimatedNode *parentNode = (RCTValueAnimatedNode *)node;
|
||||
[self->_propsDictionary setObject:@(parentNode.value) forKey:property];
|
||||
} else if ([node isKindOfClass:[RCTTransformAnimatedNode class]]) {
|
||||
RCTTransformAnimatedNode *parentNode = (RCTTransformAnimatedNode *)node;
|
||||
[self->_propsDictionary addEntriesFromDictionary:parentNode.propsDictionary];
|
||||
}
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
13
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTSubtractionAnimatedNode.h
generated
vendored
Normal file
13
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTSubtractionAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTSubtractionAnimatedNode : RCTValueAnimatedNode
|
||||
|
||||
@end
|
||||
|
27
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTSubtractionAnimatedNode.m
generated
vendored
Normal file
27
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTSubtractionAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTSubtractionAnimatedNode.h>
|
||||
|
||||
@implementation RCTSubtractionAnimatedNode
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
NSArray<NSNumber *> *inputNodes = self.config[@"input"];
|
||||
if (inputNodes.count > 1) {
|
||||
RCTValueAnimatedNode *parent1 = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNodes[0]];
|
||||
RCTValueAnimatedNode *parent2 = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:inputNodes[1]];
|
||||
if ([parent1 isKindOfClass:[RCTValueAnimatedNode class]] &&
|
||||
[parent2 isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
self.value = parent1.value - parent2.value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
13
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTTrackingAnimatedNode.h
generated
vendored
Normal file
13
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTTrackingAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 RCTTrackingAnimatedNode : RCTAnimatedNode
|
||||
|
||||
@end
|
52
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTTrackingAnimatedNode.m
generated
vendored
Normal file
52
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTTrackingAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTTrackingAnimatedNode.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
#import <React/RCTNativeAnimatedNodesManager.h>
|
||||
|
||||
@implementation RCTTrackingAnimatedNode {
|
||||
NSNumber *_animationId;
|
||||
NSNumber *_toValueNodeTag;
|
||||
NSNumber *_valueNodeTag;
|
||||
NSMutableDictionary *_animationConfig;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
if ((self = [super initWithTag:tag config:config])) {
|
||||
_animationId = config[@"animationId"];
|
||||
_toValueNodeTag = config[@"toValue"];
|
||||
_valueNodeTag = config[@"value"];
|
||||
_animationConfig = [NSMutableDictionary dictionaryWithDictionary:config[@"animationConfig"]];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)onDetachedFromNode:(RCTAnimatedNode *)parent
|
||||
{
|
||||
[self.manager stopAnimation:_animationId];
|
||||
[super onDetachedFromNode:parent];
|
||||
}
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
|
||||
// change animation config's "toValue" to reflect updated value of the parent node
|
||||
RCTValueAnimatedNode *node = (RCTValueAnimatedNode *)[self.parentNodes objectForKey:_toValueNodeTag];
|
||||
_animationConfig[@"toValue"] = @(node.value);
|
||||
|
||||
[self.manager startAnimatingNode:_animationId
|
||||
nodeTag:_valueNodeTag
|
||||
config:_animationConfig
|
||||
endCallback:nil];
|
||||
}
|
||||
|
||||
@end
|
||||
|
14
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTTransformAnimatedNode.h
generated
vendored
Normal file
14
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTTransformAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its 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 RCTTransformAnimatedNode : RCTAnimatedNode
|
||||
|
||||
- (NSDictionary<NSString *, NSObject *> *)propsDictionary;
|
||||
|
||||
@end
|
57
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTTransformAnimatedNode.m
generated
vendored
Normal file
57
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTTransformAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTTransformAnimatedNode.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
|
||||
@implementation RCTTransformAnimatedNode
|
||||
{
|
||||
NSMutableDictionary<NSString *, NSObject *> *_propsDictionary;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
if ((self = [super initWithTag:tag config:config])) {
|
||||
_propsDictionary = [NSMutableDictionary new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSDictionary *)propsDictionary
|
||||
{
|
||||
return _propsDictionary;
|
||||
}
|
||||
|
||||
- (void)performUpdate
|
||||
{
|
||||
[super performUpdate];
|
||||
|
||||
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"];
|
||||
NSNumber *value;
|
||||
if ([type isEqualToString: @"animated"]) {
|
||||
NSNumber *nodeTag = transformConfig[@"nodeTag"];
|
||||
RCTAnimatedNode *node = [self.parentNodes objectForKey:nodeTag];
|
||||
if (![node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
continue;
|
||||
}
|
||||
RCTValueAnimatedNode *parentNode = (RCTValueAnimatedNode *)node;
|
||||
value = @(parentNode.value);
|
||||
} else {
|
||||
value = transformConfig[@"value"];
|
||||
}
|
||||
[transform addObject:@{property: value}];
|
||||
}
|
||||
|
||||
_propsDictionary[@"transform"] = transform;
|
||||
}
|
||||
|
||||
@end
|
30
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTValueAnimatedNode.h
generated
vendored
Normal file
30
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTValueAnimatedNode.h
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "RCTAnimatedNode.h"
|
||||
|
||||
@class RCTValueAnimatedNode;
|
||||
|
||||
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
||||
|
||||
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
||||
|
||||
@end
|
||||
|
||||
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
||||
|
||||
- (void)setOffset:(CGFloat)offset;
|
||||
- (void)flattenOffset;
|
||||
- (void)extractOffset;
|
||||
|
||||
@property (nonatomic, assign) CGFloat value;
|
||||
@property (nonatomic, strong) id animatedObject;
|
||||
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
||||
|
||||
@end
|
56
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTValueAnimatedNode.m
generated
vendored
Normal file
56
node_modules/react-native/Libraries/NativeAnimation/Nodes/RCTValueAnimatedNode.m
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
|
||||
@interface RCTValueAnimatedNode ()
|
||||
|
||||
@property (nonatomic, assign) CGFloat offset;
|
||||
|
||||
@end
|
||||
|
||||
@implementation RCTValueAnimatedNode
|
||||
|
||||
@synthesize value = _value;
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
if (self = [super initWithTag:tag config:config]) {
|
||||
_offset = [self.config[@"offset"] floatValue];
|
||||
_value = [self.config[@"value"] floatValue];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)flattenOffset
|
||||
{
|
||||
_value += _offset;
|
||||
_offset = 0;
|
||||
}
|
||||
|
||||
- (void)extractOffset
|
||||
{
|
||||
_offset += _value;
|
||||
_value = 0;
|
||||
}
|
||||
|
||||
- (CGFloat)value
|
||||
{
|
||||
return _value + _offset;
|
||||
}
|
||||
|
||||
- (void)setValue:(CGFloat)value
|
||||
{
|
||||
_value = value;
|
||||
|
||||
if (_valueObserver) {
|
||||
[_valueObserver animatedNode:self didUpdateValue:_value];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
40
node_modules/react-native/Libraries/NativeAnimation/RCTAnimationPlugins.h
generated
vendored
Normal file
40
node_modules/react-native/Libraries/NativeAnimation/RCTAnimationPlugins.h
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated by an internal plugin build system
|
||||
*/
|
||||
|
||||
#ifdef RN_DISABLE_OSS_PLUGIN_HEADER
|
||||
|
||||
// FB Internal: FBRCTAnimationPlugins.h is autogenerated by the build system.
|
||||
#import <React/FBRCTAnimationPlugins.h>
|
||||
|
||||
#else
|
||||
|
||||
// OSS-compatibility layer
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// RCTTurboModuleManagerDelegate should call this to resolve module classes.
|
||||
Class RCTAnimationClassProvider(const char *name);
|
||||
|
||||
// Lookup functions
|
||||
Class RCTNativeAnimatedModuleCls(void) __attribute__((used));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#endif // RN_DISABLE_OSS_PLUGIN_HEADER
|
32
node_modules/react-native/Libraries/NativeAnimation/RCTAnimationPlugins.mm
generated
vendored
Normal file
32
node_modules/react-native/Libraries/NativeAnimation/RCTAnimationPlugins.mm
generated
vendored
Normal file
@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated by an internal plugin build system
|
||||
*/
|
||||
|
||||
#ifndef RN_DISABLE_OSS_PLUGIN_HEADER
|
||||
|
||||
// OSS-compatibility layer
|
||||
|
||||
#import "RCTAnimationPlugins.h"
|
||||
|
||||
#import <string>
|
||||
#import <unordered_map>
|
||||
|
||||
Class RCTAnimationClassProvider(const char *name) {
|
||||
static std::unordered_map<std::string, Class (*)(void)> sCoreModuleClassMap = {
|
||||
{"NativeAnimatedModule", RCTNativeAnimatedModuleCls},
|
||||
};
|
||||
|
||||
auto p = sCoreModuleClassMap.find(name);
|
||||
if (p != sCoreModuleClassMap.end()) {
|
||||
auto classFunc = p->second;
|
||||
return classFunc();
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
#endif // RN_DISABLE_OSS_PLUGIN_HEADER
|
38
node_modules/react-native/Libraries/NativeAnimation/RCTAnimationUtils.h
generated
vendored
Normal file
38
node_modules/react-native/Libraries/NativeAnimation/RCTAnimationUtils.h
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <CoreGraphics/CoreGraphics.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import <React/RCTDefines.h>
|
||||
|
||||
static NSString *const EXTRAPOLATE_TYPE_IDENTITY = @"identity";
|
||||
static NSString *const EXTRAPOLATE_TYPE_CLAMP = @"clamp";
|
||||
static NSString *const EXTRAPOLATE_TYPE_EXTEND = @"extend";
|
||||
|
||||
RCT_EXTERN CGFloat RCTInterpolateValueInRange(CGFloat value,
|
||||
NSArray<NSNumber *> *inputRange,
|
||||
NSArray<NSNumber *> *outputRange,
|
||||
NSString *extrapolateLeft,
|
||||
NSString *extrapolateRight);
|
||||
|
||||
RCT_EXTERN CGFloat RCTInterpolateValue(CGFloat value,
|
||||
CGFloat inputMin,
|
||||
CGFloat inputMax,
|
||||
CGFloat outputMin,
|
||||
CGFloat outputMax,
|
||||
NSString *extrapolateLeft,
|
||||
NSString *extrapolateRight);
|
||||
|
||||
RCT_EXTERN CGFloat RCTRadiansToDegrees(CGFloat radians);
|
||||
RCT_EXTERN CGFloat RCTDegreesToRadians(CGFloat degrees);
|
||||
|
||||
/**
|
||||
* Coefficient to slow down animations, respects the ios
|
||||
* simulator `Slow Animations (⌘T)` option.
|
||||
*/
|
||||
RCT_EXTERN CGFloat RCTAnimationDragCoefficient(void);
|
115
node_modules/react-native/Libraries/NativeAnimation/RCTAnimationUtils.m
generated
vendored
Normal file
115
node_modules/react-native/Libraries/NativeAnimation/RCTAnimationUtils.m
generated
vendored
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTAnimationUtils.h>
|
||||
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
static NSUInteger _RCTFindIndexOfNearestValue(CGFloat value, NSArray<NSNumber *> *range)
|
||||
{
|
||||
NSUInteger index;
|
||||
NSUInteger rangeCount = range.count;
|
||||
for (index = 1; index < rangeCount - 1; index++) {
|
||||
NSNumber *inputValue = range[index];
|
||||
if (inputValue.doubleValue >= value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates value by remapping it linearly fromMin->fromMax to toMin->toMax
|
||||
*/
|
||||
CGFloat RCTInterpolateValue(CGFloat value,
|
||||
CGFloat inputMin,
|
||||
CGFloat inputMax,
|
||||
CGFloat outputMin,
|
||||
CGFloat outputMax,
|
||||
NSString *extrapolateLeft,
|
||||
NSString *extrapolateRight)
|
||||
{
|
||||
if (value < inputMin) {
|
||||
if ([extrapolateLeft isEqualToString:EXTRAPOLATE_TYPE_IDENTITY]) {
|
||||
return value;
|
||||
} else if ([extrapolateLeft isEqualToString:EXTRAPOLATE_TYPE_CLAMP]) {
|
||||
value = inputMin;
|
||||
} else if ([extrapolateLeft isEqualToString:EXTRAPOLATE_TYPE_EXTEND]) {
|
||||
// noop
|
||||
} else {
|
||||
RCTLogError(@"Invalid extrapolation type %@ for left extrapolation", extrapolateLeft);
|
||||
}
|
||||
}
|
||||
|
||||
if (value > inputMax) {
|
||||
if ([extrapolateRight isEqualToString:EXTRAPOLATE_TYPE_IDENTITY]) {
|
||||
return value;
|
||||
} else if ([extrapolateRight isEqualToString:EXTRAPOLATE_TYPE_CLAMP]) {
|
||||
value = inputMax;
|
||||
} else if ([extrapolateRight isEqualToString:EXTRAPOLATE_TYPE_EXTEND]) {
|
||||
// noop
|
||||
} else {
|
||||
RCTLogError(@"Invalid extrapolation type %@ for right extrapolation", extrapolateRight);
|
||||
}
|
||||
}
|
||||
|
||||
return outputMin + (value - inputMin) * (outputMax - outputMin) / (inputMax - inputMin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolates value by mapping it from the inputRange to the outputRange.
|
||||
*/
|
||||
CGFloat RCTInterpolateValueInRange(CGFloat value,
|
||||
NSArray<NSNumber *> *inputRange,
|
||||
NSArray<NSNumber *> *outputRange,
|
||||
NSString *extrapolateLeft,
|
||||
NSString *extrapolateRight)
|
||||
{
|
||||
NSUInteger rangeIndex = _RCTFindIndexOfNearestValue(value, inputRange);
|
||||
CGFloat inputMin = inputRange[rangeIndex].doubleValue;
|
||||
CGFloat inputMax = inputRange[rangeIndex + 1].doubleValue;
|
||||
CGFloat outputMin = outputRange[rangeIndex].doubleValue;
|
||||
CGFloat outputMax = outputRange[rangeIndex + 1].doubleValue;
|
||||
|
||||
return RCTInterpolateValue(value,
|
||||
inputMin,
|
||||
inputMax,
|
||||
outputMin,
|
||||
outputMax,
|
||||
extrapolateLeft,
|
||||
extrapolateRight);
|
||||
}
|
||||
|
||||
CGFloat RCTRadiansToDegrees(CGFloat radians)
|
||||
{
|
||||
return radians * 180.0 / M_PI;
|
||||
}
|
||||
|
||||
CGFloat RCTDegreesToRadians(CGFloat degrees)
|
||||
{
|
||||
return degrees / 180.0 * M_PI;
|
||||
}
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
// Based on https://stackoverflow.com/a/13307674
|
||||
float UIAnimationDragCoefficient(void);
|
||||
#endif
|
||||
|
||||
CGFloat RCTAnimationDragCoefficient()
|
||||
{
|
||||
#if TARGET_IPHONE_SIMULATOR
|
||||
if (NSClassFromString(@"XCTest") != nil) {
|
||||
// UIAnimationDragCoefficient is 10.0 in tests for some reason, but
|
||||
// we need it to be 1.0. Fixes T34233294
|
||||
return 1.0;
|
||||
} else {
|
||||
return (CGFloat)UIAnimationDragCoefficient();
|
||||
}
|
||||
#else
|
||||
return 1.0;
|
||||
#endif
|
||||
}
|
20
node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedModule.h
generated
vendored
Normal file
20
node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedModule.h
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventDispatcher.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
#import <React/RCTSurfacePresenterStub.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
#import <React/RCTUIManagerObserverCoordinator.h>
|
||||
#import <React/RCTUIManagerUtils.h>
|
||||
|
||||
#import "RCTValueAnimatedNode.h"
|
||||
|
||||
@interface RCTNativeAnimatedModule : RCTEventEmitter <RCTBridgeModule, RCTValueAnimatedNodeObserver, RCTEventDispatcherObserver, RCTUIManagerObserver, RCTSurfacePresenterObserver>
|
||||
|
||||
@end
|
350
node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm
generated
vendored
Normal file
350
node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedModule.mm
generated
vendored
Normal file
@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <FBReactNativeSpec/FBReactNativeSpec.h>
|
||||
#import <React/RCTNativeAnimatedModule.h>
|
||||
#import <React/RCTNativeAnimatedNodesManager.h>
|
||||
|
||||
#import <RCTTypeSafety/RCTConvertHelpers.h>
|
||||
|
||||
#import "RCTAnimationPlugins.h"
|
||||
|
||||
typedef void (^AnimatedOperation)(RCTNativeAnimatedNodesManager *nodesManager);
|
||||
|
||||
@interface RCTNativeAnimatedModule() <NativeAnimatedModuleSpec>
|
||||
@end
|
||||
|
||||
@implementation RCTNativeAnimatedModule
|
||||
{
|
||||
RCTNativeAnimatedNodesManager *_nodesManager;
|
||||
|
||||
// Operations called after views have been updated.
|
||||
NSMutableArray<AnimatedOperation> *_operations;
|
||||
// Operations called before views have been updated.
|
||||
NSMutableArray<AnimatedOperation> *_preOperations;
|
||||
NSMutableDictionary<NSNumber *, NSNumber *> *_animIdIsManagedByFabric;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
[_nodesManager stopAnimationLoop];
|
||||
[self.bridge.eventDispatcher removeDispatchObserver:self];
|
||||
[self.bridge.uiManager.observerCoordinator removeObserver:self];
|
||||
[self.bridge.surfacePresenter removeObserver:self];
|
||||
}
|
||||
|
||||
- (dispatch_queue_t)methodQueue
|
||||
{
|
||||
// This module needs to be on the same queue as the UIManager to avoid
|
||||
// having to lock `_operations` and `_preOperations` since `uiManagerWillPerformMounting`
|
||||
// will be called from that queue.
|
||||
return RCTGetUIManagerQueue();
|
||||
}
|
||||
|
||||
- (void)setBridge:(RCTBridge *)bridge
|
||||
{
|
||||
[super setBridge:bridge];
|
||||
|
||||
_nodesManager = [[RCTNativeAnimatedNodesManager alloc] initWithBridge:self.bridge];
|
||||
_operations = [NSMutableArray new];
|
||||
_preOperations = [NSMutableArray new];
|
||||
_animIdIsManagedByFabric = [NSMutableDictionary new];
|
||||
|
||||
[bridge.eventDispatcher addDispatchObserver:self];
|
||||
[bridge.uiManager.observerCoordinator addObserver:self];
|
||||
[bridge.surfacePresenter addObserver:self];
|
||||
}
|
||||
|
||||
#pragma mark -- API
|
||||
|
||||
RCT_EXPORT_METHOD(createAnimatedNode:(double)tag
|
||||
config:(NSDictionary<NSString *, id> *)config)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager createAnimatedNode:[NSNumber numberWithDouble:tag] config:config];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(connectAnimatedNodes:(double)parentTag
|
||||
childTag:(double)childTag)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager connectAnimatedNodes:[NSNumber numberWithDouble:parentTag] childTag:[NSNumber numberWithDouble:childTag]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(disconnectAnimatedNodes:(double)parentTag
|
||||
childTag:(double)childTag)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager disconnectAnimatedNodes:[NSNumber numberWithDouble:parentTag] childTag:[NSNumber numberWithDouble:childTag]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(startAnimatingNode:(double)animationId
|
||||
nodeTag:(double)nodeTag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
endCallback:(RCTResponseSenderBlock)callBack)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager startAnimatingNode:[NSNumber numberWithDouble:animationId] nodeTag:[NSNumber numberWithDouble:nodeTag] config:config endCallback:callBack];
|
||||
}];
|
||||
|
||||
RCTExecuteOnMainQueue(^{
|
||||
if (![self->_nodesManager isNodeManagedByFabric:[NSNumber numberWithDouble:nodeTag]]) {
|
||||
return;
|
||||
}
|
||||
|
||||
RCTExecuteOnUIManagerQueue(^{
|
||||
self->_animIdIsManagedByFabric[[NSNumber numberWithDouble:animationId]] = @YES;
|
||||
[self flushOperationQueues];
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(stopAnimation:(double)animationId)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager stopAnimation:[NSNumber numberWithDouble:animationId]];
|
||||
}];
|
||||
if ([_animIdIsManagedByFabric[[NSNumber numberWithDouble:animationId]] boolValue]) {
|
||||
[self flushOperationQueues];
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setAnimatedNodeValue:(double)nodeTag
|
||||
value:(double)value)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager setAnimatedNodeValue:[NSNumber numberWithDouble:nodeTag] value:[NSNumber numberWithDouble:value]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(setAnimatedNodeOffset:(double)nodeTag
|
||||
offset:(double)offset)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager setAnimatedNodeOffset:[NSNumber numberWithDouble:nodeTag] offset:[NSNumber numberWithDouble:offset]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(flattenAnimatedNodeOffset:(double)nodeTag)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager flattenAnimatedNodeOffset:[NSNumber numberWithDouble:nodeTag]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(extractAnimatedNodeOffset:(double)nodeTag)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager extractAnimatedNodeOffset:[NSNumber numberWithDouble:nodeTag]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(connectAnimatedNodeToView:(double)nodeTag
|
||||
viewTag:(double)viewTag)
|
||||
{
|
||||
NSString *viewName = [self.bridge.uiManager viewNameForReactTag:[NSNumber numberWithDouble:viewTag]];
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager connectAnimatedNodeToView:[NSNumber numberWithDouble:nodeTag] viewTag:[NSNumber numberWithDouble:viewTag] viewName:viewName];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(disconnectAnimatedNodeFromView:(double)nodeTag
|
||||
viewTag:(double)viewTag)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager disconnectAnimatedNodeFromView:[NSNumber numberWithDouble:nodeTag] viewTag:[NSNumber numberWithDouble:viewTag]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(restoreDefaultValues:(double)nodeTag)
|
||||
{
|
||||
[self addPreOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager restoreDefaultValues:[NSNumber numberWithDouble:nodeTag]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(dropAnimatedNode:(double)tag)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager dropAnimatedNode:[NSNumber numberWithDouble:tag]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(startListeningToAnimatedNodeValue:(double)tag)
|
||||
{
|
||||
__weak id<RCTValueAnimatedNodeObserver> valueObserver = self;
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager startListeningToAnimatedNodeValue:[NSNumber numberWithDouble:tag] valueObserver:valueObserver];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(stopListeningToAnimatedNodeValue:(double)tag)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager stopListeningToAnimatedNodeValue:[NSNumber numberWithDouble:tag]];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(addAnimatedEventToView:(double)viewTag
|
||||
eventName:(nonnull NSString *)eventName
|
||||
eventMapping:(JS::NativeAnimatedModule::EventMapping &)eventMapping)
|
||||
{
|
||||
NSMutableDictionary *eventMappingDict = [NSMutableDictionary new];
|
||||
eventMappingDict[@"nativeEventPath"] = RCTConvertVecToArray(eventMapping.nativeEventPath());
|
||||
|
||||
if (eventMapping.animatedValueTag()) {
|
||||
eventMappingDict[@"animatedValueTag"] = @(*eventMapping.animatedValueTag());
|
||||
}
|
||||
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager addAnimatedEventToView:[NSNumber numberWithDouble:viewTag] eventName:eventName eventMapping:eventMappingDict];
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(removeAnimatedEventFromView:(double)viewTag
|
||||
eventName:(nonnull NSString *)eventName
|
||||
animatedNodeTag:(double)animatedNodeTag)
|
||||
{
|
||||
[self addOperationBlock:^(RCTNativeAnimatedNodesManager *nodesManager) {
|
||||
[nodesManager removeAnimatedEventFromView:[NSNumber numberWithDouble:viewTag] eventName:eventName animatedNodeTag:[NSNumber numberWithDouble:animatedNodeTag]];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark -- Batch handling
|
||||
|
||||
- (void)addOperationBlock:(AnimatedOperation)operation
|
||||
{
|
||||
[_operations addObject:operation];
|
||||
}
|
||||
|
||||
- (void)addPreOperationBlock:(AnimatedOperation)operation
|
||||
{
|
||||
[_preOperations addObject:operation];
|
||||
}
|
||||
|
||||
- (void)flushOperationQueues
|
||||
{
|
||||
if (_preOperations.count == 0 && _operations.count == 0) {
|
||||
return;
|
||||
}
|
||||
NSArray<AnimatedOperation> *preOperations = _preOperations;
|
||||
NSArray<AnimatedOperation> *operations = _operations;
|
||||
_preOperations = [NSMutableArray new];
|
||||
_operations = [NSMutableArray new];
|
||||
|
||||
|
||||
RCTExecuteOnMainQueue(^{
|
||||
for (AnimatedOperation operation in preOperations) {
|
||||
operation(self->_nodesManager);
|
||||
}
|
||||
for (AnimatedOperation operation in operations) {
|
||||
operation(self->_nodesManager);
|
||||
}
|
||||
[self->_nodesManager updateAnimations];
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - RCTSurfacePresenterObserver
|
||||
|
||||
- (void)willMountComponentsWithRootTag:(NSInteger)rootTag
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
RCTExecuteOnUIManagerQueue(^{
|
||||
NSArray<AnimatedOperation> *preOperations = self->_preOperations;
|
||||
self->_preOperations = [NSMutableArray new];
|
||||
|
||||
RCTExecuteOnMainQueue(^{
|
||||
for (AnimatedOperation preOperation in preOperations) {
|
||||
preOperation(self->_nodesManager);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
- (void)didMountComponentsWithRootTag:(NSInteger)rootTag
|
||||
{
|
||||
RCTAssertMainQueue();
|
||||
RCTExecuteOnUIManagerQueue(^{
|
||||
NSArray<AnimatedOperation> *operations = self->_operations;
|
||||
self->_operations = [NSMutableArray new];
|
||||
|
||||
RCTExecuteOnMainQueue(^{
|
||||
for (AnimatedOperation operation in operations) {
|
||||
operation(self->_nodesManager);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark - RCTUIManagerObserver
|
||||
|
||||
- (void)uiManagerWillPerformMounting:(RCTUIManager *)uiManager
|
||||
{
|
||||
if (_preOperations.count == 0 && _operations.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray<AnimatedOperation> *preOperations = _preOperations;
|
||||
NSArray<AnimatedOperation> *operations = _operations;
|
||||
_preOperations = [NSMutableArray new];
|
||||
_operations = [NSMutableArray new];
|
||||
|
||||
[uiManager prependUIBlock:^(__unused RCTUIManager *manager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
for (AnimatedOperation operation in preOperations) {
|
||||
operation(self->_nodesManager);
|
||||
}
|
||||
}];
|
||||
|
||||
[uiManager addUIBlock:^(__unused RCTUIManager *manager, __unused NSDictionary<NSNumber *, UIView *> *viewRegistry) {
|
||||
for (AnimatedOperation operation in operations) {
|
||||
operation(self->_nodesManager);
|
||||
}
|
||||
|
||||
[self->_nodesManager updateAnimations];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark -- Events
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents
|
||||
{
|
||||
return @[@"onAnimatedValueUpdate"];
|
||||
}
|
||||
|
||||
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value
|
||||
{
|
||||
[self sendEventWithName:@"onAnimatedValueUpdate"
|
||||
body:@{@"tag": node.nodeTag, @"value": @(value)}];
|
||||
}
|
||||
|
||||
- (void)eventDispatcherWillDispatchEvent:(id<RCTEvent>)event
|
||||
{
|
||||
// Events can be dispatched from any queue so we have to make sure handleAnimatedEvent
|
||||
// is run from the main queue.
|
||||
RCTExecuteOnMainQueue(^{
|
||||
[self->_nodesManager handleAnimatedEvent:event];
|
||||
});
|
||||
}
|
||||
|
||||
- (std::shared_ptr<facebook::react::TurboModule>)
|
||||
getTurboModuleWithJsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker
|
||||
nativeInvoker:(std::shared_ptr<facebook::react::CallInvoker>)nativeInvoker
|
||||
perfLogger:(id<RCTTurboModulePerformanceLogger>)perfLogger
|
||||
{
|
||||
return std::make_shared<facebook::react::NativeAnimatedModuleSpecJSI>(self, jsInvoker, nativeInvoker, perfLogger);
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Class RCTNativeAnimatedModuleCls(void) {
|
||||
return RCTNativeAnimatedModule.class;
|
||||
}
|
88
node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h
generated
vendored
Normal file
88
node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h
generated
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTUIManager.h>
|
||||
|
||||
@protocol RCTValueAnimatedNodeObserver;
|
||||
|
||||
@interface RCTNativeAnimatedNodesManager : NSObject
|
||||
|
||||
- (nonnull instancetype)initWithBridge:(nonnull RCTBridge *)bridge;
|
||||
|
||||
- (void)updateAnimations;
|
||||
|
||||
- (void)stepAnimations:(nonnull CADisplayLink *)displaylink;
|
||||
|
||||
- (BOOL)isNodeManagedByFabric:(nonnull NSNumber *)tag;
|
||||
|
||||
// graph
|
||||
|
||||
- (void)createAnimatedNode:(nonnull NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *__nonnull)config;
|
||||
|
||||
- (void)connectAnimatedNodes:(nonnull NSNumber *)parentTag
|
||||
childTag:(nonnull NSNumber *)childTag;
|
||||
|
||||
- (void)disconnectAnimatedNodes:(nonnull NSNumber *)parentTag
|
||||
childTag:(nonnull NSNumber *)childTag;
|
||||
|
||||
- (void)connectAnimatedNodeToView:(nonnull NSNumber *)nodeTag
|
||||
viewTag:(nonnull NSNumber *)viewTag
|
||||
viewName:(nonnull NSString *)viewName;
|
||||
|
||||
- (void)restoreDefaultValues:(nonnull NSNumber *)nodeTag;
|
||||
|
||||
- (void)disconnectAnimatedNodeFromView:(nonnull NSNumber *)nodeTag
|
||||
viewTag:(nonnull NSNumber *)viewTag;
|
||||
|
||||
- (void)dropAnimatedNode:(nonnull NSNumber *)tag;
|
||||
|
||||
// mutations
|
||||
|
||||
- (void)setAnimatedNodeValue:(nonnull NSNumber *)nodeTag
|
||||
value:(nonnull NSNumber *)value;
|
||||
|
||||
- (void)setAnimatedNodeOffset:(nonnull NSNumber *)nodeTag
|
||||
offset:(nonnull NSNumber *)offset;
|
||||
|
||||
- (void)flattenAnimatedNodeOffset:(nonnull NSNumber *)nodeTag;
|
||||
|
||||
- (void)extractAnimatedNodeOffset:(nonnull NSNumber *)nodeTag;
|
||||
|
||||
// drivers
|
||||
|
||||
- (void)startAnimatingNode:(nonnull NSNumber *)animationId
|
||||
nodeTag:(nonnull NSNumber *)nodeTag
|
||||
config:(NSDictionary<NSString *, id> *__nonnull)config
|
||||
endCallback:(nullable RCTResponseSenderBlock)callBack;
|
||||
|
||||
- (void)stopAnimation:(nonnull NSNumber *)animationId;
|
||||
|
||||
- (void)stopAnimationLoop;
|
||||
|
||||
// events
|
||||
|
||||
- (void)addAnimatedEventToView:(nonnull NSNumber *)viewTag
|
||||
eventName:(nonnull NSString *)eventName
|
||||
eventMapping:(NSDictionary<NSString *, id> *__nonnull)eventMapping;
|
||||
|
||||
- (void)removeAnimatedEventFromView:(nonnull NSNumber *)viewTag
|
||||
eventName:(nonnull NSString *)eventName
|
||||
animatedNodeTag:(nonnull NSNumber *)animatedNodeTag;
|
||||
|
||||
- (void)handleAnimatedEvent:(nonnull id<RCTEvent>)event;
|
||||
|
||||
// listeners
|
||||
|
||||
- (void)startListeningToAnimatedNodeValue:(nonnull NSNumber *)tag
|
||||
valueObserver:(nonnull id<RCTValueAnimatedNodeObserver>)valueObserver;
|
||||
|
||||
- (void)stopListeningToAnimatedNodeValue:(nonnull NSNumber *)tag;
|
||||
|
||||
@end
|
466
node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m
generated
vendored
Normal file
466
node_modules/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.m
generated
vendored
Normal file
@ -0,0 +1,466 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/RCTNativeAnimatedNodesManager.h>
|
||||
|
||||
#import <React/RCTConvert.h>
|
||||
|
||||
#import <React/RCTAdditionAnimatedNode.h>
|
||||
#import <React/RCTAnimatedNode.h>
|
||||
#import <React/RCTAnimationDriver.h>
|
||||
#import <React/RCTDiffClampAnimatedNode.h>
|
||||
#import <React/RCTDivisionAnimatedNode.h>
|
||||
#import <React/RCTEventAnimation.h>
|
||||
#import <React/RCTFrameAnimation.h>
|
||||
#import <React/RCTDecayAnimation.h>
|
||||
#import <React/RCTInterpolationAnimatedNode.h>
|
||||
#import <React/RCTModuloAnimatedNode.h>
|
||||
#import <React/RCTMultiplicationAnimatedNode.h>
|
||||
#import <React/RCTPropsAnimatedNode.h>
|
||||
#import <React/RCTSpringAnimation.h>
|
||||
#import <React/RCTStyleAnimatedNode.h>
|
||||
#import <React/RCTSubtractionAnimatedNode.h>
|
||||
#import <React/RCTTransformAnimatedNode.h>
|
||||
#import <React/RCTValueAnimatedNode.h>
|
||||
#import <React/RCTTrackingAnimatedNode.h>
|
||||
|
||||
// We do some normalizing of the event names in RCTEventDispatcher#RCTNormalizeInputEventName.
|
||||
// To make things simpler just get rid of the parts we change in the event names we use here.
|
||||
// This is a lot easier than trying to denormalize because there would be multiple possible
|
||||
// denormalized forms for a single input.
|
||||
static NSString *RCTNormalizeAnimatedEventName(NSString *eventName)
|
||||
{
|
||||
if ([eventName hasPrefix:@"on"]) {
|
||||
return [eventName substringFromIndex:2];
|
||||
}
|
||||
if ([eventName hasPrefix:@"top"]) {
|
||||
return [eventName substringFromIndex:3];
|
||||
}
|
||||
return eventName;
|
||||
}
|
||||
|
||||
@implementation RCTNativeAnimatedNodesManager
|
||||
{
|
||||
__weak RCTBridge *_bridge;
|
||||
NSMutableDictionary<NSNumber *, RCTAnimatedNode *> *_animationNodes;
|
||||
// Mapping of a view tag and an event name to a list of event animation drivers. 99% of the time
|
||||
// there will be only one driver per mapping so all code code should be optimized around that.
|
||||
NSMutableDictionary<NSString *, NSMutableArray<RCTEventAnimation *> *> *_eventDrivers;
|
||||
NSMutableSet<id<RCTAnimationDriver>> *_activeAnimations;
|
||||
CADisplayLink *_displayLink;
|
||||
}
|
||||
|
||||
- (instancetype)initWithBridge:(nonnull RCTBridge *)bridge
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_bridge = bridge;
|
||||
_animationNodes = [NSMutableDictionary new];
|
||||
_eventDrivers = [NSMutableDictionary new];
|
||||
_activeAnimations = [NSMutableSet new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isNodeManagedByFabric:(nonnull NSNumber *)tag
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[tag];
|
||||
if (node) {
|
||||
return [node isManagedByFabric];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma mark -- Graph
|
||||
|
||||
- (void)createAnimatedNode:(nonnull NSNumber *)tag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
{
|
||||
static NSDictionary *map;
|
||||
static dispatch_once_t mapToken;
|
||||
dispatch_once(&mapToken, ^{
|
||||
map = @{@"style" : [RCTStyleAnimatedNode class],
|
||||
@"value" : [RCTValueAnimatedNode class],
|
||||
@"props" : [RCTPropsAnimatedNode class],
|
||||
@"interpolation" : [RCTInterpolationAnimatedNode class],
|
||||
@"addition" : [RCTAdditionAnimatedNode class],
|
||||
@"diffclamp": [RCTDiffClampAnimatedNode class],
|
||||
@"division" : [RCTDivisionAnimatedNode class],
|
||||
@"multiplication" : [RCTMultiplicationAnimatedNode class],
|
||||
@"modulus" : [RCTModuloAnimatedNode class],
|
||||
@"subtraction" : [RCTSubtractionAnimatedNode class],
|
||||
@"transform" : [RCTTransformAnimatedNode class],
|
||||
@"tracking" : [RCTTrackingAnimatedNode class]};
|
||||
});
|
||||
|
||||
NSString *nodeType = [RCTConvert NSString:config[@"type"]];
|
||||
|
||||
Class nodeClass = map[nodeType];
|
||||
if (!nodeClass) {
|
||||
RCTLogError(@"Animated node type %@ not supported natively", nodeType);
|
||||
return;
|
||||
}
|
||||
|
||||
RCTAnimatedNode *node = [[nodeClass alloc] initWithTag:tag config:config];
|
||||
node.manager = self;
|
||||
_animationNodes[tag] = node;
|
||||
[node setNeedsUpdate];
|
||||
}
|
||||
|
||||
- (void)connectAnimatedNodes:(nonnull NSNumber *)parentTag
|
||||
childTag:(nonnull NSNumber *)childTag
|
||||
{
|
||||
RCTAssertParam(parentTag);
|
||||
RCTAssertParam(childTag);
|
||||
|
||||
RCTAnimatedNode *parentNode = _animationNodes[parentTag];
|
||||
RCTAnimatedNode *childNode = _animationNodes[childTag];
|
||||
|
||||
RCTAssertParam(parentNode);
|
||||
RCTAssertParam(childNode);
|
||||
|
||||
[parentNode addChild:childNode];
|
||||
[childNode setNeedsUpdate];
|
||||
}
|
||||
|
||||
- (void)disconnectAnimatedNodes:(nonnull NSNumber *)parentTag
|
||||
childTag:(nonnull NSNumber *)childTag
|
||||
{
|
||||
RCTAssertParam(parentTag);
|
||||
RCTAssertParam(childTag);
|
||||
|
||||
RCTAnimatedNode *parentNode = _animationNodes[parentTag];
|
||||
RCTAnimatedNode *childNode = _animationNodes[childTag];
|
||||
|
||||
RCTAssertParam(parentNode);
|
||||
RCTAssertParam(childNode);
|
||||
|
||||
[parentNode removeChild:childNode];
|
||||
[childNode setNeedsUpdate];
|
||||
}
|
||||
|
||||
- (void)connectAnimatedNodeToView:(nonnull NSNumber *)nodeTag
|
||||
viewTag:(nonnull NSNumber *)viewTag
|
||||
viewName:(nonnull NSString *)viewName
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||
if ([node isKindOfClass:[RCTPropsAnimatedNode class]]) {
|
||||
[(RCTPropsAnimatedNode *)node connectToView:viewTag viewName:viewName bridge:_bridge];
|
||||
}
|
||||
[node setNeedsUpdate];
|
||||
}
|
||||
|
||||
- (void)disconnectAnimatedNodeFromView:(nonnull NSNumber *)nodeTag
|
||||
viewTag:(nonnull NSNumber *)viewTag
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||
if ([node isKindOfClass:[RCTPropsAnimatedNode class]]) {
|
||||
[(RCTPropsAnimatedNode *)node disconnectFromView:viewTag];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)restoreDefaultValues:(nonnull NSNumber *)nodeTag
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||
// Restoring default values needs to happen before UIManager operations so it is
|
||||
// possible the node hasn't been created yet if it is being connected and
|
||||
// disconnected in the same batch. In that case we don't need to restore
|
||||
// default values since it will never actually update the view.
|
||||
if (node == nil) {
|
||||
return;
|
||||
}
|
||||
if (![node isKindOfClass:[RCTPropsAnimatedNode class]]) {
|
||||
RCTLogError(@"Not a props node.");
|
||||
}
|
||||
[(RCTPropsAnimatedNode *)node restoreDefaultValues];
|
||||
}
|
||||
|
||||
- (void)dropAnimatedNode:(nonnull NSNumber *)tag
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[tag];
|
||||
if (node) {
|
||||
[node detachNode];
|
||||
[_animationNodes removeObjectForKey:tag];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -- Mutations
|
||||
|
||||
- (void)setAnimatedNodeValue:(nonnull NSNumber *)nodeTag
|
||||
value:(nonnull NSNumber *)value
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||
if (![node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
RCTLogError(@"Not a value node.");
|
||||
return;
|
||||
}
|
||||
[self stopAnimationsForNode:node];
|
||||
|
||||
RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)node;
|
||||
valueNode.value = value.floatValue;
|
||||
[valueNode setNeedsUpdate];
|
||||
}
|
||||
|
||||
- (void)setAnimatedNodeOffset:(nonnull NSNumber *)nodeTag
|
||||
offset:(nonnull NSNumber *)offset
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||
if (![node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
RCTLogError(@"Not a value node.");
|
||||
return;
|
||||
}
|
||||
|
||||
RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)node;
|
||||
[valueNode setOffset:offset.floatValue];
|
||||
[valueNode setNeedsUpdate];
|
||||
}
|
||||
|
||||
- (void)flattenAnimatedNodeOffset:(nonnull NSNumber *)nodeTag
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||
if (![node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
RCTLogError(@"Not a value node.");
|
||||
return;
|
||||
}
|
||||
|
||||
RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)node;
|
||||
[valueNode flattenOffset];
|
||||
}
|
||||
|
||||
- (void)extractAnimatedNodeOffset:(nonnull NSNumber *)nodeTag
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||
if (![node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
RCTLogError(@"Not a value node.");
|
||||
return;
|
||||
}
|
||||
|
||||
RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)node;
|
||||
[valueNode extractOffset];
|
||||
}
|
||||
|
||||
#pragma mark -- Drivers
|
||||
|
||||
- (void)startAnimatingNode:(nonnull NSNumber *)animationId
|
||||
nodeTag:(nonnull NSNumber *)nodeTag
|
||||
config:(NSDictionary<NSString *, id> *)config
|
||||
endCallback:(RCTResponseSenderBlock)callBack
|
||||
{
|
||||
// check if the animation has already started
|
||||
for (id<RCTAnimationDriver> driver in _activeAnimations) {
|
||||
if ([driver.animationId isEqual:animationId]) {
|
||||
// if the animation is running, we restart it with an updated configuration
|
||||
[driver resetAnimationConfig:config];
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
RCTValueAnimatedNode *valueNode = (RCTValueAnimatedNode *)_animationNodes[nodeTag];
|
||||
|
||||
NSString *type = config[@"type"];
|
||||
id<RCTAnimationDriver> animationDriver;
|
||||
|
||||
if ([type isEqual:@"frames"]) {
|
||||
animationDriver = [[RCTFrameAnimation alloc] initWithId:animationId
|
||||
config:config
|
||||
forNode:valueNode
|
||||
callBack:callBack];
|
||||
|
||||
} else if ([type isEqual:@"spring"]) {
|
||||
animationDriver = [[RCTSpringAnimation alloc] initWithId:animationId
|
||||
config:config
|
||||
forNode:valueNode
|
||||
callBack:callBack];
|
||||
|
||||
} else if ([type isEqual:@"decay"]) {
|
||||
animationDriver = [[RCTDecayAnimation alloc] initWithId:animationId
|
||||
config:config
|
||||
forNode:valueNode
|
||||
callBack:callBack];
|
||||
} else {
|
||||
RCTLogError(@"Unsupported animation type: %@", config[@"type"]);
|
||||
return;
|
||||
}
|
||||
|
||||
[_activeAnimations addObject:animationDriver];
|
||||
[animationDriver startAnimation];
|
||||
[self startAnimationLoopIfNeeded];
|
||||
}
|
||||
|
||||
- (void)stopAnimation:(nonnull NSNumber *)animationId
|
||||
{
|
||||
for (id<RCTAnimationDriver> driver in _activeAnimations) {
|
||||
if ([driver.animationId isEqual:animationId]) {
|
||||
[driver stopAnimation];
|
||||
[_activeAnimations removeObject:driver];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopAnimationsForNode:(nonnull RCTAnimatedNode *)node
|
||||
{
|
||||
NSMutableArray<id<RCTAnimationDriver>> *discarded = [NSMutableArray new];
|
||||
for (id<RCTAnimationDriver> driver in _activeAnimations) {
|
||||
if ([driver.valueNode isEqual:node]) {
|
||||
[discarded addObject:driver];
|
||||
}
|
||||
}
|
||||
for (id<RCTAnimationDriver> driver in discarded) {
|
||||
[driver stopAnimation];
|
||||
[_activeAnimations removeObject:driver];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -- Events
|
||||
|
||||
- (void)addAnimatedEventToView:(nonnull NSNumber *)viewTag
|
||||
eventName:(nonnull NSString *)eventName
|
||||
eventMapping:(NSDictionary<NSString *, id> *)eventMapping
|
||||
{
|
||||
NSNumber *nodeTag = [RCTConvert NSNumber:eventMapping[@"animatedValueTag"]];
|
||||
RCTAnimatedNode *node = _animationNodes[nodeTag];
|
||||
|
||||
if (!node) {
|
||||
RCTLogError(@"Animated node with tag %@ does not exists", nodeTag);
|
||||
return;
|
||||
}
|
||||
|
||||
if (![node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
RCTLogError(@"Animated node connected to event should be of type RCTValueAnimatedNode");
|
||||
return;
|
||||
}
|
||||
|
||||
NSArray<NSString *> *eventPath = [RCTConvert NSStringArray:eventMapping[@"nativeEventPath"]];
|
||||
|
||||
RCTEventAnimation *driver =
|
||||
[[RCTEventAnimation alloc] initWithEventPath:eventPath valueNode:(RCTValueAnimatedNode *)node];
|
||||
|
||||
NSString *key = [NSString stringWithFormat:@"%@%@", viewTag, RCTNormalizeAnimatedEventName(eventName)];
|
||||
if (_eventDrivers[key] != nil) {
|
||||
[_eventDrivers[key] addObject:driver];
|
||||
} else {
|
||||
NSMutableArray<RCTEventAnimation *> *drivers = [NSMutableArray new];
|
||||
[drivers addObject:driver];
|
||||
_eventDrivers[key] = drivers;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)removeAnimatedEventFromView:(nonnull NSNumber *)viewTag
|
||||
eventName:(nonnull NSString *)eventName
|
||||
animatedNodeTag:(nonnull NSNumber *)animatedNodeTag
|
||||
{
|
||||
NSString *key = [NSString stringWithFormat:@"%@%@", viewTag, RCTNormalizeAnimatedEventName(eventName)];
|
||||
if (_eventDrivers[key] != nil) {
|
||||
if (_eventDrivers[key].count == 1) {
|
||||
[_eventDrivers removeObjectForKey:key];
|
||||
} else {
|
||||
NSMutableArray<RCTEventAnimation *> *driversForKey = _eventDrivers[key];
|
||||
for (NSUInteger i = 0; i < driversForKey.count; i++) {
|
||||
if (driversForKey[i].valueNode.nodeTag == animatedNodeTag) {
|
||||
[driversForKey removeObjectAtIndex:i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleAnimatedEvent:(id<RCTEvent>)event
|
||||
{
|
||||
if (_eventDrivers.count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
NSString *key = [NSString stringWithFormat:@"%@%@", event.viewTag, RCTNormalizeAnimatedEventName(event.eventName)];
|
||||
NSMutableArray<RCTEventAnimation *> *driversForKey = _eventDrivers[key];
|
||||
if (driversForKey) {
|
||||
for (RCTEventAnimation *driver in driversForKey) {
|
||||
[self stopAnimationsForNode:driver.valueNode];
|
||||
[driver updateWithEvent:event];
|
||||
}
|
||||
|
||||
[self updateAnimations];
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -- Listeners
|
||||
|
||||
- (void)startListeningToAnimatedNodeValue:(nonnull NSNumber *)tag
|
||||
valueObserver:(id<RCTValueAnimatedNodeObserver>)valueObserver
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[tag];
|
||||
if ([node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
((RCTValueAnimatedNode *)node).valueObserver = valueObserver;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopListeningToAnimatedNodeValue:(nonnull NSNumber *)tag
|
||||
{
|
||||
RCTAnimatedNode *node = _animationNodes[tag];
|
||||
if ([node isKindOfClass:[RCTValueAnimatedNode class]]) {
|
||||
((RCTValueAnimatedNode *)node).valueObserver = nil;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -- Animation Loop
|
||||
|
||||
- (void)startAnimationLoopIfNeeded
|
||||
{
|
||||
if (!_displayLink && _activeAnimations.count > 0) {
|
||||
_displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(stepAnimations:)];
|
||||
[_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopAnimationLoopIfNeeded
|
||||
{
|
||||
if (_activeAnimations.count == 0) {
|
||||
[self stopAnimationLoop];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stopAnimationLoop
|
||||
{
|
||||
if (_displayLink) {
|
||||
[_displayLink invalidate];
|
||||
_displayLink = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)stepAnimations:(CADisplayLink *)displaylink
|
||||
{
|
||||
NSTimeInterval time = displaylink.timestamp;
|
||||
for (id<RCTAnimationDriver> animationDriver in _activeAnimations) {
|
||||
[animationDriver stepAnimationWithTime:time];
|
||||
}
|
||||
|
||||
[self updateAnimations];
|
||||
|
||||
for (id<RCTAnimationDriver> animationDriver in [_activeAnimations copy]) {
|
||||
if (animationDriver.animationHasFinished) {
|
||||
[animationDriver stopAnimation];
|
||||
[_activeAnimations removeObject:animationDriver];
|
||||
}
|
||||
}
|
||||
|
||||
[self stopAnimationLoopIfNeeded];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -- Updates
|
||||
|
||||
- (void)updateAnimations
|
||||
{
|
||||
[_animationNodes enumerateKeysAndObjectsUsingBlock:^(NSNumber *key, RCTAnimatedNode *node, BOOL *stop) {
|
||||
if (node.needsUpdate) {
|
||||
[node updateNodeIfNecessary];
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
47
node_modules/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec
generated
vendored
Normal file
47
node_modules/react-native/Libraries/NativeAnimation/React-RCTAnimation.podspec
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
require "json"
|
||||
|
||||
package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json")))
|
||||
version = package['version']
|
||||
|
||||
source = { :git => 'https://github.com/facebook/react-native.git' }
|
||||
if version == '1000.0.0'
|
||||
# This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in.
|
||||
source[:commit] = `git rev-parse HEAD`.strip
|
||||
else
|
||||
source[:tag] = "v#{version}"
|
||||
end
|
||||
|
||||
folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32'
|
||||
folly_version = '2020.01.13.00'
|
||||
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "React-RCTAnimation"
|
||||
s.version = version
|
||||
s.summary = "A native driver for the Animated API."
|
||||
s.homepage = "https://reactnative.dev/"
|
||||
s.license = package["license"]
|
||||
s.author = "Facebook, Inc. and its affiliates"
|
||||
s.platforms = { :ios => "10.0", :tvos => "10.0" }
|
||||
s.compiler_flags = folly_compiler_flags + ' -Wno-nullability-completeness'
|
||||
s.source = source
|
||||
s.source_files = "{Drivers/*,Nodes/*,*}.{m,mm}"
|
||||
s.preserve_paths = "package.json", "LICENSE", "LICENSE-docs"
|
||||
s.header_dir = "RCTAnimation"
|
||||
s.pod_target_xcconfig = {
|
||||
"USE_HEADERMAP" => "YES",
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++14",
|
||||
"HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Folly\""
|
||||
}
|
||||
|
||||
s.dependency "Folly", folly_version
|
||||
s.dependency "RCTTypeSafety", version
|
||||
s.dependency "ReactCommon/turbomodule/core", version
|
||||
s.dependency "React-jsi", version
|
||||
s.dependency "FBReactNativeSpec", version
|
||||
s.dependency "React-Core/RCTAnimationHeaders", version
|
||||
end
|
Reference in New Issue
Block a user