/** * Bridges carousel animationValue to ct-design Animated.Container. * * @example * const animated = useParallaxSlideAnimated({ animationValue, slideWidth: 320 }); * */ import { useCallback, useRef } from 'react'; import { useAnimatedStyles } from '@cleartrip/ct-design-animated'; import { runOnJS, useAnimatedReaction } from 'react-native-reanimated'; import { PARALLAX_FACTOR } from '../constants'; import { IUseParallaxSlideAnimatedParams, TParallaxSlideAnimatedStyle } from './type'; const getParallaxTranslateX = (animationValue: number, slideWidth: number): number => { 'worklet'; return -animationValue * slideWidth * PARALLAX_FACTOR; }; export const useParallaxSlideAnimated = ({ animationValue, slideWidth, }: IUseParallaxSlideAnimatedParams): TParallaxSlideAnimatedStyle => { const controllerRef = useRef<{ start?: (options?: { to?: { translateX?: number }; config?: { immediate?: boolean; duration?: number } }) => void; } | null>(null); const [animatedStyle, controller] = useAnimatedStyles( { from: { translateX: 0 }, to: { translateX: 0 }, config: { immediate: true }, }, [slideWidth], ); controllerRef.current = controller; const handleSyncTranslateX = useCallback((translateX: number) => { controllerRef.current?.start?.({ to: { translateX }, config: { immediate: true, duration: 0 }, }); }, []); useAnimatedReaction( () => getParallaxTranslateX(animationValue.value, slideWidth), (translateX) => { runOnJS(handleSyncTranslateX)(translateX); }, [animationValue, slideWidth, handleSyncTranslateX], ); return animatedStyle; };