Animations with Framer Motion
Here are some examples of simple animations with Framer Motion. Specifically how to animate the path
of an svg.
npm install framer-motion
import React from "react";
import { motion } from "framer-motion";
const iconVariants = {
hidden: {
pathLength: 0,
stroke: "rgba(24, 56, 143, 0)",
},
visible: {
pathLength: 1,
stroke: "rgba(24, 56, 143, 1)",
},
};
const Logo = () => {
return (
<svg height="48px" viewBox="0 0 13 15">
<motion.path
fill="transparent"
d="M0 14V1l6.5 6.5L13 1v13l-3.25-3.25L6.5 14l-3.25-3.25z"
//
initial="hidden"
animate="visible"
variants={iconVariants}
/>
</svg>
);
};
export default Logo;
The delay
and duration
can also be changed. I set the duration
to 1.5
since the default is quite short.
...
variants={iconVariants}
transition={{
delay: 0.3,
duration: 1.5,
}}
To only start animating when it appears in the viewport, we can manually start the animation with the help of the Intersection Observer API.
npm install react-intersection-observer
import React, { useEffect } from "react";
import { useInView } from "react-intersection-observer";
import { motion, useAnimation } from "framer-motion";
const Logo = (props) => {
const controls = useAnimation();
const [ref, inView] = useInView();
useEffect(() => {
if (inView) {
controls.start("visible");
}
}, [controls, inView]);
return (
<svg>
<motion.path
// we pass the ref to attach the intersection observer
ref={ref}
variants={{
"hidden": { ... },
"visible": { ... }
}}
initial="hidden"
// animate="visible"
animate={controls}
/>
</svg>
)
}
export default Logos
Instead of giving animate
the string "visible"
we pass it the controls
.
And when inView
changes, the animation is started with controls.start("visible");
.
Framer Motion is quite powerful but still easy to use. The attributes whileHover
and whileTap
for example are great to animate a button.
import React from "react";
import Link from "next/link";
import { motion } from "framer-motion";
const ButtonLink = ({ href, className = "", children, ...rest }) => {
className = `bg-yellow-500 hover:bg-yellow-600 text-white transition-colors py-3 px-5 rounded-md text-center ${className}`;
return (
<Link href={href} passHref>
<motion.a
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
className={className}
{...rest}
>
{children}
</motion.a>
</Link>
);
};