Some Examples » 31. Animate Presence
31. Animate Presence
Here’s an example use of Animate Presence, which lets you animate an element just before it will be removed (unmounted) from the layer tree.
Code component
The smallest motion.div
is wrapped inside an <AnimatePresence>
component. When you give it an exit
property (with the values to animate to), it will animate just before being removed (when isVisible
becomes false
).
export default function CC_31_Animate_Presence(props) {
const [isVisible, setVisible] = useState(true)
return (
<div>
<motion.div
style={{
width: 150,
height: 150,
borderRadius: 30,
backgroundColor: "rgba(255,255,255,0.5)",
cursor: "pointer",
}}
onTap={() => setVisible(!isVisible)}
>
<AnimatePresence>
{isVisible && (
<motion.div
style={{
width: 80,
height: 80,
borderRadius: 15,
backgroundColor: "#fff",
margin: 35,
}}
initial={{ opacity: 0, scale: 0.75 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0 }}
/>
)}
</AnimatePresence>
</motion.div>
</div>
)
}
Code override
This override is attached to the outer frame. It wraps the (only) child of that frame inside an <AnimatePresence>
and gives it the initial
, animate
, and exit
properties.
export function Animate_Presence(Component): ComponentType {
return (props) => {
const { children, ...rest } = props
const [isVisible, setVisible] = useState(true)
return (
<Component
{...rest}
onTap={() => setVisible(!isVisible)}
children={
<AnimatePresence>
{isVisible &&
Children.map(children, (child) =>
cloneElement(child, {
initial: { opacity: 0, scale: 0.75 },
animate: { opacity: 1, scale: 1 },
exit: { opacity: 0, scale: 0 },
})
)}
</AnimatePresence>
}
/>
)
}
}
(You can’t just change a React element—you have to make a copy of it with cloneElement()
.)
Other examples of using children
in a code override:
- 20. SVG path length
- 22. Keyframes: Morphing an SVG path
- 30. SVG gradient animation
- 34. Swapping elements