How to Simplify animations in React Native with Moti
The Moti Way 😎
Let’s get started by installing moti and its dependency Reanimated v2.
Installation
Install Moti
npm install moti
Install Reanimated 2
Moti requires that you install react-native-reanimated. The lowest version of Reanimated that has been tested on is 2.0.0-rc.0
Please follow the Expo instructions for installing react-native-reanimated v2.
You’ll need at least Expo SDK 40.
npm install react-native-reanimated@2.0.0-rc.0
Next let’s import the Image component from Moti.
Currently, Moti exports typical React Native components.
import { View, Text, ScrollView, SafeAreaView, Image } from "moti"
Since this might conflict with the names of your React Native components, It’s recommended we import them with aliases and add the required props in order to animate the Image component.
import { Image as MotiImage } from "moti"
;<MotiImage
style={{
width: 227,
height: 200,
}}
from={{
rotate: "0deg",
}}
animate={{
rotate: "360deg",
}}
transition={{
loop: true,
repeatReverse: false,
type: "timing",
duration: 3000,
}}
/>
All moti components have a few useful props:
from - The initial animation styles when the component mounts. In this case we have initial value of rotate: 0deg
animate - Animates any value passed here. In this case we have to rotate till 360deg
transition - Take full control over your animation configuration. You can set options for your entire animation (such as type: ‘timing’), or set transition options per-style.
Inside the transition prop we can set a few values which are required for our infinite animation .
We set loop: true
for infinite animation and repeatReverse: false
to avoid back and forth animation.
Here is the full code:
import React from "react"
import { StyleSheet, View } from "react-native"
import { Image as MotiImage } from "moti"
export default function App() {
return (
<View style={styles.container}>
<MotiImage
style={{
width: 227,
height: 200,
}}
from={{
rotate: "0deg",
}}
animate={{
rotate: "360deg",
}}
transition={{
loop: true,
repeatReverse: false,
type: "timing",
duration: 3000,
}}
/>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#fff",
alignItems: "center",
justifyContent: "center",
},
})
Yeah, that’s significantly less code when compared to Animated.
Get the full code here.