Everything You Need to Know About FLIP Animations in React
After the latest Safari update, the Web Animation API (WAAPI) is now supported without any flags in all modern browsers (except IE). Here is a handy example where you can check what features your browser supports. WAAPI is a great way to execute animations (need to be executed in JavaScript) because it belongs to a native API - meaning it works without any extra libraries. If you don't know WAAPI at all, here's a very good introduction to the introduction provided by Dan Wilson.
FLIP is one of the most effective animation methods. FLIP requires some JavaScript code to run.
Let's take a look at the intersection using WAAPI, FLIP and integrating it into React. But we start with no React first and then transition to React.
FLIP and WAAPI
WAAPI makes FLIP animation easier!
FLIP Quick Review: The core idea is to first place the element where you want it to end. Next, apply the transformation to move it to the starting position. Then cancel these conversions.
Animation conversion is very efficient, so FLIP is very efficient. Before WAAPI, we have to manipulate the style of the element directly to set the conversion and wait for the next frame to cancel/invert it:
// FLIP before WAAPI el.style.transform = `translateY(200px)`; requestAnimationFrame(() => { el.style.transform = ''; });
Many libraries are built on this approach. However, there are several problems with this:
- Everything felt like a huge hack.
- Reversing FLIP animations is extremely difficult. Although the CSS conversion is reversed "free" once the class is deleted, this is not the case here. Starting a new FLIP while the previous animation is running will cause a failure. Inversion requires the transformation matrix to be parsed using getComputedStyles and used it to calculate the current size before setting up a new animation.
- Advanced animation is almost impossible. For example, to prevent distorting the child of the scaled parent, we need to access the current scaled value at each frame. This can only be done by parsing the transformation matrix.
- There are many things to pay attention to in the browser. For example, sometimes to run FLIP animation perfectly in Firefox, you need to call requestAnimationFrame twice:
requestAnimationFrame(() => { requestAnimationFrame(() => { el.style.transform = ''; }); });
We do not encounter these problems when using WAAPI. The reverse function can be easily reversed. Reverse scaling of children is also possible. When errors occur, it is easy to find out the culprit, because we only use simple functions such as animate and reverse instead of combing through various things like the requestAnimationFrame method.
Here is a summary of the WAAPI version:
el.classList.toggle('someclass'); const keyframes = /* Calculate size/position difference*/; el.animate(keyframes, 2000);
FLIP and React
To understand how FLIP animations work in React, it is important to know how and most importantly why they work in pure JavaScript. Recall the composition of FLIP animation:
All content with a purple background needs to happen before the "draw" step of rendering. Otherwise, we'll see the new style flashing briefly, which is not good. In React, the situation becomes slightly more complicated, because all DOM updates are done by us.
The magic of FLIP animation is that elements are converted before the browser has the opportunity to draw. So how do we know the "before drawing" moment in React?
Let's take a look at the useLayoutEffect
hook. If you want to know what it is…this is it! Anything we pass in this callback will happen synchronously after the DOM update but before drawing . In other words, this is a great place to set up FLIP!
Let's do something that FLIP technology is very good at: animated DOM positions. If we want to animate how elements move from one DOM position to another, there is nothing CSS can do. (Imagine completing a task in the to-do list and moving it to the Completed task list, just like you would click on the project in the example below.)
Let's look at the simplest example. Clicking either of the two blocks in the following example causes them to swap positions. Without FLIP, it happens immediately.
There are a lot to do. Note how all work happens within the lifecycle hook callback: useEffect
and useLayoutEffect
. What makes it a little confusing is that the timeline of our FLIP animation is not obvious from the code itself, as it happens in two React renderings. The following is the composition of React FLIP animation to display different operation sequences:
Although useEffect
always runs after useLayoutEffect
and after browser draws, it is important that we cache the position and size of the elements after the first rendering. We don't have a chance to do this in the second render because useLayoutEffect
runs after all DOM updates. But this process is basically the same as ordinary FLIP animation.
Things to note
Like most things, there are some things to consider when using FLIP in React.
Stay within 100 milliseconds
FLIP animation is calculation. Calculation takes time, and you need to do quite a bit of work before you can show a smooth 60fps conversion. If the delay is below 100 milliseconds, people won't notice the delay, so make sure everything is below this value. The Performance tab in DevTools is a great place to check this content.
Unnecessary rendering
We cannot use useState
to cache size, position, and animation objects, because each setState
will cause unnecessary rendering and slow down the application. In the worst case, it can even lead to errors. Try using useRef
instead and treating it as an object that can be modified without rendering anything.
Layout shaking
Avoid repeated triggering of browser layout. In the context of FLIP animation, this means avoiding looping through elements and reading their locations with getBoundingClientRect
, and then animate
them immediately. Batch "read" and "write" as much as possible. This will allow for extremely smooth animations.
Animation canceled
Try to randomly click the squares in the previous demo as they move, and click again after they stop. You will see the fault. In real life, users interact with elements as they move, so it is worth making sure they are smoothly cancelled, paused, and updated.
However, not all animations can be reversed using reverse
. Sometimes we want them to stop and then move to a new position (e.g. when the list of elements is randomly disrupted). In this case, we need:
- Get the size/position of the element being moved
- Complete the current animation
- Calculate new dimensions and position differences
- Start a new animation
In React, this is harder than it seems. I wasted a lot of time working on this problem. The current animation object must be cached. A good way is to create a Map to get the animation by ID. Then we need to get the size and position of the element being moved. There are two ways to do this:
- Using function components: Just loop through each animation element in the body of the function and cache the current position.
- Use class components: Use
getSnapshotBeforeUpdate
lifecycle method.
In fact, the official React documentation recommends using getSnapshotBeforeUpdate
, "because there may be a delay between the lifecycle of the rendering phase (such as render
) and the lifecycle of the commit phase (such as getSnapshotBeforeUpdate
and componentDidUpdate
). However, there is currently no hook counterpart for this method. I found that using the body of the function component is enough.
Don't fight against the browser
I've said it before, but avoid confronting the browser and try to make things happen in the browser's way. If we need to animate simple size changes, then consider whether CSS is sufficient (e.g. transform: scale()
). I found that FLIP animation is best for where browsers really can't help:
- Animated DOM position change (as described above)
- Shared layout animation
The second is a more complex version of the first. There are two DOM elements that act as one whole and change its position (and the other is uninstalled/hidden). This trick can achieve some cool animations. For example, this animation is made with a library I built called react-easy-flip that uses this method:
Library
There are many libraries that can make FLIP animations in React easier and abstract boilerplate code. The libraries currently actively maintained include: react-flip-toolkit
and my library react-easy-flip
.
If you don't mind something heavier but capable of more general animation, check out framer-motion
. It also allows for cool shared layout animations! There is a video that explores the library in depth.
Resources and references
- Josh W. Comeau's Animation-Not Animated
- Building high-performance expansion and fold animations by Paul Lewis and Stephen McGruer
- "Magic Motion Inside" by Matt Perry
- @keyframers tweet "Using animated CSS variables from JavaScript"
- Mariko Kosaka's "Internal List of Modern Web Browsers (Part 3)"
- Alex Holachek's Simple Build Complex UI Animation in React
- David Khourshid's "Animation of Layouts with FLIP Technology"
- Kirill Vasiltsov's "Fluent animation with React Hooks"
- Jayant Bhawal's "Use React Hooks for Shared Element Conversion"
This revised output maintains the original image format and placement while paraphrasing the text to create unique content. It also addresses some minor grammatical and stylistic issues.
The above is the detailed content of Everything You Need to Know About FLIP Animations in React. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics

It's out! Congrats to the Vue team for getting it done, I know it was a massive effort and a long time coming. All new docs, as well.

With the recent climb of Bitcoin’s price over 20k $USD, and to it recently breaking 30k, I thought it’s worth taking a deep dive back into creating Ethereum

I had someone write in with this very legit question. Lea just blogged about how you can get valid CSS properties themselves from the browser. That's like this.

The other day, I spotted this particularly lovely bit from Corey Ginnivan’s website where a collection of cards stack on top of one another as you scroll.

I'd say "website" fits better than "mobile app" but I like this framing from Max Lynch:

There are a number of these desktop apps where the goal is showing your site at different dimensions all at the same time. So you can, for example, be writing

If we need to show documentation to the user directly in the WordPress editor, what is the best way to do it?

Questions about purple slash areas in Flex layouts When using Flex layouts, you may encounter some confusing phenomena, such as in the developer tools (d...
