react native infinite loop of bounce animations on a list of Views?

Viewed 41

suppose I have an array of data which in this context is store names. I need to animate them in a way like first one store enters about 10px from above to the box with scale of 0.5 and after a short delay it continues the get a bit of center and get bigger sanctimoniously (parallel) and after another delay it goes down of the box and desperate. like below:

enter image description here

so far I achieve this. and what I need is the next store to come after this one and wait for getting bigger, something like below:

enter image description here

the little above waits for the big one to drop and then start the same animation.

here is my code so far:

const TrackOrder = () => {
  const [listData, setListData] = useState([
    {
      id: 1,
      storeName: 'papa jones besiktas',
    },
    {
      id: 2,
      storeName: 'levent store',
    },
     {
       id: 3,
       storeName: 'sariyer store',
     },
  ]);
  const {colors} = useTheme();
  // let fadeAni = useRef(new Animated.Value(0.2)).current;
  let bounceLittleItem = useRef(new Animated.Value(-80)).current;
  let bounceBigItem = useRef(new Animated.Value(-100)).current;

  let scaleUp = useRef(new Animated.Value(0.5)).current;

  const styles = useMemo(
    () =>
      StyleSheet.create({
        mainContainer: {
          backgroundColor: colors.CONTRAST_PRIMARY,
          height: 100,
          borderRadius: 30,
          marginHorizontal: `${(100 - GUTTERS.SCREEN_WIDTH_IN_NUMBER) / 2}%`,
          flexDirection: 'column',
          alignItems: 'flex-start',
          justifyContent: 'center',
          paddingHorizontal: 15,
          marginTop: 25,
          overflow: 'hidden',
        },
        orderContainer: {
          flexDirection: 'row',
          alignItems: 'center',
          justifyContent: 'flex-start',
        },
        storeImage: {
          width: 45,
          height: 45,
          backgroundColor: 'yellow',
          borderRadius: 40,
          marginRight: 20,
        },
        orderStatusText: {
          color: '#fff',
          fontFamily: 'BalooPaaji2-SemiBold',
        },
        storeContainer: {
          backgroundColor: '#fff',
          paddingHorizontal: 10,
          paddingVertical: 5,
          borderRadius: 20,
        },
        storeOneBeforeLastImage: {
          width: 25,
          height: 25,
          backgroundColor: 'yellow',
          borderRadius: 40,
          // marginRight: 20,
          opacity: 0.5,
        },
      }),
    [colors],
  );


  useEffect(() => {
    const inter = setInterval(() => {
      let copyArr = [...listData];
      let last = copyArr.pop();
      copyArr.unshift(last);
      setListData(copyArr);
    }, 6000);

    return () => clearInterval(inter);
  }, [listData]);

  useEffect(() => {
    Animated.timing(bounceBigItem, {
      toValue: -30,
      duration: 2000,
      useNativeDriver: true,
    });
  }, [bounceBigItem]);

  const runAnimation = useCallback(() => {
    Animated.sequence([
      Animated.timing(bounceLittleItem, {
        toValue: -30,
        duration: 2000,
        useNativeDriver: true,
      }),
      Animated.parallel([
        Animated.timing(bounceLittleItem, {
          toValue: 20,
          duration: 1000,
          useNativeDriver: true,
        }),
        Animated.timing(scaleUp, {
          toValue: 1,
          duration: 1000,
          useNativeDriver: true,
        }),
      ]),
      Animated.delay(2000),
      Animated.timing(bounceLittleItem, {
        toValue: 100,
        duration: 1000,
        useNativeDriver: true,
      }),
    ]).start(() => {
      bounceLittleItem.setValue(-80);
      scaleUp.setValue(0.5);
      runAnimation();
    });
  }, [bounceLittleItem, scaleUp]);

  useEffect(() => runAnimation(), [runAnimation]);

  const renderViewItem = useMemo(() => {
    if (listData?.length === 0) return;
    return listData.map((el, i) => {
      return (
        <Animated.View
          key={el.id}
          style={[
            styles.orderContainer,
            i === 0
              ? {
                  transform: [{translateY: bounceLittleItem}, {scale: scaleUp}],
                }
              : {
                  transform: [{translateY: bounceBigItem}, {scale: 0.5}],
                },
          ]}
        >
          <View style={[styles.storeImage]} />
          <Text style={styles.orderStatusText}>{el.storeName}</Text>
        </Animated.View>
      );
    });
  }, [bounceBigItem, bounceLittleItem, listData, scaleUp, styles.orderContainer, styles.orderStatusText, styles.storeImage]);

  return <View style={styles.mainContainer}>{renderViewItem}</View>;
};

so, how can I achieve my desired animation which once again is first come down and as soon as getting bigger next store come down and step on first store footprints? if you have any idea I really appreciate.

0 Answers
Related