5 Quick Framer Motion Tips
September 10, 2021
Introduction
Framer Motion is a library for React used to create animations for components in a simple declarative way.
Getting Started
npm i framer-motion
or
yarn add framer-motion
Creating an animation is as simple as it gets! All you have to do is import the motion component and use its "animate" property to change the value of an attribute or a style.
If the set value is different to the element's style or the value set in the "initial" prop framer motion will automatically create an animation.
In addition the motion component gives us access to the "transition" prop which lets us control the animation's duration, delay, type or whether we want the animation to loop.
<motion.divanimate={{ scale: 1.5 }}transition={{ duration: 1, repeat: Infinity, repeatType: "reverse" }}/>
1. Use Variants
Variants are objects that contain all the necessary information to create animations. They are passed to the "variants" prop of the motion component and are used to control the elements animation state.
Using variants we avoid writing inline code and we make our code more organized and easier to read.
If we alter the variant of a motion component that has children the change we made in the parent's animate property will affect all its children, making it easy to control whole groups of elements with just one state change.
const parentVariant = {hidden: {scale: 1},visible: {opacity: 1,scale: 2,transition: {duration: 0.5,delayChildren: 0.5}}}const childVariant = {hidden: {scale: 0},visible: {scale: 1}}<motion.divvariants={parentVariant}initial="hidden"animate={isVisible ? "visible" : "hidden"}onClick={() => {setIsVisible((prev) => setIsVisible(!prev));}}><motion.div variants={childVariant} /><motion.div variants={childVariant} /><motion.div variants={childVariant} /><motion.div variants={childVariant} /></motion.div>
2. Create Dynamic Variants
Sometimes you want to create an animation that's only slightly different for each element. That's where dynamic variants come in handy.
We can accomplish that by making a function that returns a variant object and has as parameters the values we want to differentiate.
const childVariant = (scale) => ({hidden: {scale: 0},visible: {scale: scale,transition: {repeat: Infinity,duration: 2,repeatDelay: 3}}});<motion.div initial="hidden" animate="visible"><motion.div variants={childVariant(0.8)} /><motion.div variants={childVariant(1)} /><motion.div variants={childVariant(1.2)} /><motion.div variants={childVariant(1.4)} /></motion.div>
3. Targeted Transition Property
In more complex animations you don't always want all the attributes to animate for the same duration. For example, you might want an element's opacity animation to complete in 1 second, but its translateX animation to complete in 2 seconds.
All you have to do is pass an object inside the transition object that has as its key the name of the attribute you want to target.
<motion.divinitial={{ opacity: 0, x: -100}}animate={{ opacity: 1, x: 0}}transition={{opacity: {duration: 1},x: {duration: 2}}}/>
4. Animate SVGs
Animating SVGs is very similar to all other components. You turn the path element of the SVG into a motion component and use its attributes to create animations.
You can animate the SVG's fill, stroke, pathLength attributes and even the coordinates of the path itself inside the d attribute!
<svg width={300} viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><motion.pathstroke="yellow"d="M 1 10 h 30"initial={{ pathLength: 0 }}animate={{ pathLength: 1 }}transition={{ duration: 3 }}/></svg>
5. Layout Animations
Attributes that affect the components layout such as changes in position, flex and grid related attributes need a special property called layout to be animated correctly.
You have to set this property to true and change the component's style, through the style property or className, based on some state's value.
The component will then be automatically animated to its new position other components that have this prop and are affected by this change will also be automatically animated.
One use case that I've found particularly useful is animating a component from it's normal position to a fixed position on the screen, for example when the user scrolls down.
<motion.buttonlayoutstyle={isFixed ? { position: "fixed", bottom: 20 } : { position: "relative" }}/>
I hope you found this post useful in some way and learned something new! As always the best way to learn is to write the code yourself and experiment with it.
Below are links to working examples of the things I covered in this post and the official documentation of Framer Motion: