Give a motion element a layout
property and it will automatically animate when its position (or size) changes.
The motion.div
s are in a grid, which defines their actual position. What makes them change position is the fact that their key
s are changed.
The code inside useEffect()
runs every time the items
array (provided by useCycle()
) changes,… which will be every second because that’s when the setTimeout()
inside it calls setItems()
again.
const itemsA = [1, 2, 3, 4];
const itemsB = [3, 1, 4, 2];
const itemsC = [4, 3, 2, 1];
const itemsD = [2, 4, 1, 3];
const colors = ["#f44", "#3f0", "#fb0", "#0ef"];
export function Example() {
const [items, setItems] = useCycle(itemsA, itemsB, itemsC, itemsD);
useEffect(() => setTimeout(() => setItems(), 1000), [items]);
return (
<div
style={{
display: "grid",
gridTemplateColumns: "auto auto",
gridGap: 10
}}
>
{items.map((item) => (
<motion.div
style={{
width: 75,
height: 75,
borderRadius: 20,
backgroundColor: colors[item - 1]
}}
key={item}
layout
transition={{ type: "spring", stiffness: 350, damping: 25 }}
/>
))}
</div>
);
}