Skip to main content

Working with Animations

1. Using Animated API

Property Description Values
Animated.View Component that can be animated View component with animation support
Animated.Text Text component with animation support Text component with animation support
Animated.Image Image component with animation support Image component with animation support
Animated.ScrollView ScrollView component with animation support ScrollView component with animation support

Example: Basic Animation

import React, { useRef } from 'react';
import { Animated, View } from 'react-native';

const BasicAnimation = () => {
  const fadeAnim = useRef(new Animated.Value(0)).current;

  React.useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 1000,
      useNativeDriver: true
    }).start();
  }, []);

  return (
    <Animated.View style={{ opacity: fadeAnim }}>
      <Text>Fade In</Text>
    </Animated.View>
  );
};

export default BasicAnimation;

Example: Rotation Animation

import React, { useRef } from 'react';
import { Animated, View } from 'react-native';

const RotationAnimation = () => {
  const rotateAnim = useRef(new Animated.Value(0)).current;

  React.useEffect(() => {
    Animated.loop(
      Animated.timing(rotateAnim, {
        toValue: 360,
        duration: 2000,
        useNativeDriver: true
      })
    ).start();
  }, []);

  return (
    <Animated.View style={{
      transform: [{ rotate: rotateAnim.interpolate({
        inputRange: [0, 360],
        outputRange: ['0deg', '360deg']
      }) }]
    }}>
      <Text>Rotating</Text>
    </Animated.View>
  );
};

export default RotationAnimation;
Note: Use useNativeDriver: true for better performance.
Warning: Ensure all animated values are initialized with new Animated.Value().

2. Creating Timing Animations

Property Description Values
duration Duration of the animation in milliseconds number
easing Easing function to control animation curve 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out' | 'cubic-bezier(n,n,n,n)'
delay Delay before animation starts in milliseconds number
repeat Number of times to repeat the animation number | 'infinite'
repeatType How to repeat the animation 'reverse' | 'reset'

Example: Basic timing animation

import Animated, { FadeIn } from 'react-native-animatable';

<Animated.View
  animation={FadeIn}
  duration={1000}
  easing="ease-in-out"
  delay={200}
>
  <Text>Animated Text</Text>
</Animated.View>

Example: Custom easing function

import Animated from 'react-native-reanimated';

const customEasing = Animated.Easing.bezier(0.25, 0.1, 0.25, 1);

<Animated.View
  style={[
    styles.box,
    {
      animation: Animated.timing(styles.box, {
        toValue: 100,
        duration: 500,
        easing: customEasing,
      }).start(),
    },
  ]}
></Animated.View>

3. Using Spring Animations

Property Description Default Notes
mass Mass of the object being animated 1 Higher mass results in slower response to forces
stiffness Stiffness of the spring 100 Higher stiffness makes the animation more rigid
damping Damping factor of the spring 10 Higher damping reduces oscillation
restDisplacementThreshold Threshold for displacement to consider as at rest 0.001 Used to optimize performance by stopping animation when displacement is negligible
restSpeedThreshold Threshold for speed to consider as at rest 0.001 Used to optimize performance by stopping animation when speed is negligible

Example: Basic Spring Animation

import Animated, { useAnimatedStyle, withSpring } from 'react-native-reanimated';

const SpringExample = () => {
  const animatedStyle = useAnimatedStyle(() => {
    return {
      transform: [
        {
          translateX: withSpring(100),
        },
      ],
    };
  });

  return <Animated.View style={animatedStyle} />;
};

Example: Spring with Custom Configuration

import Animated, { useAnimatedStyle, withSpring } from 'react-native-reanimated';

const CustomSpringExample = () => {
  const animatedStyle = useAnimatedStyle(() => {
    return {
      transform: [
        {
          translateY: withSpring(200, {
            stiffness: 150,
            damping: 20,
            mass: 1.5,
          }),
        },
      ],
    };
  });

  return <Animated.View style={animatedStyle} />;
};
Note: The spring animation uses a physics-based model to simulate real-world spring behavior. It is ideal for creating natural, organic motion in UI elements.

4. Creating Sequences

Example: Basic Sequence

import { Animated } from &#x27;react-native&#x27;;

const fadeAnim = new Animated.Value(0);
const scaleAnim = new Animated.Value(1);

Animated.sequence([
  Animated.timing(fadeAnim, {
    toValue: 1,
    duration: 500,
    useNativeDriver: true,
  }),
  Animated.timing(scaleAnim, {
    toValue: 1.5,
    duration: 300,
    useNativeDriver: true,
  }),
]).start();
Property Description Values
Animated.sequence Creates a sequence of animations to run in order Array<Animated.Animation>
duration Duration of each animation in milliseconds number
useNativeDriver Enables native driver for performance true or false
Note: Sequences run animations one after another in the order specified.
Warning: All animations in a sequence must use the same useNativeDriver setting.

5. Running Parallel Animations

Parallel animations in Expo use the Animated.parallel function to run multiple animations simultaneously. This is useful for creating complex animation sequences that involve several properties changing at once.

Property Description Values
animations An array of animation objects to run in parallel Array of Animated instances

Example: Running Parallel Animations

import React, { useRef } from 'react';
import { Animated, View } from 'react-native';

const ParallelAnimationExample = () => {
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const scaleAnim = useRef(new Animated.Value(1)).current;

  const startParallelAnimation = () => {
    Animated.parallel([
      Animated.timing(fadeAnim, {
        toValue: 1,
        duration: 1000,
        useNativeDriver: true,
      }),
      Animated.timing(scaleAnim, {
        toValue: 1.5,
        duration: 1000,
        useNativeDriver: true,
      }),
    ]).start();
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Animated.View
        style={{
          width: 100,
          height: 100,
          backgroundColor: 'blue',
          opacity: fadeAnim,
          transform: [{ scale: scaleAnim }],
        }}
      >
      </Animated.View>
      <View style={{ marginTop: 20 }}>
        <Animated.Text
          style={{
            fontSize: 20,
            opacity: fadeAnim,
          }}
        >
          Animated Text
        </Animated.Text>
      </View>
    </View>
  );
};

export default ParallelAnimationExample;

6. Using Stagger Animations

Stagger animations in Expo allow you to create sequential animations with a time delay between each element, enhancing visual flow and engagement.

Property Description Default Value Notes
stagger Applies a stagger delay to each animation in a group false Can be a number (in ms) or an object with delay and duration
delay Initial delay before the first animation starts 0 Used in conjunction with stagger

Example: Staggering Animations

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

const StaggerExample = () => {
  const animations = [0, 1, 2, 3].map(i => new Animated.Value(0));

  const startStagger = () => {
    animations.forEach((anim, index) => {
      Animated.timing(anim, {
        toValue: 1,
        duration: 500,
        delay: index * 200, // Stagger by 200ms
        useNativeDriver: true,
      }).start();
    });
  };

  return (
    <View style={{ flexDirection: 'row', justifyContent: 'space-around' }}>
      {animations.map((anim, index) => (
        <Animated.View
          key={index}
          style={{
            width: 50,
            height: 50,
            backgroundColor: 'blue',
            opacity: anim,
            transform: [{ scale: anim }],
          }}
        />
      ))}
    </View>
  );
};

export default StaggerExample;
Note: The stagger property is not a built-in in React Native's Animated API, but can be implemented using delay in individual animations.
Warning: Ensure that the useNativeDriver is set to true for performance benefits when using Animated.

7. Implementing Native Driver

Property Description Values Notes
useNativeDriver Flag to enable native driver for animations true / false Must be set to true for animations to use native driver. Only works with specific animated properties.

Example: Using Native Driver

import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-animated';

const AnimatedComponent = () => {
  const opacity = useSharedValue(1);

  const animatedStyle = useAnimatedStyle(() => {
    return {
      opacity: opacity.value,
    };
  });

  const startAnimation = () => {
    Animated.timing(opacity, {
      toValue: 0,
      duration: 1000,
      useNativeDriver: true, // Enable native driver
    }).start();
  };

  return <Animated.View style={animatedStyle} />;
};
Note: Native driver is only supported for a limited set of animated properties. It provides better performance by running animations on the native thread instead of JavaScript.
Warning: Setting useNativeDriver to true will cause the animation to not work if any animated property is not supported by the native driver.

8. Using Reanimated

Example: Basic Reanimated Animation

import { View, Button } from 'react-native';
import { useSharedValue, withTiming } from 'react-native-reanimated';

export default function AnimatedComponent() {
  const opacity = useSharedValue(1);

  const animate = () => {
    opacity.value = withTiming(opacity.value === 1 ? 0 : 1, { duration: 500 });
  };

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <View style={{
        width: 100,
        height: 100,
        backgroundColor: 'blue',
        opacity: opacity.value
      }} />
      <Button title="Animate" onPress={animate} />
    </View>
  );
}
Property Description Values Notes
useSharedValue Creates a shared value that can be animated initialValue Used for animating values in Reanimated
withTiming Applies a timing animation to a value value, config Config includes duration and easing
withSpring Applies a spring animation to a value value, config Config includes stiffness, damping, mass
Note: Reanimated requires native code integration and must be installed via Expo.
Warning: Reanimated animations run on the native thread and cannot use React state directly.

Key Features of Reanimated

  • High-performance animations using native thread
  • Supports complex animations like springs and timing
  • Can be used with gesture handlers for interactive animations
  • Requires Expo to work in managed workflow

9. Creating Shared Values

Shared values in Expo animations allow multiple animated properties to be linked together, enabling complex animation behaviors where one property's value influences another.

Property Description Usage
sharedValue Represents a value that can be shared across multiple animated properties. const sharedValue = useSharedValue(0);
value Gets or sets the current value of the shared value. sharedValue.value = 100;

Example: Using Shared Values in Animations

import { useSharedValue, withTiming } from 'react-native-reanimated';

const sharedValue = useSharedValue(0);

const animate = () => {
  sharedValue.value = withTiming(100, { duration: 500 });
};

// In a component:
<Animated.View
  style={{
    transform: [{ translateX: sharedValue }],
  }}
></Animated.View>
Note: Shared values must be initialized with a starting value and can only be updated using animation functions like withTiming, withSpring, or withDecay.

10. Using Animated Styles

Property Values Description
animatedStyle Animated.StyleSheet Applies animated styles to components using Animated.View.
useNativeDriver true | false Enables hardware acceleration for animations. Defaults to false.
duration number Duration of the animation in milliseconds.

Example: Basic Animated Style

import React, { useRef } from 'react';
import { Animated, View } from 'react-native';

const AnimatedStyleExample = () => {
  const fadeAnim = useRef(new Animated.Value(0)).current;

  Animated.timing(fadeAnim, {
    toValue: 1,
    duration: 500,
    useNativeDriver: true
  }).start();

  return (
    <Animated.View
      style={{
        opacity: fadeAnim,
        width: 100,
        height: 100,
        backgroundColor: 'blue'
      }}
    >
    </Animated.View>
  );
};

export default AnimatedStyleExample;
Note: useNativeDriver must be set to true for performance on iOS and Android.
Warning: Not all style properties support useNativeDriver. Properties like transform and opacity are supported.

11. Implementing Gesture Handler Integration

Example: Basic Pan Gesture

import { PanGestureHandler } from 'react-native-gesture-handler';
import Animated, { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';

const translateX = useSharedValue(0);
const translateY = useSharedValue(0);

const panGesture = Gesture.Pan()
  .onUpdate((event) => {
    translateX.value = event.translationX;
    translateY.value = event.translationY;
  })
  .onEnd(() => {
    translateX.value = 0;
    translateY.value = 0;
  });

const animatedStyle = useAnimatedStyle(() => ({
  transform: [
    { translateX: translateX.value },
    { translateY: translateY.value }
  ]
}));

<PanGestureHandler onGestureEvent={panGesture}>
  <Animated.View style={animatedStyle}>
    <View style={{ width: 100, height: 100, backgroundColor: 'blue' }} />
  </Animated.View>
</PanGestureHandler>
Property Description Values Notes
onGestureEvent Callback for gesture events function Required for handling gesture updates
onHandlerStateChange Callback for handler state changes function Use to detect gesture start/end
Note: Ensure react-native-gesture-handler is properly installed and linked for iOS and Android.
Warning: useAnimatedStyle must be used inside a component that is wrapped in Animated.View or similar.

Integration Steps

  • Install react-native-gesture-handler
  • Link the library for iOS and Android
  • Create shared values for animated properties
  • Define gesture using Gesture.Pan()
  • Attach gesture to component with PanGestureHandler

12. Creating Layout Animations

Property Description Values Notes
layoutAnimation Enables layout animations for components true, false Must be set on the root component or parent container
duration Duration of the layout animation in milliseconds number Default is 200ms
easing Easing function for the animation 'easeIn', 'easeOut', 'easeInOut' Can be customized using Easing from React Native

Example: Enabling Layout Animation

import { LayoutAnimation } from 'react-native';<br><br>const toggleLayout = () => {<br>  LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);<br>};
Note: Layout animations work best with components that change size or position, such as View, Text, and Image.
Warning: Layout animations may not work as expected in all cases, especially with complex nested components or custom views.

Was this article helpful?