React Easy Flip
⚛ A lightweight React library for smooth FLIP animations
Features
-
Animates the unanimatable (DOM positions, mounts/unmounts)
-
One hook for many usecases
-
Uses the Web Animations API (WAAPI)
- Stable and smooth 60fps animations
- SSR-friendly
- Built-in easing functions
- Lightweight
Previous README versions
This is a README for v4. The v3 README can be found here.
Demo
https://react-easy-flip-demo.now.sh/
Repository: react-easy-flip-demo
You can also read about how it works in detail here.
Install
npm install react-easy-flip@beta
Get started
- Import
useFlip
hook andFlipProvider
:
import { useFlip, FlipProvider } from 'react-easy-flip'
- Wrap your app (or at least a component that contains animated children) with a
FlipProvider
<FlipProvider>
<MyApp />
</FlipProvider>
- Assign a
data-flip-root-id
to any parent of the element(s) you want to animate
<div data-flip-root-id="flip-root">
<AnimatedChildren>
</div>
- Pick a unique
data-flip-id
and assign it to the element(s) you want to animate. It can be the same as akey
prop
<img data-flip-id="animated-image" />
- Use the hook by passing it the root ID you picked in (3)
useFlip(rootId)
And that's it!
Usage details
useFlip
useFlip
requires one argument, which is an ID of the root, i.e. any parent whose children you want to animate. You can optionally pass an options object with animation options (see details below) as a second argument. Third argument is the optional dependencies which you would normally pass to a useEffect
hook: use it if you need to explicitly tell react-easy-flip
that items you want to animate changed.
useFlip(rootId, animationOptions, deps)
Animation optons
Animation options is an object.
Property | Default | Required | Type | Details |
---|---|---|---|---|
duration |
400 | false |
number |
Animation duration (ms) |
easing |
easeOutCubic |
false |
function |
Easing function (that can be imported from react-easy-flip ) |
delay |
0 | false |
number |
Animation delay |
animateColor |
false | false |
boolean |
Animate background color of the animated element |
Example:
import { easeInOutQuint } from 'react-easy-flip`
const SomeReactComponent = () => {
const animationOptions = {
duration: 2000,
easing: easeInOutQuint,
}
useFlip(rootId, animationOptions)
return (
<div data-flip-root-id="root">
<div data-flip-id="flipped" />
</div>
)
}
Exported easings
react-easy-flip
exports ready-to-use easing functions. You can see the examples here.
- linear
- easeInSine
- easeOutSine
- easeInOutSine
- easeInCubic
- easeOutCubic
- easeInOutCubic
- easeInQuint
- easeOutQuint
- easeInOutQuint
- easeInBack
- easeOutBack
- easeInOutBack
AnimateInOut (experimental)
While useFlip
can animate all kinds of position changes, it does not animate mount/unmount animations (e.g. fade in/out). For this purpose the <AnimateInOut />
component is also exported. To use it, simple wrap with it the components/elements which you want to be animated. By default the initial render is not animated, but this can be changed with a prop.
Every element wrapped with a <AnimateInOut />
must have a unique key prop.
Example:
import { AnimateInOut } from 'react-easy-flip`
const SomeReactComponent = () => {
return (
<AnimateInOut>
<div key="flipped-1" />
<div key="flipped-2" />
<div key="flipped-3" />
</AnimateInOut>
)
}
Here are all props that you can pass to <AnimateInOut />
:
Property | Default | Required | Type | Details |
---|---|---|---|---|
in |
fadeIn |
false |
AnimationKeyframes |
Mount animation options |
out |
fadeOut |
false |
AnimationKeyframes |
Unmount animation options |
playOnFirstRender |
false |
false |
boolean |
Animate on first render |
itemAmount |
undefined |
false |
number |
An explicit amount of current children (see explanation below) |
What is itemAmount
for? In most cases this is not needed. But if your element is animated with a shared layout transition (such as moving from one list to another), this means that it doesn't need an unmount animation. In order to avoid two animations being applied to one element, provide the amount. For example, if this is a todo-app-like application, keep the number of both todo and done items. Moving from todo to done doesn't change the total amount of items, but <AnimateInOut />
does not know that until you tell it. See the recipes below.
Comparison with other libraries
-
react-easy-flip
uses Web Animations API (WAAPI) for animations. No other library based on a FLIP technique currently does that. -
Similar to existing libraries such as
react-overdrive
,react-flip-move
orreact-flip-toolkit
(although only the latter seems to be maintained). -
Allows you to easily do so-called shared layout animations (e.g. smoothly move an element from one page/parent to another). Some examples are given below. This is what heavier libraries like
framer-motion
call Magic Motion. -
Additionally,
react-easy-flip
is the only lightweight FLIP library for React that provides animation via a hook. Currentlyreact-easy-flip
has the smallest bundle size. It also does not use React class components and lifecycle methods that are considered unsafe in latest releases of React.
Recipes
List sort/shuffle animation
Both x and y coordinate shuffle
Shared layout animation
This is an todo-app-like example of shared layout animations. Click on any rectangle to move it to another parent. Note that on every click an item is actually unmounted from DOM and re-mounted in the other position, but having the same data-flip-id
allows to be smoothly animated from one to another position.
Shared layout animation (navigation)
One nice usecase for shared layout animation is navigation bars where we want to move the highlighting indicator smoothly between tabs.
In/out (mount/unmount) animation (opacity)
The fade in and out keyframes are default and work out of box (= you do not need to explicitly pass them).
In/out (mount/unmount) animation (translation)
An example of passing custom animation options to <AnimateInOut>
. Here the images are moved in and out instead of simply fading in and out.
Requirements
This library requires React version 16.8.0 or higher (the one with Hooks).
Contribution
Any kind of contribution is welcome!
- Open an issue or pick an existing one that you want to work on
- Fork this repository
- Clone your fork to work on it locally
- Make changes
- Run
yarn build:dev
and make sure that it builds without crash