mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-05-10 01:15:00 +08:00
Support for Animated.interpolate
Summary:This change adds native animated support for Animated.interpolate Animated.interpolate allows for defining nodes that outputs an interpolated value of their input node based on the interpolation node configuration. For now native animated implementation only supports a linear interpolation for a given input and output ranges (ranges can consists of multiple segments). Native interpolation node is compatible with the JS implementation with the exception that not all attributes that can be used in JS are supported. Before we migrate interpolation node from JS->native we verify that only supported props are used. **Test Plan** Run JS tests: `npm test Libraries/Animated/src/__tests__/AnimatedNative-test.js` Run java tests: `buck test ReactAndroid/src/test/java/com/facebook/react/animated` Closes https://github.com/facebook/react-native/pull/7141 Differential Revision: D3216546 fb-gh-sync-id: 29876e33956615c6370ca4d332abe048f8dba5b8 fbshipit-source-id: 29876e33956615c6370ca4d332abe048f8dba5b8
This commit is contained in:
committed by
Facebook Github Bot 9
parent
a31e87b3f2
commit
dd244f5530
@@ -0,0 +1,89 @@
|
||||
package com.facebook.react.animated;
|
||||
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Animated node that corresponds to {@code AnimatedInterpolation} from AnimatedImplementation.js.
|
||||
*
|
||||
* Currently only a linear interpolation is supported on an input range of an arbitrary size.
|
||||
*/
|
||||
/*package*/ class InterpolationAnimatedNode extends ValueAnimatedNode {
|
||||
|
||||
private static double[] fromDoubleArray(ReadableArray ary) {
|
||||
double[] res = new double[ary.size()];
|
||||
for (int i = 0; i < res.length; i++) {
|
||||
res[i] = ary.getDouble(i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private static double interpolate(
|
||||
double value,
|
||||
double inputMin,
|
||||
double inputMax,
|
||||
double outputMin,
|
||||
double outputMax) {
|
||||
return outputMin + (outputMax - outputMin) *
|
||||
(value - inputMin) / (inputMax - inputMin);
|
||||
}
|
||||
|
||||
/*package*/ static double interpolate(double value, double[] inputRange, double[] outputRange) {
|
||||
int rangeIndex = findRangeIndex(value, inputRange);
|
||||
return interpolate(
|
||||
value,
|
||||
inputRange[rangeIndex],
|
||||
inputRange[rangeIndex + 1],
|
||||
outputRange[rangeIndex],
|
||||
outputRange[rangeIndex + 1]);
|
||||
}
|
||||
|
||||
private static int findRangeIndex(double value, double[] ranges) {
|
||||
int index;
|
||||
for (index = 1; index < ranges.length - 1; index++) {
|
||||
if (ranges[index] >= value) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return index - 1;
|
||||
}
|
||||
|
||||
private final double mInputRange[];
|
||||
private final double mOutputRange[];
|
||||
private @Nullable ValueAnimatedNode mParent;
|
||||
|
||||
public InterpolationAnimatedNode(ReadableMap config) {
|
||||
mInputRange = fromDoubleArray(config.getArray("inputRange"));
|
||||
mOutputRange = fromDoubleArray(config.getArray("outputRange"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttachedToNode(AnimatedNode parent) {
|
||||
if (mParent != null) {
|
||||
throw new IllegalStateException("Parent already attached");
|
||||
}
|
||||
if (!(parent instanceof ValueAnimatedNode)) {
|
||||
throw new IllegalArgumentException("Parent is of an invalid type");
|
||||
}
|
||||
mParent = (ValueAnimatedNode) parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromNode(AnimatedNode parent) {
|
||||
if (parent != mParent) {
|
||||
throw new IllegalArgumentException("Invalid parent node provided");
|
||||
}
|
||||
mParent = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
if (mParent == null) {
|
||||
throw new IllegalStateException("Trying to update interpolation node that has not been " +
|
||||
"attached to the parent");
|
||||
}
|
||||
mValue = interpolate(mParent.mValue, mInputRange, mOutputRange);
|
||||
}
|
||||
}
|
||||
@@ -72,6 +72,8 @@ import javax.annotation.Nullable;
|
||||
mUpdatedNodes.add(node);
|
||||
} else if ("props".equals(type)) {
|
||||
node = new PropsAnimatedNode(config, this);
|
||||
} else if ("interpolation".equals(type)) {
|
||||
node = new InterpolationAnimatedNode(config);
|
||||
} else if ("addition".equals(type)) {
|
||||
node = new AdditionAnimatedNode(config, this);
|
||||
} else if ("multiplication".equals(type)) {
|
||||
|
||||
Reference in New Issue
Block a user