Here's a rundown of what should happen (it's more complex than it appears at first glance!)
- When it's first rendered in React, the grid component should animate in from the left, followed by the staggered animation of its child, a list of cards, with each card fading in from above.
- New cards can be added individually to the cards array, and should be animated in with a "fade up" animation.
- Individual cards can also be removed from the cards array, and should be animated out with a "fade up" animation as they leave.
- When the grid component is unmounted, it should wait for its children to animate out before animating itself and leaving the DOM in the opposite direction from where it arrived.
- In-progress animations should be appropriately cancelled if the enter/exit state is toggled rapidly.
- If the cards were shuffled, they should still animate out with the expected staggered order.
- The sequenced "enter" and "exit" animations of both a parent and its child requires coordination between different components.
- The enter and exit animations are not simple mirrors of each other, as some libraries expect.
- The positions of the grid and cards should be animated with a spring (or, failing that, with an elastic easing), while opacity changes should have a linear easing.
- The cards animating in and out are initially staggered, but adding or removing cards one-by-one should result in a fluid animation with no delay.
- The initial staggered entry of cards should have them animating in from the top, but an individual card being added should have its own animation — fading in from the bottom.
- Toggling the example rapidly should not create a broken view— cancelled animations should be cleaned up and there shouldn't be any straggler DOM elements left behind.
- 🥇 react-transition-group & animejs
- Using
react-transition-groupand a vanilla JavaScript animation library ended up being my favorite technique, because it offers total flexibility and control, at the cost of some additional complexity. Animejsis lightweight and open source, and I find its imperative API more intuitive than the typical React approach for coordinated, complex animations.- my animation attempt
- my code
- React transition group docs
- Anime docs
- 🥈 framer-motion
- Of the react-specific animation libraries, I found this one to have the most intuitive API.
- I do wish it was possible to minimize the wait time between the parent and child animations.
- my animation attempt
- my code
- Framer motion docs
- 🥉 react-spring
- The library's use of the hooks API is very concise and expressive—it took only about 70 lines of code to implement the example!
- The library is in active development and supports a wide variety of use cases.
- I was unable to get the cards to have different animations depending on whether they were arriving as a group ("fade in down") or as an individually added card ("fade in up").
- my animation attempt
- my code
- react-spring docs
- react-transition-group & gsap
- Basically the same as the
animejsexample, just with the animation library swapped out.GSAPhas a less permissive license and it's older and heavier thananimejs, but it's battle-tested and powerful. - my animation attempt
- my code
- React transition group docs
- GSAP docs
- react-move
- A lightweight library that helps
D3andReactwork together. It ended up not being quite flexible enough for the needs of this task, though if the demo featured more traditionally D3-like interactions it would have been great. - my animation attempt
- my code
- react-move docs
- velocity-react
- A straightforward option that got me far but then ended up tripping me up when it came time to get the nested leave animations working.
- At one point, this library might have been one of the better options for animating in React, but now with
react-spring,popmotion-pose, andreact-transition-group v2there are more powerful, updated alternatives with better documentation. - my animation attempt
- my code
- velocity-react docs
- react-motion
- I found this library very difficult to use when implementing the example.
- my sad animation attempt
- my code
- react motion docs
yarnornpm installyarn startornpm start