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.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 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,
}}
/>
)
}
}