react-router-native-stack icon indicating copy to clipboard operation
react-router-native-stack copied to clipboard

Could we use animated value from 0 to 1 and interpolate

Open gabrielbull opened this issue 7 years ago • 2 comments

If we used an animated value from 0 to 1 instead of 0 to dimension we could then use that value to interpolate other animations. Take for example the header used by Apple in their Settings app:

ezgif com-video-to-gif

It uses multiple transitions derived from the animated value. Look at how the back arrow is transitioned by fade in/fade out. Also look at how the title is transitioned into the back button, the General title moves and changes color to become the back button.

These changes would need to be made

Change the pan responder to give a fraction instead of the moveX value:

https://github.com/Traviskn/react-router-native-stack/blob/c6a0e3a7e09f9b7d67db498853c60784f662685c/lib/StackTransitioner.js#L70-L72

    onPanResponderMove: (event, { moveX }) => {
-      this.animatedValue.setValue(moveX);
+      this.animatedValue.setValue(moveX / this.getDimension());
    },

Change the finish animation to go to 1:

https://github.com/Traviskn/react-router-native-stack/blob/c6a0e3a7e09f9b7d67db498853c60784f662685c/lib/StackTransitioner.js#L111-L121

  finishNavigation = duration => {
    Animated.timing(this.animatedValue, {
-      toValue: this.getDimension(),
+      toValue: 1,
      duration,
      useNativeDriver: true,
    }).start(({ finished }) => {
      if (finished) {
        this.afterPan();
      }
    });
  };

This one too:

https://github.com/Traviskn/react-router-native-stack/blob/c6a0e3a7e09f9b7d67db498853c60784f662685c/lib/StackTransitioner.js#L184-L189

          this.animation = Animated.timing(this.animatedValue, {
            duration: getDuration(routeAnimationType || nextProps.animationType, action),
-            toValue: action === PUSH ? -dimension : dimension,
+            toValue: action === PUSH ? 0: 1,
            easing: getEasing(routeAnimationType || nextProps.animationType),
            useNativeDriver: true,
          }).start()

All lines that use the animated value in getTransforms would need to be converted to interpolate:

https://github.com/Traviskn/react-router-native-stack/blob/c6a0e3a7e09f9b7d67db498853c60784f662685c/lib/getTransforms.js#L13-L16

    const baseStyle = {
      elevation: 1,
-      transform: [{ translateX: animation }],
+      transform: [{ translateX: animation.interpolate({
+        inputRange: [0, 1],
+         outputRange: [0, width]
+      }) }],
    };

gabrielbull avatar Mar 23 '18 01:03 gabrielbull

I am working on implementing that exact type of ios style transition in the header branch of this repository. So far I've been interpolating based on the animation values of 0 to dimension, but working with a value from 0 to 1 would probably be a cleaner way to go I agree

Traviskn avatar Mar 23 '18 02:03 Traviskn

After reviewing the code a bit more, my transitions are a bit more complicated that just going from 0 to dimension. Depending on the direction of the animation, I also go from 0 to -dimension. So if we wanted to take your suggested approach we would probably end up transitioning between -1, 0, and 1.

Traviskn avatar Aug 18 '18 20:08 Traviskn