this repo has no description
1import type { PropsWithChildren, ReactElement } from 'react';
2import { StyleSheet } from 'react-native';
3import Animated, {
4 interpolate,
5 useAnimatedRef,
6 useAnimatedStyle,
7 useScrollViewOffset,
8} from 'react-native-reanimated';
9
10import { ThemedView } from '@/components/ThemedView';
11import { useBottomTabOverflow } from '@/components/ui/TabBarBackground';
12import { useColorScheme } from '@/hooks/useColorScheme';
13
14const HEADER_HEIGHT = 250;
15
16type Props = PropsWithChildren<{
17 headerImage: ReactElement;
18 headerBackgroundColor: { dark: string; light: string };
19}>;
20
21export default function ParallaxScrollView({
22 children,
23 headerImage,
24 headerBackgroundColor,
25}: Props) {
26 const colorScheme = useColorScheme() ?? 'light';
27 const scrollRef = useAnimatedRef<Animated.ScrollView>();
28 const scrollOffset = useScrollViewOffset(scrollRef);
29 const bottom = useBottomTabOverflow();
30 const headerAnimatedStyle = useAnimatedStyle(() => {
31 return {
32 transform: [
33 {
34 translateY: interpolate(
35 scrollOffset.value,
36 [-HEADER_HEIGHT, 0, HEADER_HEIGHT],
37 [-HEADER_HEIGHT / 2, 0, HEADER_HEIGHT * 0.75]
38 ),
39 },
40 {
41 scale: interpolate(scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1]),
42 },
43 ],
44 };
45 });
46
47 return (
48 <ThemedView style={styles.container}>
49 <Animated.ScrollView
50 ref={scrollRef}
51 scrollEventThrottle={16}
52 scrollIndicatorInsets={{ bottom }}
53 contentContainerStyle={{ paddingBottom: bottom }}>
54 <Animated.View
55 style={[
56 styles.header,
57 { backgroundColor: headerBackgroundColor[colorScheme] },
58 headerAnimatedStyle,
59 ]}>
60 {headerImage}
61 </Animated.View>
62 <ThemedView style={styles.content}>{children}</ThemedView>
63 </Animated.ScrollView>
64 </ThemedView>
65 );
66}
67
68const styles = StyleSheet.create({
69 container: {
70 flex: 1,
71 },
72 header: {
73 height: HEADER_HEIGHT,
74 overflow: 'hidden',
75 },
76 content: {
77 flex: 1,
78 padding: 32,
79 gap: 16,
80 overflow: 'hidden',
81 },
82});