React Native: How do you animate the rotation of an Image?

JavascriptReact NativeAnimationRotationTransform

Javascript Problem Overview


Rotation is a style transform and in RN, you can rotate things like this

  render() {
    return (
      <View style={{transform:[{rotate: '10 deg'}]}}>
        <Image source={require('./logo.png')} />
      </View>
    );
  }

However, to animate things in RN, you have to use numbers, not strings. Can you still animate transforms in RN or do I have to come up with some kind of sprite sheet and change the Image src at some fps?

Javascript Solutions


Solution 1 - Javascript

You can actually animate strings using the interpolate method. interpolate takes a range of values, typically 0 to 1 works well for most things, and interpolates them into a range of values (these could be strings, numbers, even functions that return a value).

What you would do is take an existing Animated value and pass it through the interpolate function like this:

spinValue = new Animated.Value(0);

// First set up animation 
Animated.timing(
	this.spinValue,
  {
  	toValue: 1,
    duration: 3000,
    easing: Easing.linear, // Easing is an additional import from react-native
    useNativeDriver: true  // To make use of native driver for performance
  }
).start()

// Next, interpolate beginning and end values (in this case 0 and 1)
const spin = this.spinValue.interpolate({
  inputRange: [0, 1],
  outputRange: ['0deg', '360deg']
})

Then use it in your component like this:

<Animated.Image
  style={{transform: [{rotate: spin}] }}
  source={{uri: 'somesource.png'}} />

In case if you want to do the rotation in loop, then add the Animated.timing in the Animated.loop

Animated.loop(
 Animated.timing(
   this.spinValue,
   {
    toValue: 1,
    duration: 3000,
    easing: Easing.linear,
    useNativeDriver: true
   }
 )
).start();

Solution 2 - Javascript

Don't forget to add property useNativeDriver to ensure that you get the best performance out of this animation:

// First set up animation 
Animated.timing(
    this.state.spinValue,
  {
    toValue: 1,
    duration: 3000,
    easing: Easing.linear,
    useNativeDriver: true
  }
).start();

Solution 3 - Javascript

A note for the newbies like me: For animating something else you need to wrap it in for this to work. Or else the compiler will panic on that transform property:

import {Animated} from 'react-native';
...
//animation code above
...
<Animated.View style={{transform: [{rotate: spin}] }} >
   <YourComponent />
</Animated.View>

BUT for an image (Animated.Image), the example above is 100% goodness and correct.

Solution 4 - Javascript

Since most of the answers are functions & hooks based, herewith a complete example of class based Animation of Image.

import React from 'react';
import {
  SafeAreaView,
  View,
  Animated,
  Easing,
  TouchableHighlight,
  Text,
} from 'react-native';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      rotateValueHolder: new Animated.Value(0)
    };
  }
  componentDidMount = () => {
    this.startImageRotateFunction();
  }
  startImageRotateFunction = () => {
    Animated.loop(Animated.timing(this.state.rotateValueHolder, {
      toValue: 1,
      duration: 3000,
      easing: Easing.linear,
      useNativeDriver: false,
    })).start();
  };

render(){
    return(
      <SafeAreaView>
        <View>
          <Animated.Image
            style={{
              width: 200,
              height: 200,
              alignSelf:"center",
              transform:
                [
                  {
                    rotate: this.state.rotateValueHolder.interpolate(
                        {
                          inputRange: [0, 1],
                          outputRange: ['0deg', '360deg'],
                        }
                      )
                  }
                ],
            }}
              source={{uri:'https://raw.githubusercontent.com/AboutReact/sampleresource/master/old_logo.png',}}
          />
          <TouchableHighlight
            onPress={() => this.startImageRotateFunction()}>
            <Text style={{textAlign:"center"}}>
              CLICK HERE
            </Text>
          </TouchableHighlight>
        </View>
      </SafeAreaView>
    );
  }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionsdfsdfView Question on Stackoverflow
Solution 1 - JavascriptNader DabitView Answer on Stackoverflow
Solution 2 - JavascriptjeeviumView Answer on Stackoverflow
Solution 3 - Javascriptjeffski13View Answer on Stackoverflow
Solution 4 - JavascriptRahulView Answer on Stackoverflow