Animate to and from display none with Framer Motion
To animate to and from display none using Framer Motion, will make use of variants. We set our two states, hidden and shown.
Within our hidden variant, will set the property onanimationend
to display none. This will animate our menu from opacity 1, scale 1, and display block, to opacity 1 and scale 0, then once that animation is complete, will then apply display none.
const variants = {
hidden: {
opacity: 0,
scale: 0,
onanimationend: {
display: "none",
},
},
shown: {
opacity: 1,
scale: 1,
display: "block",
},
};
const variants = {
hidden: {
opacity: 0,
scale: 0,
onanimationend: {
display: "none",
},
},
shown: {
opacity: 1,
scale: 1,
display: "block",
},
};
And to implement this within our menu component, will pass the variants to our motion.ul, and animate between hidden
and shown
variants.
export default function Menu() {
const [variant, setVariant] = React.useState("hidden");
return (
<>
<button
onClick={() =>
setVariant((prevVariant) =>
prevVariant === "hidden" ? "shown" : "hidden"
)
}
>
Toggle dropdown
</button>
<motion.ul variants={variants} initial="hidden" animate={variant}>
<li>
<button>Option 1</button>
</li>
<li>
<button>Option 2</button>
</li>
<li>
<button>Option 3</button>
</li>
</motion.ul>
</>
);
}
export default function Menu() {
const [variant, setVariant] = React.useState("hidden");
return (
<>
<button
onClick={() =>
setVariant((prevVariant) =>
prevVariant === "hidden" ? "shown" : "hidden"
)
}
>
Toggle dropdown
</button>
<motion.ul variants={variants} initial="hidden" animate={variant}>
<li>
<button>Option 1</button>
</li>
<li>
<button>Option 2</button>
</li>
<li>
<button>Option 3</button>
</li>
</motion.ul>
</>
);
}