4

I am using animation for up and down in the react native, But the animation just slide from up to down and then stop at the bottom i want to move it up and down continuously. I have also used animation loop so please check and provide me solution for this

import React, { useEffect, useState } from 'react'
import { Text, View, Animated, Easing, StyleSheet } from 'react-native'
import LoaderLogo from '../../icons/commonicons/LoaderLogo'
import { Loadericon } from '../../constants/Image';
import LinearGradient from 'react-native-linear-gradient';
import { dynamicSize } from '../sizechoose';

const amimationScreen = () => {
    const startValue = new Animated.Value(0);
    const endValue = dynamicSize(225);

    const startValue2 = new Animated.Value(225);
    const endValue2 = dynamicSize(0);
    const duration = 5000;

    useEffect(() => {

        Animated.sequence([
            Animated.timing(startValue, {
                toValue: endValue,
                duration: duration,
                useNativeDriver: true,
            }),
            Animated.timing(startValue2, {
                toValue: endValue2,
                duration: duration,
                useNativeDriver: true,
            })
        ]).start()

    }, [startValue, endValue, duration]);

    return (
        <Animated.View style={[{ transform: [{ translateY: startValue }] }]}>
       <View style={{backgroundColor:'red',height:10,width:100}}>
            </View>
        </Animated.View>
    )
}


export default amimationScreen

I also tried with react-native-animatable package but it is not good to use for me as it starts animation from the top of the screen.

Rover
  • 661
  • 2
  • 18
  • 39

2 Answers2

11

This worked for me:

const App = () => {
  const animated = new Animated.Value(0);
  const duration = 5000;

  useEffect(() => {
    Animated.loop(
      Animated.sequence([
        Animated.timing(animated, {
          toValue: 255,
          duration: duration,
          useNativeDriver: true,
        }),
        Animated.timing(animated, {
          toValue: 0,
          duration: duration,
          useNativeDriver: true,
        }),
      ]),
    ).start();
  }, []);

  return (
    <Animated.View style={[{transform: [{translateY: animated}]}]}>
      <View style={{backgroundColor: 'red', height: 10, width: 100}}></View>
    </Animated.View>
  );
};

So instead of having two instances of Animated.Value for translation, create one and let it transition from 0 to 255 and from 255 back to 0 in sequence. And make it loop once the sequence has finished.


I think the main problem in your original approach is that startValue decides how the view translates since this is what you pass as the value of translateY. The downward animation therefore happens correctly in your example. The upward animation however does not happen, because startValue2 is passed to Animated.timing and startValue is not used in the translation of any views in your example.

5eb
  • 14,798
  • 5
  • 21
  • 65
3

enter image description here

import React, { useEffect, useRef, useState } from 'react';
import { Animated, Dimensions, Easing, StyleSheet, View } from 'react-native';


export const App = () => {
    const animatedValue = useRef(new Animated.Value(0)).current;
    const [isTop, setIsTop] = useState(true);

    const startAnimation = toValue => {
        Animated.timing(animatedValue, {
            toValue,
            duration: 1000,
            easing: Easing.linear,
            useNativeDriver: true
        }).start(() => {
            setIsTop(!isTop);
        })
    }

    useEffect(() => {
        startAnimation(isTop ? 1 : 0);
    }, [isTop]);

    const translateY = animatedValue.interpolate({
        inputRange: [0, 1],
        outputRange: [0, Dimensions.get('window').height - 70],
        extrapolate: 'clamp'
    })

    return (
        <View style={styles.container}>
            <Animated.View style={[styles.square, { transform: [{ translateY }] }]}>

            </Animated.View>
        </View>
    )
}


const styles = StyleSheet.create({
    container: {
        flex: 1,
        alignItems: 'center'
    },
    square: {
        width: 70,
        height: 70,
        backgroundColor: 'red'
    }
});
Leri Gogsadze
  • 2,958
  • 2
  • 15
  • 24