Skip to content

Instantly share code, notes, and snippets.

@dannyhw
Last active May 31, 2024 10:43
Show Gist options
  • Select an option

  • Save dannyhw/7b08e6e3bb7081d66a1e025c08edb8d5 to your computer and use it in GitHub Desktop.

Select an option

Save dannyhw/7b08e6e3bb7081d66a1e025c08edb8d5 to your computer and use it in GitHub Desktop.

Revisions

  1. dannyhw revised this gist May 29, 2024. 1 changed file with 0 additions and 2 deletions.
    2 changes: 0 additions & 2 deletions index.tsx
    Original file line number Diff line number Diff line change
    @@ -8,8 +8,6 @@ import Animated, {
    useScrollViewOffset,
    } from 'react-native-reanimated';
    import { useSafeAreaInsets } from 'react-native-safe-area-context';
    export const FONT_MINIMUM_SCALE = 0.8;
    export const FONT_MAXIMUM_SCALE = 1.2;

    export default function Home() {
    const insets = useSafeAreaInsets();
  2. dannyhw created this gist May 29, 2024.
    164 changes: 164 additions & 0 deletions index.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,164 @@
    import { Stack } from 'expo-router';
    import { StyleSheet, Text, View, useWindowDimensions } from 'react-native';
    import Animated, {
    Extrapolation,
    interpolate,
    useAnimatedRef,
    useAnimatedStyle,
    useScrollViewOffset,
    } from 'react-native-reanimated';
    import { useSafeAreaInsets } from 'react-native-safe-area-context';
    export const FONT_MINIMUM_SCALE = 0.8;
    export const FONT_MAXIMUM_SCALE = 1.2;

    export default function Home() {
    const insets = useSafeAreaInsets();

    const animatedRef = useAnimatedRef<Animated.ScrollView>();
    const scrollOffset = useScrollViewOffset(animatedRef);

    const { fontScale } = useWindowDimensions();

    const titleStyle = useAnimatedStyle(() => {
    const offsetAmount = 100;

    const opacity = interpolate(scrollOffset.value, [0, offsetAmount], [1, 0], Extrapolation.CLAMP);

    const totalHeight = fontScale * 24 + 24;

    const height = interpolate(
    scrollOffset.value,
    [0, offsetAmount],
    [totalHeight, 0],
    Extrapolation.CLAMP
    );

    return {
    opacity,
    justifyContent: 'center',
    alignItems: 'flex-start',
    height,
    };
    }, [fontScale, scrollOffset.value]);

    return (
    <View>
    <Stack.Screen options={{ headerShown: false }} />

    <View style={[{ paddingTop: insets.top }, styles.header]}>
    <Animated.Text style={[titleStyle, styles.title]}>Home</Animated.Text>

    <StatsBar />
    </View>

    <Animated.ScrollView
    ref={animatedRef}
    style={{ marginTop: 8 }}
    contentContainerStyle={[styles.list, { paddingBottom: insets.bottom + 16 }]}>
    <CardList />
    </Animated.ScrollView>
    </View>
    );
    }

    const styles = StyleSheet.create({
    header: {
    paddingHorizontal: 16,
    paddingBottom: 8,
    backgroundColor: 'white',

    shadowColor: '#000',
    shadowOffset: {
    width: 0,
    height: 3,
    },
    shadowOpacity: 0.27,
    shadowRadius: 4.65,

    elevation: 6,
    },
    list: {
    paddingHorizontal: 16,
    paddingTop: 16,
    },
    title: { fontSize: 24, fontWeight: 'bold', alignItems: 'center' },
    });

    const StatsBar = () => {
    return (
    <View style={{ justifyContent: 'space-between', flexDirection: 'row' }}>
    <Chip>
    <Text style={{ color: 'white' }}>credit:1$</Text>
    </Chip>
    <Chip>
    <Text>points:2</Text>
    </Chip>
    <Chip>
    <Text>abc:1</Text>
    </Chip>
    </View>
    );
    };

    const CardList = () => {
    return (
    <>
    <Card>
    <Text>Hello</Text>
    </Card>
    <Card>
    <Text>Hello</Text>
    </Card>
    <Card>
    <Text>Hello</Text>
    </Card>
    <Card>
    <Text>Hello</Text>
    </Card>
    <Card>
    <Text>Hello</Text>
    </Card>
    <Card>
    <Text>Hello</Text>
    </Card>
    </>
    );
    };

    const Card = ({ children }: { children: React.ReactNode }) => {
    return (
    <View
    style={{
    padding: 16,
    backgroundColor: 'white',
    borderRadius: 8,
    marginBottom: 16,
    height: 300,
    shadowColor: '#000',
    shadowOffset: {
    width: 0,
    height: 2,
    },
    shadowOpacity: 0.23,
    shadowRadius: 2.62,

    elevation: 4,
    }}>
    {children}
    </View>
    );
    };

    const Chip = ({ children }: { children: React.ReactNode }) => {
    return (
    <View
    style={{
    paddingHorizontal: 8,
    paddingVertical: 4,
    backgroundColor: 'violet',
    borderRadius: 8,
    }}>
    <Text style={{ color: 'white' }}>{children}</Text>
    </View>
    );
    };