Skip to content

Instantly share code, notes, and snippets.

@patissier-boulanger
Created January 5, 2023 08:47
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 patissier-boulanger/d0f3fb7908ccc7179cdf0aecb7454dd3 to your computer and use it in GitHub Desktop.
Save patissier-boulanger/d0f3fb7908ccc7179cdf0aecb7454dd3 to your computer and use it in GitHub Desktop.
medium-reanimated4
import React, {Dispatch, SetStateAction, useEffect, useState} from 'react';
import {Pressable, Text, useWindowDimensions, View} from 'react-native';
import Animated, {
Easing,
runOnJS,
useAnimatedStyle,
useSharedValue,
withSpring,
withTiming,
} from 'react-native-reanimated';
type ModalPropType = {
showModal: boolean;
setShowModal: Dispatch<SetStateAction<boolean>>;
};
const MODAL_HEIGHT = 400;
export function Modal({showModal, setShowModal}: ModalPropType) {
const backgroundColor = useSharedValue(0);
const modalBottom = useSharedValue(0);
const {height: screenHeight} = useWindowDimensions();
// 내부 상태 관리
const [shown, setShown] = useState(false);
const handleOnPress = () => {
setShown(false);
};
const backdropAnimatedStyle = useAnimatedStyle(() => {
return {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#00000099',
opacity: backgroundColor.value,
zIndex: 1,
};
});
const modalAnimatedStyle = useAnimatedStyle(() => {
return {
position: 'absolute',
alignSelf: 'center',
bottom: modalBottom.value,
zIndex: 2,
};
});
useEffect(() => {
if (showModal) {
setShown(true);
}
}, [showModal]);
useEffect(() => {
const handleCloseModal = () => {
setShown(false);
setShowModal(false);
};
if (shown) {
backgroundColor.value = withTiming(1, {
duration: 250,
easing: Easing.linear,
});
modalBottom.value = withSpring(screenHeight / 2 - MODAL_HEIGHT / 2, {
damping: 80,
overshootClamping: true,
restDisplacementThreshold: 0.1,
restSpeedThreshold: 0.1,
stiffness: 500,
});
} else {
modalBottom.value = withSpring(-MODAL_HEIGHT, {
damping: 80,
overshootClamping: true,
restDisplacementThreshold: 0.1,
restSpeedThreshold: 0.1,
stiffness: 500,
});
backgroundColor.value = withTiming(
0,
{
duration: 250,
easing: Easing.linear,
},
finished => {
if (finished) {
runOnJS(handleCloseModal)();
}
},
);
}
}, [shown, backgroundColor, modalBottom, screenHeight, setShowModal]);
//...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment