Animated expanding card using framer-motion and ReactJS

In this article, we are going to learn how to create an animated expanding card using react and framer.
Prerequisites:
- Knowledge of JavaScript (ES6).
JavaScript inbuilt methods we are going to make use are : 
- Knowledge of HTML/CSS.
- Basic knowledge of ReactJS
React hooks used in building this application are:
Framer: components and hooks we are going to make use of in this tutorial are :
- https://www.framer.com/api/frame/
- https://www.framer.com/api/scroll/
- https://www.framer.com/api/utilities/#useanimation
Creating React Application And Installing Module :
- 
Step 1: Now, you will start a new project using create-react-app so open your terminal and type. $ npx create-react-app animated-card 
- 
Step 2: After creating your project folder i.e. animated-card, move to it using the following command. $ cd animated-card 
- 
Step 3: Add the npm packages you will need during the project. $ npm install framer react-icons // For yarn $ yarn add framer react-icons 
Open the src folder and delete the following files :
- logo.svg
- serviceWorker.js
- setupTests.js
- App.css
- App.js
- App.test.js (if any)
Create a file named Card.js.
Project structure: Your project structure tree should look like this :
 
Project structure
Example:
index.js
| import React from "react"; import { Frame, Scroll } from "framer"; import Card from "./Card"; import ReactDOM from "react-dom";  import "./index.css";  // main App HOC export const App = () => {   return(     <Frame height={"100%"} width={"100%"} background={"#333"}>       <Frame width={375} height={"100%"} background={"#FFF"} center>         <Scroll width={375} height={"100%"}>           {/* Card component with props yPos,title,subtitle */}           <Card             yPos={48}             title={"GEEKSFORGEEKS"}             subtitle="Don't learn alone"          />           <Card             yPos={48 + 300 + 24}             title={"reactJS"}             subtitle="Most starred JavaScript library"          />         </Scroll>       </Frame>     </Frame>   ); };  const rootElement = document.getElementById("root"); ReactDOM.render(<App />, rootElement);  | 
index.css
| body {   margin: 0;   cursor: pointer; } | 
Card.js
| import React, { useState } from "react"; import { ImCross } from "react-icons/im"; import { Frame, Scroll, useAnimation } from "framer";  // Card component with destructured props : // yPos, title, subtitle const Card = ({ yPos, title, subtitle }) => {    // useState hook to manage the state of   // expanding of card   const [state, setState] = useState(false);    // utility function to handle   // onTap on card component   const handleTap = () => {     state ? controls.start({ y: 0 }) : setState(!state);   };    const controls = useAnimation();    // Variants allow you to define animation   // states and organise them by name.   // They allow you to control animations    // throughout a component   // tree by switching a single animate prop.   const variants = {     active: {       width: 320,       height: 800,       borderRadius: 0,       overflow: "visible",       left: 28,       right:0,       y: 0,       transition: { duration: 0.125,                      type: "spring",                      damping: 10,                      mass: 0.6 }     },     inactive: {       width: 280,       height: 280,       borderRadius: 24,       overflow: "hidden",       left: 45,       y: yPos,       transition: { duration: 0.125,                      type: "spring",                      damping: 10,                     mass: 0.6 }     }   };    return(     // basic container for layout, styling,     // animation and events.     <Frame       y={yPos}       variants={variants}       animate={state ? "active": "inactive"}       width={300}       height={300}       borderRadius={24}       style={state ? { zIndex: 10 } : { zIndex: 1 }}       left={37.5}       onTap={handleTap}       shadow={         state           ? "0 0 0 0 rgba(0, 0, 0, 0)"          : "0px 0px 20px 0px rgba(0, 0, 0, .25)"      }     >       <Scroll         width="100%"        height="100%"        backgroundColor={null}         scrollAnimate={controls}       >         <Frame           position="relative"          backgroundColor={"#09a960"}           width="100%"          height={300}         />         <Frame position="relative"               height={1200}                 background="white"/>          <Frame           top={20}           left={20}           height={""}           width={""}           background={null}           style={{             color: "white",             fontFamily: "sans-serif"          }}         >           <span style={{ fontSize: "1.6em",                           fontWeight: 600 }}>                         {title}           </span>           <br />           <span             style={{               fontSize: "1em",               fontWeight: 500,               opacity: 0.5             }}           >             {subtitle}           </span>         </Frame>       </Scroll>       {state && (         <Frame           borderRadius={20}           size={15}           top={15}           right={20}           backgroundColor={"#09a960"}           onTap={() => {             setState(false);           }}         >           <ImCross color="red"/>         </Frame>       )}     </Frame>   ); };  export defaultCard;  | 
Step to Run Application: Run the application using the following command from the root directory of the project.
npm start
Output: Now open your browser and go to http://localhost:3000/, you will see the following output:
 
				 
					


