Course Menu

Using d3-interpolate with Animated

Lets recreate an animation that we can typically use Animated for but do the interpolating ourselves using d3-interpolate.

We need to npm install d3-interpolate first. Or just execute an npm install as it should already be in our package.json. We'll pull in 2 different interpolators. We'll bring in interpolateNumber and interpolateRgb.

When we press our button we will animation our this.state.animation to 1. However we haven't hooked it up to anything, or any styling.

import React, { Component } from "react";
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Animated,
  TouchableWithoutFeedback,
} from "react-native";

import { interpolateNumber, interpolateRgb } from "d3-interpolate";

export default class animations extends Component {
  state = {
    animation: new Animated.Value(0),
  };
  handlePress = () => {
    Animated.timing(this.state.animation, {
      toValue: 1,
      duration: 500,
    }).start();
  };
  render() {
    return (
      <View style={styles.container}>
        <TouchableWithoutFeedback onPress={this.handlePress}>
          <View style={styles.box} ref={(view) => (this._view = view)} />
        </TouchableWithoutFeedback>
      </View>
    );
  }
}

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

Rather than hooking up our normal styling and using an Animated.View we setup a listener on our animated value.

We first need to craft our interpolations which we do very similar to interpolate in animated. The only difference here is that inputRange is always assumed to be [0, 1].

const positionInterpolate = interpolateNumber(0, 200);
const colorInterpolate = interpolateRgb("rgb(255,99,71)", "rgb(99,71,255)");

Then we attach our listener.

this.state.animation.addListener(({ value }) => {
  const position = positionInterpolate(value);
  const color = colorInterpolate(value);
});

And when our animation is triggered our callback gets called with an object with a key called value that has the value. Then we can call our interpolators to get the values.

this.state.animation.addListener(({ value }) => {
  const position = positionInterpolate(value);
  const color = colorInterpolate(value);
});

Then finally it's a matter of calling setNativeProps and updating our style accordingly.

const style = [
  styles.box,
  {
    backgroundColor: color,
    transform: [{ translateY: position }],
  },
];
this._view.setNativeProps({ style });

Here is what the complete code would look like all put together.

componentWillMount() {
    const positionInterpolate = interpolateNumber(0, 200);
    const colorInterpolate = interpolateRgb("rgb(255,99,71)", "rgb(99,71,255)");

    this.state.animation.addListener(({value}) => {
      const position = positionInterpolate(value);
      const color = colorInterpolate(value);

      const style = [
        styles.box,
        {
          backgroundColor: color,
          transform: [
            {translateY: position}
          ]
        }
      ];
      this._view.setNativeProps({ style });
    });
  }

Code