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.pathfill="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 observerref={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.awhileHover={{ scale: 1.1 }}whileTap={{ scale: 0.9 }}className={className}{...rest}>{children}</motion.a></Link>)}