To avoid repetition and hard to read code, using variants in framer-motion provides predefined object sets that can be used in a declarative way to define animations.
To leverage these variants, we pass the objects with their key and property pairs that define our animation.
Below is one such object:
const bannerVarients = {
subtleIn: {
x: x,
rotate: 0.5,
},
subtleOut: {
rotate: 0.5,
x: x,
boxShadow: "18px 18px 0 rgba(0, 0, 0, 0.2)",
},
overthetopIn: {
x: x,
rotate: 360,
boxShadow: "18px 18px 0 rgba(0, 0, 0, 0.2)",
},
overthetopOut: {
rotate: 0,
x: x,
boxShadow: "18px 18px 0 rgba(0, 0, 0, 0.2)",
},
};
Here we have defined objects with accompanying key value pairs to define different animation effects.
We can pass in appropriate options depending on our needs. In this case, I am passing in props from a parent component, defining particular options and making this customized animation reusable.
export const AnimatedBanner = ({ typeIn, typeOut }) => {
let x = window.innerWidth / 2;
const bannerVarients = {
subtleIn: {
x: x,
rotate: 0.5,
},
subtleOut: {
rotate: 0.5,
x: x,
boxShadow: "18px 18px 0 rgba(0, 0, 0, 0.2)",
},
overthetopIn: {
x: x,
rotate: 360,
boxShadow: "18px 18px 0 rgba(0, 0, 0, 0.2)",
},
overthetopOut: {
rotate: 0,
x: x,
boxShadow: "18px 18px 0 rgba(0, 0, 0, 0.2)",
},
};
/*
in this case,
typeIn = "overthetopIn"
typeOut = "overthetopOut"
*/
return (
<motion.div
style={{
height: "3rem",
minWidth: "15rem",
background: "linear-gradient(90deg,#009688 0%,#c6ff00 75%)",
textAlign: "center",
padding: "5px 15px 5px 15px",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
initial={typeIn}
animate={typeOut}
transition={{
type: "tween",
ease: "easeInOut",
repeat: Infinity,
repeatType: "reverse",
repeatDelay: 3,
duration: 12,
delay: 2,
}}
variants={bannerVarients}
>
Read My Blog for more cool stuff
</motion.div>
);
};
The variants property takes in the bannerVariants object with the help of the framer-motion library. The initial and animate props are restricted only to your animation imagination.