Skip to content

Instantly share code, notes, and snippets.

@alexmccabe
Created July 27, 2020 13:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexmccabe/e5cd9a71cf8e4403f7b0d76f79bf6c32 to your computer and use it in GitHub Desktop.
Save alexmccabe/e5cd9a71cf8e4403f7b0d76f79bf6c32 to your computer and use it in GitHub Desktop.
import React, { FunctionComponent, useEffect, useRef, useState } from "react";
import { Animated, StyleSheet, ViewStyle } from "react-native";
interface PropTypes {
duration?: number;
isVisible?: boolean;
style?: ViewStyle | Array<ViewStyle>;
}
/**
* Fade this components children in and out of view before toggling
* render state.
*
* @param props
* @link https://goshakkk.name/react-native-animated-appearance-disappearance/
*/
const FadeView: FunctionComponent<PropTypes> = props => {
const { children, duration, isVisible, style } = props;
const [visible, setVisible] = useState(isVisible);
const opacityAnimation = useRef(new Animated.Value(isVisible ? 1 : 0));
const interpolatedOpacity = opacityAnimation.current.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
const animatedStyle = { opacity: interpolatedOpacity };
const combinedStyles = [styles.container, style, animatedStyle];
const fadeIn = () => {
Animated.timing(opacityAnimation.current, {
duration,
toValue: 1,
}).start(() => setVisible(true));
};
const fadeOut = () => {
Animated.timing(opacityAnimation.current, {
duration,
toValue: 0,
}).start(() => setVisible(false));
};
useEffect(() => {
/**
* This part is confusing as when the animation has completed, we call
* `setVisible(true)` anyway. However, without this the animation does
* not play.
*/
if (isVisible) {
setVisible(true);
}
isVisible ? fadeIn() : fadeOut();
}, [fadeIn, fadeOut, isVisible]);
return <Animated.View style={visible ? combinedStyles : animatedStyle}>{visible ? children : null}</Animated.View>;
};
FadeView.defaultProps = {
duration: 300,
isVisible: false,
};
const styles = StyleSheet.create({
container: {
height: "100%",
width: "100%",
},
});
export default FadeView;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment