Lightweight helper lib for mounting + unmounting of child elements in an animated 'curtain' style.
(1) Expo snack showing the classical usage.
(2) Expo snack showing the horizontal usage.
- lightweight
- no actual dependency
- you decide if you want to use @react-spring/native or react-native-reanimated for the animations
This library works with both, @react-spring/native and react-native-reanimated. You need to install one of them and set the lib
prop accordingly (details below).
Installing react-native-curtains
itself:
If you use expo, use:
expo install react-native-curtains
Otherwise, for npm use:
npm i react-native-curtains --save
And for yarn use:
yarn add react-native-curtains
Use import { ReactNativeCurtains } from "react-native-curtains"
to access the main component.
The following example shows a three column usage, where the column with the key "column2"
gets removed and therefore unmounted including animation.
before | after |
<ReactNativeCurtains lib={"reanimated"}>
<View key={"column1"}>
<Text>column1</Text>
</View>
<View key={"column2"}>
<Text>column2</Text>
</View>
<View key={"column3"}>
<Text>column3</Text>
</View>
</ReactNativeCurtains> |
<ReactNativeCurtains lib={"reanimated"}>
<View key={"column1"}>
<Text>column1</Text>
</View>
<View key={"column3"}>
<Text>column3</Text>
</View>
</ReactNativeCurtains> |
Note the keys on the immediate children of <ReactNativeCurtains />
- only if those are available, the library can appropriately animate the mounting and unmounting of any given child.
Mounting additional children of course also works the same way.
This example would use react-native-reanimated
README.md as the underlying animation library, due to how the lib
prop is set to "reanimated"
- for details see section "props" below.
prop | required | default | type | description |
---|---|---|---|---|
lib | yes | "reanimated" | "spring" |
Mandatory prop to define the animation library used in the background ("reanimated" for react-native-reanimated, "spring" for @react-spring/native) |
|
AnimationModule | yes | The entire Animation Module | Import the desired module via import * as AnimationModule from "react-native-reanimated" or import * as AnimationModule from "@react-spring/native" and then pass it as the prop's value, like AnimationModule={AnimationModule} . |
|
children | yes | JSX.Element[] |
The children that will be animated upon mounting/unmounting. Make sure to use unique key s so that the library can properly do its job. |
|
animationDuration | no | 500 |
number |
The animation duration in milliseconds. |
easing | no | "linear" |
"linear" | "ease" | "quad" | "cubic" | "sin" | "circle" | "exp" | "bounce" |
Animation style, based on functions defined at https://reactnative.dev/docs/easing. However, this prop is only allowed when lib is set to "reanimated" . When using "spring" the animations will always be linear. |
useHorizontalCurtains | no | false |
boolean |
If set to true the curtains will be horizontal, meaning rows instead of columns. |
There are Pros and Cons for either library, I will quickly try to summarize what my thoughts are:
In general one might want to re-use a library if it is already part of a app. If you have already setup react-native-reanimated
, there is no need to add an additional dependency, and vice versa.
At least, almost... react-native-reanimated
behaves more smoothly, especially when using slower animation durations and quickly mounting/unmounting multiple children within a short time frame. With the @react-spring/native
this might lead to visual glitches.
So it depends on your use case. Also, it does only allow to animate in a "linear" way, while reanimated allows multiple easing functions. One upside for spring is the easier way to set it up initially (just install it and you should be good to go, reanimated on the other hand would take some additional setup steps, see their docs for details).