Skip to content

Commit

Permalink
Add support for clamping for NativeAnimated on iOS
Browse files Browse the repository at this point in the history
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 #9625

Differential Revision: D4053231

fbshipit-source-id: 29048de444ff5f6d7fe7dce7897399b483ee6d2d
  • Loading branch information
ryangomba authored and Facebook Github Bot committed Oct 20, 2016
1 parent 518915a commit 5794ff6
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 21 deletions.
5 changes: 3 additions & 2 deletions Examples/UIExplorer/js/NativeAnimationsExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ exports.examples = [
},
},
{
title: 'Scale interpolation',
title: 'Scale interpolation with clamping',
description: 'description',
render: function() {
return (
Expand All @@ -335,8 +335,9 @@ exports.examples = [
transform: [
{
scale: anim.interpolate({
inputRange: [0, 1],
inputRange: [0, 0.5],
outputRange: [1, 1.4],
extrapolateRight: 'clamp',
})
}
],
Expand Down
13 changes: 11 additions & 2 deletions Libraries/NativeAnimation/Nodes/RCTAnimationDriverNode.m
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,23 @@ - (void)stepAnimation
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];
Expand Down
21 changes: 13 additions & 8 deletions Libraries/NativeAnimation/Nodes/RCTInterpolationAnimatedNode.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ @implementation RCTInterpolationAnimatedNode
__weak RCTValueAnimatedNode *_parentNode;
NSArray<NSNumber *> *_inputRange;
NSArray<NSNumber *> *_outputRange;
NSString *_extrapolateLeft;
NSString *_extrapolateRight;
}

- (instancetype)initWithTag:(NSNumber *)tag
Expand All @@ -29,6 +31,8 @@ - (instancetype)initWithTag:(NSNumber *)tag
}
}
_outputRange = [outputRange copy];
_extrapolateLeft = config[@"extrapolateLeft"];
_extrapolateRight = config[@"extrapolateRight"];
}
return self;
}
Expand Down Expand Up @@ -70,19 +74,20 @@ - (void)performUpdate
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
14 changes: 10 additions & 4 deletions Libraries/NativeAnimation/RCTAnimationUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
38 changes: 33 additions & 5 deletions Libraries/NativeAnimation/RCTAnimationUtils.m
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 5794ff6

Please sign in to comment.