Some Examples » 33. Layout animation
33. Layout animation
Give a motion element a layout property and it will automatically animate when its position (or size) changes.
Code component
The motion.divs are in a grid, which defines their actual position. What makes them change position is the fact that their keys 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 default function CC_33_Layout_animation(props) {
const [items, setItems] = useCycle(itemsA, itemsB, itemsC, itemsD)
useEffect(() => {
setTimeout(() => setItems(), 1000)
}, [items])
return (
<div>
<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>
</div>
)
}
Code overrides
const positions = [
{ top: 0, left: 0 },
{ top: 0, left: 85 },
{ top: 85, left: 85 },
{ top: 85, left: 0 },
]
const useStore = createStore({ position: 0 })
export function Container(Component): ComponentType {
return (props) => {
const [store, setStore] = useStore()
useEffect(() => {
setTimeout(() => setStore({ position: store.position + 1 }), 1000)
}, [store])
return <Component {...props} />
}
}
export function Squares(Component): ComponentType {
return (props) => {
const { style, name, ...rest } = props
const [store, setStore] = useStore()
return (
<Component
{...rest}
layout
transition={{
type: "spring",
stiffness: 350,
damping: 25,
}}
style={{
...style,
top: positions[(store.position + Number(name)) % 4].top,
left: positions[(store.position + Number(name)) % 4].left,
}}
/>
)
}
}