diff --git a/versioned_docs/version-6.x/shared-element-transitions.md b/versioned_docs/version-6.x/shared-element-transitions.md index 9d545d71ba..4ac6ba932b 100644 --- a/versioned_docs/version-6.x/shared-element-transitions.md +++ b/versioned_docs/version-6.x/shared-element-transitions.md @@ -1,10 +1,17 @@ # Animating elements between screens -This guide covers how to animate elements between screens. This feature is known as a [Shared Element Transition](https://docs.swmansion.com/react-native-reanimated/docs/api/sharedElementTransitions) and it's implemented in the [`@react-navigation/native-stack`](/docs/native-stack-navigator) with [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/). +This guide covers how to animate elements between screens. This feature is known as a [Shared Element Transition](https://docs.swmansion.com/react-native-reanimated/docs/shared-element-transitions/overview/) and it's implemented in the [`@react-navigation/native-stack`](native-stack-navigator.md) with [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/). :::warning -As of writing this guide, Shared Element Transitions are considered an experimental feature not recommended for production use. +Shared Element Transitions are an experimental feature not recommended for production use yet. + +**Architecture support:** + +- **Reanimated 3** supports Shared Element Transitions on the **Old Architecture** (Paper). +- **Reanimated 4** supports them on the **New Architecture** (Fabric) since **4.2.0**, but the feature is behind a feature flag. You need to [enable the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag](https://docs.swmansion.com/react-native-reanimated/docs/guides/feature-flags#enable_shared_element_transitions) to use it. + +Check [the Reanimated documentation](https://docs.swmansion.com/react-native-reanimated/docs/shared-element-transitions/overview/) for details and [send feedback to the Reanimated team](https://github.com/software-mansion/react-native-reanimated) ::: @@ -16,8 +23,9 @@ As of writing this guide, Shared Element Transitions are considered an experimen Before continuing this guide make sure your app meets these criteria: -- You are using [`@react-navigation/native-stack`](native-stack-navigator.md). The Shared Element Transitions feature isn't supported in JS-based [`@react-navigation/stack`](stack-navigator.md). +- You are using [`@react-navigation/native-stack`](native-stack-navigator.md). JS-based [`@react-navigation/stack`](stack-navigator.md) or other navigators are not supported. - You have [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started) **v3.0.0 or higher** installed and configured. +- If you are using **Reanimated 4** (New Architecture), you must [enable the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag](https://docs.swmansion.com/react-native-reanimated/docs/guides/feature-flags#enable_shared_element_transitions). ## Minimal example @@ -92,21 +100,21 @@ const styles = StyleSheet.create({ ## Customizing the transition -By default, the transition animates the `width`, `height`, `originX`, `originY` and `transform` properties using `withTiming` with a 500 ms duration. You can easily customize `width`, `height`, `originX`, and `originY` props. Customizing `transform` is also possible but it's far beyond the scope of this guide. +You can customize the transition by passing a custom `SharedTransition` configuration via the `sharedTransitionStyle` prop. Apply the same `sharedTransitionStyle` to the matching element on the target screen. -:::warning +Custom transition configuration is not fully finalized and might change in a future release. -Custom SharedTransition API is not finalized and might change in a future release. +### Old Architecture (Reanimated 3) -::: - -To customize the transition you need to pass all the properties besides `transform`. +By default, the transition animates `width`, `height`, `originX`, `originY`, and `transform` using `withTiming` with a 500 ms duration. You can customize the transition using `SharedTransition.custom()`: ```jsx -import { SharedTransition } from 'react-native-reanimated'; +import { SharedTransition, withSpring } from 'react-native-reanimated'; +// highlight-start const customTransition = SharedTransition.custom((values) => { 'worklet'; + return { height: withSpring(values.targetHeight), width: withSpring(values.targetWidth), @@ -114,6 +122,7 @@ const customTransition = SharedTransition.custom((values) => { originY: withSpring(values.targetOriginY), }; }); +// highlight-end function HomeScreen() { return ( @@ -127,10 +136,55 @@ function HomeScreen() { } ``` +### New Architecture (Reanimated 4) + +On the New Architecture, the default transition animates `width`, `height`, `originX`, `originY`, `transform`, `backgroundColor`, and `opacity` using `withTiming` with a 500 ms duration. + +Currently customization is more limited due to ongoing development. You can't define fully custom animation functions. Instead, use the `SharedTransition` builder class to configure duration and spring-based animations: + +```jsx +import { SharedTransition } from 'react-native-reanimated'; + +// Customize duration and use spring animation +// highlight-next-line +const customTransition = SharedTransition.duration(550).springify(); + +function HomeScreen() { + return ( + + ); +} +``` + ## Reference You can find a full Shared Element Transitions reference in the [React Native Reanimated documentation](https://docs.swmansion.com/react-native-reanimated/docs/shared-element-transitions/overview/). +## Limitations + +Shared Element Transitions currently have several limitations to be aware of: + +- Only the [native stack navigator](native-stack-navigator.md) is supported +- Other navigators such as JS stack, drawer, and bottom tabs are not supported +- Transitions with native modals don't work properly on iOS + +### New Architecture specific limitations (Reanimated 4) + +The following limitations apply specifically when using Reanimated 4 on the New Architecture: + +- The feature must be enabled via the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag +- Custom animation functions are not supported; you can only customize duration and use spring-based animations +- Some properties (e.g., `backgroundColor`) are not supported in progress-based transitions (iOS back gesture) +- There are performance bottlenecks with transforms being recalculated too eagerly +- On iOS, you may encounter issues with vertical positioning due to header height information propagation + +The limitations will be addressed in future Reanimated releases. + ## Alternatives Alternatively, you can use [`react-native-shared-element`](https://github.com/IjzerenHein/react-native-shared-element) library with a [React Navigation binding](https://github.com/IjzerenHein/react-navigation-shared-element) which implements Shared Element Transitions in a JS-based `@react-navigation/stack` navigator. This solution, however, isn't actively maintained. diff --git a/versioned_docs/version-7.x/shared-element-transitions.md b/versioned_docs/version-7.x/shared-element-transitions.md index 18d5fd917f..d1392da51a 100644 --- a/versioned_docs/version-7.x/shared-element-transitions.md +++ b/versioned_docs/version-7.x/shared-element-transitions.md @@ -11,9 +11,14 @@ This guide covers how to animate elements between screens. This feature is known :::warning -As of writing this guide, Shared Element Transitions are considered an experimental feature not recommended for production use. +Shared Element Transitions are an experimental feature not recommended for production use yet. -Shared Element Transitions are currently only supported on **old React Native architecture** (Paper). +**Architecture support:** + +- **Reanimated 3** supports Shared Element Transitions on the **Old Architecture** (Paper). +- **Reanimated 4** supports them on the **New Architecture** (Fabric) since **4.2.0**, but the feature is behind a feature flag. You need to [enable the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag](https://docs.swmansion.com/react-native-reanimated/docs/guides/feature-flags#enable_shared_element_transitions) to use it. + +Check [the Reanimated documentation](https://docs.swmansion.com/react-native-reanimated/docs/shared-element-transitions/overview/) for details and [send feedback to the Reanimated team](https://github.com/software-mansion/react-native-reanimated) ::: @@ -25,8 +30,9 @@ Shared Element Transitions are currently only supported on **old React Native ar Before continuing this guide make sure your app meets these criteria: -- You are using [`@react-navigation/native-stack`](native-stack-navigator.md). The Shared Element Transitions feature isn't supported in JS-based [`@react-navigation/stack`](stack-navigator.md). +- You are using [`@react-navigation/native-stack`](native-stack-navigator.md). JS-based [`@react-navigation/stack`](stack-navigator.md) or other navigators are not supported. - You have [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started) **v3.0.0 or higher** installed and configured. +- If you are using **Reanimated 4** (New Architecture), you must [enable the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag](https://docs.swmansion.com/react-native-reanimated/docs/guides/feature-flags#enable_shared_element_transitions). ## Minimal example @@ -36,10 +42,7 @@ To create a shared transition: 2. Assign the same `sharedTransitionTag` to elements on different screens. 3. Navigate between screens. The transition will start automatically. - - - -```js name="Shared transition" +```js static2dynamic name="Shared transition" import * as React from 'react'; import { View, StyleSheet } from 'react-native'; import { @@ -85,14 +88,12 @@ function DetailsScreen() { ); } -// highlight-start const RootStack = createNativeStackNavigator({ screens: { Home: HomeScreen, Details: DetailsScreen, }, }); -// highlight-end const Navigation = createStaticNavigation(RootStack); @@ -108,96 +109,25 @@ const styles = StyleSheet.create({ }); ``` - - - -```js name="Shared transition" -import * as React from 'react'; -import { View, StyleSheet } from 'react-native'; -import { NavigationContainer, useNavigation } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; -import { Button } from '@react-navigation/elements'; - -import Animated from 'react-native-reanimated'; - -// highlight-next-line -const Stack = createNativeStackNavigator(); - -function HomeScreen() { - const navigation = useNavigation(); - - return ( - - - - - ); -} - -function DetailsScreen() { - const navigation = useNavigation(); - - return ( - - - - - ); -} - -export default function App() { - return ( - - - - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - }, -}); -``` - - - - `sharedTransitionTag` is a string that has to be unique in the context of a single screen, but has to match elements between screens. This prop allows Reanimated to identify and animate the elements, similarly to the [`key`](https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key) property, which tells React which element in the list is which. ## Customizing the transition -By default, the transition animates the `width`, `height`, `originX`, `originY` and `transform` properties using `withTiming` with a 500 ms duration. You can easily customize `width`, `height`, `originX`, and `originY` props. Customizing `transform` is also possible but it's far beyond the scope of this guide. +You can customize the transition by passing a custom `SharedTransition` configuration via the `sharedTransitionStyle` prop. Apply the same `sharedTransitionStyle` to the matching element on the target screen. -:::warning +Custom transition configuration is not fully finalized and might change in a future release. -Custom SharedTransition API is not finalized and might change in a future release. +### Old Architecture (Reanimated 3) -::: - -To customize the transition you need to pass all the properties besides `transform`. +By default, the transition animates `width`, `height`, `originX`, `originY`, and `transform` using `withTiming` with a 500 ms duration. You can customize the transition using `SharedTransition.custom()`: ```jsx -import { SharedTransition } from 'react-native-reanimated'; +import { SharedTransition, withSpring } from 'react-native-reanimated'; +// highlight-start const customTransition = SharedTransition.custom((values) => { 'worklet'; + return { height: withSpring(values.targetHeight), width: withSpring(values.targetWidth), @@ -205,6 +135,7 @@ const customTransition = SharedTransition.custom((values) => { originY: withSpring(values.targetOriginY), }; }); +// highlight-end function HomeScreen() { return ( @@ -212,7 +143,32 @@ function HomeScreen() { style={{ width: 300, height: 300 }} sharedTransitionTag="tag" // highlight-next-line - sharedTransitionStyle={customTransition} // add this to both elements on both screens + sharedTransitionStyle={customTransition} + /> + ); +} +``` + +### New Architecture (Reanimated 4) + +On the New Architecture, the default transition animates `width`, `height`, `originX`, `originY`, `transform`, `backgroundColor`, and `opacity` using `withTiming` with a 500 ms duration. + +Currently customization is more limited due to ongoing development. You can't define fully custom animation functions. Instead, use the `SharedTransition` builder class to configure duration and spring-based animations: + +```jsx +import { SharedTransition } from 'react-native-reanimated'; + +// Customize duration and use spring animation +// highlight-next-line +const customTransition = SharedTransition.duration(550).springify(); + +function HomeScreen() { + return ( + ); } @@ -222,8 +178,22 @@ function HomeScreen() { You can find a full Shared Element Transitions reference in the [React Native Reanimated documentation](https://docs.swmansion.com/react-native-reanimated/docs/shared-element-transitions/overview/). -## Alternatives +## Limitations + +Shared Element Transitions currently have several limitations to be aware of: + +- Only the [native stack navigator](native-stack-navigator.md) is supported +- Other navigators such as JS stack, drawer, and bottom tabs are not supported +- Transitions with native modals don't work properly on iOS + +### New Architecture specific limitations (Reanimated 4) + +The following limitations apply specifically when using Reanimated 4 on the New Architecture: -Alternatively, you can use [`react-native-shared-element`](https://github.com/IjzerenHein/react-native-shared-element) library with a [React Navigation binding](https://github.com/IjzerenHein/react-navigation-shared-element) which implements Shared Element Transitions in a JS-based `@react-navigation/stack` navigator. This solution, however, isn't actively maintained. +- The feature must be enabled via the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag +- Custom animation functions are not supported; you can only customize duration and use spring-based animations +- Some properties (e.g., `backgroundColor`) are not supported in progress-based transitions (iOS back gesture) +- There are performance bottlenecks with transforms being recalculated too eagerly +- On iOS, you may encounter issues with vertical positioning due to header height information propagation -The [`react-native-navigation`](https://github.com/wix/react-native-navigation) also comes with support for Shared Element Transitions. You can read more about it [here](https://wix.github.io/react-native-navigation/docs/style-animations#shared-element-transitions). +The limitations will be addressed in future Reanimated releases. diff --git a/versioned_docs/version-8.x/shared-element-transitions.md b/versioned_docs/version-8.x/shared-element-transitions.md index 813b90f499..89928f1e8e 100644 --- a/versioned_docs/version-8.x/shared-element-transitions.md +++ b/versioned_docs/version-8.x/shared-element-transitions.md @@ -11,9 +11,11 @@ This guide covers how to animate elements between screens. This feature is known :::warning -As of writing this guide, Shared Element Transitions are considered an experimental feature not recommended for production use. +Shared Element Transitions are an experimental feature not recommended for production use yet. -Shared Element Transitions are currently only supported on **old React Native architecture** (Paper). +**Reanimated 4** supports Shared Element Transitions on the **New Architecture** (Fabric) since **4.2.0**, but the feature is behind a feature flag. You need to [enable the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag](https://docs.swmansion.com/react-native-reanimated/docs/guides/feature-flags#enable_shared_element_transitions) to use it. + +Check [the Reanimated documentation](https://docs.swmansion.com/react-native-reanimated/docs/shared-element-transitions/overview/) for details and [send feedback to the Reanimated team](https://github.com/software-mansion/react-native-reanimated) ::: @@ -25,8 +27,9 @@ Shared Element Transitions are currently only supported on **old React Native ar Before continuing this guide make sure your app meets these criteria: -- You are using [`@react-navigation/native-stack`](native-stack-navigator.md). The Shared Element Transitions feature isn't supported in JS-based [`@react-navigation/stack`](stack-navigator.md). -- You have [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started) **v3.0.0 or higher** installed and configured. +- You are using [`@react-navigation/native-stack`](native-stack-navigator.md). JS-based [`@react-navigation/stack`](stack-navigator.md) or other navigators are not supported. +- You have [`react-native-reanimated`](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started) **v4.2.0 or higher** installed and configured. +- You have [enabled the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag](https://docs.swmansion.com/react-native-reanimated/docs/guides/feature-flags#enable_shared_element_transitions). ## Minimal example @@ -36,23 +39,23 @@ To create a shared transition: 2. Assign the same `sharedTransitionTag` to elements on different screens. 3. Navigate between screens. The transition will start automatically. - - - -```js name="Shared transition" +```js static2dynamic name="Shared transition" import * as React from 'react'; import { View, StyleSheet } from 'react-native'; import { useNavigation, createStaticNavigation, } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; +import { + createNativeStackNavigator, + createNativeStackScreen, +} from '@react-navigation/native-stack'; import { Button } from '@react-navigation/elements'; import Animated from 'react-native-reanimated'; function HomeScreen() { - const navigation = useNavigation('Home'); + const navigation = useNavigation(); return ( @@ -70,7 +73,7 @@ function HomeScreen() { } function DetailsScreen() { - const navigation = useNavigation('Details'); + const navigation = useNavigation(); return ( @@ -85,14 +88,16 @@ function DetailsScreen() { ); } -// highlight-start const RootStack = createNativeStackNavigator({ screens: { - Home: HomeScreen, - Details: DetailsScreen, + Home: createNativeStackScreen({ + screen: HomeScreen, + }), + Details: createNativeStackScreen({ + screen: DetailsScreen, + }), }, }); -// highlight-end const Navigation = createStaticNavigation(RootStack); @@ -108,103 +113,22 @@ const styles = StyleSheet.create({ }); ``` - - - -```js name="Shared transition" -import * as React from 'react'; -import { View, StyleSheet } from 'react-native'; -import { NavigationContainer, useNavigation } from '@react-navigation/native'; -import { createNativeStackNavigator } from '@react-navigation/native-stack'; -import { Button } from '@react-navigation/elements'; - -import Animated from 'react-native-reanimated'; - -// highlight-next-line -const Stack = createNativeStackNavigator(); - -function HomeScreen() { - const navigation = useNavigation('Home'); - - return ( - - - - - ); -} - -function DetailsScreen() { - const navigation = useNavigation('Details'); - - return ( - - - - - ); -} - -export default function App() { - return ( - - - - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - alignItems: 'center', - }, -}); -``` - - - - `sharedTransitionTag` is a string that has to be unique in the context of a single screen, but has to match elements between screens. This prop allows Reanimated to identify and animate the elements, similarly to the [`key`](https://react.dev/learn/rendering-lists#keeping-list-items-in-order-with-key) property, which tells React which element in the list is which. ## Customizing the transition -By default, the transition animates the `width`, `height`, `originX`, `originY` and `transform` properties using `withTiming` with a 500 ms duration. You can easily customize `width`, `height`, `originX`, and `originY` props. Customizing `transform` is also possible but it's far beyond the scope of this guide. +You can customize the transition by passing a custom `SharedTransition` configuration via the `sharedTransitionStyle` prop. Apply the same `sharedTransitionStyle` to the matching element on the target screen. -:::warning - -Custom SharedTransition API is not finalized and might change in a future release. - -::: +The default transition animates `width`, `height`, `originX`, `originY`, `transform`, `backgroundColor`, and `opacity` using `withTiming` with a 500 ms duration. -To customize the transition you need to pass all the properties besides `transform`. +Currently customization is more limited due to ongoing development. You can't define fully custom animation functions. Instead, use the `SharedTransition` builder class to configure duration and spring-based animations: ```jsx import { SharedTransition } from 'react-native-reanimated'; -const customTransition = SharedTransition.custom((values) => { - 'worklet'; - return { - height: withSpring(values.targetHeight), - width: withSpring(values.targetWidth), - originX: withSpring(values.targetOriginX), - originY: withSpring(values.targetOriginY), - }; -}); +// Customize duration and use spring animation +// highlight-next-line +const customTransition = SharedTransition.duration(550).springify(); function HomeScreen() { return ( @@ -212,18 +136,29 @@ function HomeScreen() { style={{ width: 300, height: 300 }} sharedTransitionTag="tag" // highlight-next-line - sharedTransitionStyle={customTransition} // add this to both elements on both screens + sharedTransitionStyle={customTransition} /> ); } ``` +Custom transition configuration is not fully finalized and might change in a future release. + ## Reference You can find a full Shared Element Transitions reference in the [React Native Reanimated documentation](https://docs.swmansion.com/react-native-reanimated/docs/shared-element-transitions/overview/). -## Alternatives +## Limitations + +Shared Element Transitions currently have several limitations to be aware of: -Alternatively, you can use [`react-native-shared-element`](https://github.com/IjzerenHein/react-native-shared-element) library with a [React Navigation binding](https://github.com/IjzerenHein/react-navigation-shared-element) which implements Shared Element Transitions in a JS-based `@react-navigation/stack` navigator. This solution, however, isn't actively maintained. +- Only the [native stack navigator](native-stack-navigator.md) is supported +- Other navigators such as JS stack, drawer, and bottom tabs are not supported +- Transitions with native modals don't work properly on iOS +- The feature must be enabled via the `ENABLE_SHARED_ELEMENT_TRANSITIONS` feature flag +- Custom animation functions are not supported; you can only customize duration and use spring-based animations +- Some properties (e.g., `backgroundColor`) are not supported in progress-based transitions (iOS back gesture) +- There are performance bottlenecks with transforms being recalculated too eagerly +- On iOS, you may encounter issues with vertical positioning due to header height information propagation -The [`react-native-navigation`](https://github.com/wix/react-native-navigation) also comes with support for Shared Element Transitions. You can read more about it [here](https://wix.github.io/react-native-navigation/docs/style-animations#shared-element-transitions). +The limitations will be addressed in future Reanimated releases.