-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Add screen transition animation #5274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
ef35469
Copy changes from rn-screens
piaskowyk 0329270
Call configure props
piaskowyk 97ec16b
Add example
piaskowyk a5fc158
Export types
piaskowyk 803c380
Use Screen's methods on UI
piaskowyk c74789d
Update package.json
piaskowyk a0cd9e1
Run Android on UI
piaskowyk 5b372dc
Added easing
piaskowyk d9636ac
Update screens version
piaskowyk 68c6493
Plit update
piaskowyk b2ff069
Merge branch 'main' into @piaskowyk/screen-animations-swipe-back
piaskowyk f975ef0
Run format
piaskowyk 4ed7262
Use screens as local tarball
piaskowyk 1732b3d
Compatibility without screens
piaskowyk a6c90ae
Update example
piaskowyk 8c71ce3
Update hash
piaskowyk 7a0f14c
Web mock
piaskowyk 984afad
Web mock
piaskowyk e3f60c8
Force common interface
piaskowyk 115f4e6
Update hash
piaskowyk 3fd934a
Update hash again
piaskowyk de25c01
Update gradle properties
piaskowyk 45f86f7
Update globals
piaskowyk 0858237
Update gesture simulator
piaskowyk 34385be
Update dependencies
piaskowyk 0880b7d
Update screens
piaskowyk 7f6fd8e
Add use strict
piaskowyk 5874b31
update example
piaskowyk 6dc6d95
Merge branch 'main' into @piaskowyk/screen-animations-swipe-back
piaskowyk 20685b8
Improvements after review
piaskowyk 7513d1e
Java lint
piaskowyk 5c6ca32
Align to the new screens interface
piaskowyk 4031de8
Remove dependency for RNScreensModule
piaskowyk 39d52d1
Add worklet directive
piaskowyk 5282eb9
Lint Java
piaskowyk 9aa642b
Clean up
piaskowyk 1e0c321
Update types
piaskowyk 2711ed4
Update example app
piaskowyk a68c1fc
Remove screes .tgz
piaskowyk f3136f8
Update example
piaskowyk f3b1619
Merge branch 'main' into @piaskowyk/screen-animations-swipe-back
piaskowyk 7c7bb5a
Merge branch 'main' into @piaskowyk/screen-animations-swipe-back
piaskowyk 5a7d165
Review
piaskowyk a8fac50
Restore file name
piaskowyk 1a5c16f
ScreensTurboModule mock
piaskowyk cac050d
Small refactor
piaskowyk 9e2c337
Merge branch 'main' into @piaskowyk/screen-animations-swipe-back
piaskowyk 9d9cf44
Merge branch 'main' into @piaskowyk/screen-animations-swipe-back
piaskowyk c272b60
Improvements after review part 1
piaskowyk 218cdd5
Update name
piaskowyk 8059ffa
Replace function syntax
piaskowyk f22e6cc
Restore below top screen state
piaskowyk 4dde3f8
Don't copy the event
piaskowyk 880870d
Run formatter
piaskowyk e852d6c
Remove unused export
piaskowyk 2cbeff6
Restore changes
piaskowyk 53b4e38
Merge branch 'main' into @piaskowyk/screen-animations-swipe-back
piaskowyk bffb073
Merge branch 'main' into @piaskowyk/screen-animations-swipe-back
piaskowyk File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| // @ts-nocheck - It will be removed after release of react-native-screens, because currently 'react-native-screens/gesture-handler' import doesn't exist. | ||
| import React from 'react'; | ||
| import { View, StyleSheet, Button } from 'react-native'; | ||
| import { | ||
| createNativeStackNavigator, | ||
| NativeStackScreenProps, | ||
| } from 'react-native-screens/native-stack'; | ||
| import { ParamListBase } from '@react-navigation/native'; | ||
| import { | ||
| ScreenTransition, | ||
| AnimatedScreenTransition, | ||
| } from 'react-native-reanimated'; | ||
|
|
||
| // This is a temporary workaround until react-native-screens release with 'react-native-screens/gesture-handler' import. | ||
| // import { GestureDetectorProvider } from 'react-native-screens/gesture-handler'; | ||
| function GestureDetectorProvider({ children }) { | ||
| return children; | ||
| } | ||
|
|
||
| function MainScreen({ navigation }: NativeStackScreenProps<ParamListBase>) { | ||
| return ( | ||
| <View style={[styles.container, styles.screenA]}> | ||
| <Button | ||
| title="Go ScreenB" | ||
| onPress={() => navigation.navigate('ScreenB')} | ||
| /> | ||
| <Button onPress={() => navigation.pop()} title="🔙 Back to Examples" /> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| function ScreenB({ navigation }: NativeStackScreenProps<ParamListBase>) { | ||
| return ( | ||
| <View style={[styles.container, styles.screenB]}> | ||
| <Button | ||
| title="Go ScreenC" | ||
| onPress={() => navigation.navigate('ScreenC')} | ||
| /> | ||
| <Button title="Go back" onPress={() => navigation.goBack()} /> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| function ScreenC({ navigation }: NativeStackScreenProps<ParamListBase>) { | ||
| return ( | ||
| <View style={[styles.container, styles.screenC]}> | ||
| <Button title="Go back" onPress={() => navigation.goBack()} /> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| const Stack = createNativeStackNavigator(); | ||
|
|
||
| const customTransition: AnimatedScreenTransition = { | ||
| topScreenFrame: (event, screenSize) => { | ||
| 'worklet'; | ||
| const progress = event.translationX / screenSize.width; | ||
| return { | ||
| transform: [ | ||
| { translateX: event.translationX }, | ||
| { rotate: `${20 * progress}deg` }, | ||
| ], | ||
| }; | ||
| }, | ||
| belowTopScreenFrame: (event, screenSize) => { | ||
| 'worklet'; | ||
| const progress = event.translationX / screenSize.width; | ||
| return { | ||
| transform: [{ scale: 0.7 + 0.3 * progress }], | ||
| }; | ||
| }, | ||
| }; | ||
|
|
||
| function ScreenTransitionExample(): JSX.Element { | ||
| return ( | ||
| <GestureDetectorProvider> | ||
| <Stack.Navigator | ||
| screenOptions={{ | ||
| headerHideBackButton: true, | ||
| stackAnimation: 'none', | ||
| goBackGesture: 'swipeRight', | ||
| }}> | ||
| <Stack.Screen name="ScreenA" component={MainScreen} /> | ||
| <Stack.Screen | ||
| name="ScreenB" | ||
| component={ScreenB} | ||
| options={{ transitionAnimation: customTransition }} | ||
| /> | ||
| <Stack.Screen | ||
| name="ScreenC" | ||
| component={ScreenC} | ||
| options={{ transitionAnimation: ScreenTransition.SwipeRightFade }} | ||
| /> | ||
| </Stack.Navigator> | ||
| </GestureDetectorProvider> | ||
| ); | ||
| } | ||
|
|
||
| const styles = StyleSheet.create({ | ||
| container: { | ||
| flex: 1, | ||
| paddingTop: 10, | ||
| }, | ||
| screenA: { | ||
| backgroundColor: 'moccasin', | ||
| }, | ||
| screenB: { | ||
| backgroundColor: 'thistle', | ||
| }, | ||
| screenC: { | ||
| backgroundColor: 'blue', | ||
| }, | ||
| }); | ||
|
|
||
| export default ScreenTransitionExample; |
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 characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import { StyleSheet, Text, View } from 'react-native'; | ||
|
|
||
| import React from 'react'; | ||
|
|
||
| export default function ScreenTransitionExample() { | ||
| return ( | ||
| <View style={styles.container}> | ||
| <Text>Screen transition example is not supported on web</Text> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| const styles = StyleSheet.create({ | ||
| container: { | ||
| flex: 1, | ||
| alignItems: 'center', | ||
| justifyContent: 'center', | ||
| }, | ||
| }); |
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 characters
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 characters
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 characters
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 characters
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 characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| 'use strict'; | ||
| import type { RNScreensTurboModuleType } from './commonTypes'; | ||
|
|
||
| function noopFactory<T>(defaultReturnValue?: T): () => T { | ||
| return () => { | ||
| 'worklet'; | ||
| console.warn( | ||
| '[Reanimated] RNScreensTurboModule has not been found. Check that you have installed `[email protected]` or newer in your project and rebuilt your app.' | ||
| ); | ||
| return defaultReturnValue as T; | ||
| }; | ||
| } | ||
|
|
||
| type TransactionConfig = { | ||
| topScreenId: number; | ||
| belowTopScreenId: number; | ||
| canStartTransition: boolean; | ||
| }; | ||
|
|
||
| export const RNScreensTurboModule: RNScreensTurboModuleType = | ||
| global.RNScreensTurboModule || { | ||
| startTransition: noopFactory<TransactionConfig>({ | ||
| topScreenId: -1, | ||
| belowTopScreenId: -1, | ||
| canStartTransition: false, | ||
| }), | ||
| updateTransition: noopFactory(), | ||
| finishTransition: noopFactory(), | ||
| }; |
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 characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| 'use strict'; | ||
|
|
||
| import type { LockAxis, ScreenTransitionConfig } from './commonTypes'; | ||
| import { configureProps } from '../../ConfigHelper'; | ||
| import { applyStyle } from './styleUpdater'; | ||
| import { getSwipeSimulator } from './swipeSimulator'; | ||
|
|
||
| configureProps(); | ||
|
|
||
| export function startScreenTransition( | ||
| screenTransitionConfig: ScreenTransitionConfig | ||
| ) { | ||
| 'worklet'; | ||
| const { stackTag, sharedEvent } = screenTransitionConfig; | ||
| sharedEvent.addListener(stackTag, () => { | ||
| applyStyle(screenTransitionConfig, sharedEvent.value); | ||
| }); | ||
| } | ||
|
|
||
| function getLockAxis(goBackGesture: string): LockAxis { | ||
| 'worklet'; | ||
piaskowyk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (['swipeRight', 'swipeLeft', 'horizontalSwipe'].includes(goBackGesture)) { | ||
| return 'x'; | ||
| } else if ( | ||
| ['swipeUp', 'swipeDown', 'verticalSwipe'].includes(goBackGesture) | ||
| ) { | ||
| return 'y'; | ||
| } | ||
| return undefined; | ||
| } | ||
|
|
||
| export function finishScreenTransition( | ||
| screenTransitionConfig: ScreenTransitionConfig | ||
| ) { | ||
| 'worklet'; | ||
| const { stackTag, sharedEvent, goBackGesture } = screenTransitionConfig; | ||
| sharedEvent.removeListener(stackTag); | ||
| const lockAxis = getLockAxis(goBackGesture); | ||
| const step = getSwipeSimulator( | ||
| sharedEvent.value, | ||
| screenTransitionConfig, | ||
| lockAxis | ||
| ); | ||
| step(); | ||
| } | ||
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 characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| 'use strict'; | ||
|
|
||
| import type { | ||
| MeasuredDimensions, | ||
| ShadowNodeWrapper, | ||
| SharedValue, | ||
| } from '../commonTypes'; | ||
|
|
||
| export type PanGestureHandlerEventPayload = { | ||
| x: number; | ||
| y: number; | ||
| absoluteX: number; | ||
| absoluteY: number; | ||
| translationX: number; | ||
| translationY: number; | ||
| velocityX: number; | ||
| velocityY: number; | ||
| }; | ||
|
|
||
| export type AnimatedScreenTransition = { | ||
| topScreenFrame: ( | ||
| event: PanGestureHandlerEventPayload, | ||
| screenDimensions: MeasuredDimensions | ||
| ) => Record<string, unknown>; | ||
| belowTopScreenFrame: ( | ||
| event: PanGestureHandlerEventPayload, | ||
| screenDimensions: MeasuredDimensions | ||
| ) => Record<string, unknown>; | ||
| }; | ||
|
|
||
| export type GoBackGesture = | ||
| | 'swipeRight' | ||
| | 'swipeLeft' | ||
| | 'swipeUp' | ||
| | 'swipeDown' | ||
| | 'verticalSwipe' | ||
| | 'horizontalSwipe' | ||
| | 'twoDimensionalSwipe'; | ||
|
|
||
| export type ScreenTransitionConfig = { | ||
| stackTag: number; | ||
| belowTopScreenId: number | ShadowNodeWrapper; | ||
| topScreenId: number | ShadowNodeWrapper; | ||
| screenTransition: AnimatedScreenTransition; | ||
| sharedEvent: SharedValue<PanGestureHandlerEventPayload>; | ||
| startingGesturePosition: SharedValue<PanGestureHandlerEventPayload>; | ||
| onFinishAnimation?: () => void; | ||
| isTransitionCanceled: boolean; | ||
piaskowyk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| goBackGesture: GoBackGesture; | ||
| screenDimensions: MeasuredDimensions; | ||
| }; | ||
|
|
||
| export type RNScreensTurboModuleType = { | ||
| startTransition: (stackTag: number) => { | ||
| topScreenId: number | ShadowNodeWrapper; | ||
| belowTopScreenId: number | ShadowNodeWrapper; | ||
| canStartTransition: boolean; | ||
| }; | ||
piaskowyk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| updateTransition: (stackTag: number, progress: number) => void; | ||
| finishTransition: (stackTag: number, isCanceled: boolean) => void; | ||
piaskowyk marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| export type LockAxis = 'x' | 'y' | undefined; | ||
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 characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| 'use strict'; | ||
|
|
||
| export { | ||
| startScreenTransition, | ||
| finishScreenTransition, | ||
| } from './animationManager'; | ||
| export { ScreenTransition } from './presets'; | ||
| export type { | ||
| AnimatedScreenTransition, | ||
| GoBackGesture, | ||
| ScreenTransitionConfig, | ||
| } from './commonTypes'; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.