import { LinearGradient } from "expo-linear-gradient"; import { type PropsWithChildren, type ReactElement } from "react"; import {NativeScrollEvent, NativeSyntheticEvent, View, ViewProps} from "react-native"; import Animated, { interpolate, useAnimatedRef, useAnimatedStyle, useScrollViewOffset, } from "react-native-reanimated"; interface Props extends ViewProps { headerImage: ReactElement; logo?: ReactElement; episodePoster?: ReactElement; headerHeight?: number; onEndReached?: (() => void) | null | undefined; } export const ParallaxScrollView: React.FC> = ({ children, headerImage, episodePoster, headerHeight = 400, logo, onEndReached, ...props }: Props) => { const scrollRef = useAnimatedRef(); const scrollOffset = useScrollViewOffset(scrollRef); const headerAnimatedStyle = useAnimatedStyle(() => { return { transform: [ { translateY: interpolate( scrollOffset.value, [-headerHeight, 0, headerHeight], [-headerHeight / 2, 0, headerHeight * 0.75] ), }, { scale: interpolate( scrollOffset.value, [-headerHeight, 0, headerHeight], [2, 1, 1] ), }, ], }; }); function isCloseToBottom({layoutMeasurement, contentOffset, contentSize}: NativeScrollEvent) { return layoutMeasurement.height + contentOffset.y >= contentSize.height - 20; } return ( { if (isCloseToBottom(e.nativeEvent)) onEndReached?.() }} > {logo && ( {logo} )} {headerImage} {children} ); };