Reputation: 593
I'm trying to create an onMount animation using React (and Tailwind but it doesn't matter). My current implementation is this:
const Component = () => {
const [mounted, setMounted] = useState(false)
useEffect(() => {
setTimeout(() => {
setMounted(true)
}, 250)
}, [])
return(
<nav
className={classNames(
'flex justify-between items-center transform-gpu transition-transform duration-500',
mounted ? 'translate-x-0' : '-translate-x-full')}> Some nav components </nav>
)
}
Basically, this code timeouts the state's change, which indicates when the component is mounted, and then applies CSS translate to the element.
I'm thinking about optimizing the current solution but was wondering if there are any other ways to do an onMount animations. I appreciate any advice.
I can create a SandBox example if that's necessary.
Upvotes: 6
Views: 4587
Reputation: 61
You can do so by using @keyframes. Here is a working example (note that this is using tailwindcss):
React component:
import React from 'react';
function TransitionComponent() {
return (
<div className="w-48 h-48 bg-blue-500 animate-slide-left">
{/* Content */}
</div>
);
}
export default TransitionComponent;
Global stylesheet:
@keyframes slide-left {
from {
transform: translateX(100%);
}
to {
transform: translateX(0);
}
}
.animate-slide-left {
animation: slide-left 0.5s ease-in-out;
}
With this approach you have maxium control over your animations and you do not need to install any package.
If you're using tailwind css and when you are fine with adding another dependency, I can also recommend tailwindcss-animate. It is very simple to use and specifically designed for animations on mounting events. And it has only a size of 18 kB!
Upvotes: 1
Reputation: 1651
Not sure if this precisely answers your question, but I personally like to use framer-motion for stuff like this. For example, if you want to apply an animated translateX
once the component is mounted you could do something like this:
import { motion } from "framer-motion";
function Component() {
return (
<motion.nav
initial={{ translateX: 0 }}
animate={{ translateX: 100 }}
transition={{ ease: "easeOut", duration: 2 }}
>
Some components
</motion.nav>
);
}
See this codesandbox. (Click the refresh button within the codesandbox-browser to retrigger the animation or use the mount/unmount button)
So instead of <nav>
just use <motion.nav>
and specify the animation via the framer-motion props. You can still style that element with other classes as before if you need them in addition.
Note that an even shorter way of expressing that is using the x
property, as shown here:
<motion.nav
animate={{ x: 100 }}
transition={{ ease: "easeOut", duration: 2 }}
>
Some components
</motion.nav>
You can control the animations directly as attributes or use Animate Presence to control an animation for the component when it is unmounted.
Upvotes: 3