Add support for clamping for NativeAnimated on iOS
Summary: This diff adds support for clamping on iOS. It separates out code originally submitted in #9048. Test plan (required) Run UIExplorer NativeAnimated examples before and after - compare the results. Pay special attention to the new clamped spring example. Closes https://github.com/facebook/react-native/pull/9625 Differential Revision: D4053231 fbshipit-source-id: 29048de444ff5f6d7fe7dce7897399b483ee6d2d
This commit is contained in:
parent
518915a750
commit
5794ff61bc
|
@ -320,7 +320,7 @@ exports.examples = [
|
|||
},
|
||||
},
|
||||
{
|
||||
title: 'Scale interpolation',
|
||||
title: 'Scale interpolation with clamping',
|
||||
description: 'description',
|
||||
render: function() {
|
||||
return (
|
||||
|
@ -335,8 +335,9 @@ exports.examples = [
|
|||
transform: [
|
||||
{
|
||||
scale: anim.interpolate({
|
||||
inputRange: [0, 1],
|
||||
inputRange: [0, 0.5],
|
||||
outputRange: [1, 1.4],
|
||||
extrapolateRight: 'clamp',
|
||||
})
|
||||
}
|
||||
],
|
||||
|
|
|
@ -118,14 +118,23 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
|
|||
fromInterval,
|
||||
toInterval,
|
||||
fromFrameValue.doubleValue,
|
||||
toFrameValue.doubleValue);
|
||||
toFrameValue.doubleValue,
|
||||
EXTRAPOLATE_TYPE_EXTEND,
|
||||
EXTRAPOLATE_TYPE_EXTEND);
|
||||
|
||||
[self updateOutputWithFrameOutput:frameOutput];
|
||||
}
|
||||
|
||||
- (void)updateOutputWithFrameOutput:(CGFloat)frameOutput
|
||||
{
|
||||
CGFloat outputValue = RCTInterpolateValue(frameOutput, 0, 1, _fromValue, _toValue);
|
||||
CGFloat outputValue = RCTInterpolateValue(frameOutput,
|
||||
0,
|
||||
1,
|
||||
_fromValue,
|
||||
_toValue,
|
||||
EXTRAPOLATE_TYPE_EXTEND,
|
||||
EXTRAPOLATE_TYPE_EXTEND);
|
||||
|
||||
_outputValue = @(outputValue);
|
||||
_valueNode.value = outputValue;
|
||||
[_valueNode setNeedsUpdate];
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
__weak RCTValueAnimatedNode *_parentNode;
|
||||
NSArray<NSNumber *> *_inputRange;
|
||||
NSArray<NSNumber *> *_outputRange;
|
||||
NSString *_extrapolateLeft;
|
||||
NSString *_extrapolateRight;
|
||||
}
|
||||
|
||||
- (instancetype)initWithTag:(NSNumber *)tag
|
||||
|
@ -29,6 +31,8 @@
|
|||
}
|
||||
}
|
||||
_outputRange = [outputRange copy];
|
||||
_extrapolateLeft = config[@"extrapolateLeft"];
|
||||
_extrapolateRight = config[@"extrapolateRight"];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -70,19 +74,20 @@
|
|||
return;
|
||||
}
|
||||
|
||||
NSUInteger rangeIndex = [self findIndexOfNearestValue:_parentNode.value
|
||||
inRange:_inputRange];
|
||||
CGFloat inputValue = _parentNode.value;
|
||||
NSUInteger rangeIndex = [self findIndexOfNearestValue:inputValue inRange:_inputRange];
|
||||
NSNumber *inputMin = _inputRange[rangeIndex];
|
||||
NSNumber *inputMax = _inputRange[rangeIndex + 1];
|
||||
NSNumber *outputMin = _outputRange[rangeIndex];
|
||||
NSNumber *outputMax = _outputRange[rangeIndex + 1];
|
||||
|
||||
CGFloat outputValue = RCTInterpolateValue(_parentNode.value,
|
||||
inputMin.doubleValue,
|
||||
inputMax.doubleValue,
|
||||
outputMin.doubleValue,
|
||||
outputMax.doubleValue);
|
||||
self.value = outputValue;
|
||||
self.value = RCTInterpolateValue(inputValue,
|
||||
inputMin.doubleValue,
|
||||
inputMax.doubleValue,
|
||||
outputMin.doubleValue,
|
||||
outputMax.doubleValue,
|
||||
_extrapolateLeft,
|
||||
_extrapolateRight);
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -12,11 +12,17 @@
|
|||
|
||||
#import "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 RCTInterpolateValue(CGFloat value,
|
||||
CGFloat fromMin,
|
||||
CGFloat fromMax,
|
||||
CGFloat toMin,
|
||||
CGFloat toMax);
|
||||
CGFloat inputMin,
|
||||
CGFloat inputMax,
|
||||
CGFloat outputMin,
|
||||
CGFloat outputMax,
|
||||
NSString *extrapolateLeft,
|
||||
NSString *extrapolateRight);
|
||||
|
||||
RCT_EXTERN CGFloat RCTRadiansToDegrees(CGFloat radians);
|
||||
RCT_EXTERN CGFloat RCTDegreesToRadians(CGFloat degrees);
|
||||
|
|
|
@ -9,16 +9,44 @@
|
|||
|
||||
#import "RCTAnimationUtils.h"
|
||||
|
||||
#import "RCTLog.h"
|
||||
|
||||
/**
|
||||
* Interpolates value by remapping it linearly fromMin->fromMax to toMin->toMax
|
||||
*/
|
||||
CGFloat RCTInterpolateValue(CGFloat value,
|
||||
CGFloat fromMin,
|
||||
CGFloat fromMax,
|
||||
CGFloat toMin,
|
||||
CGFloat toMax)
|
||||
CGFloat inputMin,
|
||||
CGFloat inputMax,
|
||||
CGFloat outputMin,
|
||||
CGFloat outputMax,
|
||||
NSString *extrapolateLeft,
|
||||
NSString *extrapolateRight)
|
||||
{
|
||||
return toMin + (value - fromMin) * (toMax - toMin) / (fromMax - fromMin);
|
||||
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);
|
||||
}
|
||||
|
||||
CGFloat RCTRadiansToDegrees(CGFloat radians)
|
||||
|
|
Loading…
Reference in New Issue