Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | 1x 4x 4x 4x 4x 4x 2x 2x 2x 2x 2x 2x 1x 4x | import { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
import { ANIMATION_DURATION, EASING_IN_CUBIC, EASING_OUT_CUBIC } from '@/constants/animation';
interface VisibilityOptions {
duration?: number;
initialOpacity?: number;
initialScale?: number;
targetOpacity?: number;
targetScale?: number;
mode?: 'in' | 'out';
}
export const useAnimatedVisibility = (options: VisibilityOptions = {}) => {
const {
duration = ANIMATION_DURATION,
initialOpacity = 0,
initialScale = 0,
targetOpacity = 1,
targetScale = 1,
mode = 'out',
} = options;
const opacity = useSharedValue(initialOpacity);
const scale = useSharedValue(initialScale);
const animatedStyle = useAnimatedStyle(() => ({
opacity: opacity.value,
transform: [{ scale: scale.value }],
}));
const setVisibility = (visible: boolean, callback?: () => void) => {
const easing = mode === 'out' ? EASING_OUT_CUBIC : EASING_IN_CUBIC;
const finalOpacity = visible ? targetOpacity : initialOpacity;
const finalScale = visible ? targetScale : initialScale;
opacity.value = withTiming(finalOpacity, { duration, easing });
scale.value = withTiming(finalScale, { duration, easing }, finished => {
if (finished && callback) {
callback();
}
});
};
return {
opacity,
scale,
animatedStyle,
setVisibility,
};
};
|