reactjsreact-nativereact-native-reanimated-v2

React-Native-Reanimate one component, then the next


I have two objects to animate, just sliding from one position to another

Object 1: From -200,-200 To 500, 200 Object 2: From -200,-200 To 475, 180

This trick is: after the first object has finished its move, then the second object needs to do its animated move.

The withSequence function is for updating a single shared variable several times in sequence, so it doesn't appear to work for two components with unique values.

Currently both objects animate at the same time.


Solution

  • To achieve the desired sequence of animations in React Native using Reanimated, you can use a combination of the withTiming function and the useSharedValue hook to control the animations sequentially. Here's how you can do it:

    import React from 'react';
    import { View, StyleSheet } from 'react-native';
    import Animated, { useSharedValue, useAnimatedStyle, withTiming, runOnJS } from 'react-native-reanimated';
    
    const ObjectAnimation = () => {
      const object1X = useSharedValue(-200);
      const object1Y = useSharedValue(-200);
      const object2X = useSharedValue(-200);
      const object2Y = useSharedValue(-200);
    
      // Animate object 1
      const animateObject1 = () => {
        object1X.value = withTiming(500);
        object1Y.value = withTiming(200, {}, () => {
          // After object 1 finishes its animation, start animating object 2
          runOnJS(animateObject2)();
        });
      };
    
      // Animate object 2
      const animateObject2 = () => {
        object2X.value = withTiming(475);
        object2Y.value = withTiming(180);
      };
    
      // Animated styles for object 1
      const object1Styles = useAnimatedStyle(() => ({
        transform: [{ translateX: object1X.value }, { translateY: object1Y.value }],
      }));
    
      // Animated styles for object 2
      const object2Styles = useAnimatedStyle(() => ({
        transform: [{ translateX: object2X.value }, { translateY: object2Y.value }],
      }));
    
      // Start the animation when the component mounts
      React.useEffect(() => {
        animateObject1();
      }, []);
    
      return (
        <View style={styles.container}>
          <Animated.View style={[styles.object, object1Styles]} />
          <Animated.View style={[styles.object, object2Styles]} />
        </View>
      );
    };
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
      },
      object: {
        width: 50,
        height: 50,
        backgroundColor: 'blue',
        position: 'absolute',
      },
    });
    
    export default ObjectAnimation;
    

    In this example:

    We use useSharedValue to create shared values for the x and y coordinates of both objects. We define animateObject1 and animateObject2 functions to animate each object separately. In animateObject1, we animate object 1 to its target position, and when the animation completes, we call animateObject2 to start animating object 2. We use useAnimatedStyle to create animated styles for each object based on their respective shared values. Finally, we trigger the animation of object 1 when the component mounts using useEffect.