Permalink
Browse files

Implement NativeAnimated offsets on Android

Summary:
This diff implements NativeAnimation offsets on Android. Running the examples should show no change; however, calling `setOffset()` should offset the final value for any value node by that amount. This brings Android up to date with JS and iOS animation APIs.
Closes #10680

Differential Revision: D4119609

fbshipit-source-id: 96dccdf25f67c64c6787fd9ac762ec841cefc46a
  • Loading branch information...
1 parent 68c6120 commit 8e81644f64b96ab4726ce37a6a328acbe4a32783 @ryangomba ryangomba committed with Facebook Github Bot Nov 2, 2016
@@ -39,7 +39,7 @@ public void update() {
for (int i = 0; i < mInputNodes.length; i++) {
AnimatedNode animatedNode = mNativeAnimatedNodesManager.getNodeById(mInputNodes[i]);
if (animatedNode != null && animatedNode instanceof ValueAnimatedNode) {
- mValue += ((ValueAnimatedNode) animatedNode).mValue;
+ mValue += ((ValueAnimatedNode) animatedNode).getValue();
} else {
throw new JSApplicationCausedNativeException("Illegal node ID set as an input for " +
"Animated.Add node");
@@ -48,6 +48,6 @@ private double getInputNodeValue() {
}
- return ((ValueAnimatedNode) animatedNode).mValue;
+ return ((ValueAnimatedNode) animatedNode).getValue();
}
}
@@ -38,7 +38,7 @@ public void update() {
for (int i = 0; i < mInputNodes.length; i++) {
AnimatedNode animatedNode = mNativeAnimatedNodesManager.getNodeById(mInputNodes[i]);
if (animatedNode != null && animatedNode instanceof ValueAnimatedNode) {
- double value = ((ValueAnimatedNode) animatedNode).mValue;
+ double value = ((ValueAnimatedNode) animatedNode).getValue();
if (i == 0) {
mValue = value;
continue;
@@ -136,6 +136,6 @@ public void update() {
throw new IllegalStateException("Trying to update interpolation node that has not been " +
"attached to the parent");
}
- mValue = interpolate(mParent.mValue, mInputRange, mOutputRange, mExtrapolateLeft, mExtrapolateRight);
+ mValue = interpolate(mParent.getValue(), mInputRange, mOutputRange, mExtrapolateLeft, mExtrapolateRight);
}
}
@@ -39,7 +39,7 @@ public void update() {
for (int i = 0; i < mInputNodes.length; i++) {
AnimatedNode animatedNode = mNativeAnimatedNodesManager.getNodeById(mInputNodes[i]);
if (animatedNode != null && animatedNode instanceof ValueAnimatedNode) {
- mValue *= ((ValueAnimatedNode) animatedNode).mValue;
+ mValue *= ((ValueAnimatedNode) animatedNode).getValue();
} else {
throw new JSApplicationCausedNativeException("Illegal node ID set as an input for " +
"Animated.multiply node");
@@ -243,6 +243,26 @@ public void execute(NativeAnimatedNodesManager animatedNodesManager) {
}
@ReactMethod
+ public void setAnimatedNodeOffset(final int tag, final double value) {
+ mOperations.add(new UIThreadOperation() {
+ @Override
+ public void execute(NativeAnimatedNodesManager animatedNodesManager) {
+ animatedNodesManager.setAnimatedNodeOffset(tag, value);
+ }
+ });
+ }
+
+ @ReactMethod
+ public void flattenAnimatedNodeOffset(final int tag) {
+ mOperations.add(new UIThreadOperation() {
+ @Override
+ public void execute(NativeAnimatedNodesManager animatedNodesManager) {
+ animatedNodesManager.flattenAnimatedNodeOffset(tag);
+ }
+ });
+ }
+
+ @ReactMethod
public void startAnimatingNode(
final int animationId,
final int animatedNodeTag,
@@ -136,6 +136,25 @@ public void setAnimatedNodeValue(int tag, double value) {
mUpdatedNodes.add(node);
}
+ public void setAnimatedNodeOffset(int tag, double offset) {
+ AnimatedNode node = mAnimatedNodes.get(tag);
+ if (node == null || !(node instanceof ValueAnimatedNode)) {
+ throw new JSApplicationIllegalArgumentException("Animated node with tag " + tag +
+ " does not exists or is not a 'value' node");
+ }
+ ((ValueAnimatedNode) node).mOffset = offset;
+ mUpdatedNodes.add(node);
+ }
+
+ public void flattenAnimatedNodeOffset(int tag) {
+ AnimatedNode node = mAnimatedNodes.get(tag);
+ if (node == null || !(node instanceof ValueAnimatedNode)) {
+ throw new JSApplicationIllegalArgumentException("Animated node with tag " + tag +
+ " does not exists or is not a 'value' node");
+ }
+ ((ValueAnimatedNode) node).flattenOffset();
+ }
+
public void startAnimatingNode(
int animationId,
int animatedNodeTag,
@@ -56,7 +56,7 @@ public final void updateView(UIImplementation uiImplementation) {
} else if (node instanceof StyleAnimatedNode) {
((StyleAnimatedNode) node).collectViewUpdates(propsMap);
} else if (node instanceof ValueAnimatedNode) {
- propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).mValue);
+ propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).getValue());
} else {
throw new IllegalArgumentException("Unsupported type of node used in property node " +
node.getClass());
@@ -46,7 +46,7 @@ public void collectViewUpdates(JavaOnlyMap propsMap) {
} else if (node instanceof TransformAnimatedNode) {
((TransformAnimatedNode) node).collectViewUpdates(propsMap);
} else if (node instanceof ValueAnimatedNode) {
- propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).mValue);
+ propsMap.putDouble(entry.getKey(), ((ValueAnimatedNode) node).getValue());
} else {
throw new IllegalArgumentException("Unsupported type of node used in property node " +
node.getClass());
@@ -70,7 +70,7 @@ public void collectViewUpdates(JavaOnlyMap propsMap) {
if (node == null) {
throw new IllegalArgumentException("Mapped style node does not exists");
} else if (node instanceof ValueAnimatedNode) {
- value = ((ValueAnimatedNode) node).mValue;
+ value = ((ValueAnimatedNode) node).getValue();
} else {
throw new IllegalArgumentException("Unsupported type of node used as a transform child " +
"node " + node.getClass());
@@ -19,6 +19,7 @@
*/
/*package*/ class ValueAnimatedNode extends AnimatedNode {
/*package*/ double mValue = Double.NaN;
+ /*package*/ double mOffset = 0;
private @Nullable AnimatedNodeValueListener mValueListener;
public ValueAnimatedNode() {
@@ -27,6 +28,16 @@ public ValueAnimatedNode() {
public ValueAnimatedNode(ReadableMap config) {
mValue = config.getDouble("value");
+ mOffset = config.getDouble("offset");
+ }
+
+ public double getValue() {
+ return mOffset + mValue;
+ }
+
+ public void flattenOffset() {
+ mValue += mOffset;
+ mOffset = 0;
}
public void onValueUpdate() {
@@ -121,7 +121,7 @@ public Object answer(InvocationOnMock invocation) throws Throwable {
private void createSimpleAnimatedViewWithOpacity(int viewTag, double opacity) {
mNativeAnimatedNodesManager.createAnimatedNode(
1,
- JavaOnlyMap.of("type", "value", "value", opacity));
+ JavaOnlyMap.of("type", "value", "value", opacity, "offset", 0d));
mNativeAnimatedNodesManager.createAnimatedNode(
2,
JavaOnlyMap.of("type", "style", "style", JavaOnlyMap.of("opacity", 1)));
@@ -387,10 +387,10 @@ private void createAnimatedGraphWithAdditionNode(
double secondValue) {
mNativeAnimatedNodesManager.createAnimatedNode(
1,
- JavaOnlyMap.of("type", "value", "value", 100d));
+ JavaOnlyMap.of("type", "value", "value", 100d, "offset", 0d));
mNativeAnimatedNodesManager.createAnimatedNode(
2,
- JavaOnlyMap.of("type", "value", "value", 1000d));
+ JavaOnlyMap.of("type", "value", "value", 1000d, "offset", 0d));
mNativeAnimatedNodesManager.createAnimatedNode(
3,
@@ -558,10 +558,10 @@ public void testViewReceiveUpdatesWhenOneOfAnimationHasFinished() {
public void testMultiplicationNode() {
mNativeAnimatedNodesManager.createAnimatedNode(
1,
- JavaOnlyMap.of("type", "value", "value", 1d));
+ JavaOnlyMap.of("type", "value", "value", 1d, "offset", 0d));
mNativeAnimatedNodesManager.createAnimatedNode(
2,
- JavaOnlyMap.of("type", "value", "value", 5d));
+ JavaOnlyMap.of("type", "value", "value", 5d, "offset", 0d));
mNativeAnimatedNodesManager.createAnimatedNode(
3,
@@ -669,7 +669,7 @@ public void testHandleStoppingAnimation() {
public void testInterpolationNode() {
mNativeAnimatedNodesManager.createAnimatedNode(
1,
- JavaOnlyMap.of("type", "value", "value", 10d));
+ JavaOnlyMap.of("type", "value", "value", 10d, "offset", 0d));
mNativeAnimatedNodesManager.createAnimatedNode(
2,

0 comments on commit 8e81644

Please sign in to comment.