BennoDev
BennoDev

Reputation: 239

React-Native Animate View In and Out

Currently, I am struggling with appearing and disappearing animations.. My aim is to animate a view in and again out.. but I want also that the view does 100% disappear after the animation

Idea

    ...

const visible: boolean = props.visible || false;
const [showView, setShowView] = useState<boolean>(visible);
const viewAnimation = useRef<Animatable.View & View>(null);

   useEffect(() => {
        const Animation = async () => {

            if (visible) {
                setShowView(true);
                if (viewAnimation.current)
                    await viewAnimation.current.bounceIn(2000);
            } else {
                if (viewAnimation.current)
                    await viewAnimation.current.bounceOut(2000);
                setShowView(false)
            }
        }

        Animation();
    }, [visible, viewAnimation]);

...

{showView &&
<Animatable.View ref={viewAnimation}>
...
</Animatable.View>
}

...

Problem The viewAnimationRef get set in the next render cycle and not instant after setting the showView to true -> the bounceIn animation will never get executed.. because viewAnimation.current is null..

I am using:

Maybe sb has an idea how to solve this problem ^^

Thank you

Upvotes: 2

Views: 19630

Answers (3)

Ellson Mendes
Ellson Mendes

Reputation: 29

I use a 3 step approach to create animation using the Animated library. #1 step - create the value you want to animate let motion= new Animated.Value(0);

#2 Provide a mechanism to animated this value, use one of the builtin functions, spring, decay, timing

Animated.timing(motion,{toValue:100, duration:3000}).start();

#3 Apply the animated value to a porperty of the component/object you wanna animate PS. in your case you want to animated the translation so the best approach is to assign the animated value dynamically on a style and apply the style to the componente ///create a dynamic style let myStyle = { transform:[{translateX:motion}]}

//adding the custom style to the component <YourComponent style={[anyOtherStyle, myStyle]}/>

For more about animation check out this channel: https://www.youtube.com/watch?v=DwoSyhF3CkY

Upvotes: 0

BennoDev
BennoDev

Reputation: 239

The solution is simple just wrap the Animatable.View around a normal view and hide the normal view if you want to hide it

Example:

    ...

const visible: boolean = props.visible || false;
const [showView, setShowView] = useState<boolean>(visible);
const viewAnimation = useRef<Animatable.View & View>(null);

   useEffect(() => {
        const Animation = async () => {

            if (visible) {
                setShowView(true);
                if (viewAnimation.current)
                    await viewAnimation.current.bounceIn(2000);
            } else {
                if (viewAnimation.current)
                    await viewAnimation.current.bounceOut(2000);
                setShowView(false)
            }
        }

        Animation();
    }, [visible, viewAnimation]);

...


<Animatable.View ref={viewAnimation}>
{showView &&
<View>
...
</View>
}
</Animatable.View>


...

Upvotes: 5

Ashwith Saldanha
Ashwith Saldanha

Reputation: 1728

I created an example in which translation and opacity changes and the view translates in and out of the screen

snack: https://snack.expo.io/QWWCkYS7U

export default function App() {
  const value = new Animated.Value(0);

  React.useEffect(() => {
    Animated.sequence([
      Animated.timing(value, {
        toValue: 1,
        duration: 1000,
        easing: Easing.ease,
      }),
      Animated.timing(value, {
        toValue: 0,
        duration: 1000,
        easing: Easing.ease,
      })
    ]).start()
  }, []);

  const translateX = value.interpolate({
    inputRange: [0, 1],
    outputRange: [width, 0],
  });

  const opacity = value

  return (
    <View style={styles.container}>
      <Animated.View style={[styles.view, { opacity, transform: [{ translateX }] }]} />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  view: {
    width: 300,
    height: 100,
    backgroundColor: 'red',
  },
});

Upvotes: 1

Related Questions