Hi guys, in this article we will explore the concept of animations in React Native.
React Native provides a powerful set of tools for building cross-platform mobile applications and one of the key features is its ability to create stunning animations that bring apps to life. Whether you’re building an app with complex interactions or just want to add a touch of fun, animations can help you create an engaging and memorable experience for your users. In this article, we’ll explore how to create animations in React Native, including how to use the Animated API, create custom animations, and handle different types of transitions.
The Animated API
The Animated API is a fundamental part of React Native’s animation system, providing a simple and flexible way to animate components and elements within your app. The API is based on the concept of animated values, which are values that can change over time and be animated based on specific criteria. To create an animated value, you use the Animated.Value
method, which returns a new animated value that you can use in your animations.
Once you’ve created your animated value, you can use it to animate various properties of your components, such as the position, opacity, or scale. For example, to animate the opacity of a component, you can use the Animated.timing
method, which takes an animated value and animates it over a specified duration, easing, and delays.
const opacity = new Animated.Value(0); Animated.timing(opacity, { toValue: 1, duration: 1000, easing: Easing.linear, delay: 500, }).start();
In this example, we’re creating an animated value for the opacity of a component and animating it to a value of 1 over a duration of 1000 milliseconds, using a linear easing and a delay of 500 milliseconds.
Animated.timing & Animated.Value
Let us illustrate this concept with an example that involves animating the height of a component to create a simple circle.
import React, {useState} from 'react'; import { View,Text, Animated, StyleSheet, Button } from 'react-native'; const Home = () =>{ const [animation, setAnimation] = useState(new Animated.Value(0)); const showCircle = () => { Animated.timing(animation, { toValue: 150, duration: 500, useNativeDriver: false, }).start(); }; const animatedStyles = { height: animation, }; return ( <View style={styles.container}> <Animated.View style={[styles.box, animatedStyles]} /> <Button style={styles.button} onPress={showCircle} title='Show Tomato!' /> </View> ) } const styles = StyleSheet.create({ container: { flex: 1, alignItems: 'center', justifyContent: 'center', }, box: { width: 150, height: 75, backgroundColor: 'tomato', borderRadius: 75, }, button:{ marginTop: 50, margin: 50 } }); export default Home
Animated.Parallel
Animated.parallel
is a method provided by the React Native Animated
API that allows running multiple animations in parallel. It takes an array of animation objects as an argument and runs all of them at the same time. The animations can be controlled using the Animated.timing
method or other animation methods provided by the API. Once all animations are complete, the parallel
method returns a completion
event that can be used to run further animations or perform other operations.
Let’s dive into an example to better understand the concept of Animated.parallel.
import React, { useEffect, useState } from ‘react’; import { Animated, Text, View, StyleSheet, TouchableOpacity, TouchableWithoutFeedback } from ‘react-native’; const Home = () => { const [logoOpacity, setLogoOpacity] = useState(new Animated.Value(0)); const [bgOpacity, setBgOpacity] = useState(new Animated.Value(0)); const [appNamePosition, setAppNamePosition] = useState(new Animated.Value(0)); const [appNameOpacity, setAppNameOpacity] = useState(new Animated.Value(0)); const [rotation] = useState(new Animated.Value(0)); const animate = () => { Animated.parallel([ Animated.timing(logoOpacity, { toValue: 1, duration: 1500 }), Animated.timing(appNamePosition, { toValue: 1, duration: 1000 }), Animated.timing(appNameOpacity, { toValue: 1, duration: 1500}), Animated.timing(rotation, { toValue: 360, duration: 1000, useNativeDriver: true }) ]).start(); }; const reset = () => { Animated.parallel([ Animated.timing(logoOpacity, { toValue: 0, duration: 1500 }), Animated.timing(appNamePosition, { toValue: 0, duration: 1000 }), Animated.timing(appNameOpacity, { toValue: 0, duration: 500}), Animated.timing(rotation, { toValue: 90, duration: 1000, useNativeDriver: true }) ]).start(); }; useEffect(() =>{ animate(); }, []) return (It uses Animated.parallel
to run multiple animations simultaneously and Animated.timing
to animate the values over a specified duration. The animations start when the component is rendered.
The component has two animation functions, animate
and reset
, that run different sets of animations. The animate
function is called once when the component is rendered and runs the initial animations. The reset
function runs different animations when the user interacts with the component by tapping on it.
The component has a TouchableWithoutFeedback
component that wraps the main view, and when the user taps on it, the reset
function is called. The animations update the opacity and position of an image and a text element, and the rotation of an image.
Let’s examine the results of the code in the previous example.
Animated.spring
An Animated.spring
component is used to animate values based on a spring physics model in the React Native library.
import React, { useState } from 'react'; import { Animated, Text, TouchableWithoutFeedback, View, StyleSheet } from 'react-native'; const Home = () => { const [scaleValue, setScaleValue] = useState(new Animated.Value(1)); const handlePress = () => { Animated.spring(scaleValue, { toValue: 1.2, friction: 1, tension: 40, }).start(); }; const handleRelease = () => { Animated.spring(scaleValue, { toValue: 1, friction: 1, tension: 40, }).start(); }; return ( <View style={styles.container}> <TouchableWithoutFeedback style={styles.buttonContainer} onPressIn={handlePress} onPressOut={handleRelease}> <Animated.View style={{ transform: [{ scale: scaleValue }], }} > <Text style={styles.buttonText}> Tap Me! </Text> </Animated.View> </TouchableWithoutFeedback> </View> ); }; const styles = StyleSheet.create({ container:{ backgroundColor: '#000000', flex: 1, alignContent : 'center', justifyContent: 'center' }, buttonContainer: { backgroundColor: '#0077CC', paddingVertical: 10, borderRadius: 5, borderColor: '#FFFFFF', borderWidth: 10, }, buttonText: { color: '#FFFFFF', fontWeight: 'bold', textAlign: 'center', fontSize: 18, }, }); export default Home;
In this example, when the button is pressed, the handlePress
function will be called and the scaleValue
will be animated to 1.2
. The animation will use a spring physics model with friction
set to 1
and tension
set to 40
. When the button is released, the handleRelease
function will be called and the scaleValue
will be animated back to 1
. This creates a realistic bouncing animation for the button.
Let’s examine the results of the code in the previous example.
We hope this article taught you about animations in React Native. Thank you for reading.