Files
streamyfin/components/ParallaxPage.tsx
Fredrik Burmester 75f3f483eb chore
2024-08-25 17:58:57 +02:00

83 lines
1.9 KiB
TypeScript

import type { PropsWithChildren, ReactElement } from "react";
import { View } from "react-native";
import Animated, {
interpolate,
useAnimatedRef,
useAnimatedStyle,
useScrollViewOffset,
} from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
const HEADER_HEIGHT = 400;
type Props = PropsWithChildren<{
headerImage: ReactElement;
logo?: ReactElement;
}>;
export const ParallaxScrollView: React.FC<Props> = ({
children,
headerImage,
logo,
}: Props) => {
const scrollRef = useAnimatedRef<Animated.ScrollView>();
const scrollOffset = useScrollViewOffset(scrollRef);
const headerAnimatedStyle = useAnimatedStyle(() => {
return {
transform: [
{
translateY: interpolate(
scrollOffset.value,
[-HEADER_HEIGHT, 0, HEADER_HEIGHT],
[-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75]
),
},
{
scale: interpolate(
scrollOffset.value,
[-HEADER_HEIGHT, 0, HEADER_HEIGHT],
[2, 1, 1]
),
},
],
};
});
const inset = useSafeAreaInsets();
return (
<View className="flex-1">
<Animated.ScrollView
style={{
position: "relative",
}}
ref={scrollRef}
scrollEventThrottle={16}
>
{logo && (
<View className="absolute top-[250px] h-[130px] left-0 w-full z-40 px-4 flex justify-center items-center">
{logo}
</View>
)}
<Animated.View
style={[
{
height: HEADER_HEIGHT,
backgroundColor: "black",
},
headerAnimatedStyle,
]}
>
{headerImage}
</Animated.View>
<View className="flex-1 overflow-hidden bg-black pb-24">
{children}
</View>
</Animated.ScrollView>
</View>
);
};