Recently, I decided to test my understanding of the FLIP animation technique by trying to implement it in a simple codepen experiment.
In the codepen (apologies for the messy code, I was just experimenting), I noticed an interesting behavior. When I removed the sleep function call that lasted for 0 milliseconds, the smooth transition stopped working and the div abruptly changed its position. This puzzled me as the sleep was set for such a short duration.
import React, { useRef, useState } from "https://esm.sh/react@18";
import ReactDOM from "https://esm.sh/react-dom@18";
let first = {}
let second = {}
const sleep = async (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const App = () => {
const [start, setStart] = useState(true);
const boxRefCb = async el => {
if (!el) return;
el.style.transition = "";
const x = parseInt(el?.getBoundingClientRect().x, 10);
const y = parseInt(el?.getBoundingClientRect().y, 10);
first = { x: second.x, y: second.y };
second = { x, y };
const dx = first.x - second.x;
const dy = first.y - second.y;
const transStr = `translate(${dx}px, ${dy}px)`;
el.style.transform = transStr;
await sleep(0); // comment me out
el.style.transition = "transform .5s";
el.style.transform = "";
}
return (
<>
<div style={{ display: "flex", gap: "1rem", padding: "3rem"}}>
<div ref={ start ? boxRefCb : null } style={{ visibility: start ? "" : "hidden", width: 100, height: 100, border: "solid 1px grey" }}></div>
<div ref={ !start ? boxRefCb : null } style={{ visibility: !start ? "" : "hidden", width: 100, height: 100, border: "solid 1px grey" }}></div>
</div>
<button style={{ marginLeft: "3rem"}} onClick={() => setStart(start => !start)}>start | {start.toString()}</button>
</>
);
}
ReactDOM.render(<App />,
document.getElementById("root"))
I have a feeling that there might be some event loop intricacies at play here which I am not fully grasping. Can someone provide insights on this phenomenon?