import { useEffect } from 'react'; import { Easing, cancelAnimation, useAnimatedStyle, useSharedValue, withRepeat, withTiming, } from 'react-native-reanimated'; type AnimatedStyle = { transform: Array<{ scale: number }>; opacity: number; }; export function usePulseAnimation(active: boolean, durationMs = 1600): AnimatedStyle { const scale = useSharedValue(1); const opacity = useSharedValue(active ? 1 : 0.5); useEffect(() => { if (active) { scale.value = withRepeat( withTiming(1.4, { duration: durationMs / 2, easing: Easing.out(Easing.quad) }), -1, true, ); opacity.value = withRepeat( withTiming(0.55, { duration: durationMs / 2, easing: Easing.inOut(Easing.quad) }), -1, true, ); } else { cancelAnimation(scale); cancelAnimation(opacity); scale.value = withTiming(1, { duration: 160 }); opacity.value = withTiming(0.5, { duration: 160 }); } }, [active, durationMs, scale, opacity]); return useAnimatedStyle(() => ({ transform: [{ scale: scale.value }], opacity: opacity.value, })); }