A Deep Dive into Motion Primitives

Animations are a powerful tool in a developer's arsenal. When used correctly, they can guide the user, provide feedback, and create a more engaging and polished experience. In this post, we'll explore some of the "motion primitives" used throughout this portfolio, which are powered by the incredible library Framer Motion.
The motion
Component
The core of Framer Motion is the motion
component. You can turn any HTML or SVG element into a motion component by prepending motion.
to it. For example, a div
becomes motion.div
.
This new component accepts special props that allow you to declare animations in a simple, declarative way.
<motion.div
initial={{ opacity: 0, scale: 0.5 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 0.5 }}
/>
In this example, the div
will animate from an initial state of being invisible and scaled down, to a final state of being fully visible and at its normal size.
Orchestrating Animations with Variants
For more complex animations, especially when you need to coordinate animations between parent and child elements, variants
are incredibly useful. Variants allow you to define named animation states and propagate them through the component tree.
const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.2
}
}
};
const itemVariants = {
hidden: { y: 20, opacity: 0 },
visible: { y: 0, opacity: 1 }
};
<motion.ul
variants={containerVariants}
initial="hidden"
animate="visible"
>
<motion.li variants={itemVariants} />
<motion.li variants={itemVariants} />
</motion.ul>
Here, the ul
will fade in, and then each li
child will animate in one after the other, creating a staggered effect.
Animating on Scroll
A common use case is triggering animations as elements scroll into view. Framer Motion makes this trivial with the whileInView
prop and the viewport
prop for configuration.
<motion.div
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, amount: 0.3 }}
transition={{ duration: 0.6 }}
>
This will animate in once 30% of it is visible.
</motion.div>
This is the exact technique used on the section containers in this portfolio to create that smooth, fade-in-as-you-scroll effect.
Conclusion
These are just a few of the motion primitives available in Framer Motion. By combining them, you can build everything from simple button feedback to complex, orchestrated page transitions. They provide a powerful, declarative API that makes building beautiful user interfaces a joy.