TutorialsCourses
Course Menu
Master React Native Animations

Width/Height Values

Animating width and height values will effect layout. These may not always be the most performant however sometimes they are necessary. These are commonly used when you have predefined sizing. They are also typically used for dynamic sizing. With React Native you are able to measure the size of elements asynchronously.

One common animation is an accordion. With dynamic measurement you could measure the height of some content then animate the content from a predefined height to it's actual height. There are many other possibilities but we'll cover those in our more complex examples. This may not be performant on larger blocks of content and is actually a very difficult animation.

Lets look at an example of heigh animations and how they effect layout.

export default class animations extends Component {
  state = {
    animation: new Animated.Value(100),
  };

  componentDidMount() {
    Animated.timing(this.state.animation, {
      toValue: 200,
    }).start();
  }

  render() {
    const boxStyle = {
      height: this.state.animation,
    };

    return (
      <View style={styles.container}>
        <View>
          <Animated.View style={[styles.box, boxStyle]} />
          <View style={styles.box2} />
        </View>
      </View>
    );
  }
}

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

We have a box, and a box of the same size sitting right below it. When we animate the bottom box will be pushed down as the layout of the box1 increases from 100 to 200.

export default class animations extends Component {
  state = {
    animation: new Animated.Value(1),
  };

  componentDidMount() {
    Animated.timing(this.state.animation, {
      toValue: 2,
      duration: 250,
    }).start();
  }

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

    const boxStyle = {
      transform: [
        { scaleY: this.state.animation },
        { translateY: yInterpolate },
      ],
    };

    return (
      <View style={styles.container}>
        <View>
          <View style={styles.box2} />
          <Animated.View style={[styles.box, boxStyle]} />
        </View>
      </View>
    );
  }
}

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

However if we were to use a scale the layout won't be effected but our box will still reach 200 in size. We move our first box to the bottom so it will sit on top when it animates. Now when we scaleY to increase our box1 to 200. Then also move it up -25. This will cover the previous box and not move it out of the way like when we animate the layout.

Just understand that when you need to adjust the size of a particular element and you want to do it performantly you will need to use size. However because it won't effect layout you may need to use translates to move other elements as well. This is less than ideal but may be necessary to maintain a 60 FPS animation.

Live Demo