## Flip Values

Building off of our interpolations on interpolations we can also flip numbers. `inputRange` is only able to accept values that move in an increasing fashion. However you may be constructing reversed animations that would require you to do an inputRange of `[1, 0]`.

To accommodate this we can interpolate to an `outputRange` that flips in reverse for us so that our animation is moving forward from `0 => 1` the interpolate will flip it to be animating from `1 => 0`, which then we can interpolate on our second animation in the correct direction `[0, 1]` but it will actually be animating in reverse.

``````const animatedInterpolate = this.state.animation.interpolate({
inputRange: [0, 1],
outputRange: [1, 0],
});

const reversedDirection = animatedInterpolate.interpolate({
inputRange: [0, 1],
outputRange: [1, 0.5],
});
``````

This can be confusing to understand, but just knowing that it's a thing will come in handy when you realize you need it.

Just interpolating numbers to different numbers is going to be your primary use case of using interpolate. This may be mapping values up, down, or any direction depending on what your animation requires.

Scaling values up would look something like this. We have an inputRange that will take an animation that is animating from `0` to `1`.

``````this.state.animation.interpolate({
inputRange: [0, 1],
outputRange: [0, 100],
});
``````

Now if we were to kick off an animation

``````Animated.timing(this.state.animation, {
toValue: 1,
duration: 1000,
}).start();
``````

The output over the course of `1000ms` would churn out values like so.

``````input: 0 => 0ms => output: 0
input: .1 => 100ms => output: 10
input: .2 => 200ms => output: 20
input: .3 => 300ms => output: 30
....
input: 1 => 1000ms => output: 100
``````

The same goes for the opposite direction. We can scale numbers down from larger => smaller

``````this.state.animation.interpolate({
inputRange: [0, 100],
outputRange: [0, 1],
});
``````

Kicking off an animation

``````Animated.timing(this.state.animation, {
toValue: 1,
duration: 1000,
}).start();
``````

Would produce values

``````input: 0 => 0ms => output: 0
input: 10 => 100ms => output: .1
input: 20 => 200ms => output: .2
input: 30 => 300ms => output: .3
....
input: 100 => 1000ms => output: 1
``````

These are examples where the `inputRange` is producing a linear `outputRange`, but the `inputRange` is the only thing that needs to be moving in an increasing fashion. The `outputRange` could be anything. The only requirement is that the `inputRange` and `outputRange` have the same number of items in their respective arrays.

Lets look at an interpolation

``````this.state.animation.interpolate({
inputRange: [0, 30, 50, 80, 100],
outputRange: [0, -30, -50, 0, 200],
});
``````

Lets take a look at what values would be produced with the animation

``````Animated.timing(this.state.animation, {
toValue: 1,
duration: 1000,
}).start();
``````
``````input: 0 => 0ms => 0
input 15 => 150ms => -15
input 30 => 300ms => -30
input 50 => 500ms => -50
input 65 => 650ms => -25
input 80 => 800ms => 0
input 90 => 900ms => 100
input 100 => 100ms => 200
``````

As you can see our animated value only ever increased, but our `outputRange` intermediate values were interpolated correctly based upon the steps in between each range and it's targeted output range.

Understanding all the intermediate values can be necessary however, for many animations it's not critical. Interpolate will figure out the steps correctly based upon your duration, or spring.

Now realize that `interpolate` is returning a new `Animated.Value` so what that means is you can interpolate on an interpolate.

Lets look at an example of this.

``````export default class animations extends Component {
state = {
animation: new Animated.Value(0),
};
startAnimation = () => {
Animated.timing(this.state.animation, {
toValue: 1,
duration: 1500,
}).start(() => {
Animated.timing(this.state.animation, {
toValue: 2,
duration: 300,
}).start();
});
};

render() {
const animatedInterpolate = this.state.animation.interpolate({
inputRange: [0, 1, 2],
outputRange: [0, 300, 0],
});

const interpolatedInterpolate = animatedInterpolate.interpolate({
inputRange: [0, 300],
outputRange: [1, 0.5],
});

const animatedStyles = {
transform: [{ translateY: animatedInterpolate }],
opacity: interpolatedInterpolate,
};
return (
<View style={styles.container}>
<TouchableWithoutFeedback onPress={this.startAnimation}>
<Animated.View style={[styles.box, animatedStyles]} />
</TouchableWithoutFeedback>
</View>
);
}
}

const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: "center",
justifyContent: "center",
},
box: {
width: 150,
height: 150,
backgroundColor: "tomato",
},
});
``````

Lets focus on the important piece.

Our animation is only going to 2, however our `interpolateInterpolate` is referencing the values that are in the `outputRange` of our first animated interpolate. This can be a powerful tool when passing around animated interpolations.

``````const animatedInterpolate = this.state.animation.interpolate({
inputRange: [0, 1, 2],
outputRange: [0, 300, 0],
});

const interpolatedInterpolate = animatedInterpolate.interpolate({
inputRange: [0, 300],
outputRange: [1, 0.5],
});
`````` If you do not want to expose the original animated value, or your interpolation only operates across a specific range. You can interpolate an interpolate before passing it to something that will interpolate it.

Quick example, if we had an animation that went from `0` to `300`, but something required a range from `0` to `1`. We can map our desired inputRange to an outputRange that will feed into our second animation inputRange and derive our desired outputRange.

``````const animatedInterpolate = this.state.animation.interpolate({
inputRange: [0, 300],
outputRange: [0, 1],
extrapolate: "clamp",
});

const interpolatedInterpolate = animatedInterpolate.interpolate({
inputRange: [0, 1],
outputRange: [1, 0.5],
});
``````

Interpolating interpolations can be challenging to wrap your head around but can be extremely powerful in practice.

Live Demo