How to create Tinder card swipe gesture using React and framer-motion ?

28 Oct, 2021
We can create a simple tinder app like swipe gesture using the following approach using the Framer module in ReactJS.
Prerequisites:
Knowledge of JavaScript (ES6)Knowledge of HTML/CSS.Basic knowledge of ReactJS.
Knowledge of JavaScript (ES6)
Knowledge of HTML/CSS.
Basic knowledge of ReactJS.
Framer hooks used in building this application are:
Framer useMotionValueFramer useTransformFramer useAnimation
Framer useMotionValue
Framer useTransform
Framer useAnimation
Creating React Application And Installing Module:
Step 1: Create a React application using the following command.
npx create-react-app tinder-swipe
Step 2: After creating your project folder i.e. tinder-swipe, move to it using the following command.
cd tinder-swipe
Step 3: After creating the ReactJS application, Install the framer modules using the following command.
npm install framer
Project structure: Our project structure tree should look like this:
Project structure
Approach:
We are going to use useMotionValue() to move the card as the user drags the cursor as all motion components internally use motionValues to track the state and velocity of an animating value which we’re going to get through this hook.
We are going to use useTransform() hook to rotate the card as the card moves on drag by chaining motionValue of the card with it.
Also, we are going to use useTransform() hook to change the opacity of the card as it moves by chaining it to the motionValue.
useAnimation() is a utility hook and is used to create animation controls (animControls) which can be used to manually start, stop and sequence animations on the card.
Example 1: 
index.js
import React from "react";import ReactDOM from "react-dom";import "./index.css";import { Frame, useMotionValue, useTransform, useAnimation } from "framer";  // Some styling for the cardconst style = {  backgroundImage: "URL(https://img.icons8.com/color/452/GeeksforGeeks.png)",  backgroundRepeat: "no-repeat",  backgroundSize: "contain",  backgroundColor: "#55ccff",  boxShadow: "5px 10px 18px #888888",  borderRadius: 10,  height: 300,};  const App = () => {  // To move the card as the user drags the cursor  const motionValue = useMotionValue(0);    // To rotate the card as the card moves on drag  const rotateValue = useTransform(motionValue, [-200, 200], [-50, 50]);    // To decrease opacity of the card when swiped  // on dragging card to left(-200) or right(200)  // opacity gradually changes to 0  // and when the card is in center opacity = 1  const opacityValue = useTransform(    motionValue,    [-200, -150, 0, 150, 200],    [0, 1, 1, 1, 0]  );    // Framer animation hook  const animControls = useAnimation();    return (    <div className="App">      <Frame        center        // Card can be drag only on x-axis        drag="x"        x={motionValue}        rotate={rotateValue}        opacity={opacityValue}        dragConstraints={{ left: -1000, right: 1000 }}        style={style}        onDragEnd={(event, info) => {          // If the card is dragged only upto 150 on x-axis          // bring it back to initial position          if (Math.abs(info.point.x) <= 150) {            animControls.start({ x: 0 });          } else {            // If card is dragged beyond 150            // make it disappear            // making use of ternary operator            animControls.start({ x: info.point.x < 0 ? -200 : 200 });          }        }}      />    </div>  );};  ReactDOM.render(<App />, document.getElementById("root"));
index.css
body {  margin: 0;  font-family: -apple-system, BlinkMacSystemFont,                'Segoe UI', 'Roboto', 'Oxygen',               'Ubuntu', 'Cantarell', 'Fira Sans',                'Droid Sans', 'Helvetica Neue',                sans-serif;  -webkit-font-smoothing: antialiased;  -moz-osx-font-smoothing: grayscale;}  .App {  text-align: center;}  code {  font-family: source-code-pro, Menlo,                Monaco, Consolas, 'Courier New',    monospace;}
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:
Tinder like card swipe gesture
Example 2:Creating a deck of cards
index.js
import React from 'react';import ReactDOM from 'react-dom';import './index.css';import { Frame, useMotionValue, useTransform, useAnimation } from 'framer';  // Card component with destructured propsconst Card = ({ image, color }) => {  // To move the card as the user drags the cursor  const motionValue = useMotionValue(0);    // To rotate the card as the card moves on drag  const rotateValue = useTransform(motionValue, [-200, 200], [-50, 50]);    // To decrease opacity of the card when swiped  // on dragging card to left(-200) or right(200)  // opacity gradually changes to 0  // and when the card is in center opacity = 1  const opacityValue = useTransform(    motionValue,    [-200, -150, 0, 150, 200],    [0, 1, 1, 1, 0]  );    // Framer animation hook  const animControls = useAnimation();    // Some styling for the card  // it is placed inside the card component  // to make backgroundImage and backgroundColor dynamic  const style = {    backgroundImage: `url(${image})`,    backgroundRepeat: 'no-repeat',    backgroundSize: 'contain',    backgroundColor: color,    boxShadow: '5px 10px 18px #888888',    borderRadius: 10,    height: 300  };    return (    <div className='App'>      <Frame        center        // Card can be drag only on x-axis        drag='x'        x={motionValue}        rotate={rotateValue}        opacity={opacityValue}        dragConstraints={{ left: -1000, right: 1000 }}        style={style}        onDragEnd={(event, info) => {                    // If the card is dragged only upto 150 on x-axis          // bring it back to initial position          if (Math.abs(info.point.x) <= 150) {            animControls.start({ x: 0 });          } else {                        // If card is dragged beyond 150            // make it disappear              // Making use of ternary operator            animControls.start({ x: info.point.x < 0 ? -200 : 200 });          }        }}      />    </div>  );};  const App = () => {  const cards = [    {      image: 'https://img.icons8.com/color/452/GeeksforGeeks.png',      color: '#55ccff'    },    {      image: 'https://img.icons8.com/color/452/GeeksforGeeks.png',      color: '#e8e8e8'    },    {      image: 'https://img.icons8.com/color/452/GeeksforGeeks.png',      color: '#0a043c'    },    {      image: 'https://img.icons8.com/color/452/GeeksforGeeks.png',      color: 'black'    }  ];    return (    <div className='App'>            {/* Traversing through cards arrray using map function      and populating card with different image and color */}              {cards.map((card) => (        <Card image={card.image} color={card.color} />      ))}    </div>  );};  ReactDOM.render(<App />, document.getElementById('root'));
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:
Swipeable deck of cards
akshaysingh98088
React-Questions
Technical Scripter 2020
ReactJS
Technical Scripter
Web Technologies
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
How to create a multi-page website using React.js ?
ReactJS useNavigate() Hook
Axios in React: A Guide for Beginners
How to do crud operations in ReactJS ?
React-Router Hooks
Installation of Node.js on Linux
How to insert spaces/tabs in text using HTML/CSS?
Top 10 Projects For Beginners To Practice HTML and CSS Skills
How to create footer to stay at the bottom of a Web page?
How to set the default value for an HTML <select> element ?