Created
February 19, 2022 20:17
-
-
Save Stringsaeed/bc7dbea46cc97f433d3a797cfe7f7287 to your computer and use it in GitHub Desktop.
Revisions
-
Stringsaeed created this gist
Feb 19, 2022 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,89 @@ // Animated Scroll Header Context // imports react and Animated import React, {createContext, useContext} from 'react'; import {clamp} from 'react-native-redash'; import {NativeScrollEvent, NativeSyntheticEvent, ViewStyle} from 'react-native'; import Animated, { Extrapolate, interpolate, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue, } from 'react-native-reanimated'; // context type type AnimatedScrollHeaderContextType = { scrollY?: Animated.SharedValue<number>; onScroll: (event: NativeSyntheticEvent<NativeScrollEvent>) => void; headerStyle: Animated.AnimateStyle<ViewStyle>; }; // provider props interface interface Props { children: React.ReactNode; headerHeight: number; } export interface AnimatedScrollHeaderProps extends Props {} // creates a context export const AnimatedScrollHeaderContext = createContext<AnimatedScrollHeaderContextType>({ onScroll: () => {}, headerStyle: {}, }); // creates a hook to access the context export const useAnimatedScrollHeader = () => { const context = useContext(AnimatedScrollHeaderContext); if (!context) { throw new Error( 'useAnimatedScrollHeaderContext must be used within a AnimatedScrollHeaderContextProvider', ); } return context; }; // creates a provider export const AnimatedScrollHeaderProvider: React.FC<Props> = ({ children, headerHeight, }) => { const scrollY = useSharedValue(0); const onScroll = useAnimatedScrollHandler<{prevY: number}>( { onScroll: (event, ctx) => { const diff = event.contentOffset.y - ctx.prevY; scrollY.value = clamp(scrollY.value + diff, 0, headerHeight); }, onBeginDrag: (event, ctx) => { ctx.prevY = event.contentOffset.y; }, }, [], ); const headerStyle = useAnimatedStyle( () => ({ opacity: interpolate(scrollY.value, [0, 15], [1, 0], Extrapolate.CLAMP), transform: [ { translateY: interpolate( scrollY.value, [0, 15], [0, -headerHeight], Extrapolate.CLAMP, ), }, ], }), [headerHeight], ); return ( <AnimatedScrollHeaderContext.Provider value={{scrollY, onScroll, headerStyle}}> {children} </AnimatedScrollHeaderContext.Provider> ); };