mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com> Co-authored-by: Georgijs Vilums <=> Co-authored-by: dylan-conway <dylan-conway@users.noreply.github.com> Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
import type { PropsWithChildren, ReactElement } from "react";
|
|
import { StyleSheet, useColorScheme } from "react-native";
|
|
import Animated, { interpolate, useAnimatedRef, useAnimatedStyle, useScrollViewOffset } from "react-native-reanimated";
|
|
|
|
import { ThemedView } from "@/components/ThemedView";
|
|
|
|
const HEADER_HEIGHT = 250;
|
|
|
|
type Props = PropsWithChildren<{
|
|
headerImage: ReactElement;
|
|
headerBackgroundColor: { dark: string; light: string };
|
|
}>;
|
|
|
|
export default function ParallaxScrollView({ children, headerImage, headerBackgroundColor }: Props) {
|
|
const colorScheme = useColorScheme() ?? "light";
|
|
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]),
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
return (
|
|
<ThemedView style={styles.container}>
|
|
<Animated.ScrollView ref={scrollRef} scrollEventThrottle={16}>
|
|
<Animated.View
|
|
style={[styles.header, { backgroundColor: headerBackgroundColor[colorScheme] }, headerAnimatedStyle]}
|
|
>
|
|
{headerImage}
|
|
</Animated.View>
|
|
<ThemedView style={styles.content}>{children}</ThemedView>
|
|
</Animated.ScrollView>
|
|
</ThemedView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
flex: 1,
|
|
},
|
|
header: {
|
|
height: 250,
|
|
overflow: "hidden",
|
|
},
|
|
content: {
|
|
flex: 1,
|
|
padding: 32,
|
|
gap: 16,
|
|
overflow: "hidden",
|
|
},
|
|
});
|