recording.mp4
This project demonstrates an interactive UI pattern where a main content view (an "article scroll") visually transforms as a bottom sheet slides up from the bottom of the screen. When the bottom sheet is collapsed, the article takes up most of the screen. As the bottom sheet expands, the article view animates, shrinking slightly, gaining rounded corners, and adding a shadow effect, creating the appearance of sliding underneath the bottom sheet area.
This effect is achieved using a combination of popular React Native libraries:
@gorhom/bottom-sheet: Provides the core draggable bottom sheet component.react-native-reanimated: Powers the smooth animations that react to the bottom sheet's position.react-native-gesture-handler: Essential for handling touch gestures for both the bottom sheet and the animations, requiring theGestureHandlerRootViewat the app's root.
-
GestureHandlerRootView: The entire application is wrapped inGestureHandlerRootViewinapp/index.tsxto enable gesture handling. -
Bottom Sheet Setup (
MyBottomSheet.tsx):- A standard
@gorhom/bottom-sheetcomponent is set up with desired snap points (e.g.,['10%', '50%']). - Crucially, the
animatedIndexprop of theBottomSheetcomponent is used. This prop provides a ReanimatedSharedValuethat represents the current animated position of the sheet, typically interpolating between the indices of thesnapPointsarray (e.g., 0 for the first snap point, 1 for the second, etc.).
- A standard
-
Tracking Progress (
app/index.tsx):- A
SharedValue(namedprogressin the example) is created usinguseSharedValue(0). - This
progressshared value is passed directly to theanimatedIndexprop of theMyBottomSheetcomponent. Reanimated and Gorhom Bottom Sheet handle the connection internally, soprogressautomatically updates as the sheet moves.
- A
-
Animating the Article View (
app/index.tsx&ArticleView.tsx):- An
Animated.View(wrapped in theArticleViewcomponent) contains the main scrollable content (ArticleScroll). useAnimatedStyleis used to define styles for theArticleViewthat depend on theprogressshared value.- Inside
useAnimatedStyle, theinterpolatefunction fromreact-native-reanimatedmaps theprogress.value(which changes from 0 to 1 as the sheet moves between the first two snap points) to desired style values:margin,marginTop,marginBottom: Increase as the sheet goes up, shrinking the article view.borderRadius: Increases to round the corners.shadowOffset,shadowOpacity,shadowRadius,elevation(for Android): Increase to create the shadow/depth effect.
Extrapolation.CLAMPis used ininterpolateto prevent the style values from going beyond the defined output range.
- An
-
Component Structure:
app/index.tsx: The main screen, orchestrates the interaction, holds theprogressshared value, and defines the animated styles.components/ArticleView.tsx: AnAnimated.Viewwrapper that applies the dynamic styles.components/ArticleScroll.tsx: A simpleScrollViewto hold the main content. Made reusable by acceptingchildren.components/BottomSheet.tsx: Wraps the@gorhom/bottom-sheetlogic. Made reusable by acceptingchildren.components/Content.tsx: Example content displayed within the bottom sheet.components/TriggerButton.tsx: Custom handle for the bottom sheet.
This setup creates a fluid and engaging user experience where the background content reacts dynamically to the foreground bottom sheet's position.