isak.me - a blog by isak solheim

Bi-weekly updates about things that interest me, things I have built and things I have learned.

How To Create a Rotation Animation In React Native

In this tutorial, I’ll show you how to create a button that rotates 720 degrees when it’s pressed. We will be using the React Native Animated animation system to create the rotation animation.

Creating the component

First, we create the functional component ButtonWithSpin that has a TouchableOpacity component with some text inside.

return (
  <TouchableOpacity
    onPress={async () => handleAnimation()}
    style={{ width: 60 }}
  >
    <Animated.Text style={animatedStyle}>Click me</Animated.Text>
  </TouchableOpacity>
)

Notice that the text is created using the Animated.Text component. This is because the text that is going to rotate has to be animatable. If you are rotating something else, then you can use any of these components as well:

  • Animated.Image
  • Animated.ScrollView
  • Animated.View
  • Animated.Text
  • Animated.FlatList
  • Animated.SectionList

We also use the useState Hook to store our rotateAnimation value. This is an animation value from the Animated library. We use `new Animated.Value(0) to initialize the value.

The handleAnimation function

const handleAnimation = () => {
  Animated.timing(rotateAnimation, {
    toValue: 1,
    duration: 800,
  }).start(() => {
    rotateAnimation.setValue(0)
  })
}

Animated.timing() animates a value over time using easing functions. By default, it uses the easeInOut curve which is perfect for what we are making. We pass our rotateAnimation value and a config value, where we set the duration to be 800ms. The animation is started by calling start(), and we include a callback function that resets the animation.

Interpolate

The interpolate() method maps input ranges to output ranges. A basic mapping to convert a 0–1 range to a 0–100 range would be:

value.interpolate({
  inputRange: [0, 1],
  outputRange: [0, 100],
})

You can also use the `interpolate() method to map out strings. Since we want to rotate our text from 0 degrees to 720 degrees, our code will look like this:

const interpolateRotating = rotateAnimation.interpolate({
  inputRange: [0, 1],
  outputRange: ['0deg', '720deg'],
})

const animatedStyle = {
  transform: [
    {
      rotate: interpolateRotating,
    },
  ],
}

We also created the animatedStyle object, which includes an array transform with the rotate value interpolateRotating that we just created.

Putting everything together

Add the animatedStyle object to the Animated.Text component and a width to the TouchableOpacity component and we are done!

Button spinning after click

import React, { useState } from 'react'
import { TouchableOpacity, Animated } from 'react-native'

const ButtonWithSpin = () => {
  const [rotateAnimation, setRotateAnimation] = useState(new Animated.Value(0))

  const handleAnimation = () => {
    Animated.timing(rotateAnimation, {
      toValue: 1,
      duration: 800,
    }).start(() => {
      rotateAnimation.setValue(0)
    })
  }

  const interpolateRotating = rotateAnimation.interpolate({
    inputRange: [0, 1],
    outputRange: ['0deg', '720deg'],
  })

  const animatedStyle = {
    transform: [
      {
        rotate: interpolateRotating,
      },
    ],
  }

  return (
    <TouchableOpacity
      onPress={async () => handleAnimation()}
      style={{ width: 60 }}
    >
      <Animated.Text style={animatedStyle}>Click me</Animated.Text>
    </TouchableOpacity>
  )
}

export default ButtonWithSpin

And there we have it. I hope you have found this useful.