mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-04-02 09:21:44 +08:00
Support for spring animations
Summary: This change adds support for spring animations to be run off the JS thread on android. The implementation is based on the android spring implementation from Rebound (http://facebook.github.io/rebound/) but since only a small subset of the library is used the relevant parts are copied instead of making RN to import the whole library. **Test Plan** Run java tests: `buck test ReactAndroid/src/test/java/com/facebook/react/animated` Add `useNativeDriver: true` to spring animation in animated example app, run it on android Closes https://github.com/facebook/react-native/pull/8860 Differential Revision: D3676436 fbshipit-source-id: 3a4b1b006725a938562712989b93dd4090577c48
This commit is contained in:
committed by
Facebook Github Bot 2
parent
0222107170
commit
8f75d7346f
@@ -35,6 +35,7 @@ import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.atMost;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -198,6 +199,66 @@ public class NativeAnimatedNodeTraversalTest {
|
||||
verifyNoMoreInteractions(valueListener);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringAnimation() {
|
||||
createSimpleAnimatedViewWithOpacity(1000, 0d);
|
||||
|
||||
Callback animationCallback = mock(Callback.class);
|
||||
mNativeAnimatedNodesManager.startAnimatingNode(
|
||||
1,
|
||||
1,
|
||||
JavaOnlyMap.of(
|
||||
"type",
|
||||
"spring",
|
||||
"friction",
|
||||
7d,
|
||||
"tension",
|
||||
40.0d,
|
||||
"initialVelocity",
|
||||
0d,
|
||||
"toValue",
|
||||
1d,
|
||||
"restSpeedThreshold",
|
||||
0.001d,
|
||||
"restDisplacementThreshold",
|
||||
0.001d,
|
||||
"overshootClamping",
|
||||
false),
|
||||
animationCallback);
|
||||
|
||||
ArgumentCaptor<ReactStylesDiffMap> stylesCaptor =
|
||||
ArgumentCaptor.forClass(ReactStylesDiffMap.class);
|
||||
|
||||
reset(mUIImplementationMock);
|
||||
mNativeAnimatedNodesManager.runUpdates(nextFrameTime());
|
||||
verify(mUIImplementationMock).synchronouslyUpdateViewOnUIThread(eq(1000), stylesCaptor.capture());
|
||||
assertThat(stylesCaptor.getValue().getDouble("opacity", Double.NaN)).isEqualTo(0);
|
||||
|
||||
double previousValue = 0d;
|
||||
boolean wasGreaterThanOne = false;
|
||||
/* run 3 secs of animation */
|
||||
for (int i = 0; i < 3 * 60; i++) {
|
||||
reset(mUIImplementationMock);
|
||||
mNativeAnimatedNodesManager.runUpdates(nextFrameTime());
|
||||
verify(mUIImplementationMock, atMost(1))
|
||||
.synchronouslyUpdateViewOnUIThread(eq(1000), stylesCaptor.capture());
|
||||
double currentValue = stylesCaptor.getValue().getDouble("opacity", Double.NaN);
|
||||
if (currentValue > 1d) {
|
||||
wasGreaterThanOne = true;
|
||||
}
|
||||
// verify that animation step is relatively small
|
||||
assertThat(Math.abs(currentValue - previousValue)).isLessThan(0.1d);
|
||||
previousValue = currentValue;
|
||||
}
|
||||
// verify that we've reach the final value at the end of animation
|
||||
assertThat(previousValue).isEqualTo(1d);
|
||||
// verify that value has reached some maximum value that is greater than the final value (bounce)
|
||||
assertThat(wasGreaterThanOne);
|
||||
reset(mUIImplementationMock);
|
||||
mNativeAnimatedNodesManager.runUpdates(nextFrameTime());
|
||||
verifyNoMoreInteractions(mUIImplementationMock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAnimationCallbackFinish() {
|
||||
createSimpleAnimatedViewWithOpacity(1000, 0d);
|
||||
|
||||
Reference in New Issue
Block a user