this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update output with titles

+3765 -3917
+5 -9
out/llms-full-nativewind.txt
··· 627 627 628 628 *** 629 629 630 - ## Accessing and Managing Device Color Scheme 630 + ## useColorScheme() 631 631 632 632 The `useColorScheme()` function provides a way to access and manage the device's current color scheme. 633 633 ··· 809 809 810 810 These classes are used to define how the background of an element is clipped, with support limited to web browsers. 811 811 812 - ## Responsive Design in Nativewind 812 + ## Responsive Design 813 813 814 814 **Note:**\ 815 815 The default theme of Nativewind is not specifically tailored for native devices. It currently employs breakpoints that are primarily intended for web applications. 816 816 817 817 Nativewind's approach to responsive design mirrors that of Tailwind CSS. For detailed information, please consult the official Tailwind CSS documentation. 818 818 819 - ## remapProps Utility in Nativewind 819 + ## remapProps 820 820 821 821 Nativewind offers a utility called `remapProps` to streamline the integration of third-party components that have multiple "style" props. This tool allows developers to map Tailwind CSS class names to these style props, enhancing ease of use and consistency. 822 822 ··· 4263 4263 4264 4264 This configuration allows you to specify additional class attributes that Tailwind CSS will recognize and apply. 4265 4265 4266 - ```markdown 4267 - ## Content Rules in Nativewind 4266 + ## Content 4268 4267 4269 4268 Nativewind adheres to the same content configuration guidelines as Tailwind CSS. For detailed information and solutions to potential issues, consult the official Tailwind CSS documentation. 4270 - ``` 4271 - 4272 - This reformatted markdown maintains the original message while ensuring clarity and conciseness for an AI context. 4273 4269 4274 4270 ## Overflow 4275 4271 ··· 4705 4701 } 4706 4702 ``` 4707 4703 4708 - ## Usage 4704 + ## Top / Right / Bottom / Left 4709 4705 4710 4706 For detailed information, please consult the Tailwind CSS documentation. 4711 4707
+46 -50
out/llms-full-react-native-gesture-handler.txt
··· 22 22 23 23 Software Mansion is a team of React Native Core Contributors and experts specializing in resolving various React Native challenges. Whether you need assistance with gestures, animations, or general development, we are here to help. 24 24 25 - ## Installation Guide for react-native-gesture-handler 25 + ## Installation 26 26 27 27 ### Requirements 28 28 ··· 176 176 177 177 Ensure each screen in your app is wrapped with `GestureHandlerRootView` as native navigation libraries map each screen to a separate root view. 178 178 179 - ## Rotation Gesture 179 + ## Rotation gesture 180 180 181 181 A continuous gesture capable of recognizing and tracking rotation movements. Activation occurs when fingers are placed on the screen and move in a specific manner. 182 182 ··· 302 302 303 303 - **`pointerType`**: Type of pointer device, represented by the `PointerType` enum (`TOUCH`, `STYLUS`, `MOUSE`, `KEY`, `OTHER`). 304 304 305 - ## Pinch Gesture 305 + ## Pinch gesture 306 306 307 307 A continuous gesture that recognizes pinch gestures, allowing for tracking the distance between two fingers to scale or zoom content. The gesture activates when fingers are placed on the screen and change their position. A callback can be used for continuous tracking of the pinch gesture, providing information about velocity, anchor (focal) point, and scale. 308 308 ··· 629 629 } 630 630 ``` 631 631 632 - ## Pan Gesture 632 + ## Pan gesture 633 633 634 634 A pan gesture recognizes and tracks a continuous dragging motion. It activates when a finger touches the screen and moves beyond an initial distance. 635 635 ··· 879 879 } 880 880 ``` 881 881 882 - ## Gesture States and Events 882 + ## Gesture states & events 883 883 884 884 Each gesture can be conceptualized as a "state machine." At any given moment, each handler instance is assigned a state that may change due to new touch events or specific conditions imposed by the touch system. 885 885 ··· 959 959 - **`onPointerCancelled`** 960 960 - Called when no further pointer information is available due to gesture completion or interruption. May involve multiple pointers due to event batching. 961 961 962 - ## Handler State Overview 962 + ## Handler State 963 963 964 964 Gesture handlers are conceptualized as "state machines," where each instance maintains an assigned state that can change due to new touch events or be altered by the touch system under specific conditions. There are six possible states for a gesture handler: 965 965 ··· 1036 1036 1037 1037 Signifies the end of a gesture with touches indicating completion. The state transitions to `UNDETERMINED` after resetting. 1038 1038 1039 - ```markdown 1040 - # Legacy Gesture Handlers 1039 + ## Legacy Gesture Handlers 1041 1040 1042 - ## Overview 1041 + ### Overview 1043 1042 1044 1043 The legacy gesture handler API is scheduled for removal in upcoming versions of Gesture Handler. Users are encouraged to transition to the new gestures API. For detailed migration instructions, refer to the provided upgrading guide. 1045 1044 1046 - ## Cross-Handler Interactions 1045 + ### Cross-Handler Interactions 1047 1046 1048 1047 The previous cross-handler interaction capabilities will be deprecated in future releases. Transitioning to the updated gestures API is recommended. Consult the upgrading guide for further details. 1049 1048 1050 - ## Common Handler Properties 1049 + ### Common Handler Properties 1051 1050 1052 1051 Properties common across handlers in the old API are slated for removal. Users should adopt the new gestures API and refer to the upgrading guide for assistance. 1053 1052 1054 - ## Specific Gesture Handlers 1053 + ### Specific Gesture Handlers 1055 1054 1056 - ### Pan 1055 + #### Pan 1057 1056 1058 1057 The pan gesture handler from the legacy API will be deprecated. Transitioning to the gestures API is advised. See the upgrading guide for more information. 1059 1058 1060 - ### Tap 1059 + #### Tap 1061 1060 1062 1061 The tap gesture handler in the old API will no longer be supported. Users should migrate to the new gestures API. Refer to the upgrading guide for guidance. 1063 1062 1064 - ### Long Press 1063 + #### Long Press 1065 1064 1066 1065 Long press functionality from the legacy API will be removed. Transitioning to the gestures API is recommended. Consult the upgrading guide for more details. 1067 1066 1068 - ### Rotation 1067 + #### Rotation 1069 1068 1070 1069 The rotation gesture handler in the old API will be deprecated. Migrating to the gestures API is advised. See the upgrading guide for further information. 1071 1070 1072 - ### Fling 1071 + #### Fling 1073 1072 1074 1073 Fling gesture handling from the legacy API will be removed. Users should transition to the new gestures API. Refer to the upgrading guide for assistance. 1075 1074 1076 - ### Pinch 1075 + #### Pinch 1077 1076 1078 1077 The pinch gesture handler in the old API will no longer be supported. Transitioning to the gestures API is recommended. Consult the upgrading guide for more details. 1079 1078 1080 - ### Force Touch 1079 + #### Force Touch 1081 1080 1082 1081 Force touch functionality from the legacy API will be deprecated. Migrating to the gestures API is advised. See the upgrading guide for further information. 1083 1082 1084 - ## NativeView 1083 + ### NativeView 1085 1084 1086 1085 The `NativeView` component in the old API will be removed. Users should adopt the new gestures API and refer to the upgrading guide for assistance. 1087 1086 1088 - ## createNativeWrapper() 1087 + ### createNativeWrapper() 1089 1088 1090 1089 The `createNativeWrapper()` function from the legacy API will no longer be supported. Transitioning to the gestures API is recommended. Consult the upgrading guide for more details. 1091 - ``` 1092 1090 1093 1091 ## Testing with Jest 1094 1092 ··· 1343 1341 1344 1342 By setting `touchAction` to `"pan-y"`, you allow vertical panning, which helps maintain scroll functionality in your custom swipeable component. 1345 1343 1346 - ## Cross Handler Interactions 1344 + ## Cross handler interactions 1347 1345 1348 1346 **Warning:** The old API will be removed in future versions of Gesture Handler. Please migrate to the gestures API instead. Refer to our upgrading guide for more information. 1349 1347 ··· 1429 1427 ); 1430 1428 ``` 1431 1429 1432 - ## Fling Gesture 1430 + ## Fling gesture 1433 1431 1434 1432 A discrete gesture activated by sufficiently long and fast movement. The gesture becomes ACTIVE when the movement meets these criteria, transitioning to END upon finger release. If the finger lifts before activation, recognition fails. 1435 1433 ··· 1537 1535 |`numberOfPointers`|Number of pointers currently on the screen.| 1538 1536 |`pointerType`|Type of pointer device, using `PointerType`: `TOUCH`, `STYLUS`, `MOUSE`, `KEY`, `OTHER`.| 1539 1537 1540 - ## Common Handler Properties 1538 + ## Common handler properties 1541 1539 1542 1540 **Warning:** The old API will be removed in future versions of Gesture Handler. Please migrate to the gestures API instead. Refer to our upgrading guide for more information. 1543 1541 ··· 1617 1615 1618 1616 - **Description:** Represents the number of pointers (fingers) currently on the screen. 1619 1617 1620 - ## Hover Gesture 1618 + ## Hover gesture 1621 1619 1622 1620 A continuous gesture designed to recognize hovering actions over a view. This can be triggered by moving a mouse or stylus above the view. 1623 1621 ··· 2042 2040 2043 2041 This example sets up a button that triggers an alert when held down for more than 800 milliseconds. 2044 2042 2045 - ## Custom Swipeable Components in ScrollView (Web) 2043 + ## Custom swipeable components inside ScrollView (web) 2046 2044 2047 2045 When developing custom swipeable components within a `ScrollView` on the web, you might opt for more control over their behavior by creating your own version instead of using pre-built solutions like ReanimatedSwipeable. However, one common issue encountered is that scrolling functionality may not work as expected after implementing a custom swipeable component. 2048 2046 ··· 2067 2065 2068 2066 By setting `touchAction` to `"pan-y"`, you allow the browser to handle vertical panning, which can resolve issues with scrolling when using custom swipeable components inside a `ScrollView`. 2069 2067 2070 - ## Migrating Away from RNGHEnabledRootView 2068 + ## Migrating off RNGHEnabledRootView 2071 2069 2072 2070 ### Update `MainActivity.java` 2073 2071 ··· 2117 2115 2118 2116 **Note:** `GestureHandlerRootView` behaves like a standard `View`. To ensure it fills the screen, you must pass `{ flex: 1 }`, similar to how you would with a regular View. By default, it will take on the size of its nested content. 2119 2117 2120 - ## Rotation Gesture Handler 2118 + ## RotationGestureHandler 2121 2119 2122 2120 > **Warning:**\ 2123 2121 > The old API will be deprecated in future versions of Gesture Handler. It is recommended to migrate to the gestures API. Refer to our upgrading guide for more details. ··· 2259 2257 2260 2258 This example shows a button that triggers an alert when flinged to the right or left. 2261 2259 2262 - ## Quick Start Guide 2260 + ## Quick start 2263 2261 2264 2262 RNGH2 simplifies adding gestures to your application. To implement a gesture, wrap the target view with `GestureDetector`, define the desired gesture, and pass it to the detector. 2265 2263 ··· 2391 2389 2392 2390 Now, add the `Ball` component to a view in your app to see it in action! 2393 2391 2394 - ## Native Gesture 2392 + ## Native gesture 2395 2393 2396 2394 A gesture that integrates with other touch handling components within RNGH's gesture system. This integration facilitates interactions between gestures and native components, allowing them to establish relationships with other gestures. 2397 2395 ··· 2731 2729 2732 2730 **Note**: For a detailed example, refer to the Gesture Handler Example App. 2733 2731 2734 - ## Manual Gesture 2732 + ## Manual gesture 2735 2733 2736 2734 A manual gesture lacks specific activation criteria and event data. Its state must be managed manually using a state manager, ensuring it doesn't fail when all pointers are lifted from the screen. 2737 2735 ··· 2873 2871 - `KEY`: Keyboard 2874 2872 - `OTHER`: Unknown device type 2875 2873 2876 - ## Migrating from `RNGestureHandlerEnabledRootView` (Android Only) 2874 + ## Make sure to migrate off the \`RNGestureHandlerEnabledRootView\` (Android only) 2877 2875 2878 2876 The `RNGestureHandlerEnabledRootView`, required in Gesture Handler 1 for overriding `createRootView`, was deprecated in version 2.0 and removed by version 2.4 due to its association with difficult-to-debug crashes. If you're still using it, refer to the guide on migrating off RNGHEnabledRootView. 2879 2877 ··· 2986 2984 2987 2985 For relations between gestures on the same view, use the Gesture Composition API. For different views or old gesture handlers, replace `simultaneousHandlers` with `simultaneousWithExternalGesture`, and `waitFor` with `requireExternalGestureToFail`. Use `.withRef(refObject)` to pass a ref object to an old handler. 2988 2986 2989 - ## Composed Gestures 2987 + ## Composed gestures 2990 2988 2991 2989 Composed gestures such as `Race`, `Simultaneous`, and `Exclusive` offer a straightforward method for establishing relationships between different gestures. For further information, refer to the section on Gesture Composition. 2992 2990 ··· 3012 3010 3013 3011 This example demonstrates how to use the `Race` method to compose two gestures: a pan gesture and a long press gesture. The composed gesture is then used within a `GestureDetector` component, which wraps an `Animated.View`. 3014 3012 3015 - ## Common Handler Properties 3013 + ## Common handler properties 3016 3014 3017 3015 **Warning:** The old API will be removed in future versions of Gesture Handler. Please migrate to the gestures API instead. Refer to our upgrading guide for more information. 3018 3016 ··· 3168 3166 3169 3167 The `GestureStateManager` allows manual control over gesture states. Note that react-native-reanimated is required for its use, as it enables synchronous execution of methods within worklets. 3170 3168 3171 - ## Touch Events 3169 + ## Touch events 3172 3170 3173 3171 ### Touch Event Attributes 3174 3172 ··· 3194 3192 3195 3193 - **absoluteY**: The Y coordinate of the current position of the touch relative to the window, expressed in point units. Recommended for use when the original view can be transformed due to a gesture. 3196 3194 3197 - ## Gesture State Manager 3195 + ## Gesture state manager 3198 3196 3199 3197 The `GestureStateManager` provides manual control over gesture states, requiring `react-native-reanimated` for synchronous execution of methods within worklets. 3200 3198 ··· 3220 3218 - **Purpose**: Transition the gesture to the `FAILED` state. 3221 3219 - **Effectiveness**: Ineffective if the handler has already finished. 3222 3220 3223 - ## Touch Events 3221 + ## Touch events 3224 3222 3225 3223 ### Touch Event Attributes 3226 3224 ··· 3246 3244 3247 3245 - **absoluteY**: The Y coordinate of the current position of the touch relative to the window, expressed in point units. Recommended for use when the original view can be transformed due to a gesture. 3248 3246 3249 - ## Gesture State Manager 3247 + ## Gesture state manager 3250 3248 3251 3249 The `GestureStateManager` provides manual control over gesture states, requiring `react-native-reanimated` for synchronous execution of methods within worklets. 3252 3250 ··· 3600 3598 } 3601 3599 ``` 3602 3600 3603 - ## Gesture Composition & Interactions 3601 + ## Gesture composition & interactions 3604 3602 3605 3603 In RNGH2, composing gestures has been simplified compared to previous versions. There is no longer a need to create a reference for each gesture that depends on another one. Instead, you can utilize the Race, Simultaneous, and Exclusive methods provided by the Gesture object. 3606 3604 ··· 3614 3612 3615 3613 These methods facilitate more intuitive and flexible gesture interactions within your application. 3616 3614 3617 - ## Manual Gestures 3615 + ## Manual gestures 3618 3616 3619 3617 RNGH2 introduces manual gestures and touch events, allowing for custom gesture tracking. This guide demonstrates creating a simple gesture that tracks all pointers on the screen. 3620 3618 ··· 3787 3785 3788 3786 Manual gestures offer powerful customization, enabling complex interactions. Additionally, existing gestures can be modified with `manualActivation` to control activation behavior, such as implementing drag after a long press by setting `manualActivation` on a `PanGesture`. 3789 3787 3790 - ## Pressable Component 3788 + ## Pressable 3791 3789 3792 3790 ### Overview 3793 3791 ··· 3870 3868 }); 3871 3869 ``` 3872 3870 3873 - ## Gesture Composition & Interactions 3871 + ## Gesture composition & interactions 3874 3872 3875 3873 Composing gestures in RNGH2 is straightforward. You don't need to create a ref for each gesture that depends on another one. Instead, use `Race`, `Simultaneous`, and `Exclusive` methods provided by the `Gesture` object. 3876 3874 ··· 4428 4426 4429 4427 We are grateful for our sponsors who enable the development of this library and contribute to enhancing the React Native ecosystem. Special thanks to all our supporters! 4430 4428 4431 - ## Troubleshooting Guide 4429 + ## Troubleshooting 4432 4430 4433 4431 ### Seeking Help with Issues 4434 4432 ··· 4510 4508 4511 4509 This ensures proper workletization for asynchronous operations within gestures. 4512 4510 4513 - ## Tap Gesture 4511 + ## Tap gesture 4514 4512 4515 4513 A tap gesture recognizes one or multiple taps. It detects brief touches on the screen by fingers, which must remain relatively stationary from their initial positions. You can configure tap gestures to recognize single, double, or triple taps based on specific requirements such as `minPointers`, `numberOfTaps`, `maxDist`, `maxDuration`, and `maxDelayMs`. 4516 4514 ··· 4811 4809 }); 4812 4810 ``` 4813 4811 4814 - ## Swipeable Component 4812 + ## Swipeable 4815 4813 4816 4814 **Caution:** This component facilitates the implementation of swipeable rows or similar interactions. It renders its children within a panable container, allowing for horizontal swiping left and right. Depending on whether the user swipes left or right, one of two "action" containers can be displayed, rendered by `renderLeftActions` or `renderRightActions` props. 4817 4815 ··· 4988 4986 4989 4987 For a comparison of both touchable implementations, refer to our touchables example. 4990 4988 4991 - ```markdown 4992 - # Handler State 4989 + ## Handler State 4993 4990 4994 4991 Gesture handlers are conceptualized as "state machines" according to the description provided in "About Gesture Handlers". This means they operate through a series of states, transitioning between them based on specific inputs or events. 4995 - ``` 4996 4992 4997 - ## How It Works 4993 + ## How does it work? 4998 4994 4999 4995 ### Units 5000 4996
+3655 -3817
out/llms-full-react-native-reanimated.txt
··· 1 - # React Native Reanimated 1 + # React NativeReanimated 2 2 3 3 ### Create Smooth Animations with an Excellent Developer Experience 4 4 ··· 221 221 |-|-|-| 222 222 |✅|✅|✅| 223 223 224 - ## useAnimatedScrollHandler 224 + ## Shared Element Transitions 225 225 226 - The `useAnimatedScrollHandler` hook provides an event handler reference that can be utilized with React Native's scrollable components. This hook is part of the `react-native-reanimated` library. 226 + > **Caution:**\ 227 + > Shared Element Transition is an experimental feature and not recommended for production use yet. Feedback is welcomed to enhance its implementation. 228 + 229 + Shared Element Transition enables a smooth transformation of a component from one screen to another. 227 230 228 231 ### Reference 229 232 230 233 ```typescript 231 - import { useAnimatedScrollHandler } from 'react-native-reanimated'; 234 + import Animated from 'react-native-reanimated'; 232 235 233 - function App() { 234 - const offsetY = useSharedValue(0); 236 + const Stack = createNativeStackNavigator(); 235 237 236 - const scrollHandler = useAnimatedScrollHandler((event) => { 237 - offsetY.value = event.contentOffset.y; 238 - }); 239 - 240 - // ... 241 - 242 - return <Animated.ScrollView onScroll={scrollHandler} />; 238 + function One({ navigation }) { 239 + return ( 240 + <> 241 + <Animated.View sharedTransitionTag="sharedTag" /> 242 + <Button title="Two" onPress={() => navigation.navigate('Two')} /> 243 + </> 244 + ); 243 245 } 244 - ``` 245 - 246 - #### Arguments 247 246 248 - ##### `handlers` 249 - 250 - An object containing custom keys that correspond to native event names. Available keys include: 251 - 252 - - `onScroll` 253 - - `onBeginDrag` 254 - - `onEndDrag` 255 - - `onMomentumBegin` 256 - - `onMomentumEnd` 257 - 258 - Each key should map to an individual worklet function. These functions are triggered when the associated events occur on a connected Scrollable component. 259 - 260 - The event worklets receive two parameters: 261 - 262 - - `event`: An object containing information about the scroll. The structure of this payload varies based on the event type. Refer to React Native's ScrollView documentation for details. 263 - 264 - - `context`: A plain JavaScript object used for storing state that persists between scroll events. This allows communication between multiple event handlers when provided as an object of worklets. 265 - 266 - ##### `dependencies` (Optional) 267 - 268 - An optional array of dependencies, relevant only when using Reanimated without the Babel plugin on the Web. 269 - 270 - #### Returns 271 - 272 - The hook returns a handler object suitable for integration with a scrollable container. The returned handler should be assigned to the `onScroll` parameter, regardless of whether it is configured to handle scroll, momentum, or drag events. For proper functionality, use containers wrapped with `Animated`, such as `Animated.ScrollView`. 273 - 274 - ### Example 275 - 276 - ### Remarks 277 - 278 - - The returned handler can be passed to multiple components. It will invoke for the specified events whenever any component dispatches them. 279 - - If a single worklet function of type `(event) => void` is provided instead of an object mapping functions to event keys, it is treated as a handler for the `onScroll` event. 280 - - Only the `onScroll` event is supported on Web. 281 - 282 - ### Platform Compatibility 283 - 284 - |Android|iOS|Web| 285 - |-|-|-| 286 - |✅|✅|✅| 287 - 288 - ## useEvent Hook Overview 289 - 290 - The `useEvent` hook is a foundational tool in React Native Reanimated that provides an event handler for native events. It's particularly useful for creating custom hooks like `useScrollViewOffset` or `useAnimatedScrollHandler`. 291 - 292 - ### Reference Usage 293 - 294 - ```typescript 295 - import { useEvent } from 'react-native-reanimated'; 296 - 297 - function useAnimatedPagerScrollHandler(handlers, dependencies) { 298 - const { context, doDependenciesDiffer } = useHandler(handlers, dependencies); 299 - 300 - return useEvent( 301 - (event) => { 302 - 'worklet'; 303 - const { onPageScroll } = handlers; 304 - 305 - if (onPageScroll && event.eventName.endsWith('onPageScroll')) { 306 - onPageScroll(event, context); 307 - } 308 - }, 309 - ['onPageScroll'], 310 - doDependenciesDiffer 247 + function Two({ navigation }) { 248 + return ( 249 + <> 250 + <Animated.View sharedTransitionTag="sharedTag" /> 251 + <Button title="One" onPress={() => navigation.navigate('One')} /> 252 + </> 311 253 ); 312 254 } 313 255 314 - return <Animated.View onScroll={useAnimatedPagerScrollHandler} />; 256 + export default function SharedElementExample() { 257 + return ( 258 + <NavigationContainer> 259 + <Stack.Navigator screenOptions={{ headerShown: true }}> 260 + <Stack.Screen name="One" component={One} /> 261 + <Stack.Screen name="Two" component={Two} /> 262 + </Stack.Navigator> 263 + </NavigationContainer> 264 + ); 265 + } 315 266 ``` 316 267 317 - #### Arguments 318 - 319 - - **`handler`**: A function that receives an event object containing the native payload. This can be utilized within custom handler hooks' worklets. 320 - 321 - - `event`: The event object, whose payload varies based on the event type. 322 - 323 - - **`eventNames` (Optional)**: An array specifying which event names should trigger the handler. 268 + ### Overview 324 269 325 - - **`rebuild` (Optional)**: A boolean indicating if the handler needs to be rebuilt. 270 + When Reanimated detects a component with a `sharedTransitionTag` being mounted or unmounted, it searches for the last registered view with the same tag. If two matching components are found, their styles are captured and both views are temporarily moved to a transition container during the animation. Afterward, they return to their original parent. 326 271 327 - #### Returns 272 + Without custom animations, properties like `width`, `height`, `originX`, `originY`, and `transformMatrix` animate by default over 500ms using `withTiming`. 328 273 329 - The hook returns an event handler that is invoked when a native event occurs. This handler can be connected to multiple components, triggering for each component's specific events. 274 + ### Implementation 330 275 331 - ### Example 276 + To create a shared transition between components on different screens, assign the same `sharedTransitionTag`. Unique tags are required for multiple shared views on the same screen. 332 277 333 - For simpler implementations, consider using `useScrollViewOffset`. 334 - 335 - ### Remarks 336 - 337 - - Note that not all scroll events are supported on the web; only `onScroll` is consistently available across browsers. 338 - 339 - ### Platform Compatibility 340 - 341 - |Android|iOS|Web| 342 - |-|-|-| 343 - |✅|✅|✅| 344 - 345 - This overview provides a concise guide to using the `useEvent` hook effectively within React Native Reanimated projects. 346 - 347 - ## useHandler Hook in React Native Reanimated 348 - 349 - The `useHandler` hook is a foundational tool within the React Native Reanimated library. It provides a context object and an indicator to determine if worklets require rebuilding. This functionality facilitates the creation of custom event handler hooks, such as `useScrollViewOffset` or `useAnimatedScrollHandler`. 350 - 351 - ### Reference 278 + **Screen A** 352 279 353 280 ```typescript 354 - import { useEvent, useHandler } from "react-native-reanimated" 355 - 356 - function useAnimatedPagerScrollHandler( 357 - handlers: Record<string, (event: any, context: object) => void>, 358 - dependencies?: any[] 359 - ) { 360 - const { context, doDependenciesDiffer, useWeb } = useHandler( 361 - handlers, 362 - dependencies 363 - ) 364 - 365 - return useEvent( 366 - (event: any) => { 367 - "worklet" 368 - const { onPageScroll } = handlers 369 - 370 - if (onPageScroll && event.eventName.endsWith("onPageScroll")) { 371 - onPageScroll(event, context) 372 - } 373 - }, 374 - ["onPageScroll"], 375 - doDependenciesDiffer 376 - ) 377 - } 281 + <View 282 + sharedTransitionTag="sharedTag" 283 + style={{ width: 150, height: 150, backgroundColor: 'green' }} 284 + /> 378 285 ``` 379 286 380 - #### Arguments 287 + **Screen B** 381 288 382 - ##### `handlers` 289 + ```typescript 290 + <View 291 + sharedTransitionTag="sharedTag" 292 + style={{ width: 100, height: 100, backgroundColor: 'green' }} 293 + /> 294 + ``` 383 295 384 - An object containing keys that correspond to native event names. The values should be individual worklets. Each worklet is triggered when its associated event is dispatched on the connected animated component. 296 + ### Custom Animation 385 297 386 - Each event worklet receives: 298 + Custom animations can be created using `SharedTransition.custom` for regular animations or `SharedTransition.progressAnimation` for progress-based ones. 387 299 388 - - `event`: An event object whose payload varies based on the event type. 389 - - `context`: A plain JavaScript object for storing state, persisting between events. This allows communication among multiple event handlers provided as an object of worklets. 300 + ```typescript 301 + import { SharedTransition } from "react-native-reanimated" 390 302 391 - ##### `dependencies` (Optional) 392 - 393 - An optional array of dependencies. This is relevant when using Reanimated without its Babel plugin in a web environment. 394 - 395 - #### Returns 396 - 397 - The hook returns: 398 - 399 - - A context reused by event handlers. 400 - - An indicator to determine if worklets should be rebuilt. 401 - - A boolean, `useWeb`, to check for the web environment if different implementations are needed. 402 - 403 - ### Example 303 + const transition = SharedTransition.custom((values) => { 304 + "worklet" 305 + return { 306 + height: withSpring(values.targetHeight), 307 + width: withSpring(values.targetWidth), 308 + } 309 + }) 310 + .progressAnimation((values, progress) => { 311 + "worklet" 312 + const getValue = ( 313 + progress: number, 314 + target: number, 315 + current: number 316 + ): number => { 317 + return progress * (target - current) + current 318 + } 319 + return { 320 + width: getValue(progress, values.targetWidth, values.currentWidth), 321 + height: getValue(progress, values.targetHeight, values.currentHeight), 322 + } 323 + }) 324 + .defaultTransitionType(SharedTransitionType.ANIMATION) 325 + ``` 404 326 405 - For simpler implementations, consider using `useScrollViewOffset`. 327 + By setting `defaultTransitionType(SharedTransitionType.ANIMATION)`, the custom animation is used for screen transitions, while progress-based animations apply during swipe-back gestures (iOS only). Use `defaultTransitionType(SharedTransitionType.PROGRESS_ANIMATION)` to apply progress-based animations in both scenarios. 406 328 407 - ### Platform Compatibility 408 - 409 - |Android|iOS|Web| 410 - |-|-|-| 411 - |✅|✅|✅| 412 - 413 - This documentation provides a comprehensive overview of how to utilize the `useHandler` hook within React Native Reanimated for creating custom event handlers. 414 - 415 - ## Keyframe Animations 416 - 417 - Keyframes provide a schema for defining animations, offering more flexibility than standard Entering and Exiting presets. They allow you to create complex animations with ease. 418 - 419 - ### Reference 329 + To use a custom animation, pass it as `sharedTransitionStyle` to components. Different animations can be assigned to different components sharing the same tag for directional transitions. 420 330 421 331 ```typescript 422 - import { Keyframe } from 'react-native-reanimated'; 423 - 424 - const keyframe = new Keyframe({ 425 - 0: { 426 - transform: [{ rotate: '0deg' }], 427 - }, 428 - 45: { 429 - transform: [{ rotate: '100deg' }], 430 - easing: Easing.exp, 431 - }, 432 - 100: { 433 - transform: [{ rotate: '45deg' }], 434 - }, 435 - }); 436 - 437 - function App() { 438 - return <Animated.View entering={keyframe} />; 439 - } 332 + <View 333 + sharedTransitionTag="reanimatedTransition" 334 + sharedTransitionStyle={transition} 335 + style={{ backgroundColor: 'blue', width: 200, height: 100 }} 336 + /> 440 337 ``` 441 338 442 - #### Arguments 443 - 444 - ##### `definitions` 445 - 446 - An object containing animation definitions. The keys should be within the range of `0-100`, representing the progress of the animation. Values consist of style properties and optionally an easing function, defaulting to `Easing.linear` if not specified. 447 - 448 - Key values include: 339 + ### Example 449 340 450 - - `0` or `from`: Represents the initial state. 451 - - Intermediate points (e.g., `45`): Represent intermediate states. 452 - - `100` or `to`: Represents the final state. 341 + Your browser does not support the video tag. 453 342 454 - The key `0` (or `from`) should define the style at the start of the animation, while `100` (or `to`) defines it at the end. 343 + Your browser does not support the video tag. 455 344 456 - ### Modifiers 345 + Expand the full code: 457 346 458 347 ```typescript 459 - keyframe 460 - .duration(1000) 461 - .delay(500) 462 - .reduceMotion(ReduceMotion.Never) 463 - .withCallback((finished) => { 464 - console.log(`finished without interruptions: ${finished}`) 465 - }) 348 + <Pressable onPress={() => goToDetails('countryside')}> 349 + <Animated.View 350 + sharedTransitionTag={'countryside'} 351 + style={[ 352 + styles.imageOne, 353 + { backgroundColor: gallery.countryside.color }, 354 + ]} 355 + /> 356 + </Pressable> 357 + <View style={styles.row}> 358 + <Pressable onPress={() => goToDetails('florence')}> 359 + <Animated.View 360 + sharedTransitionTag={'florence'} 361 + style={[ 362 + { width: width / 2 - 35 }, 363 + styles.imageTwo, 364 + { backgroundColor: gallery.florence.color }, 365 + ]} 366 + /> 367 + </Pressable> 368 + <Pressable onPress={() => goToDetails('dawn')}> 369 + <Animated.View 370 + sharedTransitionTag={'dawn'} 371 + style={[ 372 + { width: width / 2 - 35 }, 373 + styles.imageThree, 374 + { backgroundColor: gallery.dawn.color }, 375 + ]} 376 + /> 377 + </Pressable> 378 + </View> 466 379 ``` 467 380 468 - - `.duration(durationMs: number)` sets the animation length in milliseconds, defaulting to `500`. 469 - - `.delay(durationMs: number)` specifies a delay before starting the animation, defaulting to `0`. 470 - - `.reduceMotion(reduceMotion: ReduceMotion)` adjusts the animation based on the device's reduced motion setting. 471 - - `.withCallback(callback: (finished: boolean) => void)` triggers after the animation ends, indicating if it finished without interruptions. 472 - 473 381 ### Remarks 474 382 475 - - Providing keyframe `0` or `from` is mandatory as it defines the initial state of the object to be animated. 476 - - Ensure all style properties intended for animation have an initial value in other keyframes. 477 - - Easing should only be applied to subsequent keyframes, not to keyframe `0`. 478 - - Avoid using both `0` and `from`, or `100` and `to`, as it causes parsing conflicts. 479 - - When animating transform styles, maintain the order of properties consistently across all keyframes. 383 + - Only the native stack is supported. 384 + - Animatable properties include `width`, `height`, `originX`, `originY`, and `transformMatrix`. 385 + - Layout for shared view children isn't computed during transitions. 386 + - Currently supports only the old React Native architecture (Paper). 387 + - Future support for the new React Native architecture (Fabric) is planned. 480 388 481 389 ### Platform Compatibility 482 390 483 391 |Android|iOS|Web| 484 392 |-|-|-| 485 - |✅|✅|✅| 393 + |✅|✅|❌| 486 394 487 395 ## Troubleshooting 488 396 ··· 737 645 738 646 For more information, refer to Reanimated's documentation on worklets. 739 647 740 - ## Shared Element Transitions 741 - 742 - > **Caution:**\ 743 - > Shared Element Transition is an experimental feature and not recommended for production use yet. Feedback is welcomed to enhance its implementation. 744 - 745 - Shared Element Transition enables a smooth transformation of a component from one screen to another. 746 - 747 - ### Reference 748 - 749 - ```typescript 750 - import Animated from 'react-native-reanimated'; 751 - 752 - const Stack = createNativeStackNavigator(); 753 - 754 - function One({ navigation }) { 755 - return ( 756 - <> 757 - <Animated.View sharedTransitionTag="sharedTag" /> 758 - <Button title="Two" onPress={() => navigation.navigate('Two')} /> 759 - </> 760 - ); 761 - } 762 - 763 - function Two({ navigation }) { 764 - return ( 765 - <> 766 - <Animated.View sharedTransitionTag="sharedTag" /> 767 - <Button title="One" onPress={() => navigation.navigate('One')} /> 768 - </> 769 - ); 770 - } 771 - 772 - export default function SharedElementExample() { 773 - return ( 774 - <NavigationContainer> 775 - <Stack.Navigator screenOptions={{ headerShown: true }}> 776 - <Stack.Screen name="One" component={One} /> 777 - <Stack.Screen name="Two" component={Two} /> 778 - </Stack.Navigator> 779 - </NavigationContainer> 780 - ); 781 - } 782 - ``` 783 - 784 - ### Overview 785 - 786 - When Reanimated detects a component with a `sharedTransitionTag` being mounted or unmounted, it searches for the last registered view with the same tag. If two matching components are found, their styles are captured and both views are temporarily moved to a transition container during the animation. Afterward, they return to their original parent. 787 - 788 - Without custom animations, properties like `width`, `height`, `originX`, `originY`, and `transformMatrix` animate by default over 500ms using `withTiming`. 789 - 790 - ### Implementation 791 - 792 - To create a shared transition between components on different screens, assign the same `sharedTransitionTag`. Unique tags are required for multiple shared views on the same screen. 793 - 794 - **Screen A** 795 - 796 - ```typescript 797 - <View 798 - sharedTransitionTag="sharedTag" 799 - style={{ width: 150, height: 150, backgroundColor: 'green' }} 800 - /> 801 - ``` 802 - 803 - **Screen B** 804 - 805 - ```typescript 806 - <View 807 - sharedTransitionTag="sharedTag" 808 - style={{ width: 100, height: 100, backgroundColor: 'green' }} 809 - /> 810 - ``` 811 - 812 - ### Custom Animation 813 - 814 - Custom animations can be created using `SharedTransition.custom` for regular animations or `SharedTransition.progressAnimation` for progress-based ones. 815 - 816 - ```typescript 817 - import { SharedTransition } from "react-native-reanimated" 818 - 819 - const transition = SharedTransition.custom((values) => { 820 - "worklet" 821 - return { 822 - height: withSpring(values.targetHeight), 823 - width: withSpring(values.targetWidth), 824 - } 825 - }) 826 - .progressAnimation((values, progress) => { 827 - "worklet" 828 - const getValue = ( 829 - progress: number, 830 - target: number, 831 - current: number 832 - ): number => { 833 - return progress * (target - current) + current 834 - } 835 - return { 836 - width: getValue(progress, values.targetWidth, values.currentWidth), 837 - height: getValue(progress, values.targetHeight, values.currentHeight), 838 - } 839 - }) 840 - .defaultTransitionType(SharedTransitionType.ANIMATION) 841 - ``` 842 - 843 - By setting `defaultTransitionType(SharedTransitionType.ANIMATION)`, the custom animation is used for screen transitions, while progress-based animations apply during swipe-back gestures (iOS only). Use `defaultTransitionType(SharedTransitionType.PROGRESS_ANIMATION)` to apply progress-based animations in both scenarios. 844 - 845 - To use a custom animation, pass it as `sharedTransitionStyle` to components. Different animations can be assigned to different components sharing the same tag for directional transitions. 846 - 847 - ```typescript 848 - <View 849 - sharedTransitionTag="reanimatedTransition" 850 - sharedTransitionStyle={transition} 851 - style={{ backgroundColor: 'blue', width: 200, height: 100 }} 852 - /> 853 - ``` 854 - 855 - ### Example 856 - 857 - Your browser does not support the video tag. 858 - 859 - Your browser does not support the video tag. 860 - 861 - Expand the full code: 862 - 863 - ```typescript 864 - <Pressable onPress={() => goToDetails('countryside')}> 865 - <Animated.View 866 - sharedTransitionTag={'countryside'} 867 - style={[ 868 - styles.imageOne, 869 - { backgroundColor: gallery.countryside.color }, 870 - ]} 871 - /> 872 - </Pressable> 873 - <View style={styles.row}> 874 - <Pressable onPress={() => goToDetails('florence')}> 875 - <Animated.View 876 - sharedTransitionTag={'florence'} 877 - style={[ 878 - { width: width / 2 - 35 }, 879 - styles.imageTwo, 880 - { backgroundColor: gallery.florence.color }, 881 - ]} 882 - /> 883 - </Pressable> 884 - <Pressable onPress={() => goToDetails('dawn')}> 885 - <Animated.View 886 - sharedTransitionTag={'dawn'} 887 - style={[ 888 - { width: width / 2 - 35 }, 889 - styles.imageThree, 890 - { backgroundColor: gallery.dawn.color }, 891 - ]} 892 - /> 893 - </Pressable> 894 - </View> 895 - ``` 896 - 897 - ### Remarks 898 - 899 - - Only the native stack is supported. 900 - - Animatable properties include `width`, `height`, `originX`, `originY`, and `transformMatrix`. 901 - - Layout for shared view children isn't computed during transitions. 902 - - Currently supports only the old React Native architecture (Paper). 903 - - Future support for the new React Native architecture (Fabric) is planned. 904 - 905 - ### Platform Compatibility 906 - 907 - |Android|iOS|Web| 908 - |-|-|-| 909 - |✅|✅|❌| 910 - 911 648 ## useAnimatedScrollHandler 912 649 913 650 The `useAnimatedScrollHandler` hook provides an event handler reference that can be utilized with React Native's scrollable components. This hook is part of the `react-native-reanimated` library. ··· 972 709 |-|-|-| 973 710 |✅|✅|✅| 974 711 975 - ## scrollTo Function in React Native Reanimated 712 + ## useAnimatedScrollHandler 976 713 977 - The `scrollTo` function allows you to synchronously scroll a component to a specified X or Y offset. 714 + The `useAnimatedScrollHandler` hook provides an event handler reference that can be utilized with React Native's scrollable components. This hook is part of the `react-native-reanimated` library. 978 715 979 716 ### Reference 980 717 981 718 ```typescript 982 - import { scrollTo } from 'react-native-reanimated'; 719 + import { useAnimatedScrollHandler } from 'react-native-reanimated'; 983 720 984 721 function App() { 985 - const animatedRef = useAnimatedRef(); 986 - const scrollY = useSharedValue(0); 722 + const offsetY = useSharedValue(0); 987 723 988 - useDerivedValue(() => { 989 - scrollTo(animatedRef, 0, scrollY.value, true); 724 + const scrollHandler = useAnimatedScrollHandler((event) => { 725 + offsetY.value = event.contentOffset.y; 990 726 }); 991 727 992 - return ( 993 - <Animated.ScrollView ref={animatedRef}>{/* ... */}</Animated.ScrollView> 994 - ); 728 + // ... 729 + 730 + return <Animated.ScrollView onScroll={scrollHandler} />; 995 731 } 996 732 ``` 997 733 998 734 #### Arguments 999 735 1000 - - **`animatedRef`**: An animated reference linked to the ScrollView (or another scrollable) component you wish to scroll. This animated reference must be passed to either an Animated component or a React Native built-in component. 1001 - 1002 - - **`x`**: The pixel value for horizontal scrolling on the X axis. 1003 - 1004 - - **`y`**: The pixel value for vertical scrolling on the Y axis. 1005 - 1006 - - **`animated`**: A boolean indicating if the scroll should be smooth (`true`) or instant (`false`). 1007 - 1008 - #### Returns 1009 - 1010 - The `scrollTo` function returns `undefined`. 1011 - 1012 - ### Remarks 1013 - 1014 - - The `scrollTo` function must be invoked from the UI thread. 1015 - - It supports `Animated.FlatList`. 1016 - - Typically works with other ScrollView-like and FlatList-like components if they use a `ScrollView` internally and are animated. 1017 - - Scrollable components need to implement the `getScrollableNode` method (and `getNativeScrollRef` for New Architecture) to be compatible with `scrollTo`. 1018 - 1019 - ### Platform Compatibility 1020 - 1021 - |Android|iOS|Web| 1022 - |-|-|-| 1023 - |✅|✅|✅| 1024 - 1025 - ## getRelativeCoords Functionality 1026 - 1027 - The `getRelativeCoords` function is used to determine the screen location relative to a specified view. 1028 - 1029 - ### Reference Code 1030 - 1031 - ```typescript 1032 - import { getRelativeCoords } from 'react-native-reanimated'; 1033 - 1034 - const Comp = () => { 1035 - const animatedRef = useAnimatedRef(); 1036 - 1037 - const gestureHandler = useAnimatedGestureHandler({ 1038 - onEnd: (event) => { 1039 - const coords = getRelativeCoords( 1040 - animatedRef, 1041 - event.absoluteX, 1042 - event.absoluteY 1043 - ); 1044 - }, 1045 - }); 1046 - 1047 - return ( 1048 - <View ref={animatedRef}> 1049 - <PanGestureHandler onGestureEvent={gestureHandler}> 1050 - <Animated.View style={[styles.box]} /> 1051 - </PanGestureHandler> 1052 - </View> 1053 - ); 1054 - }; 1055 - ``` 1056 - 1057 - ### Arguments 1058 - 1059 - - **`animatedRef`**: This is the result of `useAnimatedRef`, which extends a standard React ref to deliver the view tag on the UI thread. It should be passed as a prop to the view relative to which coordinates are needed. 736 + ##### `handlers` 1060 737 1061 - - **`absoluteX`**: A number representing the absolute x-coordinate. 738 + An object containing custom keys that correspond to native event names. Available keys include: 1062 739 1063 - - **`absoluteY`**: A number representing the absolute y-coordinate. 1064 - 1065 - ### Returns 1066 - 1067 - An object containing: 1068 - 1069 - - `x`: The relative x-coordinate. 1070 - - `y`: The relative y-coordinate. 740 + - `onScroll` 741 + - `onBeginDrag` 742 + - `onEndDrag` 743 + - `onMomentumBegin` 744 + - `onMomentumEnd` 1071 745 1072 - ### Platform Compatibility 746 + Each key should map to an individual worklet function. These functions are triggered when the associated events occur on a connected Scrollable component. 1073 747 1074 - |Android|iOS|Web| 1075 - |-|-|-| 1076 - |✅|✅|✅| 748 + The event worklets receive two parameters: 1077 749 1078 - ## useAnimatedGestureHandler 750 + - `event`: An object containing information about the scroll. The structure of this payload varies based on the event type. Refer to React Native's ScrollView documentation for details. 1079 751 1080 - **Warning:**\ 1081 - The `useAnimatedGestureHandler` hook allows for the creation of animations based on gesture handlers. It is essential to provide the object created by this hook to the `onGestureEvent` property of a gesture handler component. 1082 - 1083 - This hook necessitates that `react-native-gesture-handler` be installed and configured within your project. 1084 - 1085 - ### Reference 1086 - 1087 - ```typescript 1088 - import { useAnimatedGestureHandler } from 'react-native-reanimated'; 1089 - import { PanGestureHandler } from 'react-native-gesture-handler'; 1090 - 1091 - function App() { 1092 - const x = useSharedValue(0); 1093 - 1094 - const gestureHandler = useAnimatedGestureHandler({ 1095 - onStart: (_, ctx) => { 1096 - ctx.startX = x.value; 1097 - }, 1098 - onActive: (event, ctx) => { 1099 - x.value = ctx.startX + event.translationX; 1100 - }, 1101 - }); 1102 - 1103 - return ( 1104 - <PanGestureHandler onGestureEvent={gestureHandler}> 1105 - <Animated.View /> 1106 - </PanGestureHandler> 1107 - ); 1108 - } 1109 - ``` 1110 - 1111 - #### Arguments 1112 - 1113 - ##### `gestureHandlers` 1114 - 1115 - The primary argument is an object that can include one or more handlers. These handlers are set under the following keys: `onStart`, `onActive`, `onEnd`, `onFail`, `onCancel`, and `onFinish`. 1116 - 1117 - Each handler will be activated based on the current state of the associated gesture handler. For further details, refer to the Gesture Handler documentation. The handler receives: 1118 - 1119 - - `event` \[object] - an event object containing the payload specific to the type of gesture handler (e.g., `PanGestureHandler`, `RotationGestureHandler`). 1120 - 1121 - - `context` \[object] - a JavaScript object for storing state information. This context can be read and modified, persisting between events and across handlers for all selected states. 752 + - `context`: A plain JavaScript object used for storing state that persists between scroll events. This allows communication between multiple event handlers when provided as an object of worklets. 1122 753 1123 754 ##### `dependencies` (Optional) 1124 755 1125 - An optional array of dependencies is relevant only when using Reanimated without the Babel plugin on the Web. 756 + An optional array of dependencies, relevant only when using Reanimated without the Babel plugin on the Web. 1126 757 1127 758 #### Returns 1128 759 1129 - The `useAnimatedGestureHandler` hook returns a handler object that can be attached to gesture handler components from the `react-native-gesture-handler` library. This object must be passed to the `onGestureEvent` property of a gesture handler component. 760 + The hook returns a handler object suitable for integration with a scrollable container. The returned handler should be assigned to the `onScroll` parameter, regardless of whether it is configured to handle scroll, momentum, or drag events. For proper functionality, use containers wrapped with `Animated`, such as `Animated.ScrollView`. 1130 761 1131 762 ### Example 1132 763 1133 - ### Platform Compatibility 1134 - 1135 - |Android|iOS|Web| 1136 - |-|-|-| 1137 - |✅|✅|⚠️| 1138 - 1139 - - On the Web, it is necessary to pass the returned handler object to both `onGestureEvent` and `onHandlerStateChange` parameters. 1140 - 1141 - ## useScrollViewOffset Hook 1142 - 1143 - The `useScrollViewOffset` hook enables the creation of animations based on a `ScrollView`'s offset. It automatically determines whether the `ScrollView` is oriented horizontally or vertically. 1144 - 1145 - ### Reference 764 + ### Remarks 1146 765 1147 - ```typescript 1148 - import { useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated'; 1149 - 1150 - function App() { 1151 - const animatedRef = useAnimatedRef(); 1152 - const scrollOffset = useScrollViewOffset(animatedRef); 1153 - 1154 - return ( 1155 - <Animated.ScrollView ref={animatedRef}> 1156 - {/* Content goes here */} 1157 - </Animated.ScrollView> 1158 - ); 1159 - } 1160 - ``` 1161 - 1162 - #### Arguments 1163 - 1164 - ##### `animatedRef` 1165 - 1166 - An animated reference linked to the `ScrollView` component you wish to monitor. This animated reference must be assigned either to an Animated component or a React Native built-in component. 1167 - 1168 - ##### `initialRef` (Optional) 1169 - 1170 - A shared value that can optionally be updated with the scroll offset. If not provided, a new shared value will be created internally by default. 1171 - 1172 - #### Returns 1173 - 1174 - The hook returns a shared value representing the current offset of the `ScrollView`. 1175 - 1176 - ### Example Usage 1177 - 1178 - - The `animatedRef` argument can be dynamically changed, and the hook will continue to provide accurate values based on the connected `ScrollView`. For instance: 1179 - 1180 - ```typescript 1181 - useScrollViewOffset(someState ? someScrollRefA : someScrollRefB) 1182 - ``` 766 + - The returned handler can be passed to multiple components. It will invoke for the specified events whenever any component dispatches them. 767 + - If a single worklet function of type `(event) => void` is provided instead of an object mapping functions to event keys, it is treated as a handler for the `onScroll` event. 768 + - Only the `onScroll` event is supported on Web. 1183 769 1184 770 ### Platform Compatibility 1185 771 ··· 1187 773 |-|-|-| 1188 774 |✅|✅|✅| 1189 775 1190 - ```markdown 1191 - # Advanced APIs - Version 3.x 1192 - 1193 - ## measure 1194 - 1195 - `measure` allows synchronous retrieval of a view's dimensions and position on the screen, executed on the UI thread. 1196 - 1197 - ## useAnimatedReaction 1198 - 1199 - `useAnimatedReaction` enables response to changes in a shared value. It is particularly useful for comparing previous values stored in the shared value with their current counterparts. 1200 - 1201 - ## useFrameCallback 1202 - 1203 - `useFrameCallback` facilitates running a function during each frame update. 1204 - 1205 776 ## useEvent 1206 777 1207 - `useEvent` is a foundational hook that returns an event handler triggered by native events. This can be utilized to create custom event handler hooks, such as `useScrollViewOffset` or `useAnimatedScrollHandler`. 778 + The `useEvent` hook is a foundational tool in React Native Reanimated that provides an event handler for native events. It's particularly useful for creating custom hooks like `useScrollViewOffset` or `useAnimatedScrollHandler`. 1208 779 1209 - ## useHandler 1210 - 1211 - `useHandler` is another fundamental hook providing a context object and a value indicating if the worklet requires rebuilding. It aids in creating custom event handler hooks like `useScrollViewOffset` or `useAnimatedScrollHandler`. 1212 - 1213 - ## useComposedEventHandler 1214 - 1215 - This hook allows for the composition of `useEvent`-based event handlers (e.g., `useAnimatedScrollHandler` or custom ones) into a single, unified event handler. 1216 - 1217 - ## dispatchCommand 1218 - 1219 - `dispatchCommand` enables execution of commands on a native component directly from the UI thread. 1220 - 1221 - ## setNativeProps 1222 - 1223 - `setNativeProps` allows for imperative updates to component properties. 1224 - 1225 - ## makeMutable 1226 - 1227 - The use of `makeMutable` is generally discouraged. It's advised to opt for the `useSharedValue` hook unless you are fully aware of its implications and consequences (refer to the Remarks section). 1228 - ``` 1229 - 1230 - ## Handling Gestures 1231 - 1232 - This section covers handling gestures using Reanimated in conjunction with React Native Gesture Handler. We'll focus on `Tap` and `Pan` gestures and introduce the `withDecay` animation function. 1233 - 1234 - Ensure you've completed the Gesture Handler installation steps before proceeding. 1235 - 1236 - ### Handling Tap Gestures 1237 - 1238 - We begin with tap gestures, which detect brief screen touches. These can be used for custom buttons or pressable elements. 1239 - 1240 - In this example, a circle grows and changes color upon touch. 1241 - 1242 - First, wrap your app in `GestureHandlerRootView` to ensure gesture functionality: 780 + ### Reference Usage 1243 781 1244 782 ```typescript 1245 - import { GestureHandlerRootView } from 'react-native-gesture-handler'; 1246 - 1247 - function App() { 1248 - return ( 1249 - <GestureHandlerRootView style={{ flex: 1 }}> 1250 - {/* rest of the app */} 1251 - </GestureHandlerRootView> 1252 - ); 1253 - } 1254 - ``` 1255 - 1256 - Define tap gestures using `Gesture.Tap()` and chain methods like `onBegin`, `onStart`, `onEnd`, or `onFinalize` to update shared values: 1257 - 1258 - ```typescript 1259 - export default function App() { 1260 - const pressed = useSharedValue<boolean>(false); 1261 - 1262 - const tap = Gesture.Tap() 1263 - .onBegin(() => { 1264 - pressed.value = true; 1265 - }) 1266 - .onFinalize(() => { 1267 - pressed.value = false; 1268 - }); 1269 - ``` 783 + import { useEvent } from 'react-native-reanimated'; 1270 784 1271 - Access shared values safely as gesture callbacks are automatically workletized. 785 + function useAnimatedPagerScrollHandler(handlers, dependencies) { 786 + const { context, doDependenciesDiffer } = useHandler(handlers, dependencies); 1272 787 1273 - Define animation logic using `withTiming` in `useAnimatedStyle`: 788 + return useEvent( 789 + (event) => { 790 + 'worklet'; 791 + const { onPageScroll } = handlers; 1274 792 1275 - ```typescript 1276 - const animatedStyles = useAnimatedStyle(() => ({ 1277 - backgroundColor: pressed.value ? "#FFE04B" : "#B58DF1", 1278 - transform: [{ scale: withTiming(pressed.value ? 1.2 : 1) }], 1279 - })) 1280 - ``` 1281 - 1282 - Pass the gesture to `GestureDetector` and apply `animatedStyles`: 1283 - 1284 - ```typescript 1285 - return ( 1286 - <GestureHandlerRootView style={styles.container}> 1287 - <View style={styles.container}> 1288 - <GestureDetector gesture={tap}> 1289 - <Animated.View style={[styles.circle, animatedStyles]} /> 1290 - </GestureDetector> 1291 - </View> 1292 - </GestureHandlerRootView> 793 + if (onPageScroll && event.eventName.endsWith('onPageScroll')) { 794 + onPageScroll(event, context); 795 + } 796 + }, 797 + ['onPageScroll'], 798 + doDependenciesDiffer 1293 799 ); 1294 800 } 1295 - ``` 1296 801 1297 - ### Handling Pan Gestures 1298 - 1299 - Enhance the circle by making it draggable and bouncing back to its starting position upon release. Retain color highlight and scale effects. 1300 - 1301 - Switch from `Tap` to `Pan` gesture and add an `onChange` method: 1302 - 1303 - ```typescript 1304 - const offset = useSharedValue<number>(0); 1305 - 1306 - const pan = Gesture.Pan() 1307 - .onBegin(() => { 1308 - pressed.value = true; 1309 - }) 1310 - .onChange((event) => { 1311 - offset.value = event.translationX; 1312 - }) 1313 - .onFinalize(() => { 1314 - offset.value = withSpring(0); 1315 - pressed.value = false; 1316 - ``` 1317 - 1318 - Use `translationX` from the event data to move the circle. Reset `offset.value` in `onFinalize` using `withSpring`. 1319 - 1320 - Adjust `useAnimatedStyle` for handling offset: 1321 - 1322 - ```typescript 1323 - const animatedStyles = useAnimatedStyle(() => ({ 1324 - transform: [ 1325 - { translateX: offset.value }, 1326 - { scale: withTiming(pressed.value ? 1.2 : 1) }, 1327 - ], 1328 - backgroundColor: pressed.value ? "#FFE04B" : "#b58df1", 1329 - })) 1330 - ``` 1331 - 1332 - ### Using `withDecay` 1333 - 1334 - `withDecay` retains gesture velocity for decelerating animations. 1335 - 1336 - Pass final velocity in `onFinalize` to `withDecay`: 1337 - 1338 - ```typescript 1339 - const pan = Gesture.Pan() 1340 - .onChange((event) => { 1341 - offset.value += event.changeX; 1342 - }) 1343 - .onFinalize((event) => { 1344 - offset.value = withDecay({ 1345 - velocity: event.velocityX, 1346 - rubberBandEffect: true, 1347 - clamp: [ 1348 - -(width.value / 2) + SIZE / 2 + BOUNDARY_OFFSET, 1349 - width.value / 2 - SIZE / 2 - BOUNDARY_OFFSET, 1350 - ``` 1351 - 1352 - Ensure the square stays within screen bounds. 1353 - 1354 - Explore `withDecay` API for more configuration options. 1355 - 1356 - ### Summary 1357 - 1358 - This section covered gesture handling with Reanimated and Gesture Handler, focusing on `Tap`, `Pan`, and `withDecay`. Key points include: 1359 - 1360 - - Integration of Reanimated with React Native Gesture Handler. 1361 - - Creation of gestures like `Gesture.Pan()` or `Gesture.Tap()`. 1362 - - Accessing shared values in gesture callbacks without extra boilerplate. 1363 - - Using `withDecay` for decelerating animations based on gesture velocity. 1364 - 1365 - ### What's Next? 1366 - 1367 - Explore further gestures such as Pinch and Fling by reviewing the React Native Gesture Handler documentation. The next section will delve into a glossary of terms. 1368 - 1369 - ## withRepeat 1370 - 1371 - `withRepeat` is an animation modifier that allows you to repeat a specified animation a certain number of times or indefinitely. 1372 - 1373 - ### Reference 1374 - 1375 - ```typescript 1376 - import { withRepeat } from "react-native-reanimated" 1377 - 1378 - function App() { 1379 - sv.value = withRepeat(withSpring(0), 5) 1380 - // ... 1381 - } 802 + return <Animated.View onScroll={useAnimatedPagerScrollHandler} />; 1382 803 ``` 1383 804 1384 805 #### Arguments 1385 806 1386 - ##### `animation` 807 + - **`handler`**: A function that receives an event object containing the native payload. This can be utilized within custom handler hooks' worklets. 1387 808 1388 - The animation object you wish to repeat. 809 + - `event`: The event object, whose payload varies based on the event type. 1389 810 1390 - ##### `numberOfReps` (Optional) 811 + - **`eventNames` (Optional)**: An array specifying which event names should trigger the handler. 1391 812 1392 - Specifies how many times the animation should be repeated. The default is `2`. 813 + - **`rebuild` (Optional)**: A boolean indicating if the handler needs to be rebuilt. 1393 814 1394 - A non-positive value, such as `0` or `-1`, will cause the animation to repeat indefinitely until it is canceled or removed. For instance, if the component unmounts or `cancelAnimation` is invoked. 815 + #### Returns 1395 816 1396 - ##### `reverse` (Optional) 817 + The hook returns an event handler that is invoked when a native event occurs. This handler can be connected to multiple components, triggering for each component's specific events. 1397 818 1398 - Determines whether the animation should alternate directions with each repetition. The default setting is `false`. 1399 - 1400 - This feature only supports direct animation functions like `withSpring` and does not work with other animation modifiers such as `withSequence`. 1401 - 1402 - ##### `callback` (Optional) 1403 - 1404 - A function that executes upon the completion of the animation. If the animation is canceled, the callback receives `false`; otherwise, it receives `true`. 1405 - 1406 - ##### `reduceMotion` (Optional) 1407 - 1408 - Controls how the animation responds to the device's reduced motion accessibility setting. 1409 - 1410 - #### Returns 819 + ### Example 1411 820 1412 - The `withRepeat` function returns an animation object representing the current state of the animation. This can be directly assigned to a shared value or used as a style object returned from `useAnimatedStyle`. 821 + For simpler implementations, consider using `useScrollViewOffset`. 1413 822 1414 823 ### Remarks 1415 824 1416 - - The callback provided in the fourth argument is automatically workletized and executed on the UI thread. 825 + - Note that not all scroll events are supported on the web; only `onScroll` is consistently available across browsers. 1417 826 1418 827 ### Platform Compatibility 1419 828 ··· 1421 830 |-|-|-| 1422 831 |✅|✅|✅| 1423 832 1424 - ## Measure Functionality in React Native Reanimated 833 + This overview provides a concise guide to using the `useEvent` hook effectively within React Native Reanimated projects. 834 + 835 + ## useHandler 1425 836 1426 - The `measure` function allows you to synchronously obtain the dimensions and position of a view on the screen, executed on the UI thread. 837 + The `useHandler` hook is a foundational tool within the React Native Reanimated library. It provides a context object and an indicator to determine if worklets require rebuilding. This functionality facilitates the creation of custom event handler hooks, such as `useScrollViewOffset` or `useAnimatedScrollHandler`. 1427 838 1428 839 ### Reference 1429 840 1430 841 ```typescript 1431 - import { measure } from 'react-native-reanimated'; 842 + import { useEvent, useHandler } from "react-native-reanimated" 1432 843 1433 - function App() { 1434 - const animatedRef = useAnimatedRef(); 844 + function useAnimatedPagerScrollHandler( 845 + handlers: Record<string, (event: any, context: object) => void>, 846 + dependencies?: any[] 847 + ) { 848 + const { context, doDependenciesDiffer, useWeb } = useHandler( 849 + handlers, 850 + dependencies 851 + ) 1435 852 1436 - const handlePress = () => { 1437 - runOnUI(() => { 1438 - const measurement = measure(animatedRef); 1439 - if (measurement === null) { 1440 - return; 1441 - } 1442 - // Additional logic can be added here 1443 - })(); 1444 - }; 1445 - 1446 - return <Animated.View ref={animatedRef} />; 1447 - } 1448 - ``` 1449 - 1450 - #### Arguments 1451 - 1452 - - **`animatedRef`**: An animated reference linked to the component whose measurements are desired. This reference must be associated with either an Animated component or a React Native built-in component. 1453 - 1454 - #### Returns 1455 - 1456 - The `measure` function returns an object containing: 1457 - 1458 - |Field|Description| 1459 - |-|-| 1460 - |`x`|A number representing the X coordinate relative to the parent component.| 1461 - |`y`|A number representing the Y coordinate relative to the parent component.| 1462 - |`width`|A number representing the width of the component.| 1463 - |`height`|A number representing the height of the component.| 1464 - |`pageX`|A number representing the X coordinate relative to the screen.| 1465 - |`pageY`|A number representing the Y coordinate relative to the screen.| 1466 - 1467 - Alternatively, it returns `null` if the measurement could not be performed. 853 + return useEvent( 854 + (event: any) => { 855 + "worklet" 856 + const { onPageScroll } = handlers 1468 857 1469 - ### Remarks 1470 - 1471 - - **UI Thread Execution**: The `measure` function operates exclusively on the UI thread. When used within event handlers, it must be wrapped with the `runOnUI` function. 1472 - 1473 - - **Use in `useAnimatedStyle`**: Since `useAnimatedStyle` is initially evaluated on the JavaScript thread before views are attached to the native side, a condition like the following should be included: 1474 - 1475 - ```typescript 1476 - function App() { 1477 - const animatedStyles = useAnimatedStyle(() => { 1478 - if (_WORKLET) { 1479 - // Safely use measure here 1480 - const measurement = measure(animatedRef) 1481 - } 1482 - }) 1483 - } 1484 - ``` 1485 - 1486 - - **Consecutive Runs**: Subsequent executions of `useAnimatedStyle` occur on the UI thread. 1487 - 1488 - - **Alternative for Static Dimensions**: If only static dimensions are needed and measurements aren't used during animations, consider using the `onLayout` property instead. 1489 - 1490 - - **Null Check**: It's advisable to check if the measurement result is `null`, as it may happen when the reference hasn't yet attached to a view: 1491 - 1492 - ```typescript 1493 - const animatedRef = useAnimatedRef() 1494 - 1495 - const handlePress = () => { 1496 - runOnUI(() => { 1497 - const measurement = measure(animatedRef) 1498 - 1499 - if (measurement === null) { 1500 - return 1501 - } 1502 - // Additional logic can be added here 1503 - })() 1504 - } 1505 - ``` 1506 - 1507 - - **Rendered Components Only**: `measure` is applicable only to rendered components. For example, measuring off-screen items in a `FlatList` will yield `null`. 1508 - 1509 - - **Debugger Compatibility**: The `measure` function isn't available with the Remote JS Debugger. It's recommended to use Chrome DevTools (`chrome://inspect`) for debugging React Native applications. 1510 - 1511 - ### Platform Compatibility 1512 - 1513 - |Android|iOS|Web| 1514 - |-|-|-| 1515 - |✅|✅|✅| 1516 - 1517 - ## useAnimatedReaction 1518 - 1519 - The `useAnimatedReaction` hook enables responses to changes in shared values, particularly useful when comparing previous and current values stored within a shared value. 1520 - 1521 - ### Reference 1522 - 1523 - ```typescript 1524 - import { useAnimatedReaction } from "react-native-reanimated" 1525 - 1526 - function App() { 1527 - useAnimatedReaction( 1528 - () => sv.value, 1529 - (currentValue, previousValue) => { 1530 - if (currentValue !== previousValue) { 1531 - // perform an action ✨ 858 + if (onPageScroll && event.eventName.endsWith("onPageScroll")) { 859 + onPageScroll(event, context) 1532 860 } 1533 - } 861 + }, 862 + ["onPageScroll"], 863 + doDependenciesDiffer 1534 864 ) 1535 - 1536 - // ... 1537 865 } 1538 866 ``` 1539 867 1540 868 #### Arguments 1541 869 1542 - ##### `prepare` 870 + ##### `handlers` 1543 871 1544 - A function returning the value to which you want to react. This returned value serves as the first parameter for the `react` argument. 872 + An object containing keys that correspond to native event names. The values should be individual worklets. Each worklet is triggered when its associated event is dispatched on the connected animated component. 1545 873 1546 - ```typescript 1547 - function App() { 1548 - useAnimatedReaction( 1549 - () => Math.floor(sv.value), 1550 - (currentValue, previousValue) => { 1551 - // ... 1552 - } 1553 - ) 1554 - } 1555 - ``` 874 + Each event worklet receives: 1556 875 1557 - ##### `react` 1558 - 1559 - A function that responds to changes in the value provided by the `prepare` function. It receives two parameters: the current value from `prepare` and the previous value, initially set to `null`. 1560 - 1561 - ```typescript 1562 - function App() { 1563 - useAnimatedReaction( 1564 - () => Math.floor(sv.value), 1565 - (currentValue, previousValue) => { 1566 - // ... 1567 - } 1568 - ) 1569 - } 1570 - ``` 876 + - `event`: An event object whose payload varies based on the event type. 877 + - `context`: A plain JavaScript object for storing state, persisting between events. This allows communication among multiple event handlers provided as an object of worklets. 1571 878 1572 879 ##### `dependencies` (Optional) 1573 880 1574 - An optional array of dependencies. This is only relevant when using Reanimated without the Babel plugin on the Web. 881 + An optional array of dependencies. This is relevant when using Reanimated without its Babel plugin in a web environment. 1575 882 1576 883 #### Returns 1577 884 1578 - The `useAnimatedReaction` hook returns `undefined`. 885 + The hook returns: 1579 886 1580 - ### Example 887 + - A context reused by event handlers. 888 + - An indicator to determine if worklets should be rebuilt. 889 + - A boolean, `useWeb`, to check for the web environment if different implementations are needed. 1581 890 1582 - ### Remarks 891 + ### Example 1583 892 1584 - - Avoid mutating the same shared value in the `react` function that was used in the `prepare` function to prevent infinite loops. 1585 - 1586 - ```typescript 1587 - function App() { 1588 - useAnimatedReaction( 1589 - () => width.value, 1590 - (currentValue) => { 1591 - // 🚨 An infinite loop! 1592 - width.value += currentValue 1593 - } 1594 - ) 1595 - } 1596 - ``` 1597 - 1598 - - Callbacks for both `prepare` and `react` are automatically workletized, running on the UI thread. 1599 - 1600 - - While you can use `useAnimatedReaction` to react to any stateful React value, it's generally better to use a `useEffect` for such purposes. 893 + For simpler implementations, consider using `useScrollViewOffset`. 1601 894 1602 895 ### Platform Compatibility 1603 896 ··· 1605 898 |-|-|-| 1606 899 |✅|✅|✅| 1607 900 1608 - ````markdown 1609 - # withSequence 901 + This documentation provides a comprehensive overview of how to utilize the `useHandler` hook within React Native Reanimated for creating custom event handlers. 902 + 903 + ## Keyframe animations 1610 904 1611 - `withSequence` is an animation modifier that allows animations to be executed in a sequential order. 905 + Keyframes provide a schema for defining animations, offering more flexibility than standard Entering and Exiting presets. They allow you to create complex animations with ease. 1612 906 1613 - ## Reference 907 + ### Reference 1614 908 1615 909 ```typescript 1616 - import { withSequence } from "react-native-reanimated" 910 + import { Keyframe } from 'react-native-reanimated'; 911 + 912 + const keyframe = new Keyframe({ 913 + 0: { 914 + transform: [{ rotate: '0deg' }], 915 + }, 916 + 45: { 917 + transform: [{ rotate: '100deg' }], 918 + easing: Easing.exp, 919 + }, 920 + 100: { 921 + transform: [{ rotate: '45deg' }], 922 + }, 923 + }); 1617 924 1618 925 function App() { 1619 - sv.value = withSequence(withTiming(50), withTiming(0)) 1620 - // ... 926 + return <Animated.View entering={keyframe} />; 1621 927 } 1622 928 ``` 1623 - ```` 1624 929 1625 930 #### Arguments 1626 931 1627 - ##### `reduceMotion` (Optional) 932 + ##### `definitions` 1628 933 1629 - A parameter that specifies how the animation should respond to the device's reduced motion accessibility setting. 934 + An object containing animation definitions. The keys should be within the range of `0-100`, representing the progress of the animation. Values consist of style properties and optionally an easing function, defaulting to `Easing.linear` if not specified. 1630 935 1631 - ##### `...animations` 936 + Key values include: 1632 937 1633 - Any number of animation objects that will be executed in sequence. 1634 - 1635 - #### Returns 938 + - `0` or `from`: Represents the initial state. 939 + - Intermediate points (e.g., `45`): Represent intermediate states. 940 + - `100` or `to`: Represents the final state. 1636 941 1637 - The `withSequence` function returns an animation object representing the current state of the animation. This object can either be directly assigned to a shared value or used as a value for a style object returned from `useAnimatedStyle`. 942 + The key `0` (or `from`) should define the style at the start of the animation, while `100` (or `to`) defines it at the end. 1638 943 1639 - ### Example 1640 - 1641 - ### Platform Compatibility 1642 - 1643 - |Android|iOS|Web| 1644 - |-|-|-| 1645 - |✅|✅|✅| 1646 - 1647 - ```` 1648 - 1649 - # useFrameCallback in React Native Reanimated (Version: 3.x) 1650 - 1651 - ## Overview 1652 - 1653 - The `useFrameCallback` hook allows you to execute a function on every frame update within your application. 1654 - 1655 - ## Reference 944 + ### Modifiers 1656 945 1657 946 ```typescript 1658 - import { useFrameCallback } from 'react-native-reanimated'; 947 + keyframe 948 + .duration(1000) 949 + .delay(500) 950 + .reduceMotion(ReduceMotion.Never) 951 + .withCallback((finished) => { 952 + console.log(`finished without interruptions: ${finished}`) 953 + }) 954 + ``` 1659 955 1660 - function App() { 1661 - const frameCallback = useFrameCallback((frameInfo) => { 1662 - // Increment a value with each frame update 1663 - sv.value += 1; 1664 - }); 1665 - 1666 - return ( 1667 - <Button 1668 - title="Start/Stop" 1669 - onPress={() => frameCallback.setActive(!frameCallback.isActive)} 1670 - /> 1671 - ); 1672 - } 1673 - ```` 1674 - 1675 - #### Arguments 1676 - 1677 - ##### `callback` 1678 - 1679 - - A function that runs on every frame update. 1680 - - Receives a `frameInfo` object with the following properties: 1681 - - `timestamp`: The system time (in milliseconds) when the last frame was rendered. 1682 - - `timeSincePreviousFrame`: Time (in milliseconds) since the previous frame. This is `null` for the first frame after activation and approximately 16 ms on a 60 Hz display or 8 ms on a 120 Hz display, assuming no frames are dropped. 1683 - - `timeSinceFirstFrame`: The time (in milliseconds) elapsed since the callback was activated. 1684 - 1685 - ##### `autostart` (Optional) 1686 - 1687 - - Determines if the callback should start automatically. Defaults to `true`. 1688 - 1689 - #### Returns 1690 - 1691 - The `useFrameCallback` hook returns an object with these properties: 1692 - 1693 - - `setActive`: A function to start or stop the frame callback. 1694 - - `isActive`: A boolean indicating whether the callback is currently running. 1695 - - `callbackId`: A unique identifier for the frame callback. 956 + - `.duration(durationMs: number)` sets the animation length in milliseconds, defaulting to `500`. 957 + - `.delay(durationMs: number)` specifies a delay before starting the animation, defaulting to `0`. 958 + - `.reduceMotion(reduceMotion: ReduceMotion)` adjusts the animation based on the device's reduced motion setting. 959 + - `.withCallback(callback: (finished: boolean) => void)` triggers after the animation ends, indicating if it finished without interruptions. 1696 960 1697 961 ### Remarks 1698 962 1699 - - The function provided in the `callback` argument is automatically workletized and executed on the UI thread. 963 + - Providing keyframe `0` or `from` is mandatory as it defines the initial state of the object to be animated. 964 + - Ensure all style properties intended for animation have an initial value in other keyframes. 965 + - Easing should only be applied to subsequent keyframes, not to keyframe `0`. 966 + - Avoid using both `0` and `from`, or `100` and `to`, as it causes parsing conflicts. 967 + - When animating transform styles, maintain the order of properties consistently across all keyframes. 1700 968 1701 969 ### Platform Compatibility 1702 970 ··· 1704 972 |-|-|-| 1705 973 |✅|✅|✅| 1706 974 1707 - - Reference 1708 - - Arguments 1709 - - Returns 1710 - - Example 1711 - - Remarks 1712 - - Platform compatibility 975 + ## Your First Animation 976 + 977 + This section introduces you to the basics of Reanimated. If you're new to this library, you'll find guidance on creating a simple animation that lays the foundation for more advanced skills. 1713 978 1714 - ## Reduced Motion Configuration 979 + ### Using an Animated Component 1715 980 1716 - The `ReducedMotionConfig` component allows you to modify behavior based on the device's reduced motion accessibility setting. By default, it disables all animations when reduced motion is enabled on a device. You can customize this for your specific needs. For more information, refer to Accessibility and `useReducedMotion` in Reanimated. 981 + To start animating components in React Native using Reanimated, import the `Animated` object: 1717 982 1718 983 ```typescript 1719 - interface ReducedMotionConfig { 1720 - // Define properties or methods as needed 1721 - } 984 + import Animated from "react-native-reanimated" 1722 985 ``` 1723 986 1724 - This component helps ensure that your application respects user preferences regarding motion settings. 1725 - 1726 - ## Glossary of Terms 1727 - 1728 - ### Animated Component 1729 - 1730 - Animated components are those that can be animated using Reanimated. The library includes built-in components such as `Animated.View`, `Animated.Text`, and `Animated.ScrollView`. 987 + The `Animated` object wraps native components like `View`, `ScrollView`, or `FlatList`. Use these components as you would any other JSX component: 1731 988 1732 989 ```typescript 1733 990 import Animated from 'react-native-reanimated'; 1734 991 1735 - function App() { 992 + export default function App() { 1736 993 return ( 1737 994 <Animated.View 1738 995 style={{ ··· 1745 1002 } 1746 1003 ``` 1747 1004 1748 - For components not included in Reanimated, you can make their props and styles animatable by wrapping them with `createAnimatedComponent`: 1005 + ### Defining a Shared Value 1749 1006 1750 - ```typescript 1751 - import Animated from "react-native-reanimated" 1752 - import { Circle } from "react-native-svg" 1753 - 1754 - const AnimatedCircle = Animated.createAnimatedComponent(Circle) 1755 - ``` 1756 - 1757 - ### Shared Value 1758 - 1759 - Shared values are essential for animations in Reanimated. They are defined using the `useSharedValue` hook and accessed or modified via their `.value` property. 1007 + Shared values are essential for animations, acting like React state synchronized between JavaScript and the native side. Create shared values using `useSharedValue`: 1760 1008 1761 1009 ```typescript 1762 1010 import { useSharedValue } from "react-native-reanimated" 1763 - 1764 - function App() { 1765 - const sv = useSharedValue(0) 1766 - 1767 - const handlePress = () => { 1768 - sv.value += 10 1769 - } 1770 - 1771 - // rest of your glamorous code ✨ 1772 - } 1773 1011 ``` 1774 1012 1775 - Shared values can store any type and automatically synchronize data between the JavaScript thread and the UI thread. 1776 - 1777 - ### Animatable Value 1778 - 1779 - An animatable value is a type that can be used for animations, including numbers, strings, and arrays of numbers. Strings in specific formats like `"10deg"`, `"21%"`, or colors such as `"#ffaabb"` or `"rgba(100, 200, 100, 0.7)"` are also animatable. 1780 - 1781 - ### Animation Function 1782 - 1783 - Animation functions define how animations should behave. Reanimated provides three built-in animation functions: 1784 - 1785 - - `withSpring`: Creates spring-based animations. 1786 - - `withTiming`: Creates duration and easing-based animations. 1787 - - `withDecay`: Mimics motion with a given deceleration rate. 1788 - 1789 - These can be combined with modifiers for complex animations. 1790 - 1791 - ### Animation Modifier 1792 - 1793 - Animation modifiers customize animations. Known as higher-order animations, Reanimated includes: 1794 - 1795 - - `withDelay`: Adds a delay before the animation starts. 1796 - - `withRepeat`: Repeats an animation a specified number of times. 1797 - - `withSequence`: Chains animations sequentially. 1798 - - `withClamp`: Limits animation boundaries to a specific range. 1799 - 1800 - ### Animation Object 1801 - 1802 - An animation object is returned from animation functions and modifiers, containing the current state of the animation. It includes start and end conditions and an `onFrame` function for calculating each frame's state. 1803 - 1804 - When passed to a shared value, it is treated as an animatable value: 1805 - 1806 - ```typescript 1807 - sv.value = withSpring(100) 1808 - ``` 1809 - 1810 - ### Animations in Inline Styling 1811 - 1812 - Shared values can be directly used in the `style` property without `useAnimatedStyle`. 1813 - 1814 - Example: 1815 - 1816 - ```typescript 1817 - function App() { 1818 - const width = useSharedValue(100); 1819 - 1820 - return <Animated.View style={{ width }} />; 1821 - } 1822 - ``` 1823 - 1824 - ### Layout Animation Modifier 1825 - 1826 - Layout animation modifiers customize layout animations. Example usage: 1827 - 1828 - ```typescript 1829 - <Animated.View entering={FadeOutLeft.duration(500).easing(Easing.ease)} /> 1830 - ``` 1831 - 1832 - Built-in modifiers include: 1833 - 1834 - - `.duration(durationMs: number)`: Sets the animation length in milliseconds. 1835 - - `.easing(easingFunction: EasingFunction)`: Defines the animation curve. 1836 - - `.springify()`: Enables spring-based animations. 1837 - - `.damping(value: number)`: Controls how quickly a spring stops moving. 1838 - - `.withCallback(callback: (finished: boolean) => void)`: Triggers after the animation ends. 1839 - 1840 - ### Worklet 1841 - 1842 - Worklets are short-running JavaScript functions executed on the UI thread. They can also run on the JavaScript thread like regular functions. 1843 - 1844 - Code is often automatically workletized and runs on the UI thread by default: 1845 - 1846 - ```typescript 1847 - const style = useAnimatedStyle(() => { 1848 - console.log("Running on the UI thread") 1849 - return { opacity: 0.5 } 1850 - }) 1851 - ``` 1852 - 1853 - Custom worklets can be created using the `"worklet";` directive: 1854 - 1855 - ```typescript 1856 - function myWorklet() { 1857 - "worklet" 1858 - console.log("Running on the UI thread") 1859 - } 1860 - ``` 1861 - 1862 - Use `runOnUI` to manually execute worklets on the UI thread: 1863 - 1864 - ```typescript 1865 - function myWorklet(greeting) { 1866 - "worklet" 1867 - console.log(`${greeting} from the UI thread`) 1868 - } 1869 - 1870 - function onPress() { 1871 - runOnUI(myWorklet)("Howdy") 1872 - } 1873 - ``` 1874 - 1875 - ### To Workletize 1876 - 1877 - Converts a JavaScript function into an object that can be serialized and executed on the UI thread. Functions marked with `"worklet";` are automatically workletized by the Reanimated Babel plugin. 1878 - 1879 - ### JavaScript Thread 1880 - 1881 - The JavaScript thread handles code execution in the app, serving as the primary location for React Native app code execution. 1882 - 1883 - ### UI Thread 1884 - 1885 - The UI thread manages user interface updates and is also known as the Main thread. More information can be found in the Threading model article of the official React Native documentation. 1886 - 1887 - ### Reanimated Babel Plugin 1888 - 1889 - This plugin automatically workletizes certain functions used with Reanimated, reducing boilerplate code. Details are available in the Reanimated Babel plugin README. 1890 - 1891 - ## withDelay 1013 + Define shared values within your component's body to store any JS value or data structure. 1892 1014 1893 - `withDelay` is an animation modifier that allows you to initiate an animation after a specified delay period. 1894 - 1895 - ### Reference 1015 + For example, set a default value of `100` for width in an `Animated.View`: 1896 1016 1897 1017 ```typescript 1898 - import { withDelay } from "react-native-reanimated" 1899 - 1900 - function App() { 1901 - sv.value = withDelay(500, withTiming(0)) 1902 - // ... 1903 - } 1904 - ``` 1905 - 1906 - #### Arguments 1907 - 1908 - - **`delayMs`**: Specifies the duration (in milliseconds) before the animation begins. 1909 - 1910 - - **`delayedAnimation`**: The animation that will be delayed. 1911 - 1912 - - **`reduceMotion`** *(Optional)*: Determines how the animation responds to the device's reduced motion accessibility setting. 1913 - 1914 - #### Returns 1915 - 1916 - The `withDelay` function returns an animation object representing the current state of the animation. This object can either be directly assigned to a shared value or used as a value for a style object returned from `useAnimatedStyle`. 1917 - 1918 - ### Example 1919 - 1920 - *(Example content would go here)* 1921 - 1922 - ### Platform Compatibility 1923 - 1924 - |Android|iOS|Web| 1925 - |-|-|-| 1926 - |✅|✅|✅| 1927 - 1928 - *** 1929 - 1930 - ## useAnimatedKeyboard in React Native Reanimated (Version: 3.x) 1931 - 1932 - ### Overview 1933 - 1934 - The `useAnimatedKeyboard` hook allows developers to create animations that respond to the state and height of the virtual keyboard. 1935 - 1936 - > **Caution:**\ 1937 - > The Android implementation of `useAnimatedKeyboard` has limitations on devices running Android SDK versions below 30. For more details, refer to the remarks section. 1938 - 1939 - ### Reference 1940 - 1941 - ```typescript 1942 - import { useAnimatedKeyboard, useAnimatedStyle } from "react-native-reanimated" 1018 + import Animated, { useSharedValue } from 'react-native-reanimated'; 1943 1019 1944 1020 export default function App() { 1945 - const keyboard = useAnimatedKeyboard() 1946 - 1947 - const animatedStyles = useAnimatedStyle(() => ({ 1948 - transform: [{ translateY: -keyboard.height.value }], 1949 - })) 1950 - } 1951 - ``` 1952 - 1953 - #### Arguments 1954 - 1955 - ##### `options` (Optional) 1956 - 1957 - An optional configuration object that includes: 1958 - 1959 - - **isStatusBarTranslucentAndroid**:\ 1960 - Removes the top inset on Android when set to `true`, allowing for a translucent status bar. Defaults to `false`. This option is ignored on iOS. 1961 - 1962 - #### Returns 1963 - 1964 - The `useAnimatedKeyboard` hook returns an object with the following fields: 1965 - 1966 - |Name|Type|Description| 1967 - |-|-|-| 1968 - |height|`SharedValue<number>`|A shared value representing the current height of the keyboard.| 1969 - |state|`SharedValue<KeyboardState>`|A shared value indicating the current state of the keyboard. Possible states: `{ CLOSED, OPEN, CLOSING, OPENING }`| 1970 - 1971 - ### Remarks 1972 - 1973 - - **Android Specifics**:\ 1974 - Ensure that `android:windowSoftInputMode` is set to `adjustResize` in your `AndroidManifest.xml`. This setting disables the default Android behavior (resizing the view for keyboard accommodation) across the app. By using values from the `useAnimatedKeyboard` hook, you can manage the keyboard manually. Unmounting all components that use this hook will revert to the default Android behavior. 1975 - 1976 - - **Root View Management**:\ 1977 - On Android, employing the `useAnimatedKeyboard` hook expands the root view to full screen (immersive mode) and manages insets: 1978 - 1979 - - With `isStatusBarTranslucentAndroid` set to `false`, it applies a top margin based on the insets. 1980 - - When `true`, it sets the top margin to `0`. 1981 - - Similarly, with `isNavigationBarTranslucentAndroid`: 1982 - - `false`: Applies bottom margin according to the insets. 1983 - - `true`: Sets bottom margin to `0`. 1984 - 1985 - - **Native Header Navigation**:\ 1986 - On Android, using native header navigation means that `isStatusBarTranslucentAndroid` does not affect the top inset. 1987 - 1988 - - **SDK Limitations**:\ 1989 - For devices running Android SDK versions below 30, if the status bar is hidden, the keyboard reverts to default Android behavior. 1990 - 1991 - ### Platform Compatibility 1992 - 1993 - |Android|iOS|Web| 1994 - |-|-|-| 1995 - |✅|✅|❌| 1996 - 1997 - - **Reference** 1998 - 1999 - - Arguments 2000 - - Returns 2001 - 2002 - - **Example** 2003 - 2004 - - **Remarks** 2005 - 2006 - - **Platform Compatibility** 2007 - 2008 - ## useComposedEventHandler Hook 2009 - 2010 - The `useComposedEventHandler` hook allows you to combine multiple event handlers, such as those created with `useAnimatedScrollHandler`, into a single handler. 2011 - 2012 - ### Reference Example 2013 - 2014 - ```typescript 2015 - import Animated, { 2016 - useAnimatedScrollHandler, 2017 - useComposedEventHandler, 2018 - } from 'react-native-reanimated'; 2019 - 2020 - function ComposedEventHandlerExample() { 2021 - const onScrollHandler1 = useAnimatedScrollHandler({ 2022 - onScroll(e) { 2023 - console.log('Scroll handler 1 onScroll event'); 2024 - }, 2025 - }); 2026 - 2027 - const onScrollHandler2 = useAnimatedScrollHandler({ 2028 - onScroll(e) { 2029 - console.log('Scroll handler 2 onScroll event'); 2030 - }, 2031 - }); 2032 - 2033 - const composedHandler = useComposedEventHandler([ 2034 - onScrollHandler1, 2035 - onScrollHandler2, 2036 - ]); 1021 + const width = useSharedValue(100); 2037 1022 2038 1023 return ( 2039 - <View style={styles.container}> 2040 - <Animated.ScrollView style={styles.scroll} onScroll={composedHandler}> 2041 - <Content /> 2042 - </Animated.ScrollView> 2043 - </View> 1024 + <Animated.View 1025 + style={{ 1026 + width, 1027 + height: 100, 1028 + backgroundColor: 'violet', 1029 + }} 1030 + /> 2044 1031 ); 2045 1032 } 2046 1033 ``` 2047 1034 2048 - #### Arguments 2049 - 2050 - - **`handlers`**: An array of event handlers created using the `useEvent` hook. The `useComposedEventHandler` hook updates whenever there are changes in these handlers. 2051 - 2052 - #### Returns 2053 - 2054 - The hook returns a handler object that can be used with any `Animated component`. This handler should be assigned to the corresponding `onEvent` prop (e.g., `onScroll` for scroll-related handlers). For better code clarity, it's recommended to use multiple composed handlers if your aggregated handler manages various events. 2055 - 2056 - ### Remarks 2057 - 2058 - - The returned handler combines the functionalities of all provided handlers. This allows multiple handlers to respond to a single event and manage different types of events with one object. 2059 - - It functions effectively when used with multiple `Animated components`, triggering event callbacks for each connected component. 2060 - 2061 - ### Platform Compatibility 2062 - 2063 - |Android|iOS|Web| 2064 - |-|-|-| 2065 - |✅|✅|✅| 2066 - 2067 - ## dispatchCommand 2068 - 2069 - The `dispatchCommand` function enables the execution of commands directly on a native component from the UI thread. 2070 - 2071 - ### Reference 2072 - 2073 - ```typescript 2074 - import { dispatchCommand } from 'react-native-reanimated'; 2075 - 2076 - function App() { 2077 - const animatedRef = useAnimatedRef(); 2078 - 2079 - const gesture = Gesture.Tap().onStart(() => { 2080 - dispatchCommand(animatedRef, 'focus'); 2081 - }); 2082 - 2083 - return ( 2084 - <> 2085 - <AnimatedTextInput ref={animatedRef} style={styles.input} /> 2086 - <GestureDetector gesture={gesture}> 2087 - <Button title="Focus" /> 2088 - </GestureDetector> 2089 - </> 2090 - ); 2091 - } 2092 - ``` 2093 - 2094 - #### Arguments 2095 - 2096 - - **`animatedRef`**: An animated reference linked to the component you wish to update. This reference must be associated with either an Animated component or a React Native built-in component. 2097 - 2098 - - **`commandName`**: The name of the command to execute, such as `'focus'` or `'scrollToEnd'`. 2099 - 2100 - - **`args` (Optional)**: An array of arguments for the command. Defaults to an empty array if not provided. 2101 - 2102 - ### Example 2103 - 2104 - ```typescript 2105 - const goDown = Gesture.Tap().onStart(() => { 2106 - dispatchCommand(tosRef, "scrollToEnd", [true]) 2107 - dispatchCommand(loginRef, "focus") 2108 - }) 2109 - ``` 2110 - 2111 - ### Remarks 2112 - 2113 - - Commands vary depending on the component. Refer to the relevant React Native documentation for available commands specific to each component. 2114 - 2115 - ### Platform Compatibility 2116 - 2117 - |Android|iOS|Web| 2118 - |-|-|-| 2119 - |✅|✅|❌| 2120 - 2121 - ## withClamp 2122 - 2123 - `withClamp` is an animation modifier that restricts the movement of your animation within a specified range. It's typically used in conjunction with `withSpring`. 2124 - 2125 - ### Reference 2126 - 2127 - ```typescript 2128 - import { withClamp } from "react-native-reanimated" 2129 - 2130 - function App() { 2131 - sv.value = withClamp({ min: -1, max: 1 }, withSpring(0)) 2132 - // ... 2133 - } 2134 - ``` 2135 - 2136 - #### Arguments 2137 - 2138 - ##### `config` 2139 - 2140 - An object containing the following properties: 2141 - 2142 - |Name|Type|Description| 2143 - |-|-|-| 2144 - |min|number|Optional. The lowest value your animation can reach.| 2145 - |max|number|Optional. The highest value your animation can reach.| 2146 - 2147 - ##### `animation` 2148 - 2149 - The spring animation you wish to clamp. 2150 - 2151 - ```typescript 2152 - const clampedStyleWithDelay = useAnimatedStyle(() => { 2153 - return { 2154 - width: withClamp({ min: 0, max: 100 }, withSpring(randomWidth.value)), 2155 - } 2156 - }) 2157 - ``` 2158 - 2159 - #### Returns 2160 - 2161 - `withClamp` returns an animation object. This can be directly assigned to a shared value or used as a style value in `useAnimatedStyle`. 2162 - 2163 - |Platform|Supported| 2164 - |-|-| 2165 - |Android|✅| 2166 - |iOS|✅| 2167 - |Web|✅| 2168 - 2169 - ## useAnimatedSensor 2170 - 2171 - `useAnimatedSensor` allows you to create animations based on device sensor data. It provides access to: 2172 - 2173 - - **Accelerometer**: Measures device acceleration (excluding gravity) along the x, y, and z axes. 2174 - - **Gyroscope**: Captures the rotation rate of the device along the x, y, and z axes. 2175 - - **Gravity**: Provides the current gravity vector along the x, y, and z axes. 2176 - - **Magnetic Field**: Measures the Earth's magnetic field strength and direction in microtesla (μT). 2177 - - **Rotation**: Represents the device orientation using Euler angles and a quaternion. 2178 - 2179 - For comprehensive documentation, refer to the Sensors guide on Android Developers and Device Motion in Apple Developer documentation. 2180 - 2181 - ### Reference 2182 - 2183 - ```typescript 2184 - import { useAnimatedSensor, SensorType } from "react-native-reanimated" 2185 - 2186 - function App() { 2187 - const gyroscope = useAnimatedSensor(SensorType.GYROSCOPE) 2188 - 2189 - useDerivedValue(() => { 2190 - const { x, y, z } = gyroscope.sensor.value 2191 - }) 2192 - } 2193 - ``` 2194 - 2195 - #### Arguments 2196 - 2197 - ##### `sensorType` 2198 - 2199 - Specifies the sensor type using a `SensorType` enum: 2200 - 2201 - - `ACCELEROMETER`: Measures device acceleration in m/s². 2202 - - `GYROSCOPE`: Captures rotation rate in radians per second. 2203 - - `GRAVITY`: Provides gravity vector in m/s². 2204 - - `MAGNETIC_FIELD`: Measures magnetic field strength in microtesla (μT). 2205 - - `ROTATION`: Represents orientation using Euler angles and a quaternion. 2206 - 2207 - ##### `config` (Optional) 2208 - 2209 - |Name|Type|Default|Description| 2210 - |-|-|-|-| 2211 - |interval|`number \| "auto"`|`"auto"`|Time between sensor readings in milliseconds. `"auto"` matches the device's screen refresh rate.| 2212 - |adjustToInterfaceOrientation|`boolean`|`true`|Adjusts measurements to the current interface orientation.| 2213 - |iosReferenceFrame|`IOSReferenceFrame`|`IOSReferenceFrame.Auto`|Frame of reference for iOS sensors.| 2214 - 2215 - Available `IOSReferenceFrame` options: 2216 - 2217 - - `xArbitraryZVertical`: Z axis is vertical, X axis arbitrary in horizontal plane. 2218 - - `xArbitraryCorrectedZVertical`: Improved rotation accuracy with Z vertical and X arbitrary. 2219 - - `XMagneticNorthZVertical`: Z axis vertical, X points to magnetic north. 2220 - - `XTrueNorthZVertical`: Z axis vertical, X points to geographic north. 2221 - - `Auto`: Defaults based on device capabilities. 2222 - 2223 - #### Returns 2224 - 2225 - `useAnimatedSensor` returns an object: 2226 - 2227 - |Name|Type|Description| 2228 - |-|-|-| 2229 - |sensor|`SharedValue<Value3D \| ValueRotation>`|Shared value with sensor measurements.| 2230 - |unregister|`() => void`|Stops listening to sensor updates when called.| 2231 - |isAvailable|`boolean`|Indicates if the sensor is available for use.| 2232 - |config|`SensorConfig`|Contains sensor configuration details.| 2233 - 2234 - The shared value from the **rotation sensor** includes: 2235 - 2236 - - Euler angles: `roll`, `pitch`, `yaw`. 2237 - - Quaternion components: `qw`, `qx`, `qy`, `qz`. 2238 - - Interface orientation. 2239 - 2240 - Other sensors return measurements on x, y, z axes and interface orientation. 2241 - 2242 - `InterfaceOrientation` enum values: 2243 - 2244 - - `ROTATION_0`: Default rotation on Android, portrait on iOS. 2245 - - `ROTATION_90`: 90 degrees on Android, landscape right on iOS. 2246 - - `ROTATION_180`: 180 degrees on Android, upside down on iOS. 2247 - - `ROTATION_270`: 270 degrees on Android, landscape left on iOS. 2248 - 2249 - ### Example 2250 - 2251 - ```typescript 2252 - export default function App() { 2253 - const gravity = useAnimatedSensor(SensorType.GRAVITY); 2254 - 2255 - const animatedStyle = useAnimatedStyle(() => { 2256 - return { 2257 - transform: [ 2258 - { translateX: withSpring(gravity.sensor.value.x * 20) }, 2259 - { translateY: withSpring(gravity.sensor.value.y * 20) }, 2260 - ], 2261 - }; 2262 - }); 2263 - 2264 - return ( 2265 - <View style={styles.container}> 2266 - <Animated.View style={[styles.box, animatedStyle]} /> 2267 - </View> 2268 - ); 2269 - } 2270 - ``` 2271 - 2272 - ### Remarks 2273 - 2274 - - On iOS, enable location services (`Settings > Privacy > Location Services`) to read sensor data. 2275 - - On Web, ensure the device supports sensors and the application is served over HTTPS. 2276 - - Most sensors operate at resolutions up to 100Hz. 2277 - - Sensor data can be accessed on both UI and JavaScript threads. 2278 - 2279 - ### Platform Compatibility 2280 - 2281 - |Android|iOS|Web| 2282 - |-|-|-| 2283 - |✅|✅|✅| 2284 - 2285 - ## setNativeProps 2286 - 2287 - The `setNativeProps` function allows for the imperative updating of component properties in React Native. It serves as an escape hatch intended for specific edge cases. 2288 - 2289 - > **Caution:**\ 2290 - > Prefer using `useAnimatedStyle` and `useAnimatedProps` when animating styles or properties, reserving `setNativeProps` for exceptional situations. 2291 - 2292 - ### Reference 2293 - 2294 - ```typescript 2295 - import { setNativeProps } from 'react-native-reanimated'; 2296 - 2297 - function App() { 2298 - const animatedRef = useAnimatedRef(); 2299 - 2300 - const tap = Gesture.Tap().onEnd(() => { 2301 - setNativeProps(animatedRef, { text: '' }); 2302 - }); 2303 - 2304 - return <TextInput ref={animatedRef} />; 2305 - } 2306 - ``` 2307 - 2308 - #### Arguments 2309 - 2310 - - **`animatedRef`:**\ 2311 - An animated reference linked to the component you wish to update. This animated reference must be passed either to an Animated component or a React Native built-in component. 2312 - 2313 - - **`updates`:**\ 2314 - An object containing properties that need updating, which can include both style properties (e.g., `width`, `backgroundColor`) and regular properties (e.g., `text`). 2315 - 2316 - #### Returns 2317 - 2318 - The function returns `undefined`. 2319 - 2320 - ### Remarks 2321 - 2322 - - Prioritize using `useAnimatedStyle` and `useAnimatedProps` for animating styles or properties. 2323 - - Ensure that `setNativeProps` is used exclusively on the UI thread. 2324 - - The `setNativeProps` function was designed to facilitate the imperative updating of props from gesture handlers. In other scenarios, it may require an additional `runOnUI` call, making React Native's built-in `setNativeProps` more efficient with fewer runtime transitions. 2325 - 2326 - ### Platform Compatibility 2327 - 2328 - |Android|iOS|Web| 2329 - |-|-|-| 2330 - |✅|✅|✅| 2331 - 2332 - *** 2333 - 2334 - ## React Native Reanimated: useReducedMotion Hook (Version 3.x) 2335 - 2336 - ### Overview 2337 - 2338 - The `useReducedMotion` hook in React Native Reanimated allows developers to check the system's reduced motion setting. This is particularly useful for disabling animations when users prefer less motion. 2339 - 2340 - ### Reference 2341 - 2342 - ```typescript 2343 - import { useReducedMotion } from "react-native-reanimated" 2344 - 2345 - function App() { 2346 - const reduceMotion = useReducedMotion() 2347 - 2348 - if (reduceMotion) { 2349 - // Display static content ✨ 2350 - } else { 2351 - // Run animations ✨ 2352 - } 2353 - 2354 - // Additional logic... 2355 - } 2356 - ``` 2357 - 2358 - #### Returns 2359 - 2360 - The `useReducedMotion` hook returns a boolean value indicating whether the reduced motion setting was enabled at the start of the app. 2361 - 2362 - ### Example Usage 2363 - 2364 - ```typescript 2365 - import { useReducedMotion } from 'react-native-reanimated'; 2366 - 2367 - function App() { 2368 - const reduceMotion = useReducedMotion(); 2369 - 2370 - if (reduceMotion) { 2371 - return <StaticContent />; 2372 - } else { 2373 - return <AnimatedContent />; 2374 - } 2375 - } 2376 - ``` 2377 - 2378 - ### Remarks 2379 - 2380 - - Changing the reduced motion setting does not trigger a component rerender. 2381 - - Unlike `AccessibilityInfo.isReduceMotionEnabled()`, `useReducedMotion` provides the value synchronously. 2382 - 2383 - ### Platform Compatibility 2384 - 2385 - |Android|iOS|Web| 2386 - |-|-|-| 2387 - |✅|✅|✅| 2388 - 2389 - This hook is compatible across Android, iOS, and Web platforms. 2390 - 2391 - ## makeMutable 2392 - 2393 - **Caution:** The use of `makeMutable` is generally discouraged. It's recommended to opt for the `useSharedValue` hook unless you are fully aware of its implications (refer to the Remarks section). 2394 - 2395 - Internally, `makeMutable` is utilized by the `useSharedValue` hook to generate a shared value. This function allows the creation of mutable values without relying on the hook, which can be beneficial in specific scenarios such as within the global scope or when managing an array of mutable values. 2396 - 2397 - The object produced by `makeMutable` mirrors that returned by the `useSharedValue` hook, ensuring consistent usage thereafter. 2398 - 2399 - ### Reference 2400 - 2401 - ```typescript 2402 - import { makeMutable } from "react-native-reanimated" 2403 - 2404 - const mv = makeMutable(100) 2405 - ``` 2406 - 2407 - #### Arguments 2408 - 2409 - ##### `initial` 2410 - 2411 - This argument specifies the initial value to be stored in the mutable. It can encompass any JavaScript data type such as `number`, `string`, or `boolean`, and also includes complex structures like arrays and objects. 2412 - 2413 - #### Returns 2414 - 2415 - `makeMutable` yields a mutable value initialized with the provided `initial`. Access to the stored data is possible through its `value` property or via `get` and `set` methods. 2416 - 2417 - ### Example 2418 - 2419 - ### Remarks 2420 - 2421 - **Info:** The term *mutable value* refers to an object created by `makeMutable`, distinguishing it from a *shared value*, which is essentially a mutable value with automatic cleanup. 2422 - 2423 - - All remarks applicable to the `useSharedValue` hook are relevant to `makeMutable`. 2424 - - Avoid invoking `makeMutable` directly within component scope. Component re-renders will generate a new object, potentially resetting the initial value and losing previous state. 2425 - 2426 - ```typescript 2427 - function App() { 2428 - const [counter, setCounter] = useState(0) 2429 - const mv = makeMutable(counter) // 🚨 creates a new mutable value on each render 2430 - 2431 - useEffect(() => { 2432 - const interval = setInterval(() => { 2433 - setCounter((prev) => prev + 1) // updates the counter stored in component state 2434 - }, 1000) 2435 - 2436 - return () => { 2437 - clearInterval(interval) 2438 - } 2439 - }, [mv]) 2440 - 2441 - useAnimatedReaction( 2442 - () => mv.value, 2443 - (value) => { 2444 - console.log(value) // prints 0, 1, 2, ... 2445 - } 2446 - ) 2447 - } 2448 - ``` 2449 - 2450 - - Utilize `cancelAnimation` to halt all ongoing animations on a mutable value if it becomes unnecessary and animations are still active. Exercise caution with infinite animations as they require manual cancellation. 2451 - 2452 - ```typescript 2453 - function App() { 2454 - const mv = useMemo(() => makeMutable(0), []) 2455 - 2456 - useEffect(() => { 2457 - mv.value = withRepeat(withSpring(100), -1, true) // creates an infinite animation 2458 - 2459 - return () => { 2460 - cancelAnimation(mv) // ✅ stops the infinite animation on component unmount 2461 - } 2462 - }, []) 2463 - } 2464 - ``` 2465 - 2466 - - `cancelAnimation` is not needed for non-animated values as they are automatically garbage collected when no references remain. 2467 - 2468 - ```typescript 2469 - const someFlag = makeMutable(false) 2470 - 2471 - function App() { 2472 - someFlag.value = true // ✅ no need to cancel the animation later on 2473 - } 2474 - ``` 2475 - 2476 - - When opting for `makeMutable`, adhere to React's rules and avoid common pitfalls associated with `useRef`, such as modifying references during rendering (see the **Pitfall** section in the useRef documentation). 2477 - 2478 - #### Comparison with `useSharedValue` 2479 - 2480 - |Feature|`makeMutable`|`useSharedValue`| 2481 - |-|-|-| 2482 - |Object Creation|Creates a new object on each call|Reuses the same object on each call| 2483 - |Initial Value Change|A new object is created if `initial` changes|The initially created object remains unchanged if `initialValue` changes| 2484 - |Scope Usage|Can be used outside of component scope|Limited to use within component scope| 2485 - |Loop Usage|Usable in loops with variable iterations|Usable in loops only if the number of hooks (`useSharedValue` calls) is constant| 2486 - |Animation Cancellation|Does not automatically cancel animations on unmount|Automatically cancels animations when the component unmounts| 1035 + ### Using a Shared Value 2487 1036 2488 - ### Platform Compatibility 1037 + Create an animation that modifies the `width` of an element by `50px` on each button press. Modify the shared value connected to the `Animated.View`'s width property. 2489 1038 2490 - |Android|iOS|Web| 2491 - |-|-|-| 2492 - |✅|✅|✅| 2493 - 2494 - ## Accurate Call Stacks 2495 - 2496 - When debugging Reanimated code, you might come across error or warning call stacks that do not clearly point to the root cause of an issue. These stacks can be misleading because they frequently emphasize code from Reanimated's internal workings instead of highlighting the misuse of the Reanimated API, which is often the actual source of the problem. 1039 + Access and modify values stored in shared values using their `.value` property: 2497 1040 2498 1041 ```typescript 2499 - // Example TypeScript snippet for context (not part of original content) 2500 - function debugReanimatedCode() { 2501 - // Debugging logic here 2502 - } 2503 - ``` 2504 - 2505 - |Aspect|Description| 2506 - |-|-| 2507 - |**Issue**|Misleading call stacks in error or warning messages.| 2508 - |**Cause**|Call stacks often highlight Reanimated's internal code rather than API misuse.| 2509 - |**Impact**|Difficulty in identifying the true source of problems during debugging.| 2510 - 2511 - Understanding this behavior is crucial for effectively diagnosing and resolving issues within Reanimated projects. 2512 - 2513 - ## Animating Styles and Props 2514 - 2515 - In this section, we explore different methods for passing animation styles to components. We will differentiate between animating styles and props using `useAnimatedStyle` and `useAnimatedProps`. 2516 - 2517 - ### Animating Styles 2518 - 2519 - Previously, we learned about simple animations and shared values. While inline styling works well in basic cases, it has limitations, such as not allowing access to the value stored in a shared value for complex operations. 2520 - 2521 - ```typescript 1042 + import { Button, View } from 'react-native'; 2522 1043 import Animated, { useSharedValue } from 'react-native-reanimated'; 2523 1044 2524 - function App() { 1045 + export default function App() { 2525 1046 const width = useSharedValue(100); 2526 1047 2527 - return <Animated.View style={{ width }} />; 2528 - } 2529 - ``` 2530 - 2531 - For example, multiplying a shared value before assigning it to the `style` prop is not possible: 2532 - 2533 - ```typescript 2534 - <Animated.View style={{ width: width * 5 }} /> // This won't work 2535 - ``` 2536 - 2537 - Consider an example where a box moves right on button press: 2538 - 2539 - ```typescript 2540 - import { View, Button } from 'react-native'; 2541 - import Animated, { useSharedValue, withSpring } from 'react-native-reanimated'; 2542 - 2543 - function App() { 2544 - const translateX = useSharedValue(0); 2545 - 2546 1048 const handlePress = () => { 2547 - translateX.value = withSpring(translateX.value + 50); 1049 + width.value = width.value + 50; 2548 1050 }; 2549 1051 2550 1052 return ( 2551 - <View style={styles.container}> 2552 - <Animated.View style={[styles.box, { transform: [{ translateX }] }]} /> 1053 + <View style={{ flex: 1, alignItems: 'center' }}> 1054 + <Animated.View 1055 + style={{ 1056 + width, 1057 + height: 100, 1058 + backgroundColor: 'violet', 1059 + }} 1060 + /> 2553 1061 <Button onPress={handlePress} title="Click me" /> 2554 1062 </View> 2555 1063 ); 2556 1064 } 2557 1065 ``` 2558 1066 2559 - To customize shared value changes based on user input, `useAnimatedStyle` is used for more control and flexibility: 2560 - 2561 - ```typescript 2562 - export default function App() { 2563 - const translateX = useSharedValue<number>(0); 1067 + Avoid directly modifying shared values without using the `.value` property, as in `sv.value = sv.value + 100`. 2564 1068 2565 - const handlePress = () => { 2566 - translateX.value += 50; 2567 - }; 1069 + ### Using an Animation Function 2568 1070 2569 - const animatedStyles = useAnimatedStyle(() => ({ 2570 - transform: [{ translateX: withSpring(translateX.value * 2) }], 2571 - })); 2572 - 2573 - return ( 2574 - <> 2575 - <Animated.View style={[styles.box, animatedStyles]} /> 2576 - <View style={styles.container}> 2577 - <Button onPress={handlePress} title="Click me" /> 2578 - </View> 2579 - </> 2580 - ); 2581 - } 2582 - ``` 2583 - 2584 - `useAnimatedStyle` allows access to the shared value's `.value`, enabling operations like multiplication before assigning it to `style`. It also centralizes animation logic. 2585 - 2586 - ### Animating Props 2587 - 2588 - While many values are animated via the `style` property, sometimes props need animating. For example, SVG elements use props instead of styles: 1071 + To animate smoothly, import and use the `withSpring` function. Wrap it around the new width value to create a spring animation: 2589 1072 2590 1073 ```typescript 2591 - <Circle cx="50" cy="50" r="10" fill="blue" /> 2592 - ``` 2593 - 2594 - To animate non-Reanimated components' props, wrap them with `createAnimatedComponent`: 2595 - 2596 - ```typescript 2597 - import Animated from "react-native-reanimated" 2598 - import { Circle } from "react-native-svg" 2599 - 2600 - const AnimatedCircle = Animated.createAnimatedComponent(Circle) 2601 - ``` 2602 - 2603 - Animating the radius of an SVG circle can be done by passing a shared value as a prop: 2604 - 2605 - ```typescript 2606 - import { useSharedValue } from 'react-native-reanimated'; 2607 - import { Svg } from 'react-native-svg'; 2608 - 2609 - function App() { 2610 - const r = useSharedValue(10); 2611 - 2612 - return ( 2613 - <Svg> 2614 - <AnimatedCircle cx="50" cy="50" r={r} fill="blue" /> 2615 - </Svg> 2616 - ); 2617 - } 2618 - ``` 2619 - 2620 - For encapsulating animation logic and accessing `.value`, `useAnimatedProps` is used: 2621 - 2622 - ```typescript 2623 - const AnimatedCircle = Animated.createAnimatedComponent(Circle); 1074 + import { Button, View } from 'react-native'; 1075 + import Animated, { useSharedValue, withSpring } from 'react-native-reanimated'; 2624 1076 2625 1077 export default function App() { 2626 - const r = useSharedValue<number>(20); 1078 + const width = useSharedValue(100); 2627 1079 2628 1080 const handlePress = () => { 2629 - r.value += 10; 1081 + width.value = withSpring(width.value + 50); 2630 1082 }; 2631 1083 2632 - const animatedProps = useAnimatedProps(() => ({ 2633 - r: withTiming(r.value), 2634 - })); 2635 - 2636 1084 return ( 2637 - <View style={styles.container}> 2638 - <Svg style={styles.svg}> 2639 - <AnimatedCircle 2640 - cx="50%" 2641 - cy="50%" 2642 - fill="#b58df1" 2643 - animatedProps={animatedProps} 2644 - /> 2645 - </Svg> 1085 + <View style={{ flex: 1, alignItems: 'center' }}> 1086 + <Animated.View 1087 + style={{ 1088 + width, 1089 + height: 100, 1090 + backgroundColor: 'violet', 1091 + }} 1092 + /> 2646 1093 <Button onPress={handlePress} title="Click me" /> 2647 1094 </View> 2648 1095 ); 2649 1096 } 2650 1097 ``` 2651 1098 2652 - In `useAnimatedProps`, return an object with animatable props, then pass it to the `animatedProps` prop of an Animated component. 1099 + This creates a bouncy spring animation for the element's width. 2653 1100 2654 1101 ### Summary 2655 1102 2656 - - Inline styles are simple but limited for complex animations. 2657 - - Props differ from styles as they aren't passed via the `style` object. 2658 - - `useAnimatedStyle` and `useAnimatedProps` provide access to shared values' `.value`, enhancing animation control. 2659 - - Custom animatable components can be created with `Animated.createAnimatedComponent`. 2660 - 2661 - ### What's Next? 2662 - 2663 - In the next section, we'll delve into animation functions and customizing their behavior. 2664 - 2665 - ## React Native Reanimated: ReducedMotionConfig 2666 - 2667 - **Version:** 3.x 2668 - 2669 - ### Overview 2670 - 2671 - The `ReducedMotionConfig` component allows you to modify the behavior of animations based on a device's reduced motion accessibility setting. By default, it disables all animations when this setting is enabled. You can customize this behavior according to your specific needs. For more information about Accessibility and `useReducedMotion`, refer to Reanimated documentation. 2672 - 2673 - > **Caution:** The new configuration will be applied globally across the entire application. 2674 - 2675 - ### Reference 2676 - 2677 - ```typescript 2678 - import { ReducedMotionConfig, ReduceMotion } from 'react-native-reanimated'; 2679 - 2680 - function App() { 2681 - return ( 2682 - // ... 2683 - <ReducedMotionConfig mode={ReduceMotion.Never} /> 2684 - // ... 2685 - ); 2686 - } 2687 - ``` 2688 - 2689 - #### Arguments 2690 - 2691 - ##### `mode` 2692 - 2693 - This parameter determines how animations should respond to the device's reduced motion accessibility setting: 2694 - 2695 - - **`ReduceMotion.System`:** Adjusts animation behavior based on the device's reduced motion setting. Animations are disabled when this setting is enabled; otherwise, they remain active. 2696 - 2697 - - **`ReduceMotion.Always`:** Consistently disables animations, regardless of the device's accessibility configuration. 2698 - 2699 - - **`ReduceMotion.Never`:** Ensures that animations remain enabled at all times. 2700 - 2701 - ### Platform Compatibility 2702 - 2703 - |Android|iOS|Web| 2704 - |-|-|-| 2705 - |✅|✅|✅| 2706 - 2707 - - Reference 2708 - - Arguments 2709 - - Example 2710 - - Platform compatibility 2711 - 2712 - ## Accurate Call Stacks 2713 - 2714 - When debugging Reanimated code, developers might encounter misleading call stacks in errors or warnings. These stacks often highlight internal Reanimated code rather than pinpointing the misuse of the Reanimated API that caused the issue. 2715 - 2716 - To improve this situation, Reanimated offers a Metro configuration wrapper named `wrapWithReanimatedMetroConfig`. This tool adjusts your Metro config to enhance the accuracy of call stacks for warnings and errors generated by the Reanimated library. 2717 - 2718 - ### Reference 2719 - 2720 - For more precise call stacks, import `wrapWithReanimatedMetroConfig` from `react-native-reanimated/metro-config` and use it to wrap your existing Metro configuration in the `metro.config.js` file. 2721 - 2722 - ```typescript 2723 - // metro.config.js 2724 - import { wrapWithReanimatedMetroConfig } from "react-native-reanimated/metro-config" 2725 - 2726 - const config = { 2727 - // Your existing Metro configuration options 2728 - } 2729 - 2730 - export default wrapWithReanimatedMetroConfig(config) 2731 - ``` 2732 - 2733 - ### Example 2734 - 2735 - The example below illustrates the difference in call stacks before and after applying the Reanimated Metro config wrapper. The **Before** scenario shows Reanimated source code as the error origin, while the **After** scenario reveals the actual incorrect code that caused the error. 2736 - 2737 - |Before|After| 2738 - |-|-| 2739 - ||| 2740 - 2741 - ### Remarks 2742 - 2743 - - `wrapWithReanimatedMetroConfig` does not remove any stack frames; it only collapses irrelevant ones from Reanimated. To inspect these, you can expand collapsed stack frames by clicking on the **See N more frames** text at the bottom of the **Call Stack**. 2744 - 2745 - |Collapsed|Expanded| 2746 - |-|-| 2747 - ||| 2748 - 2749 - - Some errors, especially those arising from asynchronous code, may still point to Reanimated internals instead of the exact problematic line in your code. This happens because stack traces can lose track of the original code that initiated the asynchronous operation. In such cases, manual debugging based on the error message is necessary to identify the potential cause of the problem. 2750 - 2751 - ## Logger Configuration for Reanimated 2752 - 2753 - Reanimated provides warnings to highlight potential misuses of its API, such as altering shared values during component re-renders. These logs can be adjusted in verbosity. 2754 - 2755 - By default, the logger configuration requires no setup and displays all warnings and errors. To customize this behavior, use the `configureReanimatedLogger` function. 2756 - 2757 - ### Reference 2758 - 2759 - To alter the default Reanimated logger settings, import `configureReanimatedLogger` from `react-native-reanimated` and invoke it with your desired configuration: 2760 - 2761 - ```typescript 2762 - import { 2763 - configureReanimatedLogger, 2764 - ReanimatedLogLevel, 2765 - } from "react-native-reanimated" 2766 - 2767 - // Default configuration example 2768 - configureReanimatedLogger({ 2769 - level: ReanimatedLogLevel.warn, 2770 - strict: true, // Strict mode is enabled by default 2771 - }) 2772 - ``` 2773 - 2774 - #### Configuration Options 2775 - 2776 - - **`level`:** Specifies the minimum log level to display using a value from `ReanimatedLogLevel`. 2777 - 2778 - - **`strict`:** A boolean that toggles strict mode. Enabling it results in additional warnings to help identify potential code issues. 2779 - 2780 - ### Remarks 2781 - 2782 - - The logger configuration is global, affecting all Reanimated warnings and errors. It cannot be configured on a per-file or per-component basis. 2783 - 2784 - - Call `configureReanimatedLogger` before creating any Reanimated animations, typically in the root file of your application. 2785 - 2786 - - This function is intended for app developers. Library creators using Reanimated should avoid including this call in their source code to prevent overriding users' configurations with the default settings. 2787 - 2788 - ### Platform Compatibility 2789 - 2790 - |Android|iOS|Web| 2791 - |-|-|-| 2792 - |✅|✅|✅| 2793 - 2794 - ```markdown 2795 - # Guides 2796 - 2797 - ## Worklets 2798 - 2799 - Worklets are brief JavaScript functions executed on the UI thread. Reanimated utilizes worklets to compute view styles and respond to events directly on the UI thread. 2800 - 2801 - ## Accessibility 2802 - 2803 - This section delves into how Reanimated enhances accessibility in animations, particularly through its reduced motion feature. This functionality ensures a more comfortable experience for users with motion sensitivities or those who prefer minimal movement. 2804 - 2805 - ## Building for Android on Windows 2806 - 2807 - This article outlines basic troubleshooting steps for issues encountered when building React Native apps with Reanimated for Android devices from a Windows host machine. 2808 - 2809 - ## Compatibility 2810 - 2811 - Currently supported React Native versions (Paper) 2812 - 2813 - ## Contributing 2814 - 2815 - Thank you for your interest in contributing to Reanimated! Contributions, whether through triaging and commenting on issues, extending documentation, or reviewing and submitting Pull Requests, are greatly appreciated. 2816 - 2817 - ## Debugging Worklets 2818 - 2819 - Due to Reanimated's unique architecture and its use of a secondary JS runtime, debugging worklets can be challenging. 2820 - 2821 - ## Migration from 1.x 2822 - 2823 - We aimed to facilitate incremental migration from Reanimated 1 to Reanimated 2. 2824 - 2825 - ## Migration from 2.x 2826 - 2827 - Reanimated 3.x introduces no breaking changes in terms of API between versions 2.x and 3.x. All code written using the Reanimated v2 API will function in 3.x without modifications. However, Reanimated 3.x completely removes support for the Reanimated v1 API. For migration guidance from 1.x to 2.x, please refer to the Migration from 1.x to 2.x guide. 2828 - 2829 - ## Testing with Jest 2830 - 2831 - Reanimated offers a testing API based on Jest, enabling users to mock web-based animations. 2832 - 2833 - ## Troubleshooting 2834 - 2835 - Initialization issues 2836 - 2837 - ## Web Support 2838 - 2839 - Reanimated can be launched in a web browser. In this context, all functionalities are implemented purely in JavaScript, which may result in reduced animation efficiency. 2840 - ``` 2841 - 2842 - ```markdown 2843 - # Core (Version: 3.x) 2844 - 2845 - ## useSharedValue 2846 - 2847 - `useSharedValue` is used for defining shared values within your components. These shared values can be utilized across different parts of the component tree. 2848 - 2849 - ## useAnimatedStyle 2850 - 2851 - With `useAnimatedStyle`, you can create a styles object akin to StyleSheet styles, which allows animation using shared values. This enables dynamic styling changes in response to animations. 2852 - 2853 - ## useAnimatedProps 2854 - 2855 - `useAnimatedProps` facilitates the creation of an animated props object that can be animated with shared values. It is particularly useful for animating properties of third-party components by providing them with animated props. 2856 - 2857 - ## useAnimatedRef 2858 - 2859 - The `useAnimatedRef` function provides a reference to a view, which can then be used in conjunction with functions like measure, scrollTo, and useScrollViewOffset to manipulate the view's position or dimensions. 2860 - 2861 - ## useDerivedValue 2862 - 2863 - `useDerivedValue` allows for the creation of new shared values derived from existing ones. This ensures that these new values remain reactive and update automatically when their dependencies change. 2864 - 2865 - ## createAnimatedComponent 2866 - 2867 - `createAnimatedComponent` enables you to transform any React Native component into an animated version. By wrapping a component with `createAnimatedComponent`, Reanimated can animate any prop or style associated with it, enhancing the component's interactivity. 2868 - 2869 - ## cancelAnimation 2870 - 2871 - The `cancelAnimation` function is used to stop a running animation that is linked to a shared value. This allows for greater control over animations by providing the ability to halt them when necessary. 2872 - ``` 2873 - 2874 - ```markdown 2875 - # Version 3.x: Layout Animations Overview 2876 - 2877 - ## Entering/Exiting Animations 2878 - 2879 - These animations are designed to animate elements as they enter into or exit from the view hierarchy, providing a dynamic user experience. 2880 - 2881 - ## Keyframe Animations 2882 - 2883 - Keyframes offer a schema for defining complex animations. They provide greater flexibility compared to standard entering and exiting presets by allowing detailed control over animation sequences. 2884 - 2885 - ## Layout Transitions 2886 - 2887 - Layout transitions enable smooth changes during layout updates, which may involve alterations in size or position. Both aspects can be animated to enhance visual fluidity. 2888 - 2889 - ## Custom Animations 2890 - 2891 - Custom animations offer complete control over both entering/exiting animations and layout transitions. However, they are complex and challenging to maintain. It is advisable to start with predefined presets before opting for custom solutions. 2892 - 2893 - ## Skipping Layout Animations 2894 - 2895 - The `LayoutAnimationConfig` component allows you to bypass entering and exiting animations when needed. 2896 - 2897 - ## List Layout Animations 2898 - 2899 - With `itemLayoutAnimation`, you can specify a layout transition for list items during layout changes. Options include using predefined transitions like `LinearTransition` or creating custom ones. 2900 - ``` 2901 - 2902 - ## Worklets 2903 - 2904 - Worklets are short-running JavaScript functions that execute on the UI thread, enabling efficient style calculations and event reactions. Reanimated leverages worklets for these tasks. 2905 - 2906 - ### Creating Worklets 2907 - 2908 - To define a custom worklet, use the `'worklet';` directive at the start of your function: 2909 - 2910 - ```typescript 2911 - function myWorklet() { 2912 - "worklet" 2913 - console.log("Hello from a worklet") 2914 - } 2915 - ``` 2916 - 2917 - The Reanimated Babel Plugin identifies functions marked with `'worklet'`, transforming them into serializable objects—a process known as workletization. These objects can then be executed on the UI thread. 2918 - 2919 - ### Automatic Workletization 2920 - 2921 - When using Reanimated and Gesture Handler, code is typically automatically workletized and executed on the UI thread: 2922 - 2923 - ```typescript 2924 - import { useAnimatedStyle } from "react-native-reanimated" 2925 - 2926 - function App() { 2927 - const style = useAnimatedStyle(() => { 2928 - // Executed on the UI thread 2929 - return { opacity: 0.5 } 2930 - }) 2931 - } 2932 - ``` 2933 - 2934 - ### Manual Worklet Execution 2935 - 2936 - To manually schedule worklet execution, use `runOnUI`: 2937 - 2938 - ```typescript 2939 - function myWorklet() { 2940 - "worklet" 2941 - console.log("Hello from the UI thread") 2942 - } 2943 - 2944 - function onPress() { 2945 - runOnUI(myWorklet)() 2946 - } 2947 - ``` 2948 - 2949 - Arguments can be passed to worklets as follows: 2950 - 2951 - ```typescript 2952 - function myWorklet(greeting: string) { 2953 - "worklet" 2954 - console.log(`${greeting} from the UI thread`) 2955 - } 2956 - 2957 - function onPress() { 2958 - runOnUI(myWorklet)("Howdy") 2959 - } 2960 - ``` 2961 - 2962 - ### Worklet Closures 2963 - 2964 - Worklets are closures, allowing them to access variables declared outside their scope. Only referenced variables are captured: 2965 - 2966 - ```typescript 2967 - const width = 135.5 2968 - 2969 - function otherWorklet() { 2970 - "worklet" 2971 - console.log("Captured width is", width) 2972 - } 2973 - ``` 2974 - 2975 - Avoid capturing large objects within worklets to prevent performance issues: 2976 - 2977 - ```typescript 2978 - const theme = {...}; // Large object 2979 - 2980 - function myWorklet() { 2981 - 'worklet'; 2982 - console.log(theme.color); // 🚨 Captures entire `theme` object 2983 - } 2984 - ``` 2985 - 2986 - To mitigate this, assign the needed property to a separate variable: 2987 - 2988 - ```typescript 2989 - const theme = {...}; 2990 - const color = theme.color; 2991 - 2992 - function myWorklet() { 2993 - 'worklet'; 2994 - console.log(color); // ✅ Captures only `color` 2995 - } 2996 - ``` 2997 - 2998 - ### Returning Data 2999 - 3000 - Worklets can return data within the same thread: 3001 - 3002 - ```typescript 3003 - function returningWorklet() { 3004 - "worklet" 3005 - return "I'm back" // On the UI thread 3006 - } 3007 - 3008 - function someWorklet() { 3009 - "worklet" 3010 - const what = returningWorklet() // Still on the UI thread 3011 - console.log("On the UI thread, other worklet says", what) 3012 - } 3013 - ``` 3014 - 3015 - ### Data Sharing Between Threads 3016 - 3017 - Use shared values to pass data between the UI and JS threads: 3018 - 3019 - ```typescript 3020 - import { useSharedValue } from "react-native-reanimated" 3021 - 3022 - function App() { 3023 - const width = useSharedValue(100) 3024 - 3025 - function myWorklet() { 3026 - "worklet" 3027 - width.value += 50 3028 - } 3029 - 3030 - useEffect(() => { 3031 - console.log(width.value) // Accessible on both JS and UI threads 3032 - }, []) 3033 - } 3034 - ``` 3035 - 3036 - ### Running Functions on the JS Thread 3037 - 3038 - Use `runOnJS` to execute functions from the UI thread, often for non-worklet functions or React state updates: 3039 - 3040 - ```typescript 3041 - import { router } from "expo-router" 3042 - import { Gesture } from "react-native-gesture-handler" 3043 - 3044 - function App() { 3045 - const tap = Gesture.Tap().onEnd(() => { 3046 - // Worklet context 3047 - runOnJS(router.back)() 3048 - }) 3049 - } 3050 - ``` 3051 - 3052 - Ensure functions passed to `runOnJS` are defined in the JavaScript thread scope: 3053 - 3054 - ```typescript 3055 - function App() { 3056 - const tap = Gesture.Tap().onEnd(() => { 3057 - // myFunction is defined on the UI thread 🚨 3058 - const myFunction = () => {} 3059 - runOnJS(myFunction)() // 💥 Error 3060 - }) 3061 - } 3062 - ``` 3063 - 3064 - ### Custom Worklet Runtimes 3065 - 3066 - Worklets can operate in custom runtimes beyond Reanimated's default. Libraries like VisionCamera and LiveMarkdown create their own worklet environments. 3067 - 3068 - Create your own worklet runtime using `createWorkletRuntime`. 3069 - 3070 - ## Accessibility 3071 - 3072 - This section discusses how Reanimated enhances accessibility in animations, particularly through its reduced motion functionality. This feature ensures a smoother experience for users with motion sensitivities or those who prefer less movement. 3073 - 3074 - The reduced motion configuration allows you to define how animations should respond to the system's reduced motion setting. For any animation, the value can be set as follows: 3075 - 3076 - - `ReduceMotion.System`: Adjusts the animation based on whether the device's reduced motion accessibility setting is activated. If enabled, the animation is disabled; otherwise, it remains active. 3077 - - `ReduceMotion.Always`: Consistently disables the animation, regardless of the device's accessibility configuration. 3078 - - `ReduceMotion.Never`: Ensures that the animation remains enabled at all times. 3079 - 3080 - By default, all animations are configured with `ReduceMotion.System`. 3081 - 3082 - ### Reduced Motion in Animations 3083 - 3084 - ```typescript 3085 - import { withDelay, withTiming } from "react-native-reanimated" 3086 - 3087 - function App() { 3088 - sv1.value = withTiming(0, { reduceMotion: ReduceMotion.System }) 3089 - sv2.value = withDelay( 3090 - 1000, 3091 - withTiming(toValue, { duration }), 3092 - ReduceMotion.System 3093 - ) 3094 - // ... 3095 - } 3096 - ``` 3097 - 3098 - When reduced motion is enabled: 3099 - 3100 - - `withSpring` and `withTiming` return the `toValue` immediately. 3101 - - `withDecay` returns the current value immediately, considering the clamp parameter. 3102 - - `withDelay` initiates the next animation immediately. 3103 - - `withRepeat`: 3104 - - If `numberOfReps` is infinite or even and the animation is reversed, then the repeated animation does not start. 3105 - - Otherwise, the repeated animation runs once. 3106 - - `withSequence` exclusively starts animations that have reduced motion disabled. 3107 - 3108 - Higher-order animations pass the configuration to their children only if the children haven't been configured by the user. For example: 3109 - 3110 - This animation will instantaneously reach the `toValue`: 3111 - 3112 - ```typescript 3113 - import { withDelay, withTiming } from "react-native-reanimated" 3114 - 3115 - function App() { 3116 - sv.value = withDelay( 3117 - 1000, 3118 - withTiming(toValue, { duration }), 3119 - ReduceMotion.Always 3120 - ) 3121 - // ... 3122 - } 3123 - ``` 3124 - 3125 - This animation will execute as usual even if reduced motion is enabled on the device: 3126 - 3127 - ```typescript 3128 - import { withDelay, withTiming } from "react-native-reanimated" 3129 - 3130 - function App() { 3131 - sv.value = withDelay( 3132 - 1000, 3133 - withTiming(toValue, { duration }), 3134 - ReduceMotion.Never 3135 - ) 3136 - // ... 3137 - } 3138 - ``` 3139 - 3140 - And here `withTiming` will be executed as usual and without delay: 3141 - 3142 - ```typescript 3143 - import { withDelay, withTiming } from "react-native-reanimated" 3144 - 3145 - function App() { 3146 - sv.value = withDelay( 3147 - 1000, 3148 - withTiming(toValue, { duration, reduceMotion: ReduceMotion.Never }), 3149 - ReduceMotion.Always 3150 - ) 3151 - // ... 3152 - } 3153 - ``` 3154 - 3155 - ### Reduced Motion in Layout Animations 3156 - 3157 - ```typescript 3158 - import { BounceIn } from "react-native-reanimated" 3159 - 3160 - function App() { 3161 - const entering = BounceIn.reduceMotion(ReduceMotion.System) 3162 - // ... 3163 - } 3164 - ``` 3165 - 3166 - When reduced motion is enabled: 3167 - 3168 - - Entering, keyframe, and layout animations instantaneously reach their endpoints. 3169 - - Exiting animations and shared transitions are omitted. 3170 - 3171 - ### `useReducedMotion` 3172 - 3173 - This hook returns a boolean indicating whether the reduced motion setting was enabled when the app started. It can be used in conjunction with other libraries or to conditionally display animations that are less intrusive. 3174 - 3175 - ```typescript 3176 - import { BounceIn } from "react-native-reanimated" 3177 - 3178 - function App() { 3179 - const reduceMotion = useReducedMotion() 3180 - const entering = reduceMotion 3181 - ? FadeIn.reduceMotion(ReduceMotion.Never) 3182 - : BounceIn 3183 - // ... 3184 - } 3185 - ``` 3186 - 3187 - The provided content outlines a comprehensive guide for using various animations in React Native with the `react-native-reanimated` library. Below is a structured summary of the key points and features: 3188 - 3189 - #### Overview 3190 - 3191 - - **Library**: `react-native-reanimated` 3192 - - **Purpose**: To create smooth, performant animations on Android, iOS, and Web platforms. 3193 - - **Animations Covered**: 3194 - - Pinch 3195 - - Pinch Zoom 3196 - - Pinch Rotate 3197 - - Pinch Scale 3198 - - Pinch Translate 3199 - - Pinch X 3200 - - Pinch Y 3201 - - PinchXY 3202 - - PinchZoomRotate 3203 - - PinchZoomScale 3204 - - PinchZoomTranslate 3205 - - PinchZoomX 3206 - - PinchZoomY 3207 - - PinchZoomXY 3208 - - PinchZoomRotateScale 3209 - - PinchZoomRotateTranslate 3210 - - PinchZoomRotateX 3211 - - PinchZoomRotateY 3212 - - PinchZoomRotateXY 3213 - - PinchZoomScaleTranslate 3214 - - PinchZoomScaleX 3215 - - PinchZoomScaleY 3216 - - PinchZoomScaleXY 3217 - - PinchZoomTranslateX 3218 - - PinchZoomTranslateY 3219 - - PinchZoomTranslateXY 3220 - - PinchZoomRotateScaleTranslate 3221 - - PinchZoomRotateScaleX 3222 - - PinchZoomRotateScaleY 3223 - - PinchZoomRotateScaleXY 3224 - - PinchZoomRotateTranslateX 3225 - - PinchZoomRotateTranslateY 3226 - - PinchZoomRotateTranslateXY 3227 - - PinchZoomScaleTranslateX 3228 - - PinchZoomScaleTranslateY 3229 - - PinchZoomScaleTranslateXY 3230 - - PinchZoomRotateScaleTranslateX 3231 - - PinchZoomRotateScaleTranslateY 3232 - - PinchZoomRotateScaleTranslateXY 3233 - - Other animations like Bounce, Fade, Flip, etc. 3234 - 3235 - #### Animation Configuration 3236 - 3237 - ##### Time-based Modifiers 3238 - 3239 - - **Function**: `withTiming` 3240 - - **Customization**: 3241 - - `.easing(easingFunction: EasingFunction)`: Defines the animation curve. Default is `Easing.inOut(Easing.quad)`. 3242 - - Note: These modifiers do not affect spring animations. 3243 - 3244 - ##### Spring-based Modifiers 3245 - 3246 - - **Function**: `withSpring` 3247 - - **Customization**: 3248 - - `.springify()`: Enables spring-based configuration. 3249 - - `.damping(value: number)`: Controls how quickly the spring stops. Default is `10`. 3250 - - `.mass(value: number)`: Represents the weight of the spring. Lower values make animations faster. Default is `1`. 3251 - - `.stiffness(value: number)`: Determines bounciness. Default is `100`. 3252 - - `.overshootClamping(value: boolean)`: Prevents bouncing over the target position. Default is `false`. 3253 - - `.restDisplacementThreshold(value: number)`: Displacement threshold for snapping to the final position without oscillations. Default is `0.001`. 3254 - - `.restSpeedThreshold(value: number)`: Speed threshold for snapping to the final position without oscillations. Default is `2`. 3255 - 3256 - ##### Common Modifiers 3257 - 3258 - - **Customization**: 3259 - - `.duration(durationMs: number)`: Length of the animation in milliseconds. Default is `300`. 3260 - - `.delay(durationMs: number)`: Delay before starting the animation. Default is `0`. 3261 - - `.randomDelay()`: Randomizes delay between `0` and provided value, defaulting to `1000ms` if not specified. 3262 - - `.reduceMotion(reduceMotion: ReduceMotion)`: Adjusts animation based on device's reduced motion settings. 3263 - - `.withInitialValues(values: StyleProps)`: Overrides initial configuration of the animation. 3264 - - `.withCallback(callback: (finished: boolean) => void)`: Executes a callback after the animation ends, indicating if it finished without interruptions. 3265 - 3266 - #### Platform Compatibility 3267 - 3268 - - **Android**: Supported 3269 - - **iOS**: Supported 3270 - - **Web**: Supported 3271 - 3272 - This guide provides developers with the tools to create and customize animations effectively across multiple platforms using `react-native-reanimated`. 3273 - 3274 - ## Troubleshooting React Native Reanimated Build Issues on Windows 3275 - 3276 - This guide outlines basic troubleshooting steps for resolving issues encountered when building React Native apps with Reanimated for Android devices on a Windows host machine. Common errors include: 3277 - 3278 - - `Execution failed for task ':react-native-reanimated:buildCMakeDebug[x86_64]'` 3279 - - `Execution failed for task ':react-native-reanimated:buildCMakeRelWithDebInfo[arm64-v8a]'` 3280 - - `Task :react-native-reanimated:buildCMakeDebug[x86_64] FAILED` 3281 - - `C/C++: ninja: error: mkdir(...): No such file or directory` 3282 - - `C++ build system [build] failed while executing` 3283 - - `Picked up _JAVA_OPTIONS` 3284 - 3285 - ### What Not to Do 3286 - 3287 - If you encounter any of the above errors, avoid these actions: 3288 - 3289 - #### ❌ Avoid Disabling New Architecture 3290 - 3291 - Starting from React Native 0.76, New Architecture is enabled by default. Manually disabling it in `gradle.properties` does not resolve issues and merely delays them since legacy architecture will be phased out. 3292 - 3293 - #### ❌ Avoid Downgrading Android Gradle Plugin (AGP) 3294 - 3295 - Do not modify the AGP version in `gradle.properties`. Use the version specified in the official app template to prevent version conflicts and unsupported features. 3296 - 3297 - #### ❌ Avoid Downgrading Reanimated or Other Dependencies 3298 - 3299 - Downgrading increases technical debt. Newer versions of Reanimated include bug fixes and stability improvements. Always use the latest supported version, and consider upgrading all dependencies rather than downgrading them. 3300 - 3301 - #### ❌ Avoid Posting Duplicate "Same Issue" Comments 3302 - 3303 - Before reporting an error, search for similar issues on platforms like GitHub or Stack Overflow. Instead of posting duplicate comments, add a reaction to the original issue to indicate its impact. 3304 - 3305 - ### Recommended Actions 3306 - 3307 - #### ✅ Ensure Correct Environment Setup 3308 - 3309 - Follow all instructions in Set Up Your Environment. Run `npx react-native doctor` to identify any problems. Restart your terminal, IDE, or computer if changes have been made. 3310 - 3311 - #### ✅ Use Compatible Reanimated Version 3312 - 3313 - Use the latest supported version of Reanimated based on your app setup: 3314 - 3315 - - **Expo SDK**: Match major and minor versions with Expo SDK. 3316 - - Example: Expo SDK 52 supports `~3.16.x`. Update to the latest patch, e.g., `3.16.7`. 3317 - 3318 - |Expo SDK Version|Reanimated Version| 3319 - |-|-| 3320 - |`52`|`~3.16.1`| 3321 - |`51`|`~3.10.1`| 3322 - |`50`|`~3.6.2`| 3323 - 3324 - - **Expo Prebuild or React Native without Framework**: Use a version compatible with your React Native version according to the Compatibility table. 3325 - 3326 - #### ✅ Use Appropriate CMake Version 3327 - 3328 - Ensure you use CMake `3.22.1` or newer. Customize the version using the `CMAKE_VERSION` environment variable, e.g., `set CMAKE_VERSION=3.31.1`. If unset, default is `3.22.1`. 3329 - 3330 - #### ✅ Use Appropriate Ninja Version 3331 - 3332 - Use Ninja `1.12.0` or newer (latest is `1.12.1`) as older versions may not handle long paths correctly. 3333 - 3334 - #### ✅ Use Compatible Android NDK Version 3335 - 3336 - Match the NDK version with that used in the official app template. It should be installed automatically during app build. 3337 - 3338 - #### ✅ Unset `_JAVA_OPTIONS` 3339 - 3340 - Unsetting this environment variable can resolve certain errors and allow builds to pass. 3341 - 3342 - #### ✅ Enable Long Paths Support in Windows Registry 3343 - 3344 - Follow instructions to enable long paths support on Windows. 3345 - 3346 - #### ✅ Avoid Whitespace in Project Path 3347 - 3348 - Paths with spaces may cause issues. Move projects to directories without whitespace, e.g., `D:\Mobile Apps\MyAwesomeProject`. 3349 - 3350 - #### ✅ Ensure Short Project Path 3351 - 3352 - Avoid paths longer than 240 characters. Move or clone the project to a shorter path, e.g., `D:\AwesomeProject`. 3353 - 3354 - #### ✅ Remove or Invalidate Caches 3355 - 3356 - Clear compilation artifacts in directories like: 3357 - 3358 - - `android\build` 3359 - - `android\.cxx` 3360 - - `android\.gradle` 3361 - - `node_modules\react-native-reanimated\android\build` 3362 - 3363 - Invalidate Android Studio caches (File → Invalidate Caches…). 3364 - 3365 - #### ⚠️ Persistent Issues 3366 - 3367 - If problems persist after following these steps, submit an issue in the repository with full build logs and a minimal reproducible example. 3368 - 3369 - ## Compatibility Table 3370 - 3371 - ### Currently Supported React Native Versions (Paper) 3372 - 3373 - |Version|0.63|0.64|0.65|0.66|0.67|0.68|0.69|0.70|0.71|0.72|0.73|0.74|0.75|0.76|0.77|0.78|0.79|0.80| 3374 - |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-| 3375 - |3.18.0|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|yes|yes| 3376 - |3.17.4 - 3.17.5|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|yes|no| 3377 - |3.17.1 – 3.17.3|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|no|no| 3378 - |3.17.0|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|no|no|no| 3379 - |3.16.7|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|no|no|no| 3380 - |3.16.0 – 3.16.6|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|no|no|no|no| 3381 - |3.15.x|no|no|no|no|no|no|no|no|no|no|no|yes|yes|no|no|no|no|no| 3382 - |3.9.x – 3.14.x|no|no|no|no|no|no|no|no|no|no|no|yes|no|no|no|no|no|no| 3383 - |3.6.x – 3.8.x|no|no|no|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no| 3384 - |3.5.x|no|no|no|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no| 3385 - |3.3.x – 3.4.x|yes|yes|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no| 3386 - |3.0.x – 3.2.x|yes|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no| 3387 - |2.14.x – 2.17.x|yes|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no| 3388 - |2.11.x – 2.13.x|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no|no| 3389 - |2.10.x|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no|no|no| 3390 - |2.5.x – 2.9.x|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no|no|no|no| 3391 - |2.3.x – 2.4.x|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no|no|no|no|no| 3392 - 3393 - **Note:** Reanimated 2 will not receive support for the newest React Native versions. To access the latest features and updates, upgrade to Reanimated 3. 3394 - 3395 - ### Supported React Native Versions on the New Architecture (Fabric) 3396 - 3397 - To use Reanimated with the experimental New Architecture, update the package to at least version 3.0.0. Due to numerous breaking changes related to the New Architecture in each React Native version, as a rule of thumb, Reanimated supports the latest stable version of React Native. 3398 - 3399 - Reanimated supports bridgeless mode. 3400 - 3401 - |Version|0.63|0.64|0.65|0.66|0.67|0.68|0.69|0.70|0.71|0.72|0.73|0.74|0.75|0.76|0.77|0.78|0.79|0.80| 3402 - |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-| 3403 - |3.18.0|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|yes|yes| 3404 - |3.17.4 - 3.17.5|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|yes|no| 3405 - |3.17.1 – 3.17.3|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|no|no| 3406 - |3.17.0|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|no|no|no| 3407 - |3.16.7|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|no|no|no| 3408 - |3.16.0 – 3.16.6|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|no|no|no|no| 3409 - |3.15.x|no|no|no|no|no|no|no|no|no|no|no|yes|yes|no|no|no|no|no| 3410 - |3.9.x – 3.14.x|no|no|no|no|no|no|no|no|no|no|no|yes|no|no|no|no|no|no| 3411 - |3.6.x – 3.8.x|no|no|no|no|no|no|no|no|no|yes|yes|no|no|no|no|no|no|no| 3412 - |3.1.x – 3.5.x|no|no|no|no|no|no|no|no|no|yes|no|no|no|no|no|no|no|no| 3413 - |3.0.x|no|no|no|no|no|no|no|no|yes|no|no|no|no|no|no|no|no|no| 3414 - 3415 - ## Animating Styles and Props 3416 - 3417 - In the previous section, we explored creating simple animations, understanding shared values, and their application. In this part, we will delve into an alternative method for applying animation styles to components. We'll also examine the distinctions between animating styles versus props and how to manage them using `useAnimatedStyle` and `useAnimatedProps`. 3418 - 3419 - ### Animating Styles with `useAnimatedStyle` 1103 + In this section, you learned about: 3420 1104 3421 - The `useAnimatedStyle` hook allows you to define animated styles that can be applied directly to a component's style prop. This approach is particularly useful for smoothly transitioning between different visual states. 3422 - 3423 - #### Example 3424 - 3425 - ```typescript 3426 - import { useSharedValue, withSpring, useAnimatedStyle } from 'react-native-reanimated'; 3427 - 3428 - const AnimatedComponent = () => { 3429 - const opacity = useSharedValue(0); 1105 + - `Animated` components to define animatable elements. 1106 + - Shared values as the driving factor of animations using `useSharedValue`. 1107 + - Accessing and modifying shared values via their `.value` property (e.g., `sv.value = 100;`). 1108 + - Creating smooth animations by modifying shared values with functions like `withSpring`. 3430 1109 3431 - // Define the animated styles 3432 - const animatedStyles = useAnimatedStyle(() => ({ 3433 - opacity: withSpring(opacity.value), 3434 - })); 1110 + ### What's Next? 3435 1111 3436 - return <View style={[styles.view, animatedStyles]} />; 3437 - }; 3438 - ``` 1112 + In the next section, you'll explore animating styles and props using `useAnimatedStyle` and `useAnimatedProps` hooks. 3439 1113 3440 - ### Animating Props with `useAnimatedProps` 3441 - 3442 - While `useAnimatedStyle` is great for animating styles, `useAnimatedProps` allows you to animate component props. This can be useful when the animation involves more than just visual changes. 3443 - 3444 - #### Example 3445 - 3446 - ```typescript 3447 - import { useSharedValue, withTiming, useAnimatedProps } from 'react-native-reanimated'; 3448 - 3449 - const AnimatedText = () => { 3450 - const fontSize = useSharedValue(14); 3451 - 3452 - // Define animated props 3453 - const animatedProps = useAnimatedProps(() => ({ 3454 - fontSize: withTiming(fontSize.value + 10), 3455 - })); 3456 - 3457 - return <Animated.Text style={styles.text} {...animatedProps}>Hello World</Animated.Text>; 3458 - }; 3459 - ``` 3460 - 3461 - ### Key Differences 3462 - 3463 - - **`useAnimatedStyle`:** Best for animating styles directly. It provides a way to interpolate values and apply them as inline styles. 3464 - 3465 - - **`useAnimatedProps`:** Ideal for animating props of components that do not support direct style interpolation. 3466 - 3467 - By understanding these hooks, you can effectively manage animations in your React Native applications, enhancing both performance and user experience. 3468 - 3469 - ## useSharedValue 3470 - 3471 - `useSharedValue` is a hook that allows you to define shared values within your components. 3472 - 3473 - ### Reference 3474 - 3475 - ```typescript 3476 - import { useSharedValue } from "react-native-reanimated" 3477 - 3478 - function App() { 3479 - const sv = useSharedValue(100) 3480 - 3481 - // Accessing the shared value 3482 - console.log(sv.value) 3483 - 3484 - // Modifying the shared value 3485 - sv.value += 50 3486 - } 3487 - ``` 3488 - 3489 - #### Arguments 3490 - 3491 - ##### `initialValue` 3492 - 3493 - The initial value to store in the shared value. It can be any JavaScript type such as `number`, `string`, or `boolean`, and also includes data structures like `array` and `object`. 3494 - 3495 - #### Returns 3496 - 3497 - `useSharedValue` returns a shared value initialized with the provided `initialValue`. You can access this stored data using its `value` property or through `get` and `set` methods. 3498 - 3499 - ##### React Compiler Support 3500 - 3501 - When utilizing the React Compiler, avoid directly accessing or modifying the `value` property. Instead, use the `get` and `set` methods as they are compliant with React Compiler standards. 3502 - 3503 - ```typescript 3504 - function App() { 3505 - const sv = useSharedValue(100) 3506 - 3507 - const animatedStyle = useAnimatedStyle(() => { 3508 - "worklet" 3509 - return { width: sv.get() * 100 } 3510 - }) 3511 - 3512 - const handlePress = () => { 3513 - sv.set((value) => value + 1) 3514 - } 3515 - } 3516 - ``` 3517 - 3518 - ### Remarks 3519 - 3520 - - Avoid reading or modifying the shared value during a component's render. Accessing the `value` property or using `get`/`set` methods is considered a side-effect, which violates React's Rules of Render. 3521 - 3522 - - Changes to `sv.value` will update styles and synchronize the shared value across threads without triggering a typical React re-render since it's a plain JavaScript object. 3523 - 3524 - - Reading `sv.value` on the JavaScript thread may block until the value is fetched from the UI thread. This can be negligible, but if the UI thread is busy or values are read multiple times, synchronization delays might increase. 3525 - 3526 - - Changes to `sv.value` occur synchronously on the UI thread, while updates on the JavaScript thread are asynchronous. Thus, logging `value` immediately after a change will show the previous value. 3527 - 3528 - ```typescript 3529 - function App() { 3530 - const sv = useSharedValue(100) // initially set to 100 3531 - 3532 - sv.value += 50 // modifying the shared value 3533 - 3534 - console.log(sv.value) // logs 100 due to asynchronous update on JS thread 3535 - } 3536 - ``` 3537 - 3538 - - Avoid destructuring assignment with shared values. While valid in JavaScript, it prevents Reanimated from maintaining reactivity. 3539 - 3540 - ```typescript 3541 - function App() { 3542 - let { value } = sv // avoid this pattern 3543 - 3544 - console.log(value) // reading is fine 3545 - 3546 - value += 50 // does not update styles 3547 - } 3548 - ``` 3549 - 3550 - - When storing objects in a shared value, ensure to reassign the entire object rather than modifying its properties individually. 3551 - 3552 - ```typescript 3553 - function App() { 3554 - const sv = useSharedValue({ x: 0, y: 0 }) 3555 - 3556 - sv.value.x = 50 // loses reactivity 3557 - 3558 - sv.value = { x: 50, y: 0 } // correct approach 3559 - } 3560 - ``` 3561 - 3562 - - For large arrays or complex objects in a shared value, use the `.modify` method to alter the existing value without creating a new one. 3563 - 3564 - ```typescript 3565 - function App() { 3566 - const sv = useSharedValue([1, 2, 3]) 3567 - 3568 - sv.value.push(1000) // loses reactivity 3569 - 3570 - sv.value = [...sv.value, 1000] // creates a new copy 3571 - 3572 - sv.modify((value) => { 3573 - "worklet" 3574 - value.push(1000) // correct approach 3575 - return value 3576 - }) 3577 - } 3578 - ``` 3579 - 3580 - ### Platform Compatibility 3581 - 3582 - |Android|iOS|Web| 3583 - |-|-|-| 3584 - |✅|✅|✅| 3585 - 3586 - ## Contributing Guide for Reanimated 3587 - 3588 - Thank you for considering contributing to Reanimated. Contributions can range from triaging issues and enhancing documentation to reviewing Pull Requests and submitting code changes. 3589 - 3590 - ### Ways to Contribute 3591 - 3592 - 1. **Handling Open Issues**: Assist by providing detailed descriptions and reproducible examples for existing issues, which helps other contributors understand and address them more efficiently. 3593 - 3594 - 1. **Documentation Assistance**: Improve the documentation by correcting spelling and grammar or expanding explanations. You can also help update outdated pages from Reanimated v2 to the current version. For significant changes, edit locally using Docusaurus and GitHub Pages. 3595 - 3596 - 1. **Reviewing Pull Requests**: Review submitted Pull Requests to identify potential issues or bugs that may have been overlooked, ensuring high-quality contributions. 3597 - 3598 - 1. **Code Contributions**: Submit code through Pull Requests to address issues, fix bugs, or introduce new features. Beginners can start with "good first issue" tasks on GitHub. 3599 - 3600 - #### Repository Structure 3601 - 3602 - The Reanimated repository is organized as follows: 3603 - 3604 - ``` 3605 - ├── apps 3606 - │ ├── common-app // Shared source for example apps 3607 - │ ├── paper-example // React Native app using Old Architecture 3608 - │ ├── fabric-example // React Native app using New Architecture 3609 - │ ├── macos-example // React Native for MacOS wrapper 3610 - │ ├── next-example // Next.js wrapper 3611 - │ ├── tvos-example // React Native for TVOS wrapper 3612 - │ └── web-example // React Native for Web wrapper 3613 - └── packages 3614 - ├── docs-reanimated // Documentation source 3615 - ├── eslint-plugin-reanimated // ESLint plugin source 3616 - └── react-native-reanimated 3617 - ├── android // Android native code 3618 - ├── apple // iOS native code 3619 - ├── Common // Shared C++ code 3620 - ├── scripts // CI pipeline scripts 3621 - ├── src // Reanimated JS source 3622 - └── plugin // Babel plugin source 3623 - ``` 3624 - 3625 - ### Handling Open Issues 3626 - 3627 - Providing detailed descriptions and reproducible examples for issues can significantly aid other contributors. Ensure that issues include: 3628 - 3629 - - A cloneable repository. 3630 - - Clear reproduction steps. 3631 - - Comprehensive descriptions. 3632 - - Relevant stack traces. 3633 - 3634 - If these details are missing, consider asking the issue owner or providing them yourself to facilitate quicker resolutions. 3635 - 3636 - ### Documentation Assistance 3637 - 3638 - Improving documentation is a straightforward way to contribute. The Reanimated docs use Docusaurus and GitHub Pages. For minor edits, click **Edit this page** at the bottom of most pages. For more complex changes: 3639 - 3640 - 1. Clone `react-native-reanimated`. 3641 - 1. Navigate to `packages/docs-reanimated`. 3642 - 1. Run `yarn && yarn start` to preview changes locally. 3643 - 3644 - #### Documentation Structure 3645 - 3646 - Maintain a consistent structure for clarity and ease of navigation: 3647 - 3648 - 1. **Introduction**: Briefly describe the feature. 3649 - 1. **Reference**: Provide simple usage examples with type definitions. 3650 - 1. **Arguments**: Detail accepted arguments. 3651 - 1. **Returns**: Explain returned values. 3652 - 1. **Example**: Include videos, GIFs, or interactive demos in both light and dark modes. 3653 - 1. **Remarks**: Highlight non-obvious details like platform-specific quirks. 3654 - 1. **Platform Compatibility**: Specify supported platforms. 3655 - 3656 - #### Writing Style Guide 3657 - 3658 - - Use active voice for clarity (e.g., "The function receives the arguments"). 3659 - - Write short, clear sentences to aid comprehension. 3660 - - Organize information into lists for better readability. 3661 - - Avoid acronyms unless globally recognized (e.g., UI, API). 3662 - - Use contractions for a conversational tone. 3663 - 3664 - #### Embedding Interactive Examples 3665 - 3666 - Use the `InteractiveExample` component with `src` and `component` props to create engaging examples. For videos: 3667 - 3668 - ```typescript 3669 - import AnimatedKeyboardSrc from '!!raw-loader!@site/src/examples/AnimatedKeyboard'; 3670 - 3671 - <InteractiveExample 3672 - src={AnimatedKeyboardSrc} 3673 - component={ 3674 - <ThemedVideo 3675 - center 3676 - width={300} 3677 - sources={{ 3678 - light: '/recordings/useAnimatedKeyboard_light.mov', 3679 - dark: '/recordings/useAnimatedKeyboard_dark.mov', 3680 - }} 3681 - /> 3682 - } 3683 - />; 3684 - ``` 3685 - 3686 - For interactive components: 3687 - 3688 - ```typescript 3689 - import DecayTrain from '@site/src/examples/DecayTrain'; 3690 - import DecayTrainSrc from '!!raw-loader!@site/src/examples/DecayTrain'; 3691 - 3692 - <InteractiveExample 3693 - src={DecayTrainSrc} 3694 - component={<DecayTrain />} 3695 - label="Grab and drag the train" 3696 - />; 3697 - ``` 3698 - 3699 - ### Contributing Code 3700 - 3701 - Submit Pull Requests to address issues or introduce new features. Start with "good first issue" tasks if you're new to open-source contributions. 3702 - 3703 - #### Working with Android 3704 - 3705 - 1. Install dependencies: `yarn && yarn build`. 3706 - 1. Navigate to `apps/paper-example` and run `yarn start`. 3707 - 1. Open the project in Android Studio at `react-native-reanimated/apps/paper-example/android`. 3708 - 3709 - #### Working with iOS 3710 - 3711 - 1. Install dependencies: `yarn && yarn build`. 3712 - 1. Run `cd apps/paper-example/ios && bundle install && bundle exec pod install`. 3713 - 1. Start Metro bundler: `cd apps/paper-example && yarn start`. 3714 - 1. Open the project in Xcode at `react-native-reanimated/apps/paper-example/ios/ReanimatedExample.xcworkspace`. 3715 - 3716 - #### Preparing a Pull Request 3717 - 3718 - When ready, open a Pull Request using the provided template: 3719 - 3720 - 1. **Summary**: Link relevant issues and describe your changes. 3721 - 1. **Test Plan**: Provide instructions for testing, including code from `EmptyExample` if applicable. 3722 - 3723 - #### Testing Changes Locally 3724 - 3725 - To test changes in your project, create a patch with `git diff` or point to a specific commit in `package.json`. 3726 - 3727 - Thank you for contributing! 🎉 3728 - 3729 - ## Layout Transitions 1114 + ## Layout transitions 3730 1115 3731 1116 Layout transitions enable smooth animations during layout changes, which may involve alterations in size and position. Both aspects can be animated for a seamless experience. 3732 1117 ··· 3988 1373 3989 1374 This table indicates that all predefined transitions are compatible across Android, iOS, and web platforms. 3990 1375 3991 - ## Debugging Worklets 3992 - 3993 - ### Overview 3994 - 3995 - This document provides guidance on debugging Reanimated v2 worklets within React Native applications. Due to Reanimated's unique architecture and use of a secondary JavaScript runtime, traditional debugging methods may not function as expected. This article outlines compatible tools and their limitations. 3996 - 3997 - #### React Native Debugging Tools 3998 - 3999 - The following tools have been evaluated for compatibility with React Native apps using the Reanimated library: 4000 - 4001 - - **Chrome Debugger (React Native Debugger):** Utilizes a web worker in your browser to execute app JavaScript code, supporting all available runtimes in React Native. 4002 - 4003 - - **Chrome DevTools:** Connects to a remote JavaScript runtime, allowing code execution on the device. Note: Not compatible with JSC. 4004 - 4005 - - **Flipper (Hermes debugger):** Facilitates using Chrome DevTools and offers additional UI inspection tools. 4006 - 4007 - - **Safari DevTools:** Available only for iOS devices running JSC, similar in functionality to Chrome DevTools by connecting to a remote runtime. 4008 - 4009 - - **React Developer Tools:** A standalone app for debugging UI through an inspector, monitoring performance, and profiling the application. 4010 - 4011 - #### JS Context vs. UI Context 4012 - 4013 - Understanding the distinction between the JavaScript (JS) context and the User Interface (UI) context is crucial. Debugging the regular JS context remains unchanged with Reanimated; however, debugging the UI context specific to Reanimated can be challenging. 4014 - 4015 - #### Debugging Web Apps 4016 - 4017 - For web applications, standard browser tools or any preferred debugging tools can be used without issues when employing Reanimated on the web. 4018 - 4019 - ### Compatibility Summary 4020 - 4021 - |Tool|Platform|JSC|Hermes|V8| 4022 - |-|-|-|-|-| 4023 - |Chrome Debugger|Android|⚛️ ✅¹|⚛️ ✅¹|⚛️ ✅¹| 4024 - ||iOS|⚛️ ✅¹|⚛️ ✅¹|N/A| 4025 - |Chrome DevTools|Android|N/A|⚛️ ✅²|⚛️| 4026 - ||iOS|N/A|⚛️ ✅²|N/A| 4027 - |Flipper (Hermes debugger)|Android|N/A|⚛️ ✅²|⚛️| 4028 - ||iOS|N/A|⚛️ ✅²|N/A| 4029 - |Safari DevTools|Android|N/A|N/A|N/A| 4030 - ||iOS|⚛️ ✅|N/A|N/A| 4031 - |React Developer Tools|Android|⚛️|⚛️|⚛️| 4032 - ||iOS|⚛️|⚛️|N/A| 4033 - 4034 - ¹ - Functions use web implementations, running worklets on the JS thread. Measure and Layout Animations are unavailable. ² - Experimental feature. 4035 - 4036 - #### Legend 4037 - 4038 - - ⚛️ ✅: Special features for React Native apps using Reanimated 4039 - - ⚛️: Standard functionality with no worklet debugging available 4040 - - N/A: Not applicable in React Native apps 4041 - 4042 - **Note:** Console logs will always appear in the primary JS runtime as `console.log` on the UI runtime is a wrapper around the JS runtime's function. 4043 - 4044 - ### Tool-Specific Details 4045 - 4046 - #### Chrome Debugger 4047 - 4048 - |Platform|JSC|Hermes|V8| 4049 - |-|-|-|-| 4050 - |Android|⚛️ ✅|⚛️ ✅|⚛️ ✅| 4051 - |iOS|⚛️ ✅|⚛️ ✅|N/A| 4052 - 4053 - **Summary:** Functions use web implementations, running on the JS thread. Measure and Layout Animations are unavailable. 4054 - 4055 - #### Chrome DevTools 4056 - 4057 - |Platform|JSC|Hermes|V8| 4058 - |-|-|-|-| 4059 - |Android|N/A|⚛️ ✅²|⚛️| 4060 - |iOS|N/A|⚛️ ✅²|N/A| 4061 - 4062 - **Summary:** Both contexts can be debugged. This is an experimental feature. 4063 - 4064 - #### Flipper (Hermes Debugger) 4065 - 4066 - |Platform|JSC|Hermes|V8| 4067 - |-|-|-|-| 4068 - |Android|N/A|⚛️ ✅²|⚛️| 4069 - |iOS|N/A|⚛️ ✅²|N/A| 4070 - 4071 - **Summary:** Both contexts can be debugged. This is an experimental feature. 4072 - 4073 - #### Safari DevTools 4074 - 4075 - |Platform|JSC|Hermes|V8| 4076 - |-|-|-|-| 4077 - |Android|N/A|N/A|N/A| 4078 - |iOS|⚛️ ✅|N/A|N/A| 4079 - 4080 - **Summary:** Available only on iOS devices with the JSC engine. Worklet debugging is supported. 4081 - 4082 - #### React Developer Tools 4083 - 4084 - |Platform|JSC|Hermes|V8| 4085 - |-|-|-|-| 4086 - |Android|⚛️|⚛️|⚛️| 4087 - |iOS|⚛️|⚛️|N/A| 4088 - 4089 - **Summary:** Functions as expected, with profiler and layout inspector available. 4090 - 4091 - #### Additional Notes 4092 - 4093 - - **Console Logs:** Always appear in the primary JS runtime. 4094 - 4095 - - **Known Issues:** Include reload failures, breakpoint issues on iOS, unresponsive consoles without animations, and more. These do not affect release builds or debug builds where the debugger is disconnected during a reload. 4096 - 4097 - *Efforts are ongoing to enhance debugging experiences with Chrome DevTools and Flipper on Hermes.* 4098 - 4099 1376 ## Incremental Migration from Reanimated 1 to Reanimated 2 4100 1377 4101 1378 The transition from Reanimated 1 to Reanimated 2 is designed to be incremental. Upon installing Reanimated 2, users can access both the old and new APIs. The latest stable version of Reanimated 1 is included in the same package, with some exceptions due to naming collisions. To maintain a cleaner API in Reanimated 2, methods from Reanimated 1 that had naming conflicts were renamed. This approach aligns with plans to gradually phase out the older API, focusing on fixing existing issues rather than developing new features for it. Consequently, this strategy introduces some breaking changes where certain method names have been altered. However, the list of renamed methods is relatively short and these methods are not frequently used. ··· 4112 1389 - **Reanimated 1**: Use `Easing` imported from `react-native-reanimated`. 4113 1390 - **Reanimated 2**: Replace with `EasingNode`. 4114 1391 4115 - ## Getting Started 4116 - 4117 - The *Fundamentals* section aims to establish a solid understanding of the core concepts of Reanimated, empowering you to explore more complex scenarios independently. This section includes interactive examples, code snippets, and detailed explanations. 4118 - 4119 - ### What is React Native Reanimated? 1392 + ## Reanimated 3.x Overview 4120 1393 4121 - React Native Reanimated is an advanced animation library developed by Software Mansion. It enables developers to create smooth animations and interactions that run on the UI thread with ease. 4122 - 4123 - ### Quick Start 1394 + Reanimated 3.x maintains backward compatibility with the Reanimated v2 API, ensuring that all code written for version 2.x functions seamlessly in version 3.x without requiring any modifications. However, it is important to note that Reanimated 3.x completely removes support for the Reanimated v1 API. 4124 1395 4125 - To begin a new project using Expo: 1396 + For guidance on migrating from Reanimated 1.x to 2.x, please refer to the specific migration guide titled "Migration from 1.x to 2.x." 4126 1397 4127 - - **NPM**: 1398 + ## Customizing animations 4128 1399 4129 - ```bash 4130 - npx create-expo-app@latest my-app -e with-reanimated 4131 - ``` 1400 + The previous section introduced shared values in practice using `withSpring` and `withTiming` functions for creating animations. Now, you're ready to explore customizing these animations further! 4132 1401 4133 - - **YARN**: 4134 - ```bash 4135 - yarn create expo-app my-app -e with-reanimated 4136 - ``` 1402 + Reanimated provides three built-in animation functions: `withTiming`, `withSpring`, and `withDecay`. This discussion will focus on the first two, with `withDecay` covered later in the Handling Gestures section. 4137 1403 4138 - Alternatively, explore examples available on GitHub. 1404 + Customizing animation behavior in Reanimated is straightforward. You can achieve this by passing a `config` object to the second parameter of either the `withTiming` or `withSpring` function. 4139 1405 4140 - ### Installation 1406 + ### Configuring `withTiming` 4141 1407 4142 - Adding Reanimated to your project involves three main steps: 1408 + The `config` parameter for `withTiming` includes two properties: `duration` and `easing`. 4143 1409 4144 - #### Step 1: Install the Package 1410 + ```typescript 1411 + import { withTiming, Easing } from "react-native-reanimated" 4145 1412 4146 - Install the `react-native-reanimated` package from npm: 1413 + withTiming(sv.value, { 1414 + duration: 300, 1415 + easing: Easing.inOut(Easing.quad), 1416 + }) 1417 + ``` 4147 1418 4148 - - **EXPO**: 1419 + The `duration` parameter specifies the time in milliseconds for the animation to reach its target value (`toValue`). By default, this is set to `300` milliseconds. 4149 1420 4150 - ```bash 4151 - npx expo install react-native-reanimated 4152 - ``` 1421 + The `easing` parameter allows you to refine how the animation progresses over time. For instance, it can start slowly, accelerate, and then slow down again towards the end. The default easing function is `Easing.inOut(Easing.quad)`. 4153 1422 4154 - - **NPM**: 1423 + To understand its impact, compare a `linear` easing with the default easing. Reanimated offers several predefined easing functions that you can experiment with in an interactive playground or refer to the full `withTiming` API documentation. 4155 1424 4156 - ```bash 4157 - npm install react-native-reanimated 4158 - ``` 1425 + ### Configuring `withSpring` 4159 1426 4160 - - **YARN**: 4161 - ```bash 4162 - yarn add react-native-reanimated 4163 - ``` 1427 + Unlike `withTiming`, `withSpring` is physics-based and simulates real-world spring dynamics, making animations appear more realistic. 4164 1428 4165 - #### Step 2: Add Reanimated's Babel Plugin 1429 + When adjusting springs, focus on these three properties: `mass`, `stiffness` (also known as *tension*), and `damping` (also known as *friction*). 4166 1430 4167 - Include the `react-native-reanimated/plugin` in your `babel.config.js`: 1431 + ```typescript 1432 + import { withSpring } from "react-native-reanimated" 4168 1433 4169 - ```javascript 4170 - module.exports = { 4171 - presets: [ 4172 - // existing presets 4173 - ], 4174 - plugins: [ 4175 - // other plugins, 4176 - "react-native-reanimated/plugin", 4177 - ], 4178 - } 1434 + withSpring(sv.value, { 1435 + mass: 1, 1436 + stiffness: 100, 1437 + damping: 10, 1438 + }) 4179 1439 ``` 4180 1440 4181 - **Caution**: Ensure that `react-native-reanimated/plugin` is the last plugin listed. 1441 + The `mass` of a spring affects how difficult it is to move an object and bring it to a stop. It adds inertia to the movement. A higher mass results in a more sluggish motion compared to the default. 4182 1442 4183 - #### Step 3: Wrap Metro Config with Reanimated Wrapper (Recommended) 1443 + `Stiffness` determines the bounciness of the spring, akin to comparing a steel spring (high stiffness) with one made from soft plastic (low stiffness). 4184 1444 4185 - Modify your `metro.config.js` to wrap the existing configuration using `wrapWithReanimatedMetroConfig`: 1445 + `Damping` describes how quickly the animation concludes. Higher damping means the spring will settle faster. For example, consider a spring bouncing in air versus underwater; a vacuum would have zero friction and thus no damping. 4186 1446 4187 - ```javascript 4188 - // metro.config.js 4189 - const { 4190 - wrapWithReanimatedMetroConfig, 4191 - } = require("react-native-reanimated/metro-config") 1447 + Reanimated includes additional properties for customizing spring animations, which you can explore in an interactive playground or through the full `withSpring` API documentation. 4192 1448 4193 - const config = { 4194 - // Your existing Metro configuration options 4195 - } 1449 + ### Summary 4196 1450 4197 - module.exports = wrapWithReanimatedMetroConfig(config) 4198 - ``` 1451 + This section covered how to customize `withTiming` and `withSpring` animation functions: 4199 1452 4200 - #### Step 4: Clear Metro Bundler Cache (Recommended) 1453 + - Both functions accept a `config` object as their second parameter. 1454 + - You can modify `withTiming` using `duration` and `easing`. Reanimated provides an `Easing` module for convenience. 1455 + - Key properties for adjusting `withSpring` include `mass`, `stiffness`, and `damping`. 4201 1456 4202 - - **EXPO**: 1457 + ### What's Next? 4203 1458 4204 - ```bash 4205 - npx expo start -c 4206 - ``` 1459 + In the next section, you'll learn about animation modifiers like `withSequence` and `withRepeat`, enabling more complex and engaging animations. 4207 1460 4208 - - **NPM**: 1461 + ## Custom animations 4209 1462 4210 - ```bash 4211 - npm start -- --reset-cache 4212 - ``` 1463 + Custom animations provide full control over entering/exiting animations and layout transitions. However, they can be complex to understand and maintain. It's advisable to start with predefined presets before using custom animations. 4213 1464 4214 - - **YARN**: 4215 - ```bash 4216 - yarn start --reset-cache 4217 - ``` 1465 + ### Reference 4218 1466 4219 - #### Expo Development Build 4220 - 4221 - For an Expo development build, update the native code in `ios` and `android` directories by running: 4222 - 4223 - ```bash 4224 - npx expo prebuild 1467 + ```typescript 1468 + function CustomAnimation(values: any) { 1469 + "worklet" 1470 + const animations = { 1471 + // Define your animations here 1472 + } 1473 + const initialValues = { 1474 + // Set initial values for animations 1475 + } 1476 + const callback = (finished: boolean) => { 1477 + // Optional callback when the layout animation ends 1478 + } 1479 + return { 1480 + initialValues, 1481 + animations, 1482 + callback, 1483 + } 1484 + } 4225 1485 ``` 4226 1486 4227 - #### Platform-Specific Setup 1487 + ### Custom Exiting Animation 4228 1488 4229 - ##### Android 1489 + #### Arguments 4230 1490 4231 - No additional setup is required. 1491 + - `values`: Contains information about where the view was displayed and its dimensions. 1492 + - `currentOriginX`: X coordinate of the top-left corner in the parent's coordinate system. 1493 + - `currentOriginY`: Y coordinate of the top-left corner in the parent's coordinate system. 1494 + - `currentWidth`: View's width. 1495 + - `currentHeight`: View's height. 1496 + - `currentBorderRadius`: View's border radius. 1497 + - `currentGlobalOriginX`: X coordinate of the top-left corner in the global coordinate system. 1498 + - `currentGlobalOriginY`: Y coordinate of the top-left corner in the global coordinate system. 4232 1499 4233 - ##### iOS 1500 + #### Example 4234 1501 4235 - Before running your app on iOS, install pods with: 4236 - 4237 - ```bash 4238 - cd ios && pod install && cd .. 1502 + ```typescript 1503 + const customExiting = (values: any) => { 1504 + "worklet" 1505 + const animations = { 1506 + originX: withTiming(2 * WIDTH, { duration: 3000 }), 1507 + opacity: withTiming(0, { duration: 2000 }), 1508 + transform: [{ scale: withTiming(0.2, { duration: 3500 }) }], 1509 + } 1510 + const initialValues = { 1511 + originX: values.currentOriginX, 1512 + opacity: 1, 1513 + transform: [{ scale: 1 }], 1514 + } 1515 + return { 1516 + initialValues, 1517 + animations, 1518 + } 1519 + } 4239 1520 ``` 4240 1521 4241 - ##### Web 1522 + ### Custom Entering Animation 4242 1523 4243 - For web-targeted apps using react-native-web, it's recommended to use Expo. Install and add `@babel/plugin-proposal-export-namespace-from` Babel plugin in your `babel.config.js`: 1524 + #### Arguments 4244 1525 4245 - - **EXPO**: 1526 + - `values`: Contains information about where the view wants to be displayed and its dimensions. 1527 + - `targetOriginX`: X coordinate of the top-left corner in the parent's coordinate system. 1528 + - `targetOriginY`: Y coordinate of the top-left corner in the parent's coordinate system. 1529 + - `targetWidth`: View's width. 1530 + - `targetHeight`: View's height. 1531 + - `targetBorderRadius`: View's border radius. 1532 + - `targetGlobalOriginX`: X coordinate of the top-left corner in the global coordinate system. 1533 + - `targetGlobalOriginY`: Y coordinate of the top-left corner in the global coordinate system. 4246 1534 4247 - ```bash 4248 - npx expo install @babel/plugin-proposal-export-namespace-from 4249 - ``` 1535 + #### Example 4250 1536 4251 - - **NPM**: 4252 - 4253 - ```bash 4254 - npm install @babel/plugin-proposal-export-namespace-from 4255 - ``` 4256 - 4257 - - **YARN**: 4258 - ```bash 4259 - yarn add @babel/plugin-proposal-export-namespace-from 4260 - ``` 4261 - 4262 - Ensure your `babel.config.js` includes: 4263 - 4264 - ```javascript 4265 - module.exports = { 4266 - presets: [ 4267 - // existing presets 4268 - ], 4269 - plugins: [ 4270 - "@babel/plugin-proposal-export-namespace-from", 4271 - "react-native-reanimated/plugin", 4272 - ], 1537 + ```typescript 1538 + const customEntering = (targetValues: any) => { 1539 + "worklet" 1540 + const animations = { 1541 + originX: withTiming(targetValues.targetOriginX, { duration: 3000 }), 1542 + opacity: withTiming(1, { duration: 2000 }), 1543 + borderRadius: withDelay(1500, withTiming(40, { duration: 3000 })), 1544 + transform: [ 1545 + { rotate: withTiming("0deg", { duration: 4000 }) }, 1546 + { scale: withTiming(1, { duration: 3500 }) }, 1547 + ], 1548 + } 1549 + const initialValues = { 1550 + originX: -WIDTH, 1551 + opacity: 0, 1552 + borderRadius: 10, 1553 + transform: [{ rotate: "90deg" }, { scale: 0.2 }], 1554 + } 1555 + return { 1556 + initialValues, 1557 + animations, 1558 + } 4273 1559 } 4274 1560 ``` 4275 1561 4276 - **Note**: The `react-native-reanimated/plugin` should be listed last. 1562 + ### Custom Layout Transition 4277 1563 4278 - For more advanced scenarios, such as using Reanimated with `webpack` or `Next.js`, refer to the separate Web Support guide. 1564 + #### Arguments 4279 1565 4280 - ## Reanimated 3.x Overview 1566 + - `values`: Contains before and after information about the view's origin and dimensions. 1567 + - `targetOriginX`: X coordinate of the top-left corner in the parent's coordinate system. 1568 + - `targetOriginY`: Y coordinate of the top-left corner in the parent's coordinate system. 1569 + - `targetWidth`: View's width. 1570 + - `targetHeight`: View's height. 1571 + - `targetBorderRadius`: View's border radius. 1572 + - `targetGlobalOriginX`: X coordinate of the top-left corner in the global coordinate system. 1573 + - `targetGlobalOriginY`: Y coordinate of the top-left corner in the global coordinate system. 1574 + - `currentOriginX`: X coordinate of the top-left corner in the parent's coordinate system (before). 1575 + - `currentOriginY`: Y coordinate of the top-left corner in the parent's coordinate system (before). 1576 + - `currentWidth`: View's width (before). 1577 + - `currentHeight`: View's height (before). 1578 + - `currentBorderRadius`: View's border radius (before). 1579 + - `currentGlobalOriginX`: X coordinate of the top-left corner in the global coordinate system (before). 1580 + - `currentGlobalOriginY`: Y coordinate of the top-left corner in the global coordinate system (before). 4281 1581 4282 - Reanimated 3.x maintains backward compatibility with the Reanimated v2 API, ensuring that all code written for version 2.x functions seamlessly in version 3.x without requiring any modifications. However, it is important to note that Reanimated 3.x completely removes support for the Reanimated v1 API. 1582 + #### Example 4283 1583 4284 - For guidance on migrating from Reanimated 1.x to 2.x, please refer to the specific migration guide titled "Migration from 1.x to 2.x." 1584 + ```typescript 1585 + const customLayoutTransition = (values: any) => { 1586 + "worklet" 1587 + return { 1588 + animations: { 1589 + originX: withTiming(values.targetOriginX, { duration: 1000 }), 1590 + originY: withDelay( 1591 + 1000, 1592 + withTiming(values.targetOriginY, { duration: 1000 }) 1593 + ), 1594 + width: withSpring(values.targetWidth), 1595 + height: withSpring(values.targetHeight), 1596 + }, 1597 + initialValues: { 1598 + originX: values.currentOriginX, 1599 + originY: values.currentOriginY, 1600 + width: values.currentWidth, 1601 + height: values.currentHeight, 1602 + }, 1603 + } 1604 + } 1605 + ``` 4285 1606 4286 - ```markdown 4287 - # Animations (Version: 3.x) 1607 + ### Remarks 4288 1608 4289 - ## withTiming 1609 + - Each Reanimated component has a shared value that keeps the current animations assigned to it. If you start a new animation for a specific property without providing an initial value, the initial value will be taken from the last animation assigned to the component. The exception is the `Entering` animation, as previous animation values are unavailable. 4290 1610 4291 - `withTiming` allows for creating animations based on a specified duration and easing function. 1611 + ### Platform Compatibility 4292 1612 4293 - ## withSpring 1613 + |Android|iOS|Web| 1614 + |-|-|-| 1615 + |✅|✅|❌| 4294 1616 4295 - `withSpring` enables the creation of spring-based animations, providing a natural motion effect. 4296 - 4297 - ## withDecay 4298 - 4299 - `withDecay` creates animations that simulate objects in motion experiencing friction. The animation begins at a given velocity and gradually slows down according to a specified deceleration rate until it comes to a stop. 4300 - 4301 - ## withSequence 4302 - 4303 - `withSequence` is an animation modifier used for executing multiple animations one after another in sequence. 4304 - 4305 - ## withRepeat 4306 - 4307 - `withRepeat` is an animation modifier that allows an animation to be repeated a certain number of times or indefinitely. 4308 - 4309 - ## withDelay 4310 - 4311 - `withDelay` is an animation modifier that introduces a delay before starting the animation. 4312 - 4313 - ## withClamp 4314 - 4315 - `withClamp` is an animation modifier used to restrict the movement range of an animation, ensuring it stays within predefined limits. 4316 - ``` 4317 - 4318 - ## Testing with Jest and Reanimated 1617 + ## Testing with Jest 4319 1618 4320 1619 Reanimated provides a testing API based on Jest to facilitate the mocking of web-based animations. This guide outlines how to set up and use these tools effectively. 4321 1620 ··· 4425 1724 - [@testing-library/react-native](https://testing-library.com/docs/native-testing-library/intro) 4426 1725 - [@testing-library/react-hooks](https://testing-library.com/docs/react-hooks-testing-library/intro) - Useful for dealing with hooks. 4427 1726 4428 - ## Custom Animations 1727 + ## withTiming 4429 1728 4430 - Custom animations provide full control over entering/exiting animations and layout transitions. However, they can be complex to understand and maintain. It's advisable to start with predefined presets before using custom animations. 1729 + `withTiming` enables you to create animations based on duration and easing functions. 4431 1730 4432 1731 ### Reference 4433 1732 4434 1733 ```typescript 4435 - function CustomAnimation(values: any) { 4436 - "worklet" 4437 - const animations = { 4438 - // Define your animations here 4439 - } 4440 - const initialValues = { 4441 - // Set initial values for animations 4442 - } 4443 - const callback = (finished: boolean) => { 4444 - // Optional callback when the layout animation ends 4445 - } 4446 - return { 4447 - initialValues, 4448 - animations, 4449 - callback, 4450 - } 1734 + import { withTiming } from "react-native-reanimated" 1735 + 1736 + function App() { 1737 + sv.value = withTiming(0) 1738 + // ... 4451 1739 } 4452 1740 ``` 4453 - 4454 - ### Custom Exiting Animation 4455 1741 4456 1742 #### Arguments 4457 1743 4458 - - `values`: Contains information about where the view was displayed and its dimensions. 4459 - - `currentOriginX`: X coordinate of the top-left corner in the parent's coordinate system. 4460 - - `currentOriginY`: Y coordinate of the top-left corner in the parent's coordinate system. 4461 - - `currentWidth`: View's width. 4462 - - `currentHeight`: View's height. 4463 - - `currentBorderRadius`: View's border radius. 4464 - - `currentGlobalOriginX`: X coordinate of the top-left corner in the global coordinate system. 4465 - - `currentGlobalOriginY`: Y coordinate of the top-left corner in the global coordinate system. 1744 + ##### `toValue` 4466 1745 4467 - #### Example 1746 + The target value for the animation. Supported categories include: 4468 1747 4469 - ```typescript 4470 - const customExiting = (values: any) => { 4471 - "worklet" 4472 - const animations = { 4473 - originX: withTiming(2 * WIDTH, { duration: 3000 }), 4474 - opacity: withTiming(0, { duration: 2000 }), 4475 - transform: [{ scale: withTiming(0.2, { duration: 3500 }) }], 4476 - } 4477 - const initialValues = { 4478 - originX: values.currentOriginX, 4479 - opacity: 1, 4480 - transform: [{ scale: 1 }], 4481 - } 4482 - return { 4483 - initialValues, 4484 - animations, 4485 - } 4486 - } 4487 - ``` 1748 + - **Numbers**: Can be a number or a string representation of a number. 1749 + - **Suffixed Numbers**: Strings that combine numbers and units (e.g., `"5.5%"`, `"90deg"`, `"3bananas"`). Ensure no space between the number and suffix, with the suffix containing only basic English letters. 1750 + - **Colors**: 1751 + - Hexadecimal integer: e.g., `0xff1234` 1752 + - RGB: e.g., `"rgb(100, 50, 0)"` 1753 + - RGBA: e.g., `"rgba(255, 105, 180, 0.5)"` 1754 + - RGB Hexadecimal: e.g., `"#53575E"` 1755 + - HSL: e.g., `"hsl(0, 50%, 50%)"` 1756 + - Named colors: e.g., `"dodgerblue"` 1757 + - **Objects**: Objects with properties that will be animated individually. 1758 + - **Arrays**: Arrays of numbers where each value is animated separately. 1759 + - **Transformation Matrix**: An array of exactly 16 numerical values treated as a transformation matrix, decomposed into rotation, scale, and translation for animation. 4488 1760 4489 - ### Custom Entering Animation 1761 + Ensure `toValue` and the shared value being animated are of the same category (e.g., you cannot animate `width` from `100px` to `50%`). 4490 1762 4491 - #### Arguments 1763 + ##### `config` (Optional) 4492 1764 4493 - - `values`: Contains information about where the view wants to be displayed and its dimensions. 4494 - - `targetOriginX`: X coordinate of the top-left corner in the parent's coordinate system. 4495 - - `targetOriginY`: Y coordinate of the top-left corner in the parent's coordinate system. 4496 - - `targetWidth`: View's width. 4497 - - `targetHeight`: View's height. 4498 - - `targetBorderRadius`: View's border radius. 4499 - - `targetGlobalOriginX`: X coordinate of the top-left corner in the global coordinate system. 4500 - - `targetGlobalOriginY`: Y coordinate of the top-left corner in the global coordinate system. 1765 + The configuration for timing animations. Available properties: 1766 + 1767 + |Name|Type|Default|Description| 1768 + |-|-|-|-| 1769 + |duration|`number`|300|Length of the animation in milliseconds.| 1770 + |easing|`Easing`|`Easing.inOut(Easing.quad)`|An easing function defining the animation curve.| 1771 + |reduceMotion|`ReduceMotion`|`ReduceMotion.System`|Determines how the animation responds to reduced motion settings on devices.| 1772 + 1773 + ###### `Easing` 1774 + 1775 + The `easing` parameter allows fine-tuning of the animation over time, such as starting with fast acceleration and slowing down towards the end. 1776 + 1777 + Reanimated provides various easing functions in the `Easing` module. You can visualize common easing functions at [easings.net](http://easings.net/). 4501 1778 4502 - #### Example 1779 + Use built-in easings by passing them to the `withTiming` config: 4503 1780 4504 1781 ```typescript 4505 - const customEntering = (targetValues: any) => { 4506 - "worklet" 4507 - const animations = { 4508 - originX: withTiming(targetValues.targetOriginX, { duration: 3000 }), 4509 - opacity: withTiming(1, { duration: 2000 }), 4510 - borderRadius: withDelay(1500, withTiming(40, { duration: 3000 })), 4511 - transform: [ 4512 - { rotate: withTiming("0deg", { duration: 4000 }) }, 4513 - { scale: withTiming(1, { duration: 3500 }) }, 4514 - ], 4515 - } 4516 - const initialValues = { 4517 - originX: -WIDTH, 4518 - opacity: 0, 4519 - borderRadius: 10, 4520 - transform: [{ rotate: "90deg" }, { scale: 0.2 }], 4521 - } 4522 - return { 4523 - initialValues, 4524 - animations, 4525 - } 4526 - } 1782 + import { Easing } from "react-native-reanimated" 1783 + 1784 + withTiming(sv.value, { 1785 + easing: Easing.bounce, 1786 + }) 4527 1787 ``` 4528 1788 4529 - ### Custom Layout Transition 1789 + Available functions include: 4530 1790 4531 - #### Arguments 1791 + - `back`: Animation where the object slightly moves back before moving forward. 1792 + - `bezier(x1: number, y1: number, x2: number, y2: number)`: Cubic bezier curve. 1793 + - `bounce`: Bouncing animation. 1794 + - `circle`: Circular function. 1795 + - `cubic`: Cubic function. 1796 + - `ease`: Simple inertial animation. 1797 + - `elastic(bounciness?: number)`: Spring interaction. 1798 + - `exp`: Exponential function. 1799 + - `linear`: Linear function. 1800 + - `poly(n: number)`: Higher power functions like quartic, quintic. 1801 + - `quad`: Quadratic function. 1802 + - `sin`: Sinusoidal function. 1803 + 1804 + Helpers to modify easing functions: 1805 + 1806 + - `in(easing: EasingFunction)`: Runs an easing function forwards. 1807 + - `inOut(easing: EasingFunction)`: Symmetrical easing function. 1808 + - `out(easing: EasingFunction)`: Runs an easing function backwards. 1809 + 1810 + ##### `callback` (Optional) 1811 + 1812 + A function called upon animation completion. If the animation is canceled, it receives `false`; otherwise, it receives `true`. 4532 1813 4533 - - `values`: Contains before and after information about the view's origin and dimensions. 4534 - - `targetOriginX`: X coordinate of the top-left corner in the parent's coordinate system. 4535 - - `targetOriginY`: Y coordinate of the top-left corner in the parent's coordinate system. 4536 - - `targetWidth`: View's width. 4537 - - `targetHeight`: View's height. 4538 - - `targetBorderRadius`: View's border radius. 4539 - - `targetGlobalOriginX`: X coordinate of the top-left corner in the global coordinate system. 4540 - - `targetGlobalOriginY`: Y coordinate of the top-left corner in the global coordinate system. 4541 - - `currentOriginX`: X coordinate of the top-left corner in the parent's coordinate system (before). 4542 - - `currentOriginY`: Y coordinate of the top-left corner in the parent's coordinate system (before). 4543 - - `currentWidth`: View's width (before). 4544 - - `currentHeight`: View's height (before). 4545 - - `currentBorderRadius`: View's border radius (before). 4546 - - `currentGlobalOriginX`: X coordinate of the top-left corner in the global coordinate system (before). 4547 - - `currentGlobalOriginY`: Y coordinate of the top-left corner in the global coordinate system (before). 1814 + #### Returns 4548 1815 4549 - #### Example 1816 + `withTiming` returns an animation object representing the current state of the animation. It can be assigned to a shared value or used in a style object from `useAnimatedStyle`. 4550 1817 4551 - ```typescript 4552 - const customLayoutTransition = (values: any) => { 4553 - "worklet" 4554 - return { 4555 - animations: { 4556 - originX: withTiming(values.targetOriginX, { duration: 1000 }), 4557 - originY: withDelay( 4558 - 1000, 4559 - withTiming(values.targetOriginY, { duration: 1000 }) 4560 - ), 4561 - width: withSpring(values.targetWidth), 4562 - height: withSpring(values.targetHeight), 4563 - }, 4564 - initialValues: { 4565 - originX: values.currentOriginX, 4566 - originY: values.currentOriginY, 4567 - width: values.currentWidth, 4568 - height: values.currentHeight, 4569 - }, 4570 - } 4571 - } 4572 - ``` 1818 + ### Example 4573 1819 4574 1820 ### Remarks 4575 1821 4576 - - Each Reanimated component has a shared value that keeps the current animations assigned to it. If you start a new animation for a specific property without providing an initial value, the initial value will be taken from the last animation assigned to the component. The exception is the `Entering` animation, as previous animation values are unavailable. 1822 + - The callback passed as the third argument is automatically workletized and executed on the UI thread. 4577 1823 4578 1824 ### Platform Compatibility 4579 1825 4580 1826 |Android|iOS|Web| 4581 1827 |-|-|-| 4582 - |✅|✅|❌| 1828 + |✅|✅|✅| 4583 1829 4584 1830 ## useAnimatedProps 4585 1831 ··· 4939 2185 import "raf/polyfill" 4940 2186 ``` 4941 2187 4942 - ```markdown 4943 - ## About 4944 - 4945 - ### What is Reanimated Babel Plugin? 4946 - 4947 - The Reanimated Babel Plugin is a tool designed to enhance the performance of animations in React Native applications. It works by transforming animation code during the build process, allowing for more efficient execution on mobile devices. By leveraging this plugin, developers can create smooth and responsive animations that run directly on the UI thread, bypassing JavaScript's limitations. 4948 - ``` 4949 - 4950 2188 ## React Native Reanimated: List Layout Animations (Version 3.x) 4951 2189 4952 2190 ### Overview ··· 5027 2265 - **Remarks** 5028 2266 - **Platform compatibility** 5029 2267 5030 - ## withTiming 5031 - 5032 - `withTiming` enables you to create animations based on duration and easing functions. 5033 - 5034 - ### Reference 5035 - 5036 - ```typescript 5037 - import { withTiming } from "react-native-reanimated" 5038 - 5039 - function App() { 5040 - sv.value = withTiming(0) 5041 - // ... 5042 - } 5043 - ``` 5044 - 5045 - #### Arguments 5046 - 5047 - ##### `toValue` 5048 - 5049 - The target value for the animation. Supported categories include: 5050 - 5051 - - **Numbers**: Can be a number or a string representation of a number. 5052 - - **Suffixed Numbers**: Strings that combine numbers and units (e.g., `"5.5%"`, `"90deg"`, `"3bananas"`). Ensure no space between the number and suffix, with the suffix containing only basic English letters. 5053 - - **Colors**: 5054 - - Hexadecimal integer: e.g., `0xff1234` 5055 - - RGB: e.g., `"rgb(100, 50, 0)"` 5056 - - RGBA: e.g., `"rgba(255, 105, 180, 0.5)"` 5057 - - RGB Hexadecimal: e.g., `"#53575E"` 5058 - - HSL: e.g., `"hsl(0, 50%, 50%)"` 5059 - - Named colors: e.g., `"dodgerblue"` 5060 - - **Objects**: Objects with properties that will be animated individually. 5061 - - **Arrays**: Arrays of numbers where each value is animated separately. 5062 - - **Transformation Matrix**: An array of exactly 16 numerical values treated as a transformation matrix, decomposed into rotation, scale, and translation for animation. 5063 - 5064 - Ensure `toValue` and the shared value being animated are of the same category (e.g., you cannot animate `width` from `100px` to `50%`). 5065 - 5066 - ##### `config` (Optional) 5067 - 5068 - The configuration for timing animations. Available properties: 5069 - 5070 - |Name|Type|Default|Description| 5071 - |-|-|-|-| 5072 - |duration|`number`|300|Length of the animation in milliseconds.| 5073 - |easing|`Easing`|`Easing.inOut(Easing.quad)`|An easing function defining the animation curve.| 5074 - |reduceMotion|`ReduceMotion`|`ReduceMotion.System`|Determines how the animation responds to reduced motion settings on devices.| 5075 - 5076 - ###### `Easing` 5077 - 5078 - The `easing` parameter allows fine-tuning of the animation over time, such as starting with fast acceleration and slowing down towards the end. 5079 - 5080 - Reanimated provides various easing functions in the `Easing` module. You can visualize common easing functions at [easings.net](http://easings.net/). 5081 - 5082 - Use built-in easings by passing them to the `withTiming` config: 5083 - 5084 - ```typescript 5085 - import { Easing } from "react-native-reanimated" 5086 - 5087 - withTiming(sv.value, { 5088 - easing: Easing.bounce, 5089 - }) 5090 - ``` 5091 - 5092 - Available functions include: 5093 - 5094 - - `back`: Animation where the object slightly moves back before moving forward. 5095 - - `bezier(x1: number, y1: number, x2: number, y2: number)`: Cubic bezier curve. 5096 - - `bounce`: Bouncing animation. 5097 - - `circle`: Circular function. 5098 - - `cubic`: Cubic function. 5099 - - `ease`: Simple inertial animation. 5100 - - `elastic(bounciness?: number)`: Spring interaction. 5101 - - `exp`: Exponential function. 5102 - - `linear`: Linear function. 5103 - - `poly(n: number)`: Higher power functions like quartic, quintic. 5104 - - `quad`: Quadratic function. 5105 - - `sin`: Sinusoidal function. 5106 - 5107 - Helpers to modify easing functions: 5108 - 5109 - - `in(easing: EasingFunction)`: Runs an easing function forwards. 5110 - - `inOut(easing: EasingFunction)`: Symmetrical easing function. 5111 - - `out(easing: EasingFunction)`: Runs an easing function backwards. 5112 - 5113 - ##### `callback` (Optional) 5114 - 5115 - A function called upon animation completion. If the animation is canceled, it receives `false`; otherwise, it receives `true`. 5116 - 5117 - #### Returns 5118 - 5119 - `withTiming` returns an animation object representing the current state of the animation. It can be assigned to a shared value or used in a style object from `useAnimatedStyle`. 5120 - 5121 - ### Example 5122 - 5123 - ### Remarks 5124 - 5125 - - The callback passed as the third argument is automatically workletized and executed on the UI thread. 5126 - 5127 - ### Platform Compatibility 5128 - 5129 - |Android|iOS|Web| 5130 - |-|-|-| 5131 - |✅|✅|✅| 5132 - 5133 - ## Getting Started 2268 + ## Getting started 5134 2269 5135 2270 The *Fundamentals* section aims to establish a solid understanding of the core concepts of Reanimated, empowering you to explore more complex scenarios independently. This section includes interactive examples, code snippets, and detailed explanations. 5136 2271 ··· 5344 2479 |-|-|-| 5345 2480 |✅|✅|✅| 5346 2481 5347 - ```markdown 5348 - # Overview 2482 + ## Getting started 2483 + 2484 + The *Fundamentals* section aims to establish a solid understanding of the core concepts of Reanimated, empowering you to explore more complex scenarios independently. This section includes interactive examples, code snippets, and detailed explanations. 2485 + 2486 + ### What is React Native Reanimated? 2487 + 2488 + React Native Reanimated is an advanced animation library developed by Software Mansion. It enables developers to create smooth animations and interactions that run on the UI thread with ease. 2489 + 2490 + ### Quick Start 2491 + 2492 + To begin a new project using Expo: 2493 + 2494 + - **NPM**: 2495 + 2496 + ```bash 2497 + npx create-expo-app@latest my-app -e with-reanimated 2498 + ``` 5349 2499 5350 - The Shared Element Transition feature is currently in the experimental stage and should not be used in production environments at this time. Feedback from users is being sought to enhance its development and implementation. 2500 + - **YARN**: 2501 + ```bash 2502 + yarn create expo-app my-app -e with-reanimated 2503 + ``` 5351 2504 5352 - ## Key Points 2505 + Alternatively, explore examples available on GitHub. 5353 2506 5354 - - **Experimental Status**: The feature is still under development and testing. 5355 - - **Not for Production Use**: It's advised against using it in live applications until further notice. 5356 - - **Feedback Requested**: User input is crucial for refining the feature. 2507 + ### Installation 2508 + 2509 + Adding Reanimated to your project involves three main steps: 2510 + 2511 + #### Step 1: Install the Package 2512 + 2513 + Install the `react-native-reanimated` package from npm: 2514 + 2515 + - **EXPO**: 2516 + 2517 + ```bash 2518 + npx expo install react-native-reanimated 2519 + ``` 2520 + 2521 + - **NPM**: 2522 + 2523 + ```bash 2524 + npm install react-native-reanimated 2525 + ``` 2526 + 2527 + - **YARN**: 2528 + ```bash 2529 + yarn add react-native-reanimated 2530 + ``` 2531 + 2532 + #### Step 2: Add Reanimated's Babel Plugin 2533 + 2534 + Include the `react-native-reanimated/plugin` in your `babel.config.js`: 2535 + 2536 + ```javascript 2537 + module.exports = { 2538 + presets: [ 2539 + // existing presets 2540 + ], 2541 + plugins: [ 2542 + // other plugins, 2543 + "react-native-reanimated/plugin", 2544 + ], 2545 + } 5357 2546 ``` 5358 2547 5359 - ## Customizing Animations 2548 + **Caution**: Ensure that `react-native-reanimated/plugin` is the last plugin listed. 5360 2549 5361 - The previous section introduced shared values in practice using `withSpring` and `withTiming` functions for creating animations. Now, you're ready to explore customizing these animations further! 2550 + #### Step 3: Wrap Metro Config with Reanimated Wrapper (Recommended) 5362 2551 5363 - Reanimated provides three built-in animation functions: `withTiming`, `withSpring`, and `withDecay`. This discussion will focus on the first two, with `withDecay` covered later in the Handling Gestures section. 2552 + Modify your `metro.config.js` to wrap the existing configuration using `wrapWithReanimatedMetroConfig`: 5364 2553 5365 - Customizing animation behavior in Reanimated is straightforward. You can achieve this by passing a `config` object to the second parameter of either the `withTiming` or `withSpring` function. 2554 + ```javascript 2555 + // metro.config.js 2556 + const { 2557 + wrapWithReanimatedMetroConfig, 2558 + } = require("react-native-reanimated/metro-config") 5366 2559 5367 - ### Configuring `withTiming` 2560 + const config = { 2561 + // Your existing Metro configuration options 2562 + } 5368 2563 5369 - The `config` parameter for `withTiming` includes two properties: `duration` and `easing`. 2564 + module.exports = wrapWithReanimatedMetroConfig(config) 2565 + ``` 5370 2566 5371 - ```typescript 5372 - import { withTiming, Easing } from "react-native-reanimated" 2567 + #### Step 4: Clear Metro Bundler Cache (Recommended) 2568 + 2569 + - **EXPO**: 2570 + 2571 + ```bash 2572 + npx expo start -c 2573 + ``` 2574 + 2575 + - **NPM**: 2576 + 2577 + ```bash 2578 + npm start -- --reset-cache 2579 + ``` 2580 + 2581 + - **YARN**: 2582 + ```bash 2583 + yarn start --reset-cache 2584 + ``` 5373 2585 5374 - withTiming(sv.value, { 5375 - duration: 300, 5376 - easing: Easing.inOut(Easing.quad), 5377 - }) 2586 + #### Expo Development Build 2587 + 2588 + For an Expo development build, update the native code in `ios` and `android` directories by running: 2589 + 2590 + ```bash 2591 + npx expo prebuild 5378 2592 ``` 5379 2593 5380 - The `duration` parameter specifies the time in milliseconds for the animation to reach its target value (`toValue`). By default, this is set to `300` milliseconds. 2594 + #### Platform-Specific Setup 5381 2595 5382 - The `easing` parameter allows you to refine how the animation progresses over time. For instance, it can start slowly, accelerate, and then slow down again towards the end. The default easing function is `Easing.inOut(Easing.quad)`. 2596 + ##### Android 5383 2597 5384 - To understand its impact, compare a `linear` easing with the default easing. Reanimated offers several predefined easing functions that you can experiment with in an interactive playground or refer to the full `withTiming` API documentation. 2598 + No additional setup is required. 5385 2599 5386 - ### Configuring `withSpring` 2600 + ##### iOS 5387 2601 5388 - Unlike `withTiming`, `withSpring` is physics-based and simulates real-world spring dynamics, making animations appear more realistic. 2602 + Before running your app on iOS, install pods with: 5389 2603 5390 - When adjusting springs, focus on these three properties: `mass`, `stiffness` (also known as *tension*), and `damping` (also known as *friction*). 2604 + ```bash 2605 + cd ios && pod install && cd .. 2606 + ``` 5391 2607 5392 - ```typescript 5393 - import { withSpring } from "react-native-reanimated" 2608 + ##### Web 5394 2609 5395 - withSpring(sv.value, { 5396 - mass: 1, 5397 - stiffness: 100, 5398 - damping: 10, 5399 - }) 5400 - ``` 2610 + For web-targeted apps using react-native-web, it's recommended to use Expo. Install and add `@babel/plugin-proposal-export-namespace-from` Babel plugin in your `babel.config.js`: 5401 2611 5402 - The `mass` of a spring affects how difficult it is to move an object and bring it to a stop. It adds inertia to the movement. A higher mass results in a more sluggish motion compared to the default. 2612 + - **EXPO**: 5403 2613 5404 - `Stiffness` determines the bounciness of the spring, akin to comparing a steel spring (high stiffness) with one made from soft plastic (low stiffness). 2614 + ```bash 2615 + npx expo install @babel/plugin-proposal-export-namespace-from 2616 + ``` 5405 2617 5406 - `Damping` describes how quickly the animation concludes. Higher damping means the spring will settle faster. For example, consider a spring bouncing in air versus underwater; a vacuum would have zero friction and thus no damping. 2618 + - **NPM**: 5407 2619 5408 - Reanimated includes additional properties for customizing spring animations, which you can explore in an interactive playground or through the full `withSpring` API documentation. 2620 + ```bash 2621 + npm install @babel/plugin-proposal-export-namespace-from 2622 + ``` 5409 2623 5410 - ### Summary 2624 + - **YARN**: 2625 + ```bash 2626 + yarn add @babel/plugin-proposal-export-namespace-from 2627 + ``` 5411 2628 5412 - This section covered how to customize `withTiming` and `withSpring` animation functions: 2629 + Ensure your `babel.config.js` includes: 5413 2630 5414 - - Both functions accept a `config` object as their second parameter. 5415 - - You can modify `withTiming` using `duration` and `easing`. Reanimated provides an `Easing` module for convenience. 5416 - - Key properties for adjusting `withSpring` include `mass`, `stiffness`, and `damping`. 2631 + ```javascript 2632 + module.exports = { 2633 + presets: [ 2634 + // existing presets 2635 + ], 2636 + plugins: [ 2637 + "@babel/plugin-proposal-export-namespace-from", 2638 + "react-native-reanimated/plugin", 2639 + ], 2640 + } 2641 + ``` 5417 2642 5418 - ### What's Next? 2643 + **Note**: The `react-native-reanimated/plugin` should be listed last. 5419 2644 5420 - In the next section, you'll learn about animation modifiers like `withSequence` and `withRepeat`, enabling more complex and engaging animations. 2645 + For more advanced scenarios, such as using Reanimated with `webpack` or `Next.js`, refer to the separate Web Support guide. 5421 2646 5422 2647 ## withSpring 5423 2648 ··· 5592 2817 |-|-|-| 5593 2818 |✅|✅|✅| 5594 2819 5595 - ## createWorkletRuntime 2820 + ## Web Support 2821 + 2822 + Reanimated can be launched in a web browser, with all functionalities implemented purely in JavaScript. This may result in lower animation efficiency compared to native implementations. 2823 + 2824 + ### Step 1: Install the Package 2825 + 2826 + Install `@babel/plugin-proposal-export-namespace-from` using one of the following package managers: 2827 + 2828 + - **EXPO** 2829 + 2830 + ```bash 2831 + npx expo install @babel/plugin-proposal-export-namespace-from 2832 + ``` 2833 + 2834 + - **NPM** 5596 2835 5597 - The `createWorkletRuntime` function is designed to establish a new JavaScript runtime environment specifically for executing worklets, potentially on threads distinct from those used by standard JavaScript or the UI. This functionality is primarily intended for use by third-party libraries that require integration with worklets. 2836 + ```bash 2837 + npm install @babel/plugin-proposal-export-namespace-from 2838 + ``` 5598 2839 5599 - Upon invocation, `createWorkletRuntime` returns an object representing the newly created runtime. This object must be communicated to the C++ side via the JavaScript Interface (JSI) to facilitate subsequent operations and interactions within the worklet environment. 2840 + - **YARN** 2841 + ```bash 2842 + yarn add @babel/plugin-proposal-export-namespace-from 2843 + ``` 5600 2844 5601 - ## Animating Styles and Props 2845 + ### Step 2: Add Plugins to Config File 2846 + 2847 + Update your `babel.config.js` by adding the following plugins: 2848 + 2849 + ```javascript 2850 + module.exports = { 2851 + presets: [ 2852 + // Existing presets... 2853 + ], 2854 + plugins: [ 2855 + ..., 2856 + '@babel/plugin-proposal-export-namespace-from', 2857 + 'react-native-reanimated/plugin', // Ensure this is listed last 2858 + ], 2859 + }; 2860 + ``` 2861 + 2862 + **Caution:** Make sure `react-native-reanimated/plugin` is the last plugin in the list. 2863 + 2864 + ### Step 3: Launch Your App 2865 + 2866 + To start a playground app in the browser, use: 2867 + 2868 + ```bash 2869 + yarn web 2870 + ``` 2871 + 2872 + For example applications from the Reanimated repository, execute these commands at the root of the repository: 2873 + 2874 + ```bash 2875 + yarn && yarn build 2876 + ``` 2877 + 2878 + Then navigate to `apps/web-example` and run: 2879 + 2880 + ```bash 2881 + yarn start 2882 + ``` 2883 + 2884 + ### Webpack Support 2885 + 2886 + To use Reanimated in a Webpack app, adjust your configuration as follows: 2887 + 2888 + Example Webpack config with Reanimated support: 2889 + 2890 + ```javascript 2891 + const HtmlWebpackPlugin = require("html-webpack-plugin") 2892 + const webpack = require("webpack") 2893 + 2894 + module.exports = { 2895 + entry: ["babel-polyfill", "./index.js"], 2896 + plugins: [ 2897 + new HtmlWebpackPlugin({ 2898 + filename: "index.html", 2899 + template: "./index.html", 2900 + }), 2901 + new webpack.EnvironmentPlugin({ JEST_WORKER_ID: null }), 2902 + new webpack.DefinePlugin({ process: { env: {} } }), 2903 + ], 2904 + module: { 2905 + rules: [ 2906 + { 2907 + test: /\.(js|jsx)$/, 2908 + use: { 2909 + loader: "babel-loader", 2910 + options: { 2911 + presets: [ 2912 + "@babel/preset-react", 2913 + { plugins: ["@babel/plugin-proposal-class-properties"] }, 2914 + ], 2915 + }, 2916 + }, 2917 + }, 2918 + ], 2919 + }, 2920 + resolve: { 2921 + alias: { "react-native$": "react-native-web" }, 2922 + extensions: [".web.js", ".js"], 2923 + }, 2924 + } 2925 + ``` 2926 + 2927 + ### Web Without the Babel Plugin 2928 + 2929 + Reanimated can be used without its Babel plugin by manually passing dependency arrays to hooks. This approach is valid for both web and native platforms. 2930 + 2931 + Ensure these hooks include a dependency array as their last argument: 2932 + 2933 + - `useDerivedValue` 2934 + - `useAnimatedStyle` 2935 + - `useAnimatedProps` 2936 + - `useAnimatedReaction` 2937 + 2938 + Example usage: 2939 + 2940 + ```javascript 2941 + const sv = useSharedValue(0) 2942 + const dv = useDerivedValue( 2943 + () => sv.value + 1, 2944 + [sv] // dependency array here 2945 + ) 2946 + ``` 2947 + 2948 + **Caution:** Pass the root dependency (`sv`) rather than `sv.value`. 2949 + 2950 + Babel users must still install the `@babel/plugin-proposal-class-properties` plugin. 2951 + 2952 + #### ESLint Support 2953 + 2954 + To add ESLint support for Reanimated hooks, update your ESLint configuration: 2955 + 2956 + ```json 2957 + { 2958 + "rules": { 2959 + "react-hooks/exhaustive-deps": [ 2960 + "error", 2961 + { 2962 + "additionalHooks": "(useAnimatedStyle|useDerivedValue|useAnimatedProps)" 2963 + } 2964 + ] 2965 + } 2966 + } 2967 + ``` 2968 + 2969 + **Info:** This assumes the `react-hooks` ESLint plugin is installed. 2970 + 2971 + If using ESLint autofix, manually correct any `.value` additions to dependency arrays: 2972 + 2973 + ```javascript 2974 + const sv = useSharedValue(0) 2975 + 2976 + // 🚨 bad: sv.value in array 2977 + const dv = useDerivedValue(() => sv.value, [sv.value]) 2978 + 2979 + // ✅ good: sv in array 2980 + const dv = useDerivedValue(() => sv.value, [sv]) 2981 + ``` 2982 + 2983 + ### Solito / Next.js Compatibility 2984 + 2985 + An experimental SWC plugin is being developed. Until then, follow the "Web without a Babel Plugin" instructions. 2986 + 2987 + #### Next.js Polyfill 2988 + 2989 + To use Reanimated with Next.js/Solito, add the `raf` polyfill for `requestAnimationFrame`: 2990 + 2991 + ```bash 2992 + yarn add raf 2993 + ``` 2994 + 2995 + Include this at the top of your `_app.tsx`: 2996 + 2997 + ```javascript 2998 + import "raf/polyfill" 2999 + ``` 3000 + 3001 + ## runOnJS 3002 + 3003 + The `runOnJS` function allows you to asynchronously execute functions that are not workletized on the UI thread. This is particularly useful for most external libraries, as their functions typically lack the `"worklet"` directive. 3004 + 3005 + `runOnJS` is commonly used to update React state either after an animation completes or conditionally within a gesture interaction. 3006 + 3007 + ### Reference 3008 + 3009 + ```typescript 3010 + import { runOnJS } from "react-native-reanimated" 3011 + 3012 + function App() { 3013 + // Executing on the UI thread 3014 + runOnJS(navigation.goBack)() 3015 + } 3016 + ``` 3017 + 3018 + #### Arguments 3019 + 3020 + ##### `fn` 3021 + 3022 + A reference to a function you wish to execute on the JavaScript thread from the UI thread. Any arguments for your function must be passed to the function returned by `runOnJS`, e.g., `runOnJS(setValue)(10);`. 3023 + 3024 + #### Returns 3025 + 3026 + `runOnJS` returns a function that accepts arguments for the original function provided as its first argument. This returned function can be safely executed on the UI thread. 3027 + 3028 + **Note:** Ensure you call the function returned from `runOnJS`. 3029 + 3030 + ### Example 3031 + 3032 + ### Remarks 3033 + 3034 + - Functions passed to `runOnJS` must be defined within the JavaScript thread scope, such as in a component body or global scope. The following code will not work because `myFunction` is defined inside the `withTiming` callback, which runs on the UI thread: 3035 + 3036 + ```typescript 3037 + withTiming(0, {}, () => { 3038 + // myFunction is defined on the UI thread 🚨 3039 + const myFunction = () => { 3040 + // ... 3041 + } 3042 + runOnJS(myFunction)() // 💥 3043 + }) 3044 + ``` 3045 + 3046 + - A common mistake is to execute a function inside `runOnJS` like this: ~~`runOnJS(setValue(10))()`~~. The correct usage would be `runOnJS(setValue)(10)`. 3047 + 3048 + - It's safe to run functions via `runOnJS` on the JavaScript thread, as it has no adverse effects. 3049 + 3050 + ### Platform Compatibility 3051 + 3052 + |Android|iOS|Web| 3053 + |-|-|-| 3054 + |✅|✅|✅| 3055 + 3056 + ## withTiming 3057 + 3058 + `withTiming` enables you to create animations based on duration and easing functions. 3059 + 3060 + ### Reference 3061 + 3062 + ```typescript 3063 + import { withTiming } from "react-native-reanimated" 3064 + 3065 + function App() { 3066 + sv.value = withTiming(0) 3067 + // ... 3068 + } 3069 + ``` 3070 + 3071 + #### Arguments 3072 + 3073 + ##### `toValue` 3074 + 3075 + The target value for the animation. Supported categories include: 3076 + 3077 + - **Numbers**: Can be a number or a string representation of a number. 3078 + - **Suffixed Numbers**: Strings that combine numbers and units (e.g., `"5.5%"`, `"90deg"`, `"3bananas"`). Ensure no space between the number and suffix, with the suffix containing only basic English letters. 3079 + - **Colors**: 3080 + - Hexadecimal integer: e.g., `0xff1234` 3081 + - RGB: e.g., `"rgb(100, 50, 0)"` 3082 + - RGBA: e.g., `"rgba(255, 105, 180, 0.5)"` 3083 + - RGB Hexadecimal: e.g., `"#53575E"` 3084 + - HSL: e.g., `"hsl(0, 50%, 50%)"` 3085 + - Named colors: e.g., `"dodgerblue"` 3086 + - **Objects**: Objects with properties that will be animated individually. 3087 + - **Arrays**: Arrays of numbers where each value is animated separately. 3088 + - **Transformation Matrix**: An array of exactly 16 numerical values treated as a transformation matrix, decomposed into rotation, scale, and translation for animation. 3089 + 3090 + Ensure `toValue` and the shared value being animated are of the same category (e.g., you cannot animate `width` from `100px` to `50%`). 3091 + 3092 + ##### `config` (Optional) 3093 + 3094 + The configuration for timing animations. Available properties: 3095 + 3096 + |Name|Type|Default|Description| 3097 + |-|-|-|-| 3098 + |duration|`number`|300|Length of the animation in milliseconds.| 3099 + |easing|`Easing`|`Easing.inOut(Easing.quad)`|An easing function defining the animation curve.| 3100 + |reduceMotion|`ReduceMotion`|`ReduceMotion.System`|Determines how the animation responds to reduced motion settings on devices.| 3101 + 3102 + ###### `Easing` 3103 + 3104 + The `easing` parameter allows fine-tuning of the animation over time, such as starting with fast acceleration and slowing down towards the end. 3105 + 3106 + Reanimated provides various easing functions in the `Easing` module. You can visualize common easing functions at [easings.net](http://easings.net/). 3107 + 3108 + Use built-in easings by passing them to the `withTiming` config: 3109 + 3110 + ```typescript 3111 + import { Easing } from "react-native-reanimated" 3112 + 3113 + withTiming(sv.value, { 3114 + easing: Easing.bounce, 3115 + }) 3116 + ``` 3117 + 3118 + Available functions include: 3119 + 3120 + - `back`: Animation where the object slightly moves back before moving forward. 3121 + - `bezier(x1: number, y1: number, x2: number, y2: number)`: Cubic bezier curve. 3122 + - `bounce`: Bouncing animation. 3123 + - `circle`: Circular function. 3124 + - `cubic`: Cubic function. 3125 + - `ease`: Simple inertial animation. 3126 + - `elastic(bounciness?: number)`: Spring interaction. 3127 + - `exp`: Exponential function. 3128 + - `linear`: Linear function. 3129 + - `poly(n: number)`: Higher power functions like quartic, quintic. 3130 + - `quad`: Quadratic function. 3131 + - `sin`: Sinusoidal function. 3132 + 3133 + Helpers to modify easing functions: 3134 + 3135 + - `in(easing: EasingFunction)`: Runs an easing function forwards. 3136 + - `inOut(easing: EasingFunction)`: Symmetrical easing function. 3137 + - `out(easing: EasingFunction)`: Runs an easing function backwards. 3138 + 3139 + ##### `callback` (Optional) 3140 + 3141 + A function called upon animation completion. If the animation is canceled, it receives `false`; otherwise, it receives `true`. 3142 + 3143 + #### Returns 3144 + 3145 + `withTiming` returns an animation object representing the current state of the animation. It can be assigned to a shared value or used in a style object from `useAnimatedStyle`. 3146 + 3147 + ### Example 3148 + 3149 + ### Remarks 3150 + 3151 + - The callback passed as the third argument is automatically workletized and executed on the UI thread. 3152 + 3153 + ### Platform Compatibility 3154 + 3155 + |Android|iOS|Web| 3156 + |-|-|-| 3157 + |✅|✅|✅| 3158 + 3159 + ## Animating styles and props 5602 3160 5603 3161 In this section, we explore different methods for passing animation styles to components. We will differentiate between animating styles and props using `useAnimatedStyle` and `useAnimatedProps`. 5604 3162 ··· 5794 3352 |-|-|-| 5795 3353 |✅|✅|✅| 5796 3354 5797 - ## Run On JS 5798 - 5799 - The `runOnJS` function allows you to asynchronously execute functions that are not workletized on the UI thread. This is particularly useful for most external libraries, as their functions typically lack the `"worklet"` directive. 3355 + ## runOnUI 5800 3356 5801 - `runOnJS` is commonly used to update React state either after an animation completes or conditionally within a gesture interaction. 3357 + The `runOnUI` function allows you to asynchronously execute workletized functions on the UI thread. It is commonly used within an `useEffect` for initiating animations upon component mount or unmount, as well as with `measure` and `scrollTo` functions that are implemented solely on the UI thread. 5802 3358 5803 3359 ### Reference 5804 3360 5805 3361 ```typescript 5806 - import { runOnJS } from "react-native-reanimated" 3362 + import { runOnUI } from "react-native-reanimated" 5807 3363 5808 3364 function App() { 5809 - // Executing on the UI thread 5810 - runOnJS(navigation.goBack)() 3365 + // Example usage in an event handler or effect 3366 + runOnUI((greeting: string) => { 3367 + console.log(`${greeting} from the UI thread`) 3368 + })("Howdy") 3369 + 3370 + // ... 5811 3371 } 5812 3372 ``` 5813 3373 5814 3374 #### Arguments 5815 3375 5816 - ##### `fn` 3376 + ##### fn 5817 3377 5818 - A reference to a function you wish to execute on the JavaScript thread from the UI thread. Any arguments for your function must be passed to the function returned by `runOnJS`, e.g., `runOnJS(setValue)(10);`. 3378 + A reference to a function intended for execution on the UI thread, originating from the JavaScript thread. Any arguments required by your function must be passed to the function returned by `runOnUI`, e.g., `runOnUI(myWorklet)(10)`. 5819 3379 5820 3380 #### Returns 5821 3381 5822 - `runOnJS` returns a function that accepts arguments for the original function provided as its first argument. This returned function can be safely executed on the UI thread. 3382 + `runOnUI` returns a function that accepts arguments for the initially provided function. 5823 3383 5824 - **Note:** Ensure you call the function returned from `runOnJS`. 3384 + **Note:** Ensure you invoke the function returned from `runOnUI`. 5825 3385 5826 3386 ### Example 5827 3387 5828 3388 ### Remarks 5829 3389 5830 - - Functions passed to `runOnJS` must be defined within the JavaScript thread scope, such as in a component body or global scope. The following code will not work because `myFunction` is defined inside the `withTiming` callback, which runs on the UI thread: 3390 + - When creating animations, prioritize more general solutions such as `useDerivedValue`, `useAnimatedReaction`, or executing code within gesture callbacks. Resort to using `runOnUI` only after exploring these alternatives. 5831 3391 5832 - ```typescript 5833 - withTiming(0, {}, () => { 5834 - // myFunction is defined on the UI thread 🚨 5835 - const myFunction = () => { 5836 - // ... 5837 - } 5838 - runOnJS(myFunction)() // 💥 5839 - }) 5840 - ``` 3392 + - A common error is attempting to execute a function inside of `runOnUI` like this: ~~`runOnUI(myWorklet(10))()`~~. The correct usage should be `runOnUI(myWorklet)(10)`. 5841 3393 5842 - - A common mistake is to execute a function inside `runOnJS` like this: ~~`runOnJS(setValue(10))()`~~. The correct usage would be `runOnJS(setValue)(10)`. 3394 + - The callback provided as an argument is automatically workletized, making it ready for execution on the UI thread. 5843 3395 5844 - - It's safe to run functions via `runOnJS` on the JavaScript thread, as it has no adverse effects. 3396 + - Avoid executing `runOnUI` directly on the UI thread to prevent errors. 5845 3397 5846 3398 ### Platform Compatibility 5847 3399 ··· 5849 3401 |-|-|-| 5850 3402 |✅|✅|✅| 5851 3403 5852 - ## runOnUI 3404 + ## runOnRuntime 5853 3405 5854 - The `runOnUI` function allows you to asynchronously execute workletized functions on the UI thread. It is commonly used within an `useEffect` for initiating animations upon component mount or unmount, as well as with `measure` and `scrollTo` functions that are implemented solely on the UI thread. 3406 + The `runOnRuntime` function allows you to execute workletized functions asynchronously on a separate worklet runtime, which operates on a different thread. 5855 3407 5856 3408 ### Reference 5857 3409 5858 3410 ```typescript 5859 - import { runOnUI } from "react-native-reanimated" 3411 + import { createWorkletRuntime, runOnRuntime } from "react-native-reanimated" 3412 + 3413 + const workletRuntime = createWorkletRuntime("background") 5860 3414 5861 3415 function App() { 5862 3416 // Example usage in an event handler or effect 5863 - runOnUI((greeting: string) => { 5864 - console.log(`${greeting} from the UI thread`) 3417 + runOnRuntime(workletRuntime, (greeting) => { 3418 + console.log(`${greeting} from a separate thread`) 5865 3419 })("Howdy") 5866 3420 5867 3421 // ... ··· 5869 3423 ``` 5870 3424 5871 3425 #### Arguments 3426 + 3427 + ##### workletRuntime 3428 + 3429 + A reference to the worklet runtime created using `createWorkletRuntime`. 5872 3430 5873 3431 ##### fn 5874 3432 5875 - A reference to a function intended for execution on the UI thread, originating from the JavaScript thread. Any arguments required by your function must be passed to the function returned by `runOnUI`, e.g., `runOnUI(myWorklet)(10)`. 3433 + A function intended for execution on the UI thread from the JavaScript thread. The arguments for this function must be passed to the function returned by `runOnUI`, e.g., `runOnUI(myWorklet)(10)`. 5876 3434 5877 3435 #### Returns 5878 3436 5879 - `runOnUI` returns a function that accepts arguments for the initially provided function. 5880 - 5881 - **Note:** Ensure you invoke the function returned from `runOnUI`. 3437 + `runOnRuntime` returns a function that accepts arguments for the function provided as its first argument. 5882 3438 5883 - ### Example 3439 + **Note:** Ensure you call the function returned from `runOnRuntime`. 5884 3440 5885 3441 ### Remarks 5886 3442 5887 - - When creating animations, prioritize more general solutions such as `useDerivedValue`, `useAnimatedReaction`, or executing code within gesture callbacks. Resort to using `runOnUI` only after exploring these alternatives. 3443 + - A common mistake is to execute a function inside of `runOnRuntime` incorrectly, such as: ~~`runOnRuntime(myWorklet(10))()`~~. The correct usage is `runOnRuntime(myWorklet)(10)`. 5888 3444 5889 - - A common error is attempting to execute a function inside of `runOnUI` like this: ~~`runOnUI(myWorklet(10))()`~~. The correct usage should be `runOnUI(myWorklet)(10)`. 3445 + - The callback passed as an argument will not be automatically workletized. You must manually add the `'worklet';` directive to enable execution on the UI thread. 5890 3446 5891 - - The callback provided as an argument is automatically workletized, making it ready for execution on the UI thread. 3447 + - `runOnRuntime` can be called on any runtime, including the RN runtime, UI runtime, and other worklet runtimes. 5892 3448 5893 - - Avoid executing `runOnUI` directly on the UI thread to prevent errors. 3449 + - The function provided to `runOnRuntime` is added to an execution queue on a separate thread and executed asynchronously on the specified worklet runtime. Functions are executed in the order they were queued. 5894 3450 5895 3451 ### Platform Compatibility 5896 3452 5897 3453 |Android|iOS|Web| 5898 3454 |-|-|-| 5899 - |✅|✅|✅| 3455 + |✅|✅|❌| 5900 3456 5901 - ## Your First Animation 3457 + ## Applying modifiers 5902 3458 5903 - This section introduces you to the basics of Reanimated. If you're new to this library, you'll find guidance on creating a simple animation that lays the foundation for more advanced skills. 3459 + Reanimated provides built-in modifiers for customizing animations: `withRepeat`, `withSequence`, and `withDelay`. This guide demonstrates how to use these modifiers by creating a shake animation. 5904 3460 5905 - ### Using an Animated Component 3461 + ### Starting Point 5906 3462 5907 - To start animating components in React Native using Reanimated, import the `Animated` object: 3463 + We'll create an animated box that shakes on button press after a delay. The setup involves using `useAnimatedStyle` and the `withTiming` function to move the box 40px to the right smoothly. 5908 3464 5909 3465 ```typescript 5910 - import Animated from "react-native-reanimated" 5911 - ``` 3466 + export default function App() { 3467 + const offset = useSharedValue<number>(0); 5912 3468 5913 - The `Animated` object wraps native components like `View`, `ScrollView`, or `FlatList`. Use these components as you would any other JSX component: 3469 + const style = useAnimatedStyle(() => ({ 3470 + transform: [{ translateX: offset.value }], 3471 + })); 5914 3472 5915 - ```typescript 5916 - import Animated from 'react-native-reanimated'; 3473 + const OFFSET = 40; 5917 3474 5918 - export default function App() { 3475 + const handlePress = () => { 3476 + offset.value = withTiming(OFFSET); 3477 + }; 3478 + 5919 3479 return ( 5920 - <Animated.View 5921 - style={{ 5922 - width: 100, 5923 - height: 100, 5924 - backgroundColor: 'violet', 5925 - }} 5926 - /> 3480 + <View style={styles.container}> 3481 + <Animated.View style={[styles.box, style]} /> 3482 + <Button title="shake" onPress={handlePress} /> 3483 + </View> 5927 3484 ); 5928 3485 } 5929 3486 ``` 5930 3487 5931 - ### Defining a Shared Value 3488 + ### Repeating an Animation 5932 3489 5933 - Shared values are essential for animations, acting like React state synchronized between JavaScript and the native side. Create shared values using `useSharedValue`: 3490 + To create a shake effect, use the `withRepeat` modifier. This allows you to repeat an animation multiple times or indefinitely. 5934 3491 5935 3492 ```typescript 5936 - import { useSharedValue } from "react-native-reanimated" 3493 + import { withRepeat } from "react-native-reanimated" 3494 + 3495 + function App() { 3496 + sv.value = withRepeat(withTiming(50), 5) 3497 + } 5937 3498 ``` 5938 3499 5939 - Define shared values within your component's body to store any JS value or data structure. 3500 + Pass a number for repetitions or a non-positive value for infinite repetition. Use `true` as the third argument to reverse the animation direction. 5940 3501 5941 - For example, set a default value of `100` for width in an `Animated.View`: 3502 + Updated example: 5942 3503 5943 3504 ```typescript 5944 - import Animated, { useSharedValue } from 'react-native-reanimated'; 3505 + export default function App() { 3506 + const offset = useSharedValue<number>(0); 3507 + 3508 + const style = useAnimatedStyle(() => ({ 3509 + transform: [{ translateX: offset.value }], 3510 + })); 3511 + 3512 + const OFFSET = 40; 5945 3513 5946 - export default function App() { 5947 - const width = useSharedValue(100); 3514 + const handlePress = () => { 3515 + offset.value = withRepeat(withTiming(OFFSET), 5, true); 3516 + }; 5948 3517 5949 3518 return ( 5950 - <Animated.View 5951 - style={{ 5952 - width, 5953 - height: 100, 5954 - backgroundColor: 'violet', 5955 - }} 5956 - /> 3519 + <View style={styles.container}> 3520 + <Animated.View style={[styles.box, style]} /> 3521 + <Button title="shake" onPress={handlePress} /> 3522 + </View> 5957 3523 ); 5958 3524 } 5959 3525 ``` 5960 3526 5961 - ### Using a Shared Value 5962 - 5963 - Create an animation that modifies the `width` of an element by `50px` on each button press. Modify the shared value connected to the `Animated.View`'s width property. 3527 + ### Running Animations in a Sequence 5964 3528 5965 - Access and modify values stored in shared values using their `.value` property: 3529 + To enhance the animation, use `withSequence` to chain animations. This modifier starts the next animation when the previous one ends. 5966 3530 5967 3531 ```typescript 5968 - import { Button, View } from 'react-native'; 5969 - import Animated, { useSharedValue } from 'react-native-reanimated'; 3532 + import { withSequence } from "react-native-reanimated" 5970 3533 5971 - export default function App() { 5972 - const width = useSharedValue(100); 3534 + function App() { 3535 + sv.value = withSequence(withTiming(50), withTiming(0)) 3536 + } 3537 + ``` 5973 3538 5974 - const handlePress = () => { 5975 - width.value = width.value + 50; 5976 - }; 3539 + Improved example: 5977 3540 5978 - return ( 5979 - <View style={{ flex: 1, alignItems: 'center' }}> 5980 - <Animated.View 5981 - style={{ 5982 - width, 5983 - height: 100, 5984 - backgroundColor: 'violet', 5985 - }} 5986 - /> 5987 - <Button onPress={handlePress} title="Click me" /> 5988 - </View> 5989 - ); 3541 + ```typescript 3542 + const TIME = 250 3543 + 3544 + const handlePress = () => { 3545 + offset.value = withSequence( 3546 + // start from -OFFSET 3547 + withTiming(-OFFSET, { duration: TIME / 2 }), 3548 + // shake between -OFFSET and OFFSET 5 times 3549 + withRepeat(withTiming(OFFSET, { duration: TIME }), 5, true), 3550 + // go back to 0 at the end 3551 + withTiming(0, { duration: TIME / 2 }) 3552 + ) 5990 3553 } 5991 3554 ``` 5992 3555 5993 - Avoid directly modifying shared values without using the `.value` property, as in `sv.value = sv.value + 100`. 5994 - 5995 - ### Using an Animation Function 3556 + ### Starting the Animation with Delay 5996 3557 5997 - To animate smoothly, import and use the `withSpring` function. Wrap it around the new width value to create a spring animation: 3558 + Add suspense by delaying the animation start using `withDelay`. 5998 3559 5999 3560 ```typescript 6000 - import { Button, View } from 'react-native'; 6001 - import Animated, { useSharedValue, withSpring } from 'react-native-reanimated'; 3561 + import { withDelay } from "react-native-reanimated" 3562 + 3563 + function App() { 3564 + sv.value = withDelay(500, withTiming(0)) 3565 + } 3566 + ``` 6002 3567 6003 - export default function App() { 6004 - const width = useSharedValue(100); 3568 + Final example: 6005 3569 6006 - const handlePress = () => { 6007 - width.value = withSpring(width.value + 50); 6008 - }; 3570 + ```typescript 3571 + const OFFSET = 40 3572 + const TIME = 250 3573 + const DELAY = 400 6009 3574 6010 - return ( 6011 - <View style={{ flex: 1, alignItems: 'center' }}> 6012 - <Animated.View 6013 - style={{ 6014 - width, 6015 - height: 100, 6016 - backgroundColor: 'violet', 6017 - }} 6018 - /> 6019 - <Button onPress={handlePress} title="Click me" /> 6020 - </View> 6021 - ); 3575 + const handlePress = () => { 3576 + offset.value = withDelay( 3577 + DELAY, 3578 + withSequence( 3579 + // start from -OFFSET 3580 + withTiming(-OFFSET, { duration: TIME / 2 }), 3581 + // shake between -OFFSET and OFFSET 5 times 3582 + withRepeat(withTiming(OFFSET, { duration: TIME }), 5, true), 3583 + // go back to 0 at the end 3584 + withTiming(0, { duration: TIME / 2 }) 3585 + ) 3586 + ) 6022 3587 } 6023 3588 ``` 6024 3589 6025 - This creates a bouncy spring animation for the element's width. 6026 - 6027 3590 ### Summary 6028 3591 6029 - In this section, you learned about: 6030 - 6031 - - `Animated` components to define animatable elements. 6032 - - Shared values as the driving factor of animations using `useSharedValue`. 6033 - - Accessing and modifying shared values via their `.value` property (e.g., `sv.value = 100;`). 6034 - - Creating smooth animations by modifying shared values with functions like `withSpring`. 3592 + - **Modifiers**: `withRepeat`, `withSequence`, and `withDelay`. 3593 + - **`withRepeat`**: Repeats an animation a specified number of times or indefinitely. 3594 + - **`withSequence`**: Chains animations to run sequentially. 3595 + - **`withDelay`**: Delays the start of an animation. 6035 3596 6036 3597 ### What's Next? 6037 3598 6038 - In the next section, you'll explore animating styles and props using `useAnimatedStyle` and `useAnimatedProps` hooks. 3599 + Explore handling `Tap` and `Pan` gestures, and learn about the `withDecay` animation function. 6039 3600 6040 3601 ## withDecay 6041 3602 ··· 6131 3692 |-|-|-| 6132 3693 |✅|✅|✅| 6133 3694 6134 - ## runOnRuntime 3695 + ## createWorkletRuntime 6135 3696 6136 - The `runOnRuntime` function allows you to execute workletized functions asynchronously on a separate worklet runtime, which operates on a different thread. 3697 + The `createWorkletRuntime` function allows for the creation of a new JavaScript runtime that can execute worklets on threads separate from the main JavaScript or UI thread. This functionality is intended primarily for use by third-party libraries integrating with worklets. The returned value represents this runtime and should be communicated to the C++ side via JSI (JavaScript Interface) for further operations. 6137 3698 6138 3699 ### Reference 3700 + 3701 + #### Usage in JavaScript 6139 3702 6140 3703 ```typescript 6141 - import { createWorkletRuntime, runOnRuntime } from "react-native-reanimated" 6142 - 6143 - const workletRuntime = createWorkletRuntime("background") 3704 + import { createWorkletRuntime } from "react-native-reanimated" 6144 3705 6145 3706 function App() { 6146 - // Example usage in an event handler or effect 6147 - runOnRuntime(workletRuntime, (greeting) => { 6148 - console.log(`${greeting} from a separate thread`) 6149 - })("Howdy") 6150 - 6151 - // ... 3707 + const runtime = createWorkletRuntime("background") 6152 3708 } 6153 3709 ``` 6154 3710 6155 - #### Arguments 3711 + #### Usage in C++ 6156 3712 6157 - ##### workletRuntime 3713 + ```cpp 3714 + auto runtime = reanimated::extractWorkletRuntime(rt, runtimeValue); 6158 3715 6159 - A reference to the worklet runtime created using `createWorkletRuntime`. 3716 + jsi::Runtime &rt = runtime->getJSIRuntime(); 6160 3717 6161 - ##### fn 3718 + auto worklet = reanimated::extractShareableOrThrow<reanimated::ShareableWorklet>(rt, workletValue); 6162 3719 6163 - A function intended for execution on the UI thread from the JavaScript thread. The arguments for this function must be passed to the function returned by `runOnUI`, e.g., `runOnUI(myWorklet)(10)`. 3720 + runtime->runGuarded(worklet, ...args); 3721 + ``` 6164 3722 6165 - #### Returns 3723 + #### Arguments 6166 3724 6167 - `runOnRuntime` returns a function that accepts arguments for the function provided as its first argument. 3725 + - **`name`**: A string identifier for the runtime that will appear in device lists within Chrome DevTools. 6168 3726 6169 - **Note:** Ensure you call the function returned from `runOnRuntime`. 3727 + - **`initializer`** (optional): A worklet executed synchronously on the same thread immediately after the runtime's creation. This can be used to inject global variables or functions into the runtime. 3728 + 3729 + #### Returns 3730 + 3731 + The `createWorkletRuntime` function returns a `WorkletRuntime`, which is represented as a `jsi::HostObject<reanimated::WorkletRuntime>`. 6170 3732 6171 3733 ### Remarks 6172 3734 6173 - - A common mistake is to execute a function inside of `runOnRuntime` incorrectly, such as: ~~`runOnRuntime(myWorklet(10))()`~~. The correct usage is `runOnRuntime(myWorklet)(10)`. 3735 + - Worklet runtimes include built-in support for `performance.now` and `console.*` methods. Other APIs are not available by default and must be injected or captured via worklet closures. 6174 3736 6175 - - The callback passed as an argument will not be automatically workletized. You must manually add the `'worklet';` directive to enable execution on the UI thread. 3737 + - In development mode, unhandled errors thrown within the runtime (excluding those in the `initializer`) will be caught, logged to the console, and displayed in a LogBox. 6176 3738 6177 - - `runOnRuntime` can be called on any runtime, including the RN runtime, UI runtime, and other worklet runtimes. 3739 + - Chrome DevTools can be used for debugging the runtime when using Hermes. The runtime appears in the devices list as specified by the `name` argument passed to `createWorkletRuntime`. 6178 3740 6179 - - The function provided to `runOnRuntime` is added to an execution queue on a separate thread and executed asynchronously on the specified worklet runtime. Functions are executed in the order they were queued. 3741 + - Shared values have limited support within worklet runtimes. To write to a shared value from the React Native (RN) runtime and read it on the worklet runtime, use `runOnRuntime`. Otherwise, updates will only reflect in the RN and UI runtimes. 6180 3742 6181 3743 ### Platform Compatibility 6182 3744 ··· 6184 3746 |-|-|-| 6185 3747 |✅|✅|❌| 6186 3748 6187 - ## Canceling Animations with `cancelAnimation` 3749 + ## interpolate 3750 + 3751 + The `interpolate` function is used to map a numeric value from one specified range to another using linear interpolation. 3752 + 3753 + ### Reference Usage 3754 + 3755 + ```typescript 3756 + import { interpolate, Extrapolation } from "react-native-reanimated" 3757 + 3758 + function App() { 3759 + const animatedStyle = useAnimatedStyle(() => ({ 3760 + opacity: interpolate(sv.value, [0, 100], [0, 1], Extrapolation.CLAMP), 3761 + })) 3762 + } 3763 + ``` 3764 + 3765 + #### Parameters 3766 + 3767 + - **`value`**: A numeric value that will be mapped to the specified `output` range. 3768 + 3769 + - **`input`**: An array of numbers defining the input range for interpolation. 3770 + 3771 + - **`output`**: An array of numbers defining the output range for interpolation, which should have at least as many points as the input range. 3772 + 3773 + - **`extrapolate` (Optional)**: Determines behavior when `value` is outside the `input` range. Defaults to `Extrapolation.EXTEND`. 3774 + 3775 + Available options: 3776 + 3777 + - `Extrapolation.EXTEND`: Predicts values beyond the output range. 3778 + - `Extrapolation.CLAMP`: Clamps the value to the edge of the output range. 3779 + - `Extrapolation.IDENTITY`: Returns the provided value unchanged. 3780 + 3781 + String equivalents include `"extend"`, `"clamp"`, and `"identity"`. 3782 + 3783 + To apply extrapolation to a specific edge, use an object: 3784 + 3785 + ```typescript 3786 + const opacity = interpolate(sv.value, [0, 100], [0, 1], { 3787 + extrapolateLeft: Extrapolation.CLAMP, 3788 + }) 3789 + ``` 3790 + 3791 + #### Return Value 3792 + 3793 + The `interpolate` function returns a value mapped within the specified output range. 3794 + 3795 + ### Platform Compatibility 3796 + 3797 + |Android|iOS|Web| 3798 + |-|-|-| 3799 + |✅|✅|✅| 3800 + 3801 + ## cancelAnimation 6188 3802 6189 3803 The `cancelAnimation` function is used to stop an ongoing animation associated with a shared value in React Native Reanimated. 6190 3804 ··· 6226 3840 6227 3841 This function is compatible across Android, iOS, and web platforms. 6228 3842 6229 - ## createWorkletRuntime 3843 + ## Clamp Function in React Native Reanimated 6230 3844 6231 - The `createWorkletRuntime` function allows for the creation of a new JavaScript runtime that can execute worklets on threads separate from the main JavaScript or UI thread. This functionality is intended primarily for use by third-party libraries integrating with worklets. The returned value represents this runtime and should be communicated to the C++ side via JSI (JavaScript Interface) for further operations. 3845 + The `clamp` function is used to restrict a value within a specified range, ensuring it does not exceed the defined minimum and maximum bounds. 6232 3846 6233 3847 ### Reference 6234 3848 6235 - #### Usage in JavaScript 3849 + ```typescript 3850 + import { clamp } from "react-native-reanimated" 3851 + 3852 + function App() { 3853 + const result = clamp(sv.value, 0, 100) 3854 + } 3855 + ``` 3856 + 3857 + #### Arguments 3858 + 3859 + - **`value`**: A numeric value that will be returned if it falls within the specified `min` and `max` range. 3860 + 3861 + - **`min`**: The lower bound. If the provided `value` is less than this number, `min` will be returned. 3862 + 3863 + - **`max`**: The upper bound. If the provided `value` exceeds this number, `max` will be returned. 3864 + 3865 + #### Returns 3866 + 3867 + The function returns a numeric value that lies between the specified `min` and `max` bounds. 3868 + 3869 + ### Example Usage 6236 3870 6237 3871 ```typescript 6238 - import { createWorkletRuntime } from "react-native-reanimated" 3872 + import { clamp } from "react-native-reanimated" 6239 3873 6240 3874 function App() { 6241 - const runtime = createWorkletRuntime("background") 3875 + const constrainedValue = clamp(150, 0, 100) // Result will be 100 6242 3876 } 6243 3877 ``` 6244 3878 6245 - #### Usage in C++ 3879 + ### Platform Compatibility 6246 3880 6247 - ```cpp 6248 - auto runtime = reanimated::extractWorkletRuntime(rt, runtimeValue); 3881 + |Android|iOS|Web| 3882 + |-|-|-| 3883 + |✅|✅|✅| 3884 + 3885 + This function is compatible across Android, iOS, and Web platforms. 3886 + 3887 + ## interpolateColor 3888 + 3889 + The `interpolateColor` function maps an input range to output colors using linear interpolation. This is particularly useful in animations where you want a smooth transition between colors. 3890 + 3891 + ### Reference Example 3892 + 3893 + ```typescript 3894 + import { interpolateColor } from 'react-native-reanimated'; 3895 + 3896 + function App() { 3897 + const progress = useSharedValue(0); 6249 3898 6250 - jsi::Runtime &rt = runtime->getJSIRuntime(); 3899 + const animatedStyle = useAnimatedStyle(() => { 3900 + return { 3901 + backgroundColor: interpolateColor( 3902 + progress.value, 3903 + [0, 1], 3904 + ['red', 'green'] 3905 + ), 3906 + }; 3907 + }); 6251 3908 6252 - auto worklet = reanimated::extractShareableOrThrow<reanimated::ShareableWorklet>(rt, workletValue); 3909 + // ... 6253 3910 6254 - runtime->runGuarded(worklet, ...args); 3911 + return <Animated.View style={[{ width: 100, height: 100 }, animatedStyle]} />; 3912 + } 6255 3913 ``` 6256 3914 6257 3915 #### Arguments 6258 3916 6259 - - **`name`**: A string identifier for the runtime that will appear in device lists within Chrome DevTools. 3917 + - **`value`**: A number from the input range that is mapped to the output range. 3918 + 3919 + - **`input`**: An array of numbers specifying the input range for interpolation. The values should be in increasing order. 3920 + 3921 + - **`output`**: An array of color strings (e.g., `'red'`, `'#ff0000'`, `'rgba(255, 0, 0, 0.5)'`) that define the output colors. It must have at least as many points as the input range. 6260 3922 6261 - - **`initializer`** (optional): A worklet executed synchronously on the same thread immediately after the runtime's creation. This can be used to inject global variables or functions into the runtime. 3923 + - **`colorSpace`** *(Optional)*: Specifies the color space for interpolation, either `'HSV'` or `'RGB'`. Defaults to `'RGB'`. 3924 + 3925 + - **`options`** *(Optional)*: Additional parameters for color interpolation: 3926 + 3927 + |Options|Type|Default|Description| 3928 + |-|-|-|-| 3929 + |`gamma`|`number`|2.2|Gamma parameter used in gamma correction.| 3930 + |`useCorrectedHSVInterpolation`|`boolean`|true|Reduces the number of hues during interpolation by treating HSV as circular.| 3931 + 3932 + #### Options Explanation 3933 + 3934 + - **Gamma**: Colors on web/mobile are typically expressed in sRGB, a gamma-corrected color space. Operations like addition can yield incorrect results if performed directly in this non-linear space. To address this, colors are converted to linear space for interpolation and then back to sRGB. The default gamma value of 2.2 is commonly used for this conversion. 3935 + 3936 + - **Use Corrected HSV Interpolation**: This option optimizes hue transitions by selecting the shortest path on a circular spectrum (e.g., transitioning from yellow to purple via red instead of green and blue). 6262 3937 6263 3938 #### Returns 6264 3939 6265 - The `createWorkletRuntime` function returns a `WorkletRuntime`, which is represented as a `jsi::HostObject<reanimated::WorkletRuntime>`. 3940 + The function returns an interpolated color in `rgba(r, g, b, a)` format within the specified output range. 6266 3941 6267 3942 ### Remarks 6268 3943 6269 - - Worklet runtimes include built-in support for `performance.now` and `console.*` methods. Other APIs are not available by default and must be injected or captured via worklet closures. 3944 + - The function operates similarly to the `interpolate` function but specifically outputs a color string in `rgba(r, g, b, a)` notation. 3945 + 3946 + ### Platform Compatibility 3947 + 3948 + |Android|iOS|Web| 3949 + |-|-|-| 3950 + |✅|✅|✅| 3951 + 3952 + This function is versatile and compatible across major platforms, making it ideal for cross-platform applications. 3953 + 3954 + ## withSequence 3955 + 3956 + `withSequence` is an animation modifier that allows animations to be executed in a sequential order. 3957 + 3958 + ### Reference 3959 + 3960 + ```typescript 3961 + import { withSequence } from "react-native-reanimated" 3962 + 3963 + function App() { 3964 + sv.value = withSequence(withTiming(50), withTiming(0)) 3965 + // ... 3966 + } 3967 + ``` 3968 + 3969 + #### Arguments 3970 + 3971 + ##### `reduceMotion` (Optional) 3972 + 3973 + A parameter that specifies how the animation should respond to the device's reduced motion accessibility setting. 3974 + 3975 + ##### `...animations` 3976 + 3977 + Any number of animation objects that will be executed in sequence. 3978 + 3979 + #### Returns 3980 + 3981 + The `withSequence` function returns an animation object representing the current state of the animation. This object can either be directly assigned to a shared value or used as a value for a style object returned from `useAnimatedStyle`. 3982 + 3983 + ### Example 3984 + 3985 + ### Platform Compatibility 3986 + 3987 + |Android|iOS|Web| 3988 + |-|-|-| 3989 + |✅|✅|✅| 6270 3990 6271 - - In development mode, unhandled errors thrown within the runtime (excluding those in the `initializer`) will be caught, logged to the console, and displayed in a LogBox. 3991 + ## scrollTo 6272 3992 6273 - - Chrome DevTools can be used for debugging the runtime when using Hermes. The runtime appears in the devices list as specified by the `name` argument passed to `createWorkletRuntime`. 3993 + The `scrollTo` function allows you to synchronously scroll a component to a specified X or Y offset. 6274 3994 6275 - - Shared values have limited support within worklet runtimes. To write to a shared value from the React Native (RN) runtime and read it on the worklet runtime, use `runOnRuntime`. Otherwise, updates will only reflect in the RN and UI runtimes. 3995 + ### Reference 3996 + 3997 + ```typescript 3998 + import { scrollTo } from 'react-native-reanimated'; 3999 + 4000 + function App() { 4001 + const animatedRef = useAnimatedRef(); 4002 + const scrollY = useSharedValue(0); 4003 + 4004 + useDerivedValue(() => { 4005 + scrollTo(animatedRef, 0, scrollY.value, true); 4006 + }); 4007 + 4008 + return ( 4009 + <Animated.ScrollView ref={animatedRef}>{/* ... */}</Animated.ScrollView> 4010 + ); 4011 + } 4012 + ``` 4013 + 4014 + #### Arguments 4015 + 4016 + - **`animatedRef`**: An animated reference linked to the ScrollView (or another scrollable) component you wish to scroll. This animated reference must be passed to either an Animated component or a React Native built-in component. 4017 + 4018 + - **`x`**: The pixel value for horizontal scrolling on the X axis. 4019 + 4020 + - **`y`**: The pixel value for vertical scrolling on the Y axis. 4021 + 4022 + - **`animated`**: A boolean indicating if the scroll should be smooth (`true`) or instant (`false`). 4023 + 4024 + #### Returns 4025 + 4026 + The `scrollTo` function returns `undefined`. 4027 + 4028 + ### Remarks 4029 + 4030 + - The `scrollTo` function must be invoked from the UI thread. 4031 + - It supports `Animated.FlatList`. 4032 + - Typically works with other ScrollView-like and FlatList-like components if they use a `ScrollView` internally and are animated. 4033 + - Scrollable components need to implement the `getScrollableNode` method (and `getNativeScrollRef` for New Architecture) to be compatible with `scrollTo`. 6276 4034 6277 4035 ### Platform Compatibility 6278 4036 6279 4037 |Android|iOS|Web| 6280 4038 |-|-|-| 6281 - |✅|✅|❌| 4039 + |✅|✅|✅| 4040 + 4041 + ## getRelativeCoords Functionality 4042 + 4043 + The `getRelativeCoords` function is used to determine the screen location relative to a specified view. 6282 4044 6283 - ```markdown 6284 - # `useAnimatedGestureHandler` 4045 + ### Reference Code 4046 + 4047 + ```typescript 4048 + import { getRelativeCoords } from 'react-native-reanimated'; 6285 4049 6286 - **Note:** This API has been deprecated. It no longer receives updates and will be removed in a future major release of Reanimated. 4050 + const Comp = () => { 4051 + const animatedRef = useAnimatedRef(); 6287 4052 6288 - ## Overview 4053 + const gestureHandler = useAnimatedGestureHandler({ 4054 + onEnd: (event) => { 4055 + const coords = getRelativeCoords( 4056 + animatedRef, 4057 + event.absoluteX, 4058 + event.absoluteY 4059 + ); 4060 + }, 4061 + }); 6289 4062 6290 - The `useAnimatedGestureHandler` function is part of the Reanimated library, which provides tools for creating smooth animations on React Native applications. However, due to its deprecation status, developers are advised to seek alternative solutions or APIs that offer similar functionality but with ongoing support and updates. 4063 + return ( 4064 + <View ref={animatedRef}> 4065 + <PanGestureHandler onGestureEvent={gestureHandler}> 4066 + <Animated.View style={[styles.box]} /> 4067 + </PanGestureHandler> 4068 + </View> 4069 + ); 4070 + }; 6291 4071 ``` 6292 4072 6293 - ## Applying Modifiers in Reanimated 4073 + ### Arguments 4074 + 4075 + - **`animatedRef`**: This is the result of `useAnimatedRef`, which extends a standard React ref to deliver the view tag on the UI thread. It should be passed as a prop to the view relative to which coordinates are needed. 4076 + 4077 + - **`absoluteX`**: A number representing the absolute x-coordinate. 4078 + 4079 + - **`absoluteY`**: A number representing the absolute y-coordinate. 6294 4080 6295 - Reanimated provides built-in modifiers for customizing animations: `withRepeat`, `withSequence`, and `withDelay`. This guide demonstrates how to use these modifiers by creating a shake animation. 4081 + ### Returns 6296 4082 6297 - ### Starting Point 4083 + An object containing: 6298 4084 6299 - We'll create an animated box that shakes on button press after a delay. The setup involves using `useAnimatedStyle` and the `withTiming` function to move the box 40px to the right smoothly. 4085 + - `x`: The relative x-coordinate. 4086 + - `y`: The relative y-coordinate. 4087 + 4088 + ### Platform Compatibility 4089 + 4090 + |Android|iOS|Web| 4091 + |-|-|-| 4092 + |✅|✅|✅| 4093 + 4094 + ## useAnimatedGestureHandler 4095 + 4096 + **Warning:**\ 4097 + The `useAnimatedGestureHandler` hook allows for the creation of animations based on gesture handlers. It is essential to provide the object created by this hook to the `onGestureEvent` property of a gesture handler component. 4098 + 4099 + This hook necessitates that `react-native-gesture-handler` be installed and configured within your project. 4100 + 4101 + ### Reference 4102 + 4103 + ```typescript 4104 + import { useAnimatedGestureHandler } from 'react-native-reanimated'; 4105 + import { PanGestureHandler } from 'react-native-gesture-handler'; 4106 + 4107 + function App() { 4108 + const x = useSharedValue(0); 4109 + 4110 + const gestureHandler = useAnimatedGestureHandler({ 4111 + onStart: (_, ctx) => { 4112 + ctx.startX = x.value; 4113 + }, 4114 + onActive: (event, ctx) => { 4115 + x.value = ctx.startX + event.translationX; 4116 + }, 4117 + }); 4118 + 4119 + return ( 4120 + <PanGestureHandler onGestureEvent={gestureHandler}> 4121 + <Animated.View /> 4122 + </PanGestureHandler> 4123 + ); 4124 + } 4125 + ``` 4126 + 4127 + #### Arguments 4128 + 4129 + ##### `gestureHandlers` 4130 + 4131 + The primary argument is an object that can include one or more handlers. These handlers are set under the following keys: `onStart`, `onActive`, `onEnd`, `onFail`, `onCancel`, and `onFinish`. 4132 + 4133 + Each handler will be activated based on the current state of the associated gesture handler. For further details, refer to the Gesture Handler documentation. The handler receives: 4134 + 4135 + - `event` \[object] - an event object containing the payload specific to the type of gesture handler (e.g., `PanGestureHandler`, `RotationGestureHandler`). 4136 + 4137 + - `context` \[object] - a JavaScript object for storing state information. This context can be read and modified, persisting between events and across handlers for all selected states. 4138 + 4139 + ##### `dependencies` (Optional) 4140 + 4141 + An optional array of dependencies is relevant only when using Reanimated without the Babel plugin on the Web. 4142 + 4143 + #### Returns 4144 + 4145 + The `useAnimatedGestureHandler` hook returns a handler object that can be attached to gesture handler components from the `react-native-gesture-handler` library. This object must be passed to the `onGestureEvent` property of a gesture handler component. 4146 + 4147 + ### Example 4148 + 4149 + ### Platform Compatibility 4150 + 4151 + |Android|iOS|Web| 4152 + |-|-|-| 4153 + |✅|✅|⚠️| 4154 + 4155 + - On the Web, it is necessary to pass the returned handler object to both `onGestureEvent` and `onHandlerStateChange` parameters. 4156 + 4157 + ## useScrollViewOffset Hook 4158 + 4159 + The `useScrollViewOffset` hook enables the creation of animations based on a `ScrollView`'s offset. It automatically determines whether the `ScrollView` is oriented horizontally or vertically. 4160 + 4161 + ### Reference 4162 + 4163 + ```typescript 4164 + import { useAnimatedRef, useScrollViewOffset } from 'react-native-reanimated'; 4165 + 4166 + function App() { 4167 + const animatedRef = useAnimatedRef(); 4168 + const scrollOffset = useScrollViewOffset(animatedRef); 4169 + 4170 + return ( 4171 + <Animated.ScrollView ref={animatedRef}> 4172 + {/* Content goes here */} 4173 + </Animated.ScrollView> 4174 + ); 4175 + } 4176 + ``` 4177 + 4178 + #### Arguments 4179 + 4180 + ##### `animatedRef` 4181 + 4182 + An animated reference linked to the `ScrollView` component you wish to monitor. This animated reference must be assigned either to an Animated component or a React Native built-in component. 4183 + 4184 + ##### `initialRef` (Optional) 4185 + 4186 + A shared value that can optionally be updated with the scroll offset. If not provided, a new shared value will be created internally by default. 4187 + 4188 + #### Returns 4189 + 4190 + The hook returns a shared value representing the current offset of the `ScrollView`. 4191 + 4192 + ### Example Usage 4193 + 4194 + - The `animatedRef` argument can be dynamically changed, and the hook will continue to provide accurate values based on the connected `ScrollView`. For instance: 4195 + 4196 + ```typescript 4197 + useScrollViewOffset(someState ? someScrollRefA : someScrollRefB) 4198 + ``` 4199 + 4200 + ### Platform Compatibility 4201 + 4202 + |Android|iOS|Web| 4203 + |-|-|-| 4204 + |✅|✅|✅| 4205 + 4206 + ## measure 4207 + 4208 + The `measure` function allows you to synchronously obtain the dimensions and position of a view on the screen, executed on the UI thread. 4209 + 4210 + ### Reference 4211 + 4212 + ```typescript 4213 + import { measure } from 'react-native-reanimated'; 4214 + 4215 + function App() { 4216 + const animatedRef = useAnimatedRef(); 4217 + 4218 + const handlePress = () => { 4219 + runOnUI(() => { 4220 + const measurement = measure(animatedRef); 4221 + if (measurement === null) { 4222 + return; 4223 + } 4224 + // Additional logic can be added here 4225 + })(); 4226 + }; 4227 + 4228 + return <Animated.View ref={animatedRef} />; 4229 + } 4230 + ``` 4231 + 4232 + #### Arguments 4233 + 4234 + - **`animatedRef`**: An animated reference linked to the component whose measurements are desired. This reference must be associated with either an Animated component or a React Native built-in component. 4235 + 4236 + #### Returns 4237 + 4238 + The `measure` function returns an object containing: 4239 + 4240 + |Field|Description| 4241 + |-|-| 4242 + |`x`|A number representing the X coordinate relative to the parent component.| 4243 + |`y`|A number representing the Y coordinate relative to the parent component.| 4244 + |`width`|A number representing the width of the component.| 4245 + |`height`|A number representing the height of the component.| 4246 + |`pageX`|A number representing the X coordinate relative to the screen.| 4247 + |`pageY`|A number representing the Y coordinate relative to the screen.| 4248 + 4249 + Alternatively, it returns `null` if the measurement could not be performed. 4250 + 4251 + ### Remarks 4252 + 4253 + - **UI Thread Execution**: The `measure` function operates exclusively on the UI thread. When used within event handlers, it must be wrapped with the `runOnUI` function. 4254 + 4255 + - **Use in `useAnimatedStyle`**: Since `useAnimatedStyle` is initially evaluated on the JavaScript thread before views are attached to the native side, a condition like the following should be included: 4256 + 4257 + ```typescript 4258 + function App() { 4259 + const animatedStyles = useAnimatedStyle(() => { 4260 + if (_WORKLET) { 4261 + // Safely use measure here 4262 + const measurement = measure(animatedRef) 4263 + } 4264 + }) 4265 + } 4266 + ``` 4267 + 4268 + - **Consecutive Runs**: Subsequent executions of `useAnimatedStyle` occur on the UI thread. 4269 + 4270 + - **Alternative for Static Dimensions**: If only static dimensions are needed and measurements aren't used during animations, consider using the `onLayout` property instead. 4271 + 4272 + - **Null Check**: It's advisable to check if the measurement result is `null`, as it may happen when the reference hasn't yet attached to a view: 4273 + 4274 + ```typescript 4275 + const animatedRef = useAnimatedRef() 4276 + 4277 + const handlePress = () => { 4278 + runOnUI(() => { 4279 + const measurement = measure(animatedRef) 4280 + 4281 + if (measurement === null) { 4282 + return 4283 + } 4284 + // Additional logic can be added here 4285 + })() 4286 + } 4287 + ``` 4288 + 4289 + - **Rendered Components Only**: `measure` is applicable only to rendered components. For example, measuring off-screen items in a `FlatList` will yield `null`. 4290 + 4291 + - **Debugger Compatibility**: The `measure` function isn't available with the Remote JS Debugger. It's recommended to use Chrome DevTools (`chrome://inspect`) for debugging React Native applications. 4292 + 4293 + ### Platform Compatibility 4294 + 4295 + |Android|iOS|Web| 4296 + |-|-|-| 4297 + |✅|✅|✅| 4298 + 4299 + ## useAnimatedReaction 4300 + 4301 + The `useAnimatedReaction` hook enables responses to changes in shared values, particularly useful when comparing previous and current values stored within a shared value. 4302 + 4303 + ### Reference 4304 + 4305 + ```typescript 4306 + import { useAnimatedReaction } from "react-native-reanimated" 4307 + 4308 + function App() { 4309 + useAnimatedReaction( 4310 + () => sv.value, 4311 + (currentValue, previousValue) => { 4312 + if (currentValue !== previousValue) { 4313 + // perform an action ✨ 4314 + } 4315 + } 4316 + ) 4317 + 4318 + // ... 4319 + } 4320 + ``` 4321 + 4322 + #### Arguments 4323 + 4324 + ##### `prepare` 4325 + 4326 + A function returning the value to which you want to react. This returned value serves as the first parameter for the `react` argument. 4327 + 4328 + ```typescript 4329 + function App() { 4330 + useAnimatedReaction( 4331 + () => Math.floor(sv.value), 4332 + (currentValue, previousValue) => { 4333 + // ... 4334 + } 4335 + ) 4336 + } 4337 + ``` 4338 + 4339 + ##### `react` 4340 + 4341 + A function that responds to changes in the value provided by the `prepare` function. It receives two parameters: the current value from `prepare` and the previous value, initially set to `null`. 4342 + 4343 + ```typescript 4344 + function App() { 4345 + useAnimatedReaction( 4346 + () => Math.floor(sv.value), 4347 + (currentValue, previousValue) => { 4348 + // ... 4349 + } 4350 + ) 4351 + } 4352 + ``` 4353 + 4354 + ##### `dependencies` (Optional) 4355 + 4356 + An optional array of dependencies. This is only relevant when using Reanimated without the Babel plugin on the Web. 4357 + 4358 + #### Returns 4359 + 4360 + The `useAnimatedReaction` hook returns `undefined`. 4361 + 4362 + ### Example 4363 + 4364 + ### Remarks 4365 + 4366 + - Avoid mutating the same shared value in the `react` function that was used in the `prepare` function to prevent infinite loops. 4367 + 4368 + ```typescript 4369 + function App() { 4370 + useAnimatedReaction( 4371 + () => width.value, 4372 + (currentValue) => { 4373 + // 🚨 An infinite loop! 4374 + width.value += currentValue 4375 + } 4376 + ) 4377 + } 4378 + ``` 4379 + 4380 + - Callbacks for both `prepare` and `react` are automatically workletized, running on the UI thread. 4381 + 4382 + - While you can use `useAnimatedReaction` to react to any stateful React value, it's generally better to use a `useEffect` for such purposes. 4383 + 4384 + ### Platform Compatibility 4385 + 4386 + |Android|iOS|Web| 4387 + |-|-|-| 4388 + |✅|✅|✅| 4389 + 4390 + ## Animating styles and props 4391 + 4392 + In this section, we explore different methods for passing animation styles to components. We will differentiate between animating styles and props using `useAnimatedStyle` and `useAnimatedProps`. 4393 + 4394 + ### Animating Styles 4395 + 4396 + Previously, we learned about simple animations and shared values. While inline styling works well in basic cases, it has limitations, such as not allowing access to the value stored in a shared value for complex operations. 4397 + 4398 + ```typescript 4399 + import Animated, { useSharedValue } from 'react-native-reanimated'; 4400 + 4401 + function App() { 4402 + const width = useSharedValue(100); 4403 + 4404 + return <Animated.View style={{ width }} />; 4405 + } 4406 + ``` 4407 + 4408 + For example, multiplying a shared value before assigning it to the `style` prop is not possible: 4409 + 4410 + ```typescript 4411 + <Animated.View style={{ width: width * 5 }} /> // This won't work 4412 + ``` 4413 + 4414 + Consider an example where a box moves right on button press: 4415 + 4416 + ```typescript 4417 + import { View, Button } from 'react-native'; 4418 + import Animated, { useSharedValue, withSpring } from 'react-native-reanimated'; 4419 + 4420 + function App() { 4421 + const translateX = useSharedValue(0); 4422 + 4423 + const handlePress = () => { 4424 + translateX.value = withSpring(translateX.value + 50); 4425 + }; 4426 + 4427 + return ( 4428 + <View style={styles.container}> 4429 + <Animated.View style={[styles.box, { transform: [{ translateX }] }]} /> 4430 + <Button onPress={handlePress} title="Click me" /> 4431 + </View> 4432 + ); 4433 + } 4434 + ``` 4435 + 4436 + To customize shared value changes based on user input, `useAnimatedStyle` is used for more control and flexibility: 6300 4437 6301 4438 ```typescript 6302 4439 export default function App() { 6303 - const offset = useSharedValue<number>(0); 4440 + const translateX = useSharedValue<number>(0); 4441 + 4442 + const handlePress = () => { 4443 + translateX.value += 50; 4444 + }; 6304 4445 6305 - const style = useAnimatedStyle(() => ({ 6306 - transform: [{ translateX: offset.value }], 4446 + const animatedStyles = useAnimatedStyle(() => ({ 4447 + transform: [{ translateX: withSpring(translateX.value * 2) }], 6307 4448 })); 6308 4449 6309 - const OFFSET = 40; 4450 + return ( 4451 + <> 4452 + <Animated.View style={[styles.box, animatedStyles]} /> 4453 + <View style={styles.container}> 4454 + <Button onPress={handlePress} title="Click me" /> 4455 + </View> 4456 + </> 4457 + ); 4458 + } 4459 + ``` 4460 + 4461 + `useAnimatedStyle` allows access to the shared value's `.value`, enabling operations like multiplication before assigning it to `style`. It also centralizes animation logic. 4462 + 4463 + ### Animating Props 4464 + 4465 + While many values are animated via the `style` property, sometimes props need animating. For example, SVG elements use props instead of styles: 4466 + 4467 + ```typescript 4468 + <Circle cx="50" cy="50" r="10" fill="blue" /> 4469 + ``` 4470 + 4471 + To animate non-Reanimated components' props, wrap them with `createAnimatedComponent`: 4472 + 4473 + ```typescript 4474 + import Animated from "react-native-reanimated" 4475 + import { Circle } from "react-native-svg" 4476 + 4477 + const AnimatedCircle = Animated.createAnimatedComponent(Circle) 4478 + ``` 4479 + 4480 + Animating the radius of an SVG circle can be done by passing a shared value as a prop: 4481 + 4482 + ```typescript 4483 + import { useSharedValue } from 'react-native-reanimated'; 4484 + import { Svg } from 'react-native-svg'; 4485 + 4486 + function App() { 4487 + const r = useSharedValue(10); 4488 + 4489 + return ( 4490 + <Svg> 4491 + <AnimatedCircle cx="50" cy="50" r={r} fill="blue" /> 4492 + </Svg> 4493 + ); 4494 + } 4495 + ``` 4496 + 4497 + For encapsulating animation logic and accessing `.value`, `useAnimatedProps` is used: 4498 + 4499 + ```typescript 4500 + const AnimatedCircle = Animated.createAnimatedComponent(Circle); 4501 + 4502 + export default function App() { 4503 + const r = useSharedValue<number>(20); 6310 4504 6311 4505 const handlePress = () => { 6312 - offset.value = withTiming(OFFSET); 4506 + r.value += 10; 6313 4507 }; 6314 4508 4509 + const animatedProps = useAnimatedProps(() => ({ 4510 + r: withTiming(r.value), 4511 + })); 4512 + 6315 4513 return ( 6316 4514 <View style={styles.container}> 6317 - <Animated.View style={[styles.box, style]} /> 6318 - <Button title="shake" onPress={handlePress} /> 4515 + <Svg style={styles.svg}> 4516 + <AnimatedCircle 4517 + cx="50%" 4518 + cy="50%" 4519 + fill="#b58df1" 4520 + animatedProps={animatedProps} 4521 + /> 4522 + </Svg> 4523 + <Button onPress={handlePress} title="Click me" /> 6319 4524 </View> 6320 4525 ); 6321 4526 } 6322 4527 ``` 6323 4528 6324 - ### Repeating an Animation 4529 + In `useAnimatedProps`, return an object with animatable props, then pass it to the `animatedProps` prop of an Animated component. 6325 4530 6326 - To create a shake effect, use the `withRepeat` modifier. This allows you to repeat an animation multiple times or indefinitely. 4531 + ### Summary 4532 + 4533 + - Inline styles are simple but limited for complex animations. 4534 + - Props differ from styles as they aren't passed via the `style` object. 4535 + - `useAnimatedStyle` and `useAnimatedProps` provide access to shared values' `.value`, enhancing animation control. 4536 + - Custom animatable components can be created with `Animated.createAnimatedComponent`. 4537 + 4538 + ### What's Next? 4539 + 4540 + In the next section, we'll delve into animation functions and customizing their behavior. 4541 + 4542 + ## useFrameCallback in React Native Reanimated (Version: 3.x) 4543 + 4544 + ### Overview 4545 + 4546 + The `useFrameCallback` hook allows you to execute a function on every frame update within your application. 4547 + 4548 + ### Reference 6327 4549 6328 4550 ```typescript 6329 - import { withRepeat } from "react-native-reanimated" 4551 + import { useFrameCallback } from 'react-native-reanimated'; 6330 4552 6331 4553 function App() { 6332 - sv.value = withRepeat(withTiming(50), 5) 4554 + const frameCallback = useFrameCallback((frameInfo) => { 4555 + // Increment a value with each frame update 4556 + sv.value += 1; 4557 + }); 4558 + 4559 + return ( 4560 + <Button 4561 + title="Start/Stop" 4562 + onPress={() => frameCallback.setActive(!frameCallback.isActive)} 4563 + /> 4564 + ); 6333 4565 } 6334 4566 ``` 6335 4567 6336 - Pass a number for repetitions or a non-positive value for infinite repetition. Use `true` as the third argument to reverse the animation direction. 4568 + #### Arguments 6337 4569 6338 - Updated example: 4570 + ##### `callback` 4571 + 4572 + - A function that runs on every frame update. 4573 + - Receives a `frameInfo` object with the following properties: 4574 + - `timestamp`: The system time (in milliseconds) when the last frame was rendered. 4575 + - `timeSincePreviousFrame`: Time (in milliseconds) since the previous frame. This is `null` for the first frame after activation and approximately 16 ms on a 60 Hz display or 8 ms on a 120 Hz display, assuming no frames are dropped. 4576 + - `timeSinceFirstFrame`: The time (in milliseconds) elapsed since the callback was activated. 4577 + 4578 + ##### `autostart` (Optional) 4579 + 4580 + - Determines if the callback should start automatically. Defaults to `true`. 4581 + 4582 + #### Returns 4583 + 4584 + The `useFrameCallback` hook returns an object with these properties: 4585 + 4586 + - `setActive`: A function to start or stop the frame callback. 4587 + - `isActive`: A boolean indicating whether the callback is currently running. 4588 + - `callbackId`: A unique identifier for the frame callback. 4589 + 4590 + ### Remarks 4591 + 4592 + - The function provided in the `callback` argument is automatically workletized and executed on the UI thread. 4593 + 4594 + ### Platform Compatibility 4595 + 4596 + |Android|iOS|Web| 4597 + |-|-|-| 4598 + |✅|✅|✅| 4599 + 4600 + - Reference 4601 + - Arguments 4602 + - Returns 4603 + - Example 4604 + - Remarks 4605 + - Platform compatibility 4606 + 4607 + ## Handling gestures 4608 + 4609 + This section covers handling gestures using Reanimated in conjunction with React Native Gesture Handler. We'll focus on `Tap` and `Pan` gestures and introduce the `withDecay` animation function. 4610 + 4611 + Ensure you've completed the Gesture Handler installation steps before proceeding. 4612 + 4613 + ### Handling Tap Gestures 4614 + 4615 + We begin with tap gestures, which detect brief screen touches. These can be used for custom buttons or pressable elements. 4616 + 4617 + In this example, a circle grows and changes color upon touch. 4618 + 4619 + First, wrap your app in `GestureHandlerRootView` to ensure gesture functionality: 4620 + 4621 + ```typescript 4622 + import { GestureHandlerRootView } from 'react-native-gesture-handler'; 4623 + 4624 + function App() { 4625 + return ( 4626 + <GestureHandlerRootView style={{ flex: 1 }}> 4627 + {/* rest of the app */} 4628 + </GestureHandlerRootView> 4629 + ); 4630 + } 4631 + ``` 4632 + 4633 + Define tap gestures using `Gesture.Tap()` and chain methods like `onBegin`, `onStart`, `onEnd`, or `onFinalize` to update shared values: 6339 4634 6340 4635 ```typescript 6341 4636 export default function App() { 6342 - const offset = useSharedValue<number>(0); 4637 + const pressed = useSharedValue<boolean>(false); 6343 4638 6344 - const style = useAnimatedStyle(() => ({ 6345 - transform: [{ translateX: offset.value }], 6346 - })); 4639 + const tap = Gesture.Tap() 4640 + .onBegin(() => { 4641 + pressed.value = true; 4642 + }) 4643 + .onFinalize(() => { 4644 + pressed.value = false; 4645 + }); 4646 + ``` 6347 4647 6348 - const OFFSET = 40; 4648 + Access shared values safely as gesture callbacks are automatically workletized. 4649 + 4650 + Define animation logic using `withTiming` in `useAnimatedStyle`: 4651 + 4652 + ```typescript 4653 + const animatedStyles = useAnimatedStyle(() => ({ 4654 + backgroundColor: pressed.value ? "#FFE04B" : "#B58DF1", 4655 + transform: [{ scale: withTiming(pressed.value ? 1.2 : 1) }], 4656 + })) 4657 + ``` 6349 4658 6350 - const handlePress = () => { 6351 - offset.value = withRepeat(withTiming(OFFSET), 5, true); 6352 - }; 4659 + Pass the gesture to `GestureDetector` and apply `animatedStyles`: 6353 4660 4661 + ```typescript 6354 4662 return ( 6355 - <View style={styles.container}> 6356 - <Animated.View style={[styles.box, style]} /> 6357 - <Button title="shake" onPress={handlePress} /> 6358 - </View> 4663 + <GestureHandlerRootView style={styles.container}> 4664 + <View style={styles.container}> 4665 + <GestureDetector gesture={tap}> 4666 + <Animated.View style={[styles.circle, animatedStyles]} /> 4667 + </GestureDetector> 4668 + </View> 4669 + </GestureHandlerRootView> 6359 4670 ); 6360 4671 } 6361 4672 ``` 6362 4673 6363 - ### Running Animations in a Sequence 4674 + ### Handling Pan Gestures 4675 + 4676 + Enhance the circle by making it draggable and bouncing back to its starting position upon release. Retain color highlight and scale effects. 4677 + 4678 + Switch from `Tap` to `Pan` gesture and add an `onChange` method: 4679 + 4680 + ```typescript 4681 + const offset = useSharedValue<number>(0); 4682 + 4683 + const pan = Gesture.Pan() 4684 + .onBegin(() => { 4685 + pressed.value = true; 4686 + }) 4687 + .onChange((event) => { 4688 + offset.value = event.translationX; 4689 + }) 4690 + .onFinalize(() => { 4691 + offset.value = withSpring(0); 4692 + pressed.value = false; 4693 + ``` 6364 4694 6365 - To enhance the animation, use `withSequence` to chain animations. This modifier starts the next animation when the previous one ends. 4695 + Use `translationX` from the event data to move the circle. Reset `offset.value` in `onFinalize` using `withSpring`. 4696 + 4697 + Adjust `useAnimatedStyle` for handling offset: 6366 4698 6367 4699 ```typescript 6368 - import { withSequence } from "react-native-reanimated" 4700 + const animatedStyles = useAnimatedStyle(() => ({ 4701 + transform: [ 4702 + { translateX: offset.value }, 4703 + { scale: withTiming(pressed.value ? 1.2 : 1) }, 4704 + ], 4705 + backgroundColor: pressed.value ? "#FFE04B" : "#b58df1", 4706 + })) 4707 + ``` 4708 + 4709 + ### Using `withDecay` 4710 + 4711 + `withDecay` retains gesture velocity for decelerating animations. 4712 + 4713 + Pass final velocity in `onFinalize` to `withDecay`: 4714 + 4715 + ```typescript 4716 + const pan = Gesture.Pan() 4717 + .onChange((event) => { 4718 + offset.value += event.changeX; 4719 + }) 4720 + .onFinalize((event) => { 4721 + offset.value = withDecay({ 4722 + velocity: event.velocityX, 4723 + rubberBandEffect: true, 4724 + clamp: [ 4725 + -(width.value / 2) + SIZE / 2 + BOUNDARY_OFFSET, 4726 + width.value / 2 - SIZE / 2 - BOUNDARY_OFFSET, 4727 + ``` 4728 + 4729 + Ensure the square stays within screen bounds. 4730 + 4731 + Explore `withDecay` API for more configuration options. 4732 + 4733 + ### Summary 4734 + 4735 + This section covered gesture handling with Reanimated and Gesture Handler, focusing on `Tap`, `Pan`, and `withDecay`. Key points include: 4736 + 4737 + - Integration of Reanimated with React Native Gesture Handler. 4738 + - Creation of gestures like `Gesture.Pan()` or `Gesture.Tap()`. 4739 + - Accessing shared values in gesture callbacks without extra boilerplate. 4740 + - Using `withDecay` for decelerating animations based on gesture velocity. 4741 + 4742 + ### What's Next? 4743 + 4744 + Explore further gestures such as Pinch and Fling by reviewing the React Native Gesture Handler documentation. The next section will delve into a glossary of terms. 4745 + 4746 + ## withRepeat 4747 + 4748 + `withRepeat` is an animation modifier that allows you to repeat a specified animation a certain number of times or indefinitely. 4749 + 4750 + ### Reference 4751 + 4752 + ```typescript 4753 + import { withRepeat } from "react-native-reanimated" 6369 4754 6370 4755 function App() { 6371 - sv.value = withSequence(withTiming(50), withTiming(0)) 4756 + sv.value = withRepeat(withSpring(0), 5) 4757 + // ... 6372 4758 } 6373 4759 ``` 6374 4760 6375 - Improved example: 4761 + #### Arguments 4762 + 4763 + ##### `animation` 4764 + 4765 + The animation object you wish to repeat. 4766 + 4767 + ##### `numberOfReps` (Optional) 4768 + 4769 + Specifies how many times the animation should be repeated. The default is `2`. 4770 + 4771 + A non-positive value, such as `0` or `-1`, will cause the animation to repeat indefinitely until it is canceled or removed. For instance, if the component unmounts or `cancelAnimation` is invoked. 4772 + 4773 + ##### `reverse` (Optional) 4774 + 4775 + Determines whether the animation should alternate directions with each repetition. The default setting is `false`. 4776 + 4777 + This feature only supports direct animation functions like `withSpring` and does not work with other animation modifiers such as `withSequence`. 4778 + 4779 + ##### `callback` (Optional) 4780 + 4781 + A function that executes upon the completion of the animation. If the animation is canceled, the callback receives `false`; otherwise, it receives `true`. 4782 + 4783 + ##### `reduceMotion` (Optional) 4784 + 4785 + Controls how the animation responds to the device's reduced motion accessibility setting. 4786 + 4787 + #### Returns 4788 + 4789 + The `withRepeat` function returns an animation object representing the current state of the animation. This can be directly assigned to a shared value or used as a style object returned from `useAnimatedStyle`. 4790 + 4791 + ### Remarks 4792 + 4793 + - The callback provided in the fourth argument is automatically workletized and executed on the UI thread. 4794 + 4795 + ### Platform Compatibility 4796 + 4797 + |Android|iOS|Web| 4798 + |-|-|-| 4799 + |✅|✅|✅| 4800 + 4801 + ## useComposedEventHandler 4802 + 4803 + The `useComposedEventHandler` hook allows you to combine multiple event handlers, such as those created with `useAnimatedScrollHandler`, into a single handler. 4804 + 4805 + ### Reference Example 6376 4806 6377 4807 ```typescript 6378 - const TIME = 250 4808 + import Animated, { 4809 + useAnimatedScrollHandler, 4810 + useComposedEventHandler, 4811 + } from 'react-native-reanimated'; 4812 + 4813 + function ComposedEventHandlerExample() { 4814 + const onScrollHandler1 = useAnimatedScrollHandler({ 4815 + onScroll(e) { 4816 + console.log('Scroll handler 1 onScroll event'); 4817 + }, 4818 + }); 4819 + 4820 + const onScrollHandler2 = useAnimatedScrollHandler({ 4821 + onScroll(e) { 4822 + console.log('Scroll handler 2 onScroll event'); 4823 + }, 4824 + }); 4825 + 4826 + const composedHandler = useComposedEventHandler([ 4827 + onScrollHandler1, 4828 + onScrollHandler2, 4829 + ]); 6379 4830 6380 - const handlePress = () => { 6381 - offset.value = withSequence( 6382 - // start from -OFFSET 6383 - withTiming(-OFFSET, { duration: TIME / 2 }), 6384 - // shake between -OFFSET and OFFSET 5 times 6385 - withRepeat(withTiming(OFFSET, { duration: TIME }), 5, true), 6386 - // go back to 0 at the end 6387 - withTiming(0, { duration: TIME / 2 }) 6388 - ) 4831 + return ( 4832 + <View style={styles.container}> 4833 + <Animated.ScrollView style={styles.scroll} onScroll={composedHandler}> 4834 + <Content /> 4835 + </Animated.ScrollView> 4836 + </View> 4837 + ); 6389 4838 } 6390 4839 ``` 6391 4840 6392 - ### Starting the Animation with Delay 4841 + #### Arguments 4842 + 4843 + - **`handlers`**: An array of event handlers created using the `useEvent` hook. The `useComposedEventHandler` hook updates whenever there are changes in these handlers. 4844 + 4845 + #### Returns 4846 + 4847 + The hook returns a handler object that can be used with any `Animated component`. This handler should be assigned to the corresponding `onEvent` prop (e.g., `onScroll` for scroll-related handlers). For better code clarity, it's recommended to use multiple composed handlers if your aggregated handler manages various events. 4848 + 4849 + ### Remarks 4850 + 4851 + - The returned handler combines the functionalities of all provided handlers. This allows multiple handlers to respond to a single event and manage different types of events with one object. 4852 + - It functions effectively when used with multiple `Animated components`, triggering event callbacks for each connected component. 4853 + 4854 + ### Platform Compatibility 4855 + 4856 + |Android|iOS|Web| 4857 + |-|-|-| 4858 + |✅|✅|✅| 4859 + 4860 + ## withDelay 4861 + 4862 + `withDelay` is an animation modifier that allows you to initiate an animation after a specified delay period. 6393 4863 6394 - Add suspense by delaying the animation start using `withDelay`. 4864 + ### Reference 6395 4865 6396 4866 ```typescript 6397 4867 import { withDelay } from "react-native-reanimated" 6398 4868 6399 4869 function App() { 6400 4870 sv.value = withDelay(500, withTiming(0)) 4871 + // ... 6401 4872 } 6402 4873 ``` 6403 4874 6404 - Final example: 4875 + #### Arguments 4876 + 4877 + - **`delayMs`**: Specifies the duration (in milliseconds) before the animation begins. 4878 + 4879 + - **`delayedAnimation`**: The animation that will be delayed. 4880 + 4881 + - **`reduceMotion`** *(Optional)*: Determines how the animation responds to the device's reduced motion accessibility setting. 4882 + 4883 + #### Returns 4884 + 4885 + The `withDelay` function returns an animation object representing the current state of the animation. This object can either be directly assigned to a shared value or used as a value for a style object returned from `useAnimatedStyle`. 4886 + 4887 + ### Example 4888 + 4889 + *(Example content would go here)* 4890 + 4891 + ### Platform Compatibility 4892 + 4893 + |Android|iOS|Web| 4894 + |-|-|-| 4895 + |✅|✅|✅| 4896 + 4897 + *** 4898 + 4899 + ## useAnimatedSensor 4900 + 4901 + `useAnimatedSensor` allows you to create animations based on device sensor data. It provides access to: 4902 + 4903 + - **Accelerometer**: Measures device acceleration (excluding gravity) along the x, y, and z axes. 4904 + - **Gyroscope**: Captures the rotation rate of the device along the x, y, and z axes. 4905 + - **Gravity**: Provides the current gravity vector along the x, y, and z axes. 4906 + - **Magnetic Field**: Measures the Earth's magnetic field strength and direction in microtesla (μT). 4907 + - **Rotation**: Represents the device orientation using Euler angles and a quaternion. 4908 + 4909 + For comprehensive documentation, refer to the Sensors guide on Android Developers and Device Motion in Apple Developer documentation. 4910 + 4911 + ### Reference 6405 4912 6406 4913 ```typescript 6407 - const OFFSET = 40 6408 - const TIME = 250 6409 - const DELAY = 400 4914 + import { useAnimatedSensor, SensorType } from "react-native-reanimated" 4915 + 4916 + function App() { 4917 + const gyroscope = useAnimatedSensor(SensorType.GYROSCOPE) 6410 4918 6411 - const handlePress = () => { 6412 - offset.value = withDelay( 6413 - DELAY, 6414 - withSequence( 6415 - // start from -OFFSET 6416 - withTiming(-OFFSET, { duration: TIME / 2 }), 6417 - // shake between -OFFSET and OFFSET 5 times 6418 - withRepeat(withTiming(OFFSET, { duration: TIME }), 5, true), 6419 - // go back to 0 at the end 6420 - withTiming(0, { duration: TIME / 2 }) 6421 - ) 6422 - ) 4919 + useDerivedValue(() => { 4920 + const { x, y, z } = gyroscope.sensor.value 4921 + }) 6423 4922 } 6424 4923 ``` 6425 4924 6426 - ### Summary 4925 + #### Arguments 6427 4926 6428 - - **Modifiers**: `withRepeat`, `withSequence`, and `withDelay`. 6429 - - **`withRepeat`**: Repeats an animation a specified number of times or indefinitely. 6430 - - **`withSequence`**: Chains animations to run sequentially. 6431 - - **`withDelay`**: Delays the start of an animation. 4927 + ##### `sensorType` 6432 4928 6433 - ### What's Next? 4929 + Specifies the sensor type using a `SensorType` enum: 6434 4930 6435 - Explore handling `Tap` and `Pan` gestures, and learn about the `withDecay` animation function. 4931 + - `ACCELEROMETER`: Measures device acceleration in m/s². 4932 + - `GYROSCOPE`: Captures rotation rate in radians per second. 4933 + - `GRAVITY`: Provides gravity vector in m/s². 4934 + - `MAGNETIC_FIELD`: Measures magnetic field strength in microtesla (μT). 4935 + - `ROTATION`: Represents orientation using Euler angles and a quaternion. 6436 4936 6437 - ````markdown 6438 - # `useAnimatedScrollHandler` 4937 + ##### `config` (Optional) 6439 4938 6440 - The `useAnimatedScrollHandler` is a custom hook designed to provide an event handler for managing animated scrolling within React Native applications. This hook integrates seamlessly with various scrollable components, enabling developers to implement smooth and responsive animations. 4939 + |Name|Type|Default|Description| 4940 + |-|-|-|-| 4941 + |interval|`number \| "auto"`|`"auto"`|Time between sensor readings in milliseconds. `"auto"` matches the device's screen refresh rate.| 4942 + |adjustToInterfaceOrientation|`boolean`|`true`|Adjusts measurements to the current interface orientation.| 4943 + |iosReferenceFrame|`IOSReferenceFrame`|`IOSReferenceFrame.Auto`|Frame of reference for iOS sensors.| 6441 4944 6442 - ## Usage 4945 + Available `IOSReferenceFrame` options: 6443 4946 6444 - To utilize the `useAnimatedScrollHandler`, you need to import it from its respective library or module where it's defined. Once imported, this hook can be invoked within a functional component to obtain an event handler reference that is specifically tailored for animated scroll events. 4947 + - `xArbitraryZVertical`: Z axis is vertical, X axis arbitrary in horizontal plane. 4948 + - `xArbitraryCorrectedZVertical`: Improved rotation accuracy with Z vertical and X arbitrary. 4949 + - `XMagneticNorthZVertical`: Z axis vertical, X points to magnetic north. 4950 + - `XTrueNorthZVertical`: Z axis vertical, X points to geographic north. 4951 + - `Auto`: Defaults based on device capabilities. 4952 + 4953 + #### Returns 4954 + 4955 + `useAnimatedSensor` returns an object: 4956 + 4957 + |Name|Type|Description| 4958 + |-|-|-| 4959 + |sensor|`SharedValue<Value3D \| ValueRotation>`|Shared value with sensor measurements.| 4960 + |unregister|`() => void`|Stops listening to sensor updates when called.| 4961 + |isAvailable|`boolean`|Indicates if the sensor is available for use.| 4962 + |config|`SensorConfig`|Contains sensor configuration details.| 4963 + 4964 + The shared value from the **rotation sensor** includes: 4965 + 4966 + - Euler angles: `roll`, `pitch`, `yaw`. 4967 + - Quaternion components: `qw`, `qx`, `qy`, `qz`. 4968 + - Interface orientation. 4969 + 4970 + Other sensors return measurements on x, y, z axes and interface orientation. 4971 + 4972 + `InterfaceOrientation` enum values: 4973 + 4974 + - `ROTATION_0`: Default rotation on Android, portrait on iOS. 4975 + - `ROTATION_90`: 90 degrees on Android, landscape right on iOS. 4976 + - `ROTATION_180`: 180 degrees on Android, upside down on iOS. 4977 + - `ROTATION_270`: 270 degrees on Android, landscape left on iOS. 6445 4978 6446 4979 ### Example 6447 4980 6448 - Below is a basic example demonstrating how to use `useAnimatedScrollHandler` in conjunction with a React Native ScrollView: 4981 + ```typescript 4982 + export default function App() { 4983 + const gravity = useAnimatedSensor(SensorType.GRAVITY); 4984 + 4985 + const animatedStyle = useAnimatedStyle(() => { 4986 + return { 4987 + transform: [ 4988 + { translateX: withSpring(gravity.sensor.value.x * 20) }, 4989 + { translateY: withSpring(gravity.sensor.value.y * 20) }, 4990 + ], 4991 + }; 4992 + }); 4993 + 4994 + return ( 4995 + <View style={styles.container}> 4996 + <Animated.View style={[styles.box, animatedStyle]} /> 4997 + </View> 4998 + ); 4999 + } 5000 + ``` 5001 + 5002 + ### Remarks 5003 + 5004 + - On iOS, enable location services (`Settings > Privacy > Location Services`) to read sensor data. 5005 + - On Web, ensure the device supports sensors and the application is served over HTTPS. 5006 + - Most sensors operate at resolutions up to 100Hz. 5007 + - Sensor data can be accessed on both UI and JavaScript threads. 5008 + 5009 + ### Platform Compatibility 5010 + 5011 + |Android|iOS|Web| 5012 + |-|-|-| 5013 + |✅|✅|✅| 5014 + 5015 + ## dispatchCommand 5016 + 5017 + The `dispatchCommand` function enables the execution of commands directly on a native component from the UI thread. 5018 + 5019 + ### Reference 6449 5020 6450 5021 ```typescript 6451 - import { useAnimatedScrollHandler } from 'react-native-reanimated'; 6452 - import { ScrollView, View, Text } from 'react-native'; 5022 + import { dispatchCommand } from 'react-native-reanimated'; 6453 5023 6454 - const MyComponent = () => { 6455 - const scrollHandler = useAnimatedScrollHandler({ 6456 - onScroll: (event) => { 6457 - // Handle the scroll event with animation logic here 6458 - console.log(event.contentOffset); 6459 - }, 5024 + function App() { 5025 + const animatedRef = useAnimatedRef(); 5026 + 5027 + const gesture = Gesture.Tap().onStart(() => { 5028 + dispatchCommand(animatedRef, 'focus'); 6460 5029 }); 6461 5030 6462 5031 return ( 6463 - <ScrollView 6464 - horizontal 6465 - pagingEnabled 6466 - showsHorizontalScrollIndicator={false} 6467 - onScroll={scrollHandler} 6468 - > 6469 - {/* Your content goes here */} 6470 - <View style={{ width: '100%', height: 200, backgroundColor: 'red' }} /> 6471 - <View style={{ width: '100%', height: 200, backgroundColor: 'blue' }} /> 6472 - <View style={{ width: '100%', height: 200, backgroundColor: 'green' }} /> 6473 - </ScrollView> 5032 + <> 5033 + <AnimatedTextInput ref={animatedRef} style={styles.input} /> 5034 + <GestureDetector gesture={gesture}> 5035 + <Button title="Focus" /> 5036 + </GestureDetector> 5037 + </> 6474 5038 ); 6475 - }; 5039 + } 5040 + ``` 6476 5041 6477 - export default MyComponent; 5042 + #### Arguments 5043 + 5044 + - **`animatedRef`**: An animated reference linked to the component you wish to update. This reference must be associated with either an Animated component or a React Native built-in component. 5045 + 5046 + - **`commandName`**: The name of the command to execute, such as `'focus'` or `'scrollToEnd'`. 5047 + 5048 + - **`args` (Optional)**: An array of arguments for the command. Defaults to an empty array if not provided. 5049 + 5050 + ### Example 5051 + 5052 + ```typescript 5053 + const goDown = Gesture.Tap().onStart(() => { 5054 + dispatchCommand(tosRef, "scrollToEnd", [true]) 5055 + dispatchCommand(loginRef, "focus") 5056 + }) 6478 5057 ``` 6479 - ```` 6480 5058 6481 - In this example, `useAnimatedScrollHandler` is used to create a scroll handler that logs the current content offset whenever a scroll event occurs. This setup allows for enhanced control over scrolling animations within the component. 5059 + ### Remarks 6482 5060 6483 - ### Parameters 5061 + - Commands vary depending on the component. Refer to the relevant React Native documentation for available commands specific to each component. 6484 5062 6485 - The hook accepts an object with various properties that define how the scroll events should be handled: 5063 + ### Platform Compatibility 6486 5064 6487 - - **onScroll**: A function that receives the scroll event details, such as `contentOffset`, and can contain logic to animate or respond to the scroll action. 6488 - - Additional optional parameters may include `onBeginDrag`, `onActiveDrag`, `onEndDrag`, etc., depending on the specific requirements of your animation. 5065 + |Android|iOS|Web| 5066 + |-|-|-| 5067 + |✅|✅|❌| 6489 5068 6490 - ### Benefits 5069 + ## setNativeProps 6491 5070 6492 - Using `useAnimatedScrollHandler` offers several advantages: 5071 + The `setNativeProps` function allows for the imperative updating of component properties in React Native. It serves as an escape hatch intended for specific edge cases. 6493 5072 6494 - - **Performance**: By leveraging React Native Reanimated, this hook ensures that animations are performed smoothly and efficiently. 6495 - - **Flexibility**: Developers can customize scroll behavior extensively through various event handlers. 6496 - - **Integration**: Seamlessly works with existing React Native components like ScrollView, FlatList, etc. 5073 + > **Caution:**\ 5074 + > Prefer using `useAnimatedStyle` and `useAnimatedProps` when animating styles or properties, reserving `setNativeProps` for exceptional situations. 6497 5075 6498 - By incorporating `useAnimatedScrollHandler` into your project, you can enhance the user experience with fluid and responsive scrolling animations. 5076 + ### Reference 6499 5077 6500 - ```` 5078 + ```typescript 5079 + import { setNativeProps } from 'react-native-reanimated'; 5080 + 5081 + function App() { 5082 + const animatedRef = useAnimatedRef(); 5083 + 5084 + const tap = Gesture.Tap().onEnd(() => { 5085 + setNativeProps(animatedRef, { text: '' }); 5086 + }); 5087 + 5088 + return <TextInput ref={animatedRef} />; 5089 + } 5090 + ``` 5091 + 5092 + #### Arguments 5093 + 5094 + - **`animatedRef`:**\ 5095 + An animated reference linked to the component you wish to update. This animated reference must be passed either to an Animated component or a React Native built-in component. 5096 + 5097 + - **`updates`:**\ 5098 + An object containing properties that need updating, which can include both style properties (e.g., `width`, `backgroundColor`) and regular properties (e.g., `text`). 5099 + 5100 + #### Returns 5101 + 5102 + The function returns `undefined`. 5103 + 5104 + ### Remarks 5105 + 5106 + - Prioritize using `useAnimatedStyle` and `useAnimatedProps` for animating styles or properties. 5107 + - Ensure that `setNativeProps` is used exclusively on the UI thread. 5108 + - The `setNativeProps` function was designed to facilitate the imperative updating of props from gesture handlers. In other scenarios, it may require an additional `runOnUI` call, making React Native's built-in `setNativeProps` more efficient with fewer runtime transitions. 5109 + 5110 + ### Platform Compatibility 5111 + 5112 + |Android|iOS|Web| 5113 + |-|-|-| 5114 + |✅|✅|✅| 5115 + 5116 + *** 5117 + 5118 + ## React Native Reanimated: useReducedMotion Hook (Version 3.x) 6501 5119 6502 - # Interpolation with `react-native-reanimated` 5120 + ### Overview 6503 5121 6504 - The `interpolate` function is used to map a numeric value from one specified range to another using linear interpolation. 5122 + The `useReducedMotion` hook in React Native Reanimated allows developers to check the system's reduced motion setting. This is particularly useful for disabling animations when users prefer less motion. 6505 5123 6506 - ## Reference Usage 5124 + ### Reference 6507 5125 6508 5126 ```typescript 6509 - import { interpolate, Extrapolation } from 'react-native-reanimated'; 5127 + import { useReducedMotion } from "react-native-reanimated" 6510 5128 6511 5129 function App() { 6512 - const animatedStyle = useAnimatedStyle(() => ({ 6513 - opacity: interpolate(sv.value, [0, 100], [0, 1], Extrapolation.CLAMP), 6514 - })); 5130 + const reduceMotion = useReducedMotion() 5131 + 5132 + if (reduceMotion) { 5133 + // Display static content ✨ 5134 + } else { 5135 + // Run animations ✨ 5136 + } 5137 + 5138 + // Additional logic... 6515 5139 } 6516 - ```` 5140 + ``` 6517 5141 6518 - #### Parameters 5142 + #### Returns 6519 5143 6520 - - **`value`**: A numeric value that will be mapped to the specified `output` range. 5144 + The `useReducedMotion` hook returns a boolean value indicating whether the reduced motion setting was enabled at the start of the app. 6521 5145 6522 - - **`input`**: An array of numbers defining the input range for interpolation. 5146 + ### Example Usage 6523 5147 6524 - - **`output`**: An array of numbers defining the output range for interpolation, which should have at least as many points as the input range. 5148 + ```typescript 5149 + import { useReducedMotion } from 'react-native-reanimated'; 6525 5150 6526 - - **`extrapolate` (Optional)**: Determines behavior when `value` is outside the `input` range. Defaults to `Extrapolation.EXTEND`. 5151 + function App() { 5152 + const reduceMotion = useReducedMotion(); 6527 5153 6528 - Available options: 5154 + if (reduceMotion) { 5155 + return <StaticContent />; 5156 + } else { 5157 + return <AnimatedContent />; 5158 + } 5159 + } 5160 + ``` 6529 5161 6530 - - `Extrapolation.EXTEND`: Predicts values beyond the output range. 6531 - - `Extrapolation.CLAMP`: Clamps the value to the edge of the output range. 6532 - - `Extrapolation.IDENTITY`: Returns the provided value unchanged. 5162 + ### Remarks 6533 5163 6534 - String equivalents include `"extend"`, `"clamp"`, and `"identity"`. 5164 + - Changing the reduced motion setting does not trigger a component rerender. 5165 + - Unlike `AccessibilityInfo.isReduceMotionEnabled()`, `useReducedMotion` provides the value synchronously. 5166 + 5167 + ### Platform Compatibility 5168 + 5169 + |Android|iOS|Web| 5170 + |-|-|-| 5171 + |✅|✅|✅| 5172 + 5173 + This hook is compatible across Android, iOS, and Web platforms. 5174 + 5175 + ## makeMutable 5176 + 5177 + **Caution:** The use of `makeMutable` is generally discouraged. It's recommended to opt for the `useSharedValue` hook unless you are fully aware of its implications (refer to the Remarks section). 6535 5178 6536 - To apply extrapolation to a specific edge, use an object: 5179 + Internally, `makeMutable` is utilized by the `useSharedValue` hook to generate a shared value. This function allows the creation of mutable values without relying on the hook, which can be beneficial in specific scenarios such as within the global scope or when managing an array of mutable values. 6537 5180 6538 - ```typescript 6539 - const opacity = interpolate(sv.value, [0, 100], [0, 1], { 6540 - extrapolateLeft: Extrapolation.CLAMP, 6541 - }) 6542 - ``` 5181 + The object produced by `makeMutable` mirrors that returned by the `useSharedValue` hook, ensuring consistent usage thereafter. 6543 5182 6544 - #### Return Value 5183 + ### Reference 6545 5184 6546 - The `interpolate` function returns a value mapped within the specified output range. 5185 + ```typescript 5186 + import { makeMutable } from "react-native-reanimated" 5187 + 5188 + const mv = makeMutable(100) 5189 + ``` 5190 + 5191 + #### Arguments 5192 + 5193 + ##### `initial` 5194 + 5195 + This argument specifies the initial value to be stored in the mutable. It can encompass any JavaScript data type such as `number`, `string`, or `boolean`, and also includes complex structures like arrays and objects. 5196 + 5197 + #### Returns 5198 + 5199 + `makeMutable` yields a mutable value initialized with the provided `initial`. Access to the stored data is possible through its `value` property or via `get` and `set` methods. 5200 + 5201 + ### Example 5202 + 5203 + ### Remarks 5204 + 5205 + **Info:** The term *mutable value* refers to an object created by `makeMutable`, distinguishing it from a *shared value*, which is essentially a mutable value with automatic cleanup. 5206 + 5207 + - All remarks applicable to the `useSharedValue` hook are relevant to `makeMutable`. 5208 + - Avoid invoking `makeMutable` directly within component scope. Component re-renders will generate a new object, potentially resetting the initial value and losing previous state. 5209 + 5210 + ```typescript 5211 + function App() { 5212 + const [counter, setCounter] = useState(0) 5213 + const mv = makeMutable(counter) // 🚨 creates a new mutable value on each render 5214 + 5215 + useEffect(() => { 5216 + const interval = setInterval(() => { 5217 + setCounter((prev) => prev + 1) // updates the counter stored in component state 5218 + }, 1000) 5219 + 5220 + return () => { 5221 + clearInterval(interval) 5222 + } 5223 + }, [mv]) 5224 + 5225 + useAnimatedReaction( 5226 + () => mv.value, 5227 + (value) => { 5228 + console.log(value) // prints 0, 1, 2, ... 5229 + } 5230 + ) 5231 + } 5232 + ``` 5233 + 5234 + - Utilize `cancelAnimation` to halt all ongoing animations on a mutable value if it becomes unnecessary and animations are still active. Exercise caution with infinite animations as they require manual cancellation. 5235 + 5236 + ```typescript 5237 + function App() { 5238 + const mv = useMemo(() => makeMutable(0), []) 5239 + 5240 + useEffect(() => { 5241 + mv.value = withRepeat(withSpring(100), -1, true) // creates an infinite animation 5242 + 5243 + return () => { 5244 + cancelAnimation(mv) // ✅ stops the infinite animation on component unmount 5245 + } 5246 + }, []) 5247 + } 5248 + ``` 5249 + 5250 + - `cancelAnimation` is not needed for non-animated values as they are automatically garbage collected when no references remain. 5251 + 5252 + ```typescript 5253 + const someFlag = makeMutable(false) 5254 + 5255 + function App() { 5256 + someFlag.value = true // ✅ no need to cancel the animation later on 5257 + } 5258 + ``` 5259 + 5260 + - When opting for `makeMutable`, adhere to React's rules and avoid common pitfalls associated with `useRef`, such as modifying references during rendering (see the **Pitfall** section in the useRef documentation). 5261 + 5262 + #### Comparison with `useSharedValue` 5263 + 5264 + |Feature|`makeMutable`|`useSharedValue`| 5265 + |-|-|-| 5266 + |Object Creation|Creates a new object on each call|Reuses the same object on each call| 5267 + |Initial Value Change|A new object is created if `initial` changes|The initially created object remains unchanged if `initialValue` changes| 5268 + |Scope Usage|Can be used outside of component scope|Limited to use within component scope| 5269 + |Loop Usage|Usable in loops with variable iterations|Usable in loops only if the number of hooks (`useSharedValue` calls) is constant| 5270 + |Animation Cancellation|Does not automatically cancel animations on unmount|Automatically cancels animations when the component unmounts| 6547 5271 6548 5272 ### Platform Compatibility 6549 5273 ··· 6551 5275 |-|-|-| 6552 5276 |✅|✅|✅| 6553 5277 6554 - ## Clamp Function in React Native Reanimated 5278 + ## Accurate Call Stacks 5279 + 5280 + When debugging Reanimated code, developers might encounter misleading call stacks in errors or warnings. These stacks often highlight internal Reanimated code rather than pinpointing the misuse of the Reanimated API that caused the issue. 5281 + 5282 + To improve this situation, Reanimated offers a Metro configuration wrapper named `wrapWithReanimatedMetroConfig`. This tool adjusts your Metro config to enhance the accuracy of call stacks for warnings and errors generated by the Reanimated library. 5283 + 5284 + ### Reference 5285 + 5286 + For more precise call stacks, import `wrapWithReanimatedMetroConfig` from `react-native-reanimated/metro-config` and use it to wrap your existing Metro configuration in the `metro.config.js` file. 5287 + 5288 + ```typescript 5289 + // metro.config.js 5290 + import { wrapWithReanimatedMetroConfig } from "react-native-reanimated/metro-config" 5291 + 5292 + const config = { 5293 + // Your existing Metro configuration options 5294 + } 5295 + 5296 + export default wrapWithReanimatedMetroConfig(config) 5297 + ``` 5298 + 5299 + ### Example 5300 + 5301 + The example below illustrates the difference in call stacks before and after applying the Reanimated Metro config wrapper. The **Before** scenario shows Reanimated source code as the error origin, while the **After** scenario reveals the actual incorrect code that caused the error. 5302 + 5303 + |Before|After| 5304 + |-|-| 5305 + ||| 5306 + 5307 + ### Remarks 5308 + 5309 + - `wrapWithReanimatedMetroConfig` does not remove any stack frames; it only collapses irrelevant ones from Reanimated. To inspect these, you can expand collapsed stack frames by clicking on the **See N more frames** text at the bottom of the **Call Stack**. 5310 + 5311 + |Collapsed|Expanded| 5312 + |-|-| 5313 + ||| 5314 + 5315 + - Some errors, especially those arising from asynchronous code, may still point to Reanimated internals instead of the exact problematic line in your code. This happens because stack traces can lose track of the original code that initiated the asynchronous operation. In such cases, manual debugging based on the error message is necessary to identify the potential cause of the problem. 5316 + 5317 + ## withClamp 6555 5318 6556 - The `clamp` function is used to restrict a value within a specified range, ensuring it does not exceed the defined minimum and maximum bounds. 5319 + `withClamp` is an animation modifier that restricts the movement of your animation within a specified range. It's typically used in conjunction with `withSpring`. 6557 5320 6558 5321 ### Reference 6559 5322 6560 5323 ```typescript 6561 - import { clamp } from "react-native-reanimated" 5324 + import { withClamp } from "react-native-reanimated" 6562 5325 6563 5326 function App() { 6564 - const result = clamp(sv.value, 0, 100) 5327 + sv.value = withClamp({ min: -1, max: 1 }, withSpring(0)) 5328 + // ... 6565 5329 } 6566 5330 ``` 6567 5331 6568 5332 #### Arguments 6569 5333 6570 - - **`value`**: A numeric value that will be returned if it falls within the specified `min` and `max` range. 5334 + ##### `config` 5335 + 5336 + An object containing the following properties: 5337 + 5338 + |Name|Type|Description| 5339 + |-|-|-| 5340 + |min|number|Optional. The lowest value your animation can reach.| 5341 + |max|number|Optional. The highest value your animation can reach.| 6571 5342 6572 - - **`min`**: The lower bound. If the provided `value` is less than this number, `min` will be returned. 5343 + ##### `animation` 5344 + 5345 + The spring animation you wish to clamp. 6573 5346 6574 - - **`max`**: The upper bound. If the provided `value` exceeds this number, `max` will be returned. 5347 + ```typescript 5348 + const clampedStyleWithDelay = useAnimatedStyle(() => { 5349 + return { 5350 + width: withClamp({ min: 0, max: 100 }, withSpring(randomWidth.value)), 5351 + } 5352 + }) 5353 + ``` 6575 5354 6576 5355 #### Returns 6577 5356 6578 - The function returns a numeric value that lies between the specified `min` and `max` bounds. 5357 + `withClamp` returns an animation object. This can be directly assigned to a shared value or used as a style value in `useAnimatedStyle`. 5358 + 5359 + |Platform|Supported| 5360 + |-|-| 5361 + |Android|✅| 5362 + |iOS|✅| 5363 + |Web|✅| 5364 + 5365 + ## Logger configuration 5366 + 5367 + Reanimated provides warnings to highlight potential misuses of its API, such as altering shared values during component re-renders. These logs can be adjusted in verbosity. 5368 + 5369 + By default, the logger configuration requires no setup and displays all warnings and errors. To customize this behavior, use the `configureReanimatedLogger` function. 5370 + 5371 + ### Reference 5372 + 5373 + To alter the default Reanimated logger settings, import `configureReanimatedLogger` from `react-native-reanimated` and invoke it with your desired configuration: 5374 + 5375 + ```typescript 5376 + import { 5377 + configureReanimatedLogger, 5378 + ReanimatedLogLevel, 5379 + } from "react-native-reanimated" 5380 + 5381 + // Default configuration example 5382 + configureReanimatedLogger({ 5383 + level: ReanimatedLogLevel.warn, 5384 + strict: true, // Strict mode is enabled by default 5385 + }) 5386 + ``` 5387 + 5388 + #### Configuration Options 5389 + 5390 + - **`level`:** Specifies the minimum log level to display using a value from `ReanimatedLogLevel`. 5391 + 5392 + - **`strict`:** A boolean that toggles strict mode. Enabling it results in additional warnings to help identify potential code issues. 5393 + 5394 + ### Remarks 5395 + 5396 + - The logger configuration is global, affecting all Reanimated warnings and errors. It cannot be configured on a per-file or per-component basis. 5397 + 5398 + - Call `configureReanimatedLogger` before creating any Reanimated animations, typically in the root file of your application. 6579 5399 6580 - ### Example Usage 5400 + - This function is intended for app developers. Library creators using Reanimated should avoid including this call in their source code to prevent overriding users' configurations with the default settings. 5401 + 5402 + ### Platform Compatibility 5403 + 5404 + |Android|iOS|Web| 5405 + |-|-|-| 5406 + |✅|✅|✅| 5407 + 5408 + ## React Native Reanimated: ReducedMotionConfig 5409 + 5410 + **Version:** 3.x 5411 + 5412 + ### Overview 5413 + 5414 + The `ReducedMotionConfig` component allows you to modify the behavior of animations based on a device's reduced motion accessibility setting. By default, it disables all animations when this setting is enabled. You can customize this behavior according to your specific needs. For more information about Accessibility and `useReducedMotion`, refer to Reanimated documentation. 5415 + 5416 + > **Caution:** The new configuration will be applied globally across the entire application. 5417 + 5418 + ### Reference 6581 5419 6582 5420 ```typescript 6583 - import { clamp } from "react-native-reanimated" 5421 + import { ReducedMotionConfig, ReduceMotion } from 'react-native-reanimated'; 6584 5422 6585 5423 function App() { 6586 - const constrainedValue = clamp(150, 0, 100) // Result will be 100 5424 + return ( 5425 + // ... 5426 + <ReducedMotionConfig mode={ReduceMotion.Never} /> 5427 + // ... 5428 + ); 6587 5429 } 6588 5430 ``` 6589 5431 5432 + #### Arguments 5433 + 5434 + ##### `mode` 5435 + 5436 + This parameter determines how animations should respond to the device's reduced motion accessibility setting: 5437 + 5438 + - **`ReduceMotion.System`:** Adjusts animation behavior based on the device's reduced motion setting. Animations are disabled when this setting is enabled; otherwise, they remain active. 5439 + 5440 + - **`ReduceMotion.Always`:** Consistently disables animations, regardless of the device's accessibility configuration. 5441 + 5442 + - **`ReduceMotion.Never`:** Ensures that animations remain enabled at all times. 5443 + 6590 5444 ### Platform Compatibility 6591 5445 6592 5446 |Android|iOS|Web| 6593 5447 |-|-|-| 6594 5448 |✅|✅|✅| 6595 5449 6596 - This function is compatible across Android, iOS, and Web platforms. 5450 + - Reference 5451 + - Arguments 5452 + - Example 5453 + - Platform compatibility 5454 + 5455 + ## Worklets 6597 5456 6598 - ## interpolateColor Function 5457 + Worklets are short-running JavaScript functions that execute on the UI thread, enabling efficient style calculations and event reactions. Reanimated leverages worklets for these tasks. 6599 5458 6600 - The `interpolateColor` function maps an input range to output colors using linear interpolation. This is particularly useful in animations where you want a smooth transition between colors. 5459 + ### Creating Worklets 6601 5460 6602 - ### Reference Example 5461 + To define a custom worklet, use the `'worklet';` directive at the start of your function: 6603 5462 6604 5463 ```typescript 6605 - import { interpolateColor } from 'react-native-reanimated'; 5464 + function myWorklet() { 5465 + "worklet" 5466 + console.log("Hello from a worklet") 5467 + } 5468 + ``` 5469 + 5470 + The Reanimated Babel Plugin identifies functions marked with `'worklet'`, transforming them into serializable objects—a process known as workletization. These objects can then be executed on the UI thread. 5471 + 5472 + ### Automatic Workletization 5473 + 5474 + When using Reanimated and Gesture Handler, code is typically automatically workletized and executed on the UI thread: 5475 + 5476 + ```typescript 5477 + import { useAnimatedStyle } from "react-native-reanimated" 6606 5478 6607 5479 function App() { 6608 - const progress = useSharedValue(0); 5480 + const style = useAnimatedStyle(() => { 5481 + // Executed on the UI thread 5482 + return { opacity: 0.5 } 5483 + }) 5484 + } 5485 + ``` 5486 + 5487 + ### Manual Worklet Execution 5488 + 5489 + To manually schedule worklet execution, use `runOnUI`: 6609 5490 6610 - const animatedStyle = useAnimatedStyle(() => { 6611 - return { 6612 - backgroundColor: interpolateColor( 6613 - progress.value, 6614 - [0, 1], 6615 - ['red', 'green'] 6616 - ), 6617 - }; 6618 - }); 5491 + ```typescript 5492 + function myWorklet() { 5493 + "worklet" 5494 + console.log("Hello from the UI thread") 5495 + } 6619 5496 5497 + function onPress() { 5498 + runOnUI(myWorklet)() 5499 + } 5500 + ``` 5501 + 5502 + Arguments can be passed to worklets as follows: 5503 + 5504 + ```typescript 5505 + function myWorklet(greeting: string) { 5506 + "worklet" 5507 + console.log(`${greeting} from the UI thread`) 5508 + } 5509 + 5510 + function onPress() { 5511 + runOnUI(myWorklet)("Howdy") 5512 + } 5513 + ``` 5514 + 5515 + ### Worklet Closures 5516 + 5517 + Worklets are closures, allowing them to access variables declared outside their scope. Only referenced variables are captured: 5518 + 5519 + ```typescript 5520 + const width = 135.5 5521 + 5522 + function otherWorklet() { 5523 + "worklet" 5524 + console.log("Captured width is", width) 5525 + } 5526 + ``` 5527 + 5528 + Avoid capturing large objects within worklets to prevent performance issues: 5529 + 5530 + ```typescript 5531 + const theme = {...}; // Large object 5532 + 5533 + function myWorklet() { 5534 + 'worklet'; 5535 + console.log(theme.color); // 🚨 Captures entire `theme` object 5536 + } 5537 + ``` 5538 + 5539 + To mitigate this, assign the needed property to a separate variable: 5540 + 5541 + ```typescript 5542 + const theme = {...}; 5543 + const color = theme.color; 5544 + 5545 + function myWorklet() { 5546 + 'worklet'; 5547 + console.log(color); // ✅ Captures only `color` 5548 + } 5549 + ``` 5550 + 5551 + ### Returning Data 5552 + 5553 + Worklets can return data within the same thread: 5554 + 5555 + ```typescript 5556 + function returningWorklet() { 5557 + "worklet" 5558 + return "I'm back" // On the UI thread 5559 + } 5560 + 5561 + function someWorklet() { 5562 + "worklet" 5563 + const what = returningWorklet() // Still on the UI thread 5564 + console.log("On the UI thread, other worklet says", what) 5565 + } 5566 + ``` 5567 + 5568 + ### Data Sharing Between Threads 5569 + 5570 + Use shared values to pass data between the UI and JS threads: 5571 + 5572 + ```typescript 5573 + import { useSharedValue } from "react-native-reanimated" 5574 + 5575 + function App() { 5576 + const width = useSharedValue(100) 5577 + 5578 + function myWorklet() { 5579 + "worklet" 5580 + width.value += 50 5581 + } 5582 + 5583 + useEffect(() => { 5584 + console.log(width.value) // Accessible on both JS and UI threads 5585 + }, []) 5586 + } 5587 + ``` 5588 + 5589 + ### Running Functions on the JS Thread 5590 + 5591 + Use `runOnJS` to execute functions from the UI thread, often for non-worklet functions or React state updates: 5592 + 5593 + ```typescript 5594 + import { router } from "expo-router" 5595 + import { Gesture } from "react-native-gesture-handler" 5596 + 5597 + function App() { 5598 + const tap = Gesture.Tap().onEnd(() => { 5599 + // Worklet context 5600 + runOnJS(router.back)() 5601 + }) 5602 + } 5603 + ``` 5604 + 5605 + Ensure functions passed to `runOnJS` are defined in the JavaScript thread scope: 5606 + 5607 + ```typescript 5608 + function App() { 5609 + const tap = Gesture.Tap().onEnd(() => { 5610 + // myFunction is defined on the UI thread 🚨 5611 + const myFunction = () => {} 5612 + runOnJS(myFunction)() // 💥 Error 5613 + }) 5614 + } 5615 + ``` 5616 + 5617 + ### Custom Worklet Runtimes 5618 + 5619 + Worklets can operate in custom runtimes beyond Reanimated's default. Libraries like VisionCamera and LiveMarkdown create their own worklet environments. 5620 + 5621 + Create your own worklet runtime using `createWorkletRuntime`. 5622 + 5623 + ## Accessibility 5624 + 5625 + This section discusses how Reanimated enhances accessibility in animations, particularly through its reduced motion functionality. This feature ensures a smoother experience for users with motion sensitivities or those who prefer less movement. 5626 + 5627 + The reduced motion configuration allows you to define how animations should respond to the system's reduced motion setting. For any animation, the value can be set as follows: 5628 + 5629 + - `ReduceMotion.System`: Adjusts the animation based on whether the device's reduced motion accessibility setting is activated. If enabled, the animation is disabled; otherwise, it remains active. 5630 + - `ReduceMotion.Always`: Consistently disables the animation, regardless of the device's accessibility configuration. 5631 + - `ReduceMotion.Never`: Ensures that the animation remains enabled at all times. 5632 + 5633 + By default, all animations are configured with `ReduceMotion.System`. 5634 + 5635 + ### Reduced Motion in Animations 5636 + 5637 + ```typescript 5638 + import { withDelay, withTiming } from "react-native-reanimated" 5639 + 5640 + function App() { 5641 + sv1.value = withTiming(0, { reduceMotion: ReduceMotion.System }) 5642 + sv2.value = withDelay( 5643 + 1000, 5644 + withTiming(toValue, { duration }), 5645 + ReduceMotion.System 5646 + ) 6620 5647 // ... 5648 + } 5649 + ``` 5650 + 5651 + When reduced motion is enabled: 5652 + 5653 + - `withSpring` and `withTiming` return the `toValue` immediately. 5654 + - `withDecay` returns the current value immediately, considering the clamp parameter. 5655 + - `withDelay` initiates the next animation immediately. 5656 + - `withRepeat`: 5657 + - If `numberOfReps` is infinite or even and the animation is reversed, then the repeated animation does not start. 5658 + - Otherwise, the repeated animation runs once. 5659 + - `withSequence` exclusively starts animations that have reduced motion disabled. 5660 + 5661 + Higher-order animations pass the configuration to their children only if the children haven't been configured by the user. For example: 6621 5662 6622 - return <Animated.View style={[{ width: 100, height: 100 }, animatedStyle]} />; 5663 + This animation will instantaneously reach the `toValue`: 5664 + 5665 + ```typescript 5666 + import { withDelay, withTiming } from "react-native-reanimated" 5667 + 5668 + function App() { 5669 + sv.value = withDelay( 5670 + 1000, 5671 + withTiming(toValue, { duration }), 5672 + ReduceMotion.Always 5673 + ) 5674 + // ... 5675 + } 5676 + ``` 5677 + 5678 + This animation will execute as usual even if reduced motion is enabled on the device: 5679 + 5680 + ```typescript 5681 + import { withDelay, withTiming } from "react-native-reanimated" 5682 + 5683 + function App() { 5684 + sv.value = withDelay( 5685 + 1000, 5686 + withTiming(toValue, { duration }), 5687 + ReduceMotion.Never 5688 + ) 5689 + // ... 5690 + } 5691 + ``` 5692 + 5693 + And here `withTiming` will be executed as usual and without delay: 5694 + 5695 + ```typescript 5696 + import { withDelay, withTiming } from "react-native-reanimated" 5697 + 5698 + function App() { 5699 + sv.value = withDelay( 5700 + 1000, 5701 + withTiming(toValue, { duration, reduceMotion: ReduceMotion.Never }), 5702 + ReduceMotion.Always 5703 + ) 5704 + // ... 5705 + } 5706 + ``` 5707 + 5708 + ### Reduced Motion in Layout Animations 5709 + 5710 + ```typescript 5711 + import { BounceIn } from "react-native-reanimated" 5712 + 5713 + function App() { 5714 + const entering = BounceIn.reduceMotion(ReduceMotion.System) 5715 + // ... 5716 + } 5717 + ``` 5718 + 5719 + When reduced motion is enabled: 5720 + 5721 + - Entering, keyframe, and layout animations instantaneously reach their endpoints. 5722 + - Exiting animations and shared transitions are omitted. 5723 + 5724 + ### `useReducedMotion` 5725 + 5726 + This hook returns a boolean indicating whether the reduced motion setting was enabled when the app started. It can be used in conjunction with other libraries or to conditionally display animations that are less intrusive. 5727 + 5728 + ```typescript 5729 + import { BounceIn } from "react-native-reanimated" 5730 + 5731 + function App() { 5732 + const reduceMotion = useReducedMotion() 5733 + const entering = reduceMotion 5734 + ? FadeIn.reduceMotion(ReduceMotion.Never) 5735 + : BounceIn 5736 + // ... 5737 + } 5738 + ``` 5739 + 5740 + ## Glossary of terms 5741 + 5742 + ### Animated Component 5743 + 5744 + Animated components are those that can be animated using Reanimated. The library includes built-in components such as `Animated.View`, `Animated.Text`, and `Animated.ScrollView`. 5745 + 5746 + ```typescript 5747 + import Animated from 'react-native-reanimated'; 5748 + 5749 + function App() { 5750 + return ( 5751 + <Animated.View 5752 + style={{ 5753 + width: 100, 5754 + height: 100, 5755 + backgroundColor: 'violet', 5756 + }} 5757 + /> 5758 + ); 5759 + } 5760 + ``` 5761 + 5762 + For components not included in Reanimated, you can make their props and styles animatable by wrapping them with `createAnimatedComponent`: 5763 + 5764 + ```typescript 5765 + import Animated from "react-native-reanimated" 5766 + import { Circle } from "react-native-svg" 5767 + 5768 + const AnimatedCircle = Animated.createAnimatedComponent(Circle) 5769 + ``` 5770 + 5771 + ### Shared Value 5772 + 5773 + Shared values are essential for animations in Reanimated. They are defined using the `useSharedValue` hook and accessed or modified via their `.value` property. 5774 + 5775 + ```typescript 5776 + import { useSharedValue } from "react-native-reanimated" 5777 + 5778 + function App() { 5779 + const sv = useSharedValue(0) 5780 + 5781 + const handlePress = () => { 5782 + sv.value += 10 5783 + } 5784 + 5785 + // rest of your glamorous code ✨ 5786 + } 5787 + ``` 5788 + 5789 + Shared values can store any type and automatically synchronize data between the JavaScript thread and the UI thread. 5790 + 5791 + ### Animatable Value 5792 + 5793 + An animatable value is a type that can be used for animations, including numbers, strings, and arrays of numbers. Strings in specific formats like `"10deg"`, `"21%"`, or colors such as `"#ffaabb"` or `"rgba(100, 200, 100, 0.7)"` are also animatable. 5794 + 5795 + ### Animation Function 5796 + 5797 + Animation functions define how animations should behave. Reanimated provides three built-in animation functions: 5798 + 5799 + - `withSpring`: Creates spring-based animations. 5800 + - `withTiming`: Creates duration and easing-based animations. 5801 + - `withDecay`: Mimics motion with a given deceleration rate. 5802 + 5803 + These can be combined with modifiers for complex animations. 5804 + 5805 + ### Animation Modifier 5806 + 5807 + Animation modifiers customize animations. Known as higher-order animations, Reanimated includes: 5808 + 5809 + - `withDelay`: Adds a delay before the animation starts. 5810 + - `withRepeat`: Repeats an animation a specified number of times. 5811 + - `withSequence`: Chains animations sequentially. 5812 + - `withClamp`: Limits animation boundaries to a specific range. 5813 + 5814 + ### Animation Object 5815 + 5816 + An animation object is returned from animation functions and modifiers, containing the current state of the animation. It includes start and end conditions and an `onFrame` function for calculating each frame's state. 5817 + 5818 + When passed to a shared value, it is treated as an animatable value: 5819 + 5820 + ```typescript 5821 + sv.value = withSpring(100) 5822 + ``` 5823 + 5824 + ### Animations in Inline Styling 5825 + 5826 + Shared values can be directly used in the `style` property without `useAnimatedStyle`. 5827 + 5828 + Example: 5829 + 5830 + ```typescript 5831 + function App() { 5832 + const width = useSharedValue(100); 5833 + 5834 + return <Animated.View style={{ width }} />; 5835 + } 5836 + ``` 5837 + 5838 + ### Layout Animation Modifier 5839 + 5840 + Layout animation modifiers customize layout animations. Example usage: 5841 + 5842 + ```typescript 5843 + <Animated.View entering={FadeOutLeft.duration(500).easing(Easing.ease)} /> 5844 + ``` 5845 + 5846 + Built-in modifiers include: 5847 + 5848 + - `.duration(durationMs: number)`: Sets the animation length in milliseconds. 5849 + - `.easing(easingFunction: EasingFunction)`: Defines the animation curve. 5850 + - `.springify()`: Enables spring-based animations. 5851 + - `.damping(value: number)`: Controls how quickly a spring stops moving. 5852 + - `.withCallback(callback: (finished: boolean) => void)`: Triggers after the animation ends. 5853 + 5854 + ### Worklet 5855 + 5856 + Worklets are short-running JavaScript functions executed on the UI thread. They can also run on the JavaScript thread like regular functions. 5857 + 5858 + Code is often automatically workletized and runs on the UI thread by default: 5859 + 5860 + ```typescript 5861 + const style = useAnimatedStyle(() => { 5862 + console.log("Running on the UI thread") 5863 + return { opacity: 0.5 } 5864 + }) 5865 + ``` 5866 + 5867 + Custom worklets can be created using the `"worklet";` directive: 5868 + 5869 + ```typescript 5870 + function myWorklet() { 5871 + "worklet" 5872 + console.log("Running on the UI thread") 6623 5873 } 6624 5874 ``` 6625 5875 6626 - #### Arguments 5876 + Use `runOnUI` to manually execute worklets on the UI thread: 5877 + 5878 + ```typescript 5879 + function myWorklet(greeting) { 5880 + "worklet" 5881 + console.log(`${greeting} from the UI thread`) 5882 + } 5883 + 5884 + function onPress() { 5885 + runOnUI(myWorklet)("Howdy") 5886 + } 5887 + ``` 5888 + 5889 + ### To Workletize 5890 + 5891 + Converts a JavaScript function into an object that can be serialized and executed on the UI thread. Functions marked with `"worklet";` are automatically workletized by the Reanimated Babel plugin. 5892 + 5893 + ### JavaScript Thread 5894 + 5895 + The JavaScript thread handles code execution in the app, serving as the primary location for React Native app code execution. 5896 + 5897 + ### UI Thread 5898 + 5899 + The UI thread manages user interface updates and is also known as the Main thread. More information can be found in the Threading model article of the official React Native documentation. 5900 + 5901 + ### Reanimated Babel Plugin 5902 + 5903 + This plugin automatically workletizes certain functions used with Reanimated, reducing boilerplate code. Details are available in the Reanimated Babel plugin README. 5904 + 5905 + ## Entering/Exiting animations 5906 + 5907 + The provided content outlines a comprehensive guide for using various animations in React Native with the `react-native-reanimated` library. Below is a structured summary of the key points and features: 5908 + 5909 + #### Overview 5910 + 5911 + - **Library**: `react-native-reanimated` 5912 + - **Purpose**: To create smooth, performant animations on Android, iOS, and Web platforms. 5913 + - **Animations Covered**: 5914 + - Pinch 5915 + - Pinch Zoom 5916 + - Pinch Rotate 5917 + - Pinch Scale 5918 + - Pinch Translate 5919 + - Pinch X 5920 + - Pinch Y 5921 + - PinchXY 5922 + - PinchZoomRotate 5923 + - PinchZoomScale 5924 + - PinchZoomTranslate 5925 + - PinchZoomX 5926 + - PinchZoomY 5927 + - PinchZoomXY 5928 + - PinchZoomRotateScale 5929 + - PinchZoomRotateTranslate 5930 + - PinchZoomRotateX 5931 + - PinchZoomRotateY 5932 + - PinchZoomRotateXY 5933 + - PinchZoomScaleTranslate 5934 + - PinchZoomScaleX 5935 + - PinchZoomScaleY 5936 + - PinchZoomScaleXY 5937 + - PinchZoomTranslateX 5938 + - PinchZoomTranslateY 5939 + - PinchZoomTranslateXY 5940 + - PinchZoomRotateScaleTranslate 5941 + - PinchZoomRotateScaleX 5942 + - PinchZoomRotateScaleY 5943 + - PinchZoomRotateScaleXY 5944 + - PinchZoomRotateTranslateX 5945 + - PinchZoomRotateTranslateY 5946 + - PinchZoomRotateTranslateXY 5947 + - PinchZoomScaleTranslateX 5948 + - PinchZoomScaleTranslateY 5949 + - PinchZoomScaleTranslateXY 5950 + - PinchZoomRotateScaleTranslateX 5951 + - PinchZoomRotateScaleTranslateY 5952 + - PinchZoomRotateScaleTranslateXY 5953 + - Other animations like Bounce, Fade, Flip, etc. 6627 5954 6628 - - **`value`**: A number from the input range that is mapped to the output range. 5955 + #### Animation Configuration 6629 5956 6630 - - **`input`**: An array of numbers specifying the input range for interpolation. The values should be in increasing order. 5957 + ##### Time-based Modifiers 6631 5958 6632 - - **`output`**: An array of color strings (e.g., `'red'`, `'#ff0000'`, `'rgba(255, 0, 0, 0.5)'`) that define the output colors. It must have at least as many points as the input range. 5959 + - **Function**: `withTiming` 5960 + - **Customization**: 5961 + - `.easing(easingFunction: EasingFunction)`: Defines the animation curve. Default is `Easing.inOut(Easing.quad)`. 5962 + - Note: These modifiers do not affect spring animations. 6633 5963 6634 - - **`colorSpace`** *(Optional)*: Specifies the color space for interpolation, either `'HSV'` or `'RGB'`. Defaults to `'RGB'`. 5964 + ##### Spring-based Modifiers 6635 5965 6636 - - **`options`** *(Optional)*: Additional parameters for color interpolation: 5966 + - **Function**: `withSpring` 5967 + - **Customization**: 5968 + - `.springify()`: Enables spring-based configuration. 5969 + - `.damping(value: number)`: Controls how quickly the spring stops. Default is `10`. 5970 + - `.mass(value: number)`: Represents the weight of the spring. Lower values make animations faster. Default is `1`. 5971 + - `.stiffness(value: number)`: Determines bounciness. Default is `100`. 5972 + - `.overshootClamping(value: boolean)`: Prevents bouncing over the target position. Default is `false`. 5973 + - `.restDisplacementThreshold(value: number)`: Displacement threshold for snapping to the final position without oscillations. Default is `0.001`. 5974 + - `.restSpeedThreshold(value: number)`: Speed threshold for snapping to the final position without oscillations. Default is `2`. 5975 + 5976 + ##### Common Modifiers 5977 + 5978 + - **Customization**: 5979 + - `.duration(durationMs: number)`: Length of the animation in milliseconds. Default is `300`. 5980 + - `.delay(durationMs: number)`: Delay before starting the animation. Default is `0`. 5981 + - `.randomDelay()`: Randomizes delay between `0` and provided value, defaulting to `1000ms` if not specified. 5982 + - `.reduceMotion(reduceMotion: ReduceMotion)`: Adjusts animation based on device's reduced motion settings. 5983 + - `.withInitialValues(values: StyleProps)`: Overrides initial configuration of the animation. 5984 + - `.withCallback(callback: (finished: boolean) => void)`: Executes a callback after the animation ends, indicating if it finished without interruptions. 6637 5985 6638 - |Options|Type|Default|Description| 6639 - |-|-|-|-| 6640 - |`gamma`|`number`|2.2|Gamma parameter used in gamma correction.| 6641 - |`useCorrectedHSVInterpolation`|`boolean`|true|Reduces the number of hues during interpolation by treating HSV as circular.| 5986 + #### Platform Compatibility 6642 5987 6643 - #### Options Explanation 5988 + - **Android**: Supported 5989 + - **iOS**: Supported 5990 + - **Web**: Supported 6644 5991 6645 - - **Gamma**: Colors on web/mobile are typically expressed in sRGB, a gamma-corrected color space. Operations like addition can yield incorrect results if performed directly in this non-linear space. To address this, colors are converted to linear space for interpolation and then back to sRGB. The default gamma value of 2.2 is commonly used for this conversion. 5992 + This guide provides developers with the tools to create and customize animations effectively across multiple platforms using `react-native-reanimated`. 6646 5993 6647 - - **Use Corrected HSV Interpolation**: This option optimizes hue transitions by selecting the shortest path on a circular spectrum (e.g., transitioning from yellow to purple via red instead of green and blue). 5994 + ## Troubleshooting React Native Reanimated Build Issues on Windows 5995 + 5996 + This guide outlines basic troubleshooting steps for resolving issues encountered when building React Native apps with Reanimated for Android devices on a Windows host machine. Common errors include: 5997 + 5998 + - `Execution failed for task ':react-native-reanimated:buildCMakeDebug[x86_64]'` 5999 + - `Execution failed for task ':react-native-reanimated:buildCMakeRelWithDebInfo[arm64-v8a]'` 6000 + - `Task :react-native-reanimated:buildCMakeDebug[x86_64] FAILED` 6001 + - `C/C++: ninja: error: mkdir(...): No such file or directory` 6002 + - `C++ build system [build] failed while executing` 6003 + - `Picked up _JAVA_OPTIONS` 6004 + 6005 + ### What Not to Do 6006 + 6007 + If you encounter any of the above errors, avoid these actions: 6008 + 6009 + #### ❌ Avoid Disabling New Architecture 6010 + 6011 + Starting from React Native 0.76, New Architecture is enabled by default. Manually disabling it in `gradle.properties` does not resolve issues and merely delays them since legacy architecture will be phased out. 6012 + 6013 + #### ❌ Avoid Downgrading Android Gradle Plugin (AGP) 6014 + 6015 + Do not modify the AGP version in `gradle.properties`. Use the version specified in the official app template to prevent version conflicts and unsupported features. 6016 + 6017 + #### ❌ Avoid Downgrading Reanimated or Other Dependencies 6018 + 6019 + Downgrading increases technical debt. Newer versions of Reanimated include bug fixes and stability improvements. Always use the latest supported version, and consider upgrading all dependencies rather than downgrading them. 6020 + 6021 + #### ❌ Avoid Posting Duplicate "Same Issue" Comments 6022 + 6023 + Before reporting an error, search for similar issues on platforms like GitHub or Stack Overflow. Instead of posting duplicate comments, add a reaction to the original issue to indicate its impact. 6024 + 6025 + ### Recommended Actions 6026 + 6027 + #### ✅ Ensure Correct Environment Setup 6028 + 6029 + Follow all instructions in Set Up Your Environment. Run `npx react-native doctor` to identify any problems. Restart your terminal, IDE, or computer if changes have been made. 6030 + 6031 + #### ✅ Use Compatible Reanimated Version 6032 + 6033 + Use the latest supported version of Reanimated based on your app setup: 6034 + 6035 + - **Expo SDK**: Match major and minor versions with Expo SDK. 6036 + - Example: Expo SDK 52 supports `~3.16.x`. Update to the latest patch, e.g., `3.16.7`. 6037 + 6038 + |Expo SDK Version|Reanimated Version| 6039 + |-|-| 6040 + |`52`|`~3.16.1`| 6041 + |`51`|`~3.10.1`| 6042 + |`50`|`~3.6.2`| 6043 + 6044 + - **Expo Prebuild or React Native without Framework**: Use a version compatible with your React Native version according to the Compatibility table. 6045 + 6046 + #### ✅ Use Appropriate CMake Version 6047 + 6048 + Ensure you use CMake `3.22.1` or newer. Customize the version using the `CMAKE_VERSION` environment variable, e.g., `set CMAKE_VERSION=3.31.1`. If unset, default is `3.22.1`. 6049 + 6050 + #### ✅ Use Appropriate Ninja Version 6051 + 6052 + Use Ninja `1.12.0` or newer (latest is `1.12.1`) as older versions may not handle long paths correctly. 6053 + 6054 + #### ✅ Use Compatible Android NDK Version 6055 + 6056 + Match the NDK version with that used in the official app template. It should be installed automatically during app build. 6057 + 6058 + #### ✅ Unset `_JAVA_OPTIONS` 6059 + 6060 + Unsetting this environment variable can resolve certain errors and allow builds to pass. 6061 + 6062 + #### ✅ Enable Long Paths Support in Windows Registry 6063 + 6064 + Follow instructions to enable long paths support on Windows. 6065 + 6066 + #### ✅ Avoid Whitespace in Project Path 6067 + 6068 + Paths with spaces may cause issues. Move projects to directories without whitespace, e.g., `D:\Mobile Apps\MyAwesomeProject`. 6069 + 6070 + #### ✅ Ensure Short Project Path 6071 + 6072 + Avoid paths longer than 240 characters. Move or clone the project to a shorter path, e.g., `D:\AwesomeProject`. 6073 + 6074 + #### ✅ Remove or Invalidate Caches 6075 + 6076 + Clear compilation artifacts in directories like: 6077 + 6078 + - `android\build` 6079 + - `android\.cxx` 6080 + - `android\.gradle` 6081 + - `node_modules\react-native-reanimated\android\build` 6082 + 6083 + Invalidate Android Studio caches (File → Invalidate Caches…). 6084 + 6085 + #### ⚠️ Persistent Issues 6086 + 6087 + If problems persist after following these steps, submit an issue in the repository with full build logs and a minimal reproducible example. 6088 + 6089 + ## Compatibility Table 6090 + 6091 + ### Currently Supported React Native Versions (Paper) 6092 + 6093 + |Version|0.63|0.64|0.65|0.66|0.67|0.68|0.69|0.70|0.71|0.72|0.73|0.74|0.75|0.76|0.77|0.78|0.79|0.80| 6094 + |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-| 6095 + |3.18.0|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|yes|yes| 6096 + |3.17.4 - 3.17.5|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|yes|no| 6097 + |3.17.1 – 3.17.3|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|no|no| 6098 + |3.17.0|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|no|no|no| 6099 + |3.16.7|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|no|no|no| 6100 + |3.16.0 – 3.16.6|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|no|no|no|no| 6101 + |3.15.x|no|no|no|no|no|no|no|no|no|no|no|yes|yes|no|no|no|no|no| 6102 + |3.9.x – 3.14.x|no|no|no|no|no|no|no|no|no|no|no|yes|no|no|no|no|no|no| 6103 + |3.6.x – 3.8.x|no|no|no|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no| 6104 + |3.5.x|no|no|no|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no| 6105 + |3.3.x – 3.4.x|yes|yes|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no| 6106 + |3.0.x – 3.2.x|yes|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no| 6107 + |2.14.x – 2.17.x|yes|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no| 6108 + |2.11.x – 2.13.x|yes|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no|no| 6109 + |2.10.x|yes|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no|no|no| 6110 + |2.5.x – 2.9.x|yes|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no|no|no|no| 6111 + |2.3.x – 2.4.x|yes|yes|yes|yes|yes|no|no|no|no|no|no|no|no|no|no|no|no|no| 6112 + 6113 + **Note:** Reanimated 2 will not receive support for the newest React Native versions. To access the latest features and updates, upgrade to Reanimated 3. 6114 + 6115 + ### Supported React Native Versions on the New Architecture (Fabric) 6116 + 6117 + To use Reanimated with the experimental New Architecture, update the package to at least version 3.0.0. Due to numerous breaking changes related to the New Architecture in each React Native version, as a rule of thumb, Reanimated supports the latest stable version of React Native. 6118 + 6119 + Reanimated supports bridgeless mode. 6120 + 6121 + |Version|0.63|0.64|0.65|0.66|0.67|0.68|0.69|0.70|0.71|0.72|0.73|0.74|0.75|0.76|0.77|0.78|0.79|0.80| 6122 + |-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-|-| 6123 + |3.18.0|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|yes|yes| 6124 + |3.17.4 - 3.17.5|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|yes|no| 6125 + |3.17.1 – 3.17.3|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|no|no| 6126 + |3.17.0|no|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|no|no|no| 6127 + |3.16.7|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|yes|no|no|no| 6128 + |3.16.0 – 3.16.6|no|no|no|no|no|no|no|no|no|no|no|yes|yes|yes|no|no|no|no| 6129 + |3.15.x|no|no|no|no|no|no|no|no|no|no|no|yes|yes|no|no|no|no|no| 6130 + |3.9.x – 3.14.x|no|no|no|no|no|no|no|no|no|no|no|yes|no|no|no|no|no|no| 6131 + |3.6.x – 3.8.x|no|no|no|no|no|no|no|no|no|yes|yes|no|no|no|no|no|no|no| 6132 + |3.1.x – 3.5.x|no|no|no|no|no|no|no|no|no|yes|no|no|no|no|no|no|no|no| 6133 + |3.0.x|no|no|no|no|no|no|no|no|yes|no|no|no|no|no|no|no|no|no| 6134 + 6135 + ## useSharedValue 6136 + 6137 + `useSharedValue` is a hook that allows you to define shared values within your components. 6138 + 6139 + ### Reference 6140 + 6141 + ```typescript 6142 + import { useSharedValue } from "react-native-reanimated" 6143 + 6144 + function App() { 6145 + const sv = useSharedValue(100) 6146 + 6147 + // Accessing the shared value 6148 + console.log(sv.value) 6149 + 6150 + // Modifying the shared value 6151 + sv.value += 50 6152 + } 6153 + ``` 6154 + 6155 + #### Arguments 6156 + 6157 + ##### `initialValue` 6158 + 6159 + The initial value to store in the shared value. It can be any JavaScript type such as `number`, `string`, or `boolean`, and also includes data structures like `array` and `object`. 6648 6160 6649 6161 #### Returns 6650 6162 6651 - The function returns an interpolated color in `rgba(r, g, b, a)` format within the specified output range. 6163 + `useSharedValue` returns a shared value initialized with the provided `initialValue`. You can access this stored data using its `value` property or through `get` and `set` methods. 6164 + 6165 + ##### React Compiler Support 6166 + 6167 + When utilizing the React Compiler, avoid directly accessing or modifying the `value` property. Instead, use the `get` and `set` methods as they are compliant with React Compiler standards. 6168 + 6169 + ```typescript 6170 + function App() { 6171 + const sv = useSharedValue(100) 6172 + 6173 + const animatedStyle = useAnimatedStyle(() => { 6174 + "worklet" 6175 + return { width: sv.get() * 100 } 6176 + }) 6177 + 6178 + const handlePress = () => { 6179 + sv.set((value) => value + 1) 6180 + } 6181 + } 6182 + ``` 6652 6183 6653 6184 ### Remarks 6654 6185 6655 - - The function operates similarly to the `interpolate` function but specifically outputs a color string in `rgba(r, g, b, a)` notation. 6186 + - Avoid reading or modifying the shared value during a component's render. Accessing the `value` property or using `get`/`set` methods is considered a side-effect, which violates React's Rules of Render. 6187 + 6188 + - Changes to `sv.value` will update styles and synchronize the shared value across threads without triggering a typical React re-render since it's a plain JavaScript object. 6189 + 6190 + - Reading `sv.value` on the JavaScript thread may block until the value is fetched from the UI thread. This can be negligible, but if the UI thread is busy or values are read multiple times, synchronization delays might increase. 6191 + 6192 + - Changes to `sv.value` occur synchronously on the UI thread, while updates on the JavaScript thread are asynchronous. Thus, logging `value` immediately after a change will show the previous value. 6193 + 6194 + ```typescript 6195 + function App() { 6196 + const sv = useSharedValue(100) // initially set to 100 6197 + 6198 + sv.value += 50 // modifying the shared value 6199 + 6200 + console.log(sv.value) // logs 100 due to asynchronous update on JS thread 6201 + } 6202 + ``` 6203 + 6204 + - Avoid destructuring assignment with shared values. While valid in JavaScript, it prevents Reanimated from maintaining reactivity. 6205 + 6206 + ```typescript 6207 + function App() { 6208 + let { value } = sv // avoid this pattern 6209 + 6210 + console.log(value) // reading is fine 6211 + 6212 + value += 50 // does not update styles 6213 + } 6214 + ``` 6215 + 6216 + - When storing objects in a shared value, ensure to reassign the entire object rather than modifying its properties individually. 6217 + 6218 + ```typescript 6219 + function App() { 6220 + const sv = useSharedValue({ x: 0, y: 0 }) 6221 + 6222 + sv.value.x = 50 // loses reactivity 6223 + 6224 + sv.value = { x: 50, y: 0 } // correct approach 6225 + } 6226 + ``` 6227 + 6228 + - For large arrays or complex objects in a shared value, use the `.modify` method to alter the existing value without creating a new one. 6229 + 6230 + ```typescript 6231 + function App() { 6232 + const sv = useSharedValue([1, 2, 3]) 6233 + 6234 + sv.value.push(1000) // loses reactivity 6235 + 6236 + sv.value = [...sv.value, 1000] // creates a new copy 6237 + 6238 + sv.modify((value) => { 6239 + "worklet" 6240 + value.push(1000) // correct approach 6241 + return value 6242 + }) 6243 + } 6244 + ``` 6656 6245 6657 6246 ### Platform Compatibility 6658 6247 ··· 6660 6249 |-|-|-| 6661 6250 |✅|✅|✅| 6662 6251 6663 - This function is versatile and compatible across major platforms, making it ideal for cross-platform applications. 6252 + ## Contributing 6253 + 6254 + Thank you for considering contributing to Reanimated. Contributions can range from triaging issues and enhancing documentation to reviewing Pull Requests and submitting code changes. 6255 + 6256 + ### Ways to Contribute 6257 + 6258 + 1. **Handling Open Issues**: Assist by providing detailed descriptions and reproducible examples for existing issues, which helps other contributors understand and address them more efficiently. 6259 + 6260 + 1. **Documentation Assistance**: Improve the documentation by correcting spelling and grammar or expanding explanations. You can also help update outdated pages from Reanimated v2 to the current version. For significant changes, edit locally using Docusaurus and GitHub Pages. 6261 + 6262 + 1. **Reviewing Pull Requests**: Review submitted Pull Requests to identify potential issues or bugs that may have been overlooked, ensuring high-quality contributions. 6263 + 6264 + 1. **Code Contributions**: Submit code through Pull Requests to address issues, fix bugs, or introduce new features. Beginners can start with "good first issue" tasks on GitHub. 6265 + 6266 + #### Repository Structure 6267 + 6268 + The Reanimated repository is organized as follows: 6269 + 6270 + ``` 6271 + ├── apps 6272 + │ ├── common-app // Shared source for example apps 6273 + │ ├── paper-example // React Native app using Old Architecture 6274 + │ ├── fabric-example // React Native app using New Architecture 6275 + │ ├── macos-example // React Native for MacOS wrapper 6276 + │ ├── next-example // Next.js wrapper 6277 + │ ├── tvos-example // React Native for TVOS wrapper 6278 + │ └── web-example // React Native for Web wrapper 6279 + └── packages 6280 + ├── docs-reanimated // Documentation source 6281 + ├── eslint-plugin-reanimated // ESLint plugin source 6282 + └── react-native-reanimated 6283 + ├── android // Android native code 6284 + ├── apple // iOS native code 6285 + ├── Common // Shared C++ code 6286 + ├── scripts // CI pipeline scripts 6287 + ├── src // Reanimated JS source 6288 + └── plugin // Babel plugin source 6289 + ``` 6290 + 6291 + ### Handling Open Issues 6292 + 6293 + Providing detailed descriptions and reproducible examples for issues can significantly aid other contributors. Ensure that issues include: 6294 + 6295 + - A cloneable repository. 6296 + - Clear reproduction steps. 6297 + - Comprehensive descriptions. 6298 + - Relevant stack traces. 6299 + 6300 + If these details are missing, consider asking the issue owner or providing them yourself to facilitate quicker resolutions. 6301 + 6302 + ### Documentation Assistance 6303 + 6304 + Improving documentation is a straightforward way to contribute. The Reanimated docs use Docusaurus and GitHub Pages. For minor edits, click **Edit this page** at the bottom of most pages. For more complex changes: 6305 + 6306 + 1. Clone `react-native-reanimated`. 6307 + 1. Navigate to `packages/docs-reanimated`. 6308 + 1. Run `yarn && yarn start` to preview changes locally. 6309 + 6310 + #### Documentation Structure 6311 + 6312 + Maintain a consistent structure for clarity and ease of navigation: 6313 + 6314 + 1. **Introduction**: Briefly describe the feature. 6315 + 1. **Reference**: Provide simple usage examples with type definitions. 6316 + 1. **Arguments**: Detail accepted arguments. 6317 + 1. **Returns**: Explain returned values. 6318 + 1. **Example**: Include videos, GIFs, or interactive demos in both light and dark modes. 6319 + 1. **Remarks**: Highlight non-obvious details like platform-specific quirks. 6320 + 1. **Platform Compatibility**: Specify supported platforms. 6321 + 6322 + #### Writing Style Guide 6323 + 6324 + - Use active voice for clarity (e.g., "The function receives the arguments"). 6325 + - Write short, clear sentences to aid comprehension. 6326 + - Organize information into lists for better readability. 6327 + - Avoid acronyms unless globally recognized (e.g., UI, API). 6328 + - Use contractions for a conversational tone. 6329 + 6330 + #### Embedding Interactive Examples 6331 + 6332 + Use the `InteractiveExample` component with `src` and `component` props to create engaging examples. For videos: 6333 + 6334 + ```typescript 6335 + import AnimatedKeyboardSrc from '!!raw-loader!@site/src/examples/AnimatedKeyboard'; 6336 + 6337 + <InteractiveExample 6338 + src={AnimatedKeyboardSrc} 6339 + component={ 6340 + <ThemedVideo 6341 + center 6342 + width={300} 6343 + sources={{ 6344 + light: '/recordings/useAnimatedKeyboard_light.mov', 6345 + dark: '/recordings/useAnimatedKeyboard_dark.mov', 6346 + }} 6347 + /> 6348 + } 6349 + />; 6350 + ``` 6351 + 6352 + For interactive components: 6353 + 6354 + ```typescript 6355 + import DecayTrain from '@site/src/examples/DecayTrain'; 6356 + import DecayTrainSrc from '!!raw-loader!@site/src/examples/DecayTrain'; 6357 + 6358 + <InteractiveExample 6359 + src={DecayTrainSrc} 6360 + component={<DecayTrain />} 6361 + label="Grab and drag the train" 6362 + />; 6363 + ``` 6364 + 6365 + ### Contributing Code 6366 + 6367 + Submit Pull Requests to address issues or introduce new features. Start with "good first issue" tasks if you're new to open-source contributions. 6368 + 6369 + #### Working with Android 6370 + 6371 + 1. Install dependencies: `yarn && yarn build`. 6372 + 1. Navigate to `apps/paper-example` and run `yarn start`. 6373 + 1. Open the project in Android Studio at `react-native-reanimated/apps/paper-example/android`. 6374 + 6375 + #### Working with iOS 6376 + 6377 + 1. Install dependencies: `yarn && yarn build`. 6378 + 1. Run `cd apps/paper-example/ios && bundle install && bundle exec pod install`. 6379 + 1. Start Metro bundler: `cd apps/paper-example && yarn start`. 6380 + 1. Open the project in Xcode at `react-native-reanimated/apps/paper-example/ios/ReanimatedExample.xcworkspace`. 6381 + 6382 + #### Preparing a Pull Request 6383 + 6384 + When ready, open a Pull Request using the provided template: 6385 + 6386 + 1. **Summary**: Link relevant issues and describe your changes. 6387 + 1. **Test Plan**: Provide instructions for testing, including code from `EmptyExample` if applicable. 6388 + 6389 + #### Testing Changes Locally 6390 + 6391 + To test changes in your project, create a patch with `git diff` or point to a specific commit in `package.json`. 6392 + 6393 + Thank you for contributing! 🎉 6394 + 6395 + ## Debugging worklets 6396 + 6397 + ### Overview 6398 + 6399 + This document provides guidance on debugging Reanimated v2 worklets within React Native applications. Due to Reanimated's unique architecture and use of a secondary JavaScript runtime, traditional debugging methods may not function as expected. This article outlines compatible tools and their limitations. 6400 + 6401 + #### React Native Debugging Tools 6402 + 6403 + The following tools have been evaluated for compatibility with React Native apps using the Reanimated library: 6404 + 6405 + - **Chrome Debugger (React Native Debugger):** Utilizes a web worker in your browser to execute app JavaScript code, supporting all available runtimes in React Native. 6406 + 6407 + - **Chrome DevTools:** Connects to a remote JavaScript runtime, allowing code execution on the device. Note: Not compatible with JSC. 6408 + 6409 + - **Flipper (Hermes debugger):** Facilitates using Chrome DevTools and offers additional UI inspection tools. 6410 + 6411 + - **Safari DevTools:** Available only for iOS devices running JSC, similar in functionality to Chrome DevTools by connecting to a remote runtime. 6412 + 6413 + - **React Developer Tools:** A standalone app for debugging UI through an inspector, monitoring performance, and profiling the application. 6414 + 6415 + #### JS Context vs. UI Context 6416 + 6417 + Understanding the distinction between the JavaScript (JS) context and the User Interface (UI) context is crucial. Debugging the regular JS context remains unchanged with Reanimated; however, debugging the UI context specific to Reanimated can be challenging. 6418 + 6419 + #### Debugging Web Apps 6420 + 6421 + For web applications, standard browser tools or any preferred debugging tools can be used without issues when employing Reanimated on the web. 6422 + 6423 + ### Compatibility Summary 6424 + 6425 + |Tool|Platform|JSC|Hermes|V8| 6426 + |-|-|-|-|-| 6427 + |Chrome Debugger|Android|⚛️ ✅¹|⚛️ ✅¹|⚛️ ✅¹| 6428 + ||iOS|⚛️ ✅¹|⚛️ ✅¹|N/A| 6429 + |Chrome DevTools|Android|N/A|⚛️ ✅²|⚛️| 6430 + ||iOS|N/A|⚛️ ✅²|N/A| 6431 + |Flipper (Hermes debugger)|Android|N/A|⚛️ ✅²|⚛️| 6432 + ||iOS|N/A|⚛️ ✅²|N/A| 6433 + |Safari DevTools|Android|N/A|N/A|N/A| 6434 + ||iOS|⚛️ ✅|N/A|N/A| 6435 + |React Developer Tools|Android|⚛️|⚛️|⚛️| 6436 + ||iOS|⚛️|⚛️|N/A| 6437 + 6438 + ¹ - Functions use web implementations, running worklets on the JS thread. Measure and Layout Animations are unavailable. ² - Experimental feature. 6439 + 6440 + #### Legend 6441 + 6442 + - ⚛️ ✅: Special features for React Native apps using Reanimated 6443 + - ⚛️: Standard functionality with no worklet debugging available 6444 + - N/A: Not applicable in React Native apps 6445 + 6446 + **Note:** Console logs will always appear in the primary JS runtime as `console.log` on the UI runtime is a wrapper around the JS runtime's function. 6447 + 6448 + ### Tool-Specific Details 6449 + 6450 + #### Chrome Debugger 6451 + 6452 + |Platform|JSC|Hermes|V8| 6453 + |-|-|-|-| 6454 + |Android|⚛️ ✅|⚛️ ✅|⚛️ ✅| 6455 + |iOS|⚛️ ✅|⚛️ ✅|N/A| 6456 + 6457 + **Summary:** Functions use web implementations, running on the JS thread. Measure and Layout Animations are unavailable. 6458 + 6459 + #### Chrome DevTools 6460 + 6461 + |Platform|JSC|Hermes|V8| 6462 + |-|-|-|-| 6463 + |Android|N/A|⚛️ ✅²|⚛️| 6464 + |iOS|N/A|⚛️ ✅²|N/A| 6465 + 6466 + **Summary:** Both contexts can be debugged. This is an experimental feature. 6467 + 6468 + #### Flipper (Hermes Debugger) 6469 + 6470 + |Platform|JSC|Hermes|V8| 6471 + |-|-|-|-| 6472 + |Android|N/A|⚛️ ✅²|⚛️| 6473 + |iOS|N/A|⚛️ ✅²|N/A| 6474 + 6475 + **Summary:** Both contexts can be debugged. This is an experimental feature. 6476 + 6477 + #### Safari DevTools 6478 + 6479 + |Platform|JSC|Hermes|V8| 6480 + |-|-|-|-| 6481 + |Android|N/A|N/A|N/A| 6482 + |iOS|⚛️ ✅|N/A|N/A| 6483 + 6484 + **Summary:** Available only on iOS devices with the JSC engine. Worklet debugging is supported. 6485 + 6486 + #### React Developer Tools 6487 + 6488 + |Platform|JSC|Hermes|V8| 6489 + |-|-|-|-| 6490 + |Android|⚛️|⚛️|⚛️| 6491 + |iOS|⚛️|⚛️|N/A| 6492 + 6493 + **Summary:** Functions as expected, with profiler and layout inspector available. 6494 + 6495 + #### Additional Notes 6496 + 6497 + - **Console Logs:** Always appear in the primary JS runtime. 6498 + 6499 + - **Known Issues:** Include reload failures, breakpoint issues on iOS, unresponsive consoles without animations, and more. These do not affect release builds or debug builds where the debugger is disconnected during a reload. 6500 + 6501 + *Efforts are ongoing to enhance debugging experiences with Chrome DevTools and Flipper on Hermes.*
+59 -41
out/llms-full-react-native.txt
··· 44 44 45 45 With an understanding of how to navigate these guides, it's time to explore the foundation of React Native: Native Components. 46 46 47 - ## Animated Library Overview 47 + ## Animated 48 48 49 49 The `Animated` library is designed for creating fluid, powerful animations that are easy to build and maintain. It emphasizes declarative relationships between inputs and outputs, configurable transforms, and control over animation execution through `start`/`stop` methods. 50 50 ··· 922 922 - `hidesWhenStopped` (iOS) 923 923 - `size` 924 924 925 - ## Button Component 925 + ## Button 926 926 927 927 The Button component is designed to render consistently across different platforms, offering a basic level of customization. If the default appearance does not meet your needs, consider creating a custom button using Pressable. For guidance, refer to the source code of the Button component. 928 928 ··· 970 970 ||- false||| 971 971 972 972 This table summarizes the properties available for the Button component, detailing their purpose and default values where applicable. 973 + 974 + ## Image 973 975 974 976 To integrate image handling capabilities in your React Native application, you can utilize the `<Image />` component along with various methods and properties provided for efficient image management. Below is an overview of how to use these features effectively: 975 977 ··· 1175 1177 1176 1178 For events with capture equivalents, the gesture state is updated once in the capture phase and can be used in the bubble phase. Be cautious with `onStartShould*` callbacks; they only reflect updated `gestureState` for start/end events that bubble/capture to the Node. Once a node becomes the responder, every start/end event updates the `gestureState`. Note that `numberActiveTouches` may not always be accurate unless you are the responder. 1177 1179 1178 - ## Installing Dependencies 1180 + ## Installing dependencies 1179 1181 1180 1182 To develop a React Native app, ensure you have Node, Watchman, the React Native CLI, a JDK, and Android Studio installed. While any editor can be used for development, Android Studio is necessary for setting up the Android build environment. 1181 1183 ··· 1324 1326 - For integrating React Native into an existing app, refer to the Integration guide. 1325 1327 - To learn more about React Native, explore the Introduction to React Native. 1326 1328 1327 - ## ImageBackground Component Overview 1329 + ## ImageBackground 1328 1330 1329 1331 The `<ImageBackground>` component is designed for developers who are accustomed to using `background-image` in web development. It functions similarly to the `<Image>` component, allowing you to layer additional content on top of an image. 1330 1332 ··· 1419 1421 |-|-| 1420 1422 |number|`0`| 1421 1423 1422 - ## Modal Component 1424 + ## Modal 1423 1425 1424 1426 The Modal component provides a straightforward method to display content above an enclosing view. 1425 1427 ··· 1580 1582 |-|-| 1581 1583 |bool|`true`| 1582 1584 1585 + ## Key Concepts 1586 + 1583 1587 To integrate React Native into an existing iOS application, follow these steps carefully. This guide assumes you have a basic understanding of both iOS development using Xcode and JavaScript/React Native. 1584 1588 1585 1589 #### Prerequisites ··· 1860 1864 |radius|number|No|Sets the radius of the ripple effect.| 1861 1865 |foreground|boolean|No|If true, adds the ripple effect to the view's foreground instead of the background. Useful when child views have their own backgrounds or images are displayed, preventing the ripple from being obscured.| 1862 1866 1863 - ## RefreshControl Component 1867 + ## RefreshControl 1864 1868 1865 1869 The `RefreshControl` component is designed to be used within a ScrollView or ListView, providing pull-to-refresh functionality. When the scroll position (`scrollY`) reaches zero and the user swipes down, an `onRefresh` event is triggered. 1866 1870 ··· 2107 2111 2108 2112 > **Deprecated Notice:** The support for TV devices has been transitioned to a separate repository named "React Native for TV." For detailed guidance on projects targeting Apple TV or Android TV, please refer to the *README* file within that repository. 2109 2113 2114 + ## ScrollView 2115 + 2110 2116 The provided documentation outlines various properties and methods associated with a ScrollView component, likely from a mobile development framework such as React Native. Below is a summary of the key features: 2111 2117 2112 2118 #### Properties ··· 2214 2220 2215 2221 Here, `"providesModuleNodeModules"` is a list of modules added to the Haste module search path, and `"platforms"` specifies valid platform suffixes. 2216 2222 2217 - ## StatusBar Component 2223 + ## StatusBar 2218 2224 2219 2225 The `StatusBar` component manages the app's status bar, which is typically located at the top of the screen. It displays information such as time, network status, battery level, and other status icons. 2220 2226 ··· 2384 2390 |`'light-content'`|string|White texts and icons.| 2385 2391 |`'dark-content'`|string|Dark texts and icons (requires API>=23 on Android).| 2386 2392 2387 - ## Enabling USB Debugging on Android Devices 2393 + ## 1. Enable Debugging over USB 2388 2394 2389 2395 Most Android devices restrict app installations to those downloaded from Google Play by default. To install apps during development, enable USB Debugging on your device. 2390 2396 ··· 2515 2521 2516 2522 This guide covers enabling USB debugging, setting up an Android device for React Native development, connecting to the development server via USB or Wi-Fi, and preparing your app for production release. Follow these steps to streamline your development workflow. 2517 2523 2518 - ## Switch Component 2524 + ## Switch 2519 2525 2520 2526 The `Switch` component renders a boolean input and functions as a controlled component. It necessitates an `onValueChange` callback to update its `value` prop, ensuring that user interactions are accurately reflected in the UI. Without updating the `value` prop, the component will persistently display the initially supplied value. 2521 2527 ··· 2570 2576 - **Description**: Determines the state of the switch. If set to `true`, the switch is on; otherwise, it's off. The default value is `false`. 2571 2577 - **Type**: `bool` 2572 2578 2573 - ## Fast Refresh in React Native 2579 + ## Fast Refresh 2574 2580 2575 2581 Fast Refresh is a feature in React Native that provides near-instant feedback when changes are made to your React components. By default, this feature is enabled and can be toggled through the "Enable Fast Refresh" option in the React Native Dev Menu. With it activated, most edits should become visible within seconds. 2576 2582 ··· 2620 2626 2621 2627 This behavior can lead to unexpected results, such as an empty-array `useEffect` running once during Fast Refresh. Writing resilient code for occasional `useEffect` re-runs is beneficial and aligns with best practices, facilitating future dependency additions. 2622 2628 2623 - ## Metro Configuration in React Native 2629 + ## Metro 2624 2630 2625 2631 React Native utilizes Metro to compile JavaScript code and manage assets. Below are guidelines for configuring Metro within your project. 2626 2632 ··· 2712 2718 - Visit the [Metro website](https://metrobundler.dev/docs/configuration) for more information. 2713 2719 - Watch the "Metro & React Native DevX" talk at App.js 2023 for insights into Metro's role in React Native development. 2714 2720 2715 - ## Using Libraries in React Native 2721 + ## Using Libraries 2716 2722 2717 2723 React Native offers built-in Core Components and APIs, but you can also leverage a vast community of developers to find additional libraries that extend your app's functionality. 2718 2724 ··· 2820 2826 ```shell 2821 2827 npm install @react-native-community/netinfo@^2.0.0 2822 2828 ``` 2829 + 2830 + ## Text 2823 2831 2824 2832 Here's a structured overview and explanation of the `Text` component in React Native, focusing on its properties and usage: 2825 2833 ··· 2895 2903 2896 2904 The `Text` component in React Native is highly customizable, supporting various styling and accessibility options. Understanding its properties allows developers to create rich, interactive text elements tailored to specific application needs. 2897 2905 2906 + ## TextInput 2907 + 2898 2908 Here is a structured overview of the properties, methods, and known issues related to the `TextInput` component in React Native: 2899 2909 2900 2910 #### Properties ··· 2971 2981 2972 2982 This overview provides a comprehensive guide to using and understanding the `TextInput` component in React Native, including its properties, methods, and known issues. 2973 2983 2974 - ## TouchableHighlight Component 2984 + ## TouchableHighlight 2975 2985 2976 2986 > For a more robust and future-proof approach to handling touch-based input, consider using the Pressable API. 2977 2987 ··· 3041 3051 - **testOnly\_pressed**: Useful for snapshot tests. 3042 3052 - Type: bool 3043 3053 3044 - ## TouchableOpacity Component 3054 + ## TouchableOpacity 3045 3055 3046 3056 > For a more comprehensive and future-proof approach to handling touch-based input, consider using the Pressable API. 3047 3057 ··· 3106 3116 - **Platform**: Android 3107 3117 - Description: Identifies the next focusable view when navigating up using a TV remote, as detailed in the View component documentation. 3108 3118 3109 - ## Upgrading React Native Versions 3119 + ## Upgrading to new versions 3110 3120 3111 3121 Upgrading to newer versions of React Native provides access to additional APIs, views, developer tools, and other enhancements. Although the process requires some effort, we aim to make it as straightforward as possible. 3112 3122 ··· 3223 3233 |`testID`|Used to locate this view in end-to-end tests.|string| 3224 3234 |`touchSoundDisabled` (Android)|If set to true, prevents the system sound from playing on touch.|Boolean| 3225 3235 3226 - ## Text 3236 + ## View 3227 3237 3228 3238 #### Accessibility Properties 3229 3239 ··· 3317 3327 3318 3328 This documentation provides comprehensive details on how to configure various aspects of a `View`, focusing on accessibility, layout, interaction, and identification. 3319 3329 3320 - ## Style in React Native 3330 + ## Style 3321 3331 3322 3332 In React Native, styling your application is done using JavaScript. Core components accept a `style` prop, which typically mirrors CSS conventions but uses camel casing for property names (e.g., `backgroundColor` instead of `background-color`). 3323 3333 ··· 3379 3389 3380 3390 To occupy a specific portion of the screen without using the `flex` layout, you can use **percentage values** in the component's style. Like flex dimensions, percentage dimensions require that the parent has defined dimensions. 3381 3391 3382 - ## DrawerLayoutAndroid Component 3392 + ## DrawerLayoutAndroid 3383 3393 3384 3394 The `DrawerLayoutAndroid` is a React component specifically designed for Android platforms. It encapsulates the platform's native `DrawerLayout`. This layout typically serves as a navigation drawer, which can be rendered using the `renderNavigationView` prop. The main content of your application resides within its direct children. 3385 3395 ··· 3516 3526 3517 3527 Opens the navigation drawer. 3518 3528 3519 - ## Flexbox Layout in React Native 3529 + ## Layout with Flexbox 3520 3530 3521 3531 Flexbox provides a consistent way to design layouts across different screen sizes. In React Native, it shares similarities with CSS on the web but has specific differences such as default values for properties like `flexDirection`, `alignContent`, and `flexShrink`. 3522 3532 ··· 3956 3966 - **react-native#18997**: Does not support multiline `TextInput`. 3957 3967 - **react-native#20157**: Incompatible with a bottom tab bar. 3958 3968 3959 - ## SafeAreaView Overview 3969 + ## SafeAreaView 3960 3970 3961 3971 The `SafeAreaView` component ensures that content is displayed within the safe area boundaries of a device. It's specifically designed for iOS devices running version 11 or later. 3962 3972 ··· 3974 3984 3975 3985 `SafeAreaView` inherits all View Props. Note that any padding specified in styles applied to a `SafeAreaView` will be ignored, as the component uses its own padding logic. This can lead to different results across platforms. For more details, refer to issue #22211. 3976 3986 3977 - ## Image Style Properties 3987 + ## Image Style Props 3978 3988 3979 3989 ### Examples 3980 3990 ··· 4137 4147 |-| 4138 4148 |color| 4139 4149 4140 - ## Shadow Properties in React Native 4150 + ## Shadow Props 4141 4151 4142 4152 - TypeScript 4143 4153 - JavaScript ··· 4215 4225 |-| 4216 4226 |number| 4217 4227 4218 - ## Text Style Properties 4228 + ## Text Style Props 4219 4229 4220 4230 ### Example 4221 4231 ··· 4389 4399 - `'all'` 4390 4400 - **Default**: `none` 4391 4401 4392 - ## View Style Properties 4402 + ## View Style Props 4393 4403 4394 4404 ### Example 4395 4405 ··· 4685 4695 4686 4696 - `boxShadow` 4687 4697 4688 - ## Handling Touches in React Native 4698 + ## Handling Touches 4689 4699 4690 4700 Users primarily interact with mobile applications through touch gestures such as tapping buttons, scrolling lists, or zooming maps. React Native offers components to manage common gestures and a comprehensive gesture responder system for advanced recognition. The `Button` component is particularly useful for basic interactions. 4691 4701 ··· 5229 5239 5230 5240 React Navigation also offers packages for different navigators, such as tabs and drawers, enabling various navigation patterns in your app. For a comprehensive introduction to React Navigation, refer to the React Navigation Getting Started Guide. 5231 5241 5232 - ## Troubleshooting Guide for React Native Setup 5242 + ## Troubleshooting 5233 5243 5234 5244 This guide addresses common issues encountered during the setup of React Native. If you face an issue not listed here, consider searching for it on GitHub. 5235 5245 ··· 5673 5683 5674 5684 Having covered React and React Native’s Core Components, let's explore handling `<TextInput>` further. 5675 5685 5676 - ## Core Components and APIs in React Native 5686 + ## Core Components and APIs 5677 5687 5678 5688 React Native offers a variety of built-in core components that can be utilized directly within your application. These components are accessible via the navigation sidebar or the top menu for narrower screens. 5679 5689 ··· 5898 5908 export default MyScrollView; 5899 5909 ``` 5900 5910 5901 - ## Using List Views in React Native 5911 + ## Using List Views 5902 5912 5903 5913 React Native offers several components designed for presenting lists of data efficiently. The primary choices are `FlatList` and `SectionList`. 5904 5914 ··· 6085 6095 6086 6096 **Pro tip:** Configure your Web bundler to ignore `.native.js` extensions to avoid including unused code in production, reducing bundle size. 6087 6097 6098 + ## Accessibility 6099 + 6088 6100 #### Overview of Accessibility Features in React Native 6089 6101 6090 6102 React Native provides several accessibility features that help developers create applications usable by everyone, including people with disabilities. These features are crucial for ensuring inclusivity and compliance with accessibility standards like WCAG (Web Content Accessibility Guidelines). ··· 6466 6478 - Safari Developer Tools (Direct JSC Debugging) 6467 6479 - Remote JavaScript Debugging (Removed) 6468 6480 6469 - ## Testing Guide for Code Quality Assurance 6481 + ## Testing 6470 6482 6471 6483 As your codebase grows, small errors can lead to significant failures. Bugs negatively impact user experience and business outcomes. To prevent fragile programming, testing is essential before releasing software. 6472 6484 ··· 7002 7014 |userInterfaceStyleiOS|string|Interface style for the alert, set to `light` or `dark`, otherwise defaults to system style.| 7003 7015 |onDismissAndroid|function|Callback fired when the alert is dismissed.| 7004 7016 7005 - ## Optimizing JavaScript Loading 7017 + ## Optimizing JavaScript loading 7006 7018 7007 7019 Parsing and executing JavaScript code requires both memory and time. As applications grow, it becomes beneficial to delay loading code until it's needed for the first time. React Native includes standard optimizations by default, but additional techniques can further enhance app efficiency. For very large apps, advanced automatic optimizations are available, though they come with tradeoffs. 7008 7020 ··· 7944 7956 7945 7957 This structure is generated using the value `all` for `codegenConfig.type`. Use `modules` to exclude `react/renderer/components/`, and `components` to exclude other files. 7946 7958 7947 - ## Codegen CLI Overview 7959 + ## The Codegen CLI 7948 7960 7949 7961 The **Codegen** CLI simplifies running tasks by eliminating the need to remember complex commands or manually execute scripts. It facilitates executing `@react-native/codegen` for React Native projects with ease. 7950 7962 ··· 8013 8025 8014 8026 By following these steps, you can streamline your development process and ensure that your library remains compatible with various React Native versions. 8015 8027 8016 - ## Introduction 8028 + ## Native Platform 8017 8029 8018 8030 ### Overview 8019 8031 ··· 8047 8059 **Previous:** The Codegen CLI\ 8048 8060 **Next:** Android and iOS 8049 8061 8050 - ## BackHandler API Overview 8062 + ## BackHandler 8051 8063 8052 8064 The **BackHandler** API is designed for Android devices to manage hardware button presses related to back navigation. It allows developers to register event listeners and control the application's response to these events. 8053 8065 ··· 8117 8129 ```typescript 8118 8130 static exitApp(); 8119 8131 ``` 8132 + 8133 + ## Native Modules 8120 8134 8121 8135 To implement a cross-platform `localStorage` solution using React Native's TurboModule system, you need to set up both Android and iOS platforms. Below is a step-by-step guide based on the provided instructions: 8122 8136 ··· 8347 8361 ``` 8348 8362 8349 8363 This setup provides a consistent `localStorage` API across both platforms using React Native's TurboModule system. 8364 + 8365 + ## Cross-Platform Native Modules (C++) 8350 8366 8351 8367 Creating a cross-platform native module using C++ is an efficient way to share platform-agnostic code between Android and iOS. This guide walks through the process of creating a pure C++ Turbo Native Module, which allows you to write your logic once and reuse it across platforms. 8352 8368 ··· 8671 8687 8672 8688 You've successfully created a C++ Turbo Native Module that works on both Android and iOS. This setup allows you to write platform-agnostic code in C++, reducing redundancy and improving maintainability across platforms. 8673 8689 8690 + ## Native Components 8691 + 8674 8692 To create a native web view component in React Native, you need to implement platform-specific code for both Android and iOS. Below is a step-by-step guide on how to achieve this: 8675 8693 8676 8694 #### Step 1: Set Up Your Project ··· 9123 9141 9124 9142 Congratulations! You've published your first React Native library. 9125 9143 9126 - ## ToastAndroid API in React Native 9144 + ## ToastAndroid 9127 9145 9128 9146 The `ToastAndroid` API in React Native provides access to Android's native toast notifications. It offers methods for displaying short or long messages with optional positioning and offset adjustments. 9129 9147 ··· 9423 9441 9424 9442 If native usage is required, include the library's headers by going to your project file, selecting `Build Settings`, and searching for `Header Search Paths`. Add the path to your library. (Previously recommended using `recursive` is now discouraged due to potential build failures, especially with CocoaPods.) 9425 9443 9426 - ## Running on Simulator 9444 + ## Running On Simulator 9427 9445 9428 9446 ### Starting the Simulator 9429 9447 ··· 9751 9769 9752 9770 **Example:** 9753 9771 9754 - ## Appearance Module 9772 + ## Appearance 9755 9773 9756 9774 The `Appearance` module provides information about the user's appearance preferences, such as their preferred color scheme (light or dark). 9757 9775 ··· 10643 10661 10644 10662 > **Note**: Ensure any `View` intended to receive accessibility focus has `accessible={true}`. 10645 10663 10646 - ## AppState Overview 10664 + ## AppState 10647 10665 10648 10666 The `AppState` module provides information about whether an application is in the foreground or background and notifies you of any state changes. It's particularly useful for determining how to handle push notifications based on the app's current state. 10649 10667 ··· 11672 11690 11673 11691 A line with `hairlineWidth` might not be visible if your simulator is downscaled. 11674 11692 11675 - ## Dimensions in React Native 11693 + ## Dimensions 11676 11694 11677 11695 `useWindowDimensions` is the recommended API for React components, as it updates automatically with changes to the window's dimensions. This aligns well with the React paradigm. 11678 11696 ··· 11765 11783 |scale|number| 11766 11784 |fontScale|number| 11767 11785 11768 - ## Props in React Native 11786 + ## Props 11769 11787 11770 11788 In React Native, most components are customizable through parameters known as `props`, short for properties. These allow developers to tailor component behavior and appearance. 11771 11789 ··· 12010 12028 12011 12029 Register the value to the profile name on the systrace timeline. 12012 12030 12013 - ## Easing Module 12031 + ## Easing 12014 12032 12015 12033 The `Easing` module provides a collection of common easing functions used to create physically believable motion in animations, particularly with `Animated.timing()`. 12016 12034 ··· 12497 12515 12498 12516 Indicates the width in pixels of the window or screen that your application occupies. 12499 12517 12500 - ## Keyboard Module 12518 + ## Keyboard 12501 12519 12502 12520 The `Keyboard` module provides functionality for controlling and responding to keyboard events in your application. It allows you to listen for native keyboard notifications, dismiss the keyboard, and synchronize layout animations with keyboard movements. 12503 12521