UNPKG

@hoddy-ui/core

Version:

Core rich react native components written in typescript

107 lines (98 loc) 2.33 kB
import { useEffect } from "react"; import { Platform } from "react-native"; import { Easing, interpolate, useAnimatedStyle, useSharedValue, withDelay, withTiming, } from "react-native-reanimated"; import useAppState from "./useAppState"; interface UseRollAnimationProps { duration?: number; delay?: number; closeAfter?: number | null; initialTranslateY?: number; initialRotate?: string; } export const useRollAnimation = ({ duration = 500, delay = 0, closeAfter = null, initialTranslateY = 100, initialRotate = "0deg", }: UseRollAnimationProps = {}) => { const translateY = useSharedValue(initialTranslateY); const rotate = useSharedValue(0); const { isActive } = useAppState(); const animatedStyle = useAnimatedStyle(() => { // Interpolate rotation from 0-1 to initial rotation to 360deg const rotateInterpolated = interpolate( rotate.value, [0, 1], [parseFloat(initialRotate.replace("deg", "")), 360] ); return { transform: [ { translateY: translateY.value }, { rotate: `${rotateInterpolated}deg` }, ], }; }); useEffect(() => { if (!isActive && Platform.OS === "ios") { translateY.value = initialTranslateY; rotate.value = 0; return; } // Start roll-in animation with easing (parallel animations) translateY.value = withDelay( delay, withTiming(0, { duration, easing: Easing.out(Easing.ease), }) ); rotate.value = withDelay( delay, withTiming( 1, { duration, easing: Easing.out(Easing.ease), }, () => { if (closeAfter) { translateY.value = withDelay( closeAfter, withTiming(initialTranslateY, { duration, easing: Easing.out(Easing.ease), }) ); rotate.value = withDelay( closeAfter, withTiming(0, { duration, easing: Easing.out(Easing.ease), }) ); } } ) ); }, [ translateY, rotate, duration, delay, closeAfter, initialTranslateY, initialRotate, isActive, ]); return { animatedStyle, }; };