Как создать жест смахивания карты Tinder с помощью React и framer-motion?
Мы можем создать простое приложение Tinder, такое как жест смахивания, используя следующий подход, используя модуль Framer в ReactJS.
Предпосылки:
- Знание JavaScript (ES6)
- Знание HTML/CSS.
- Базовые знания ReactJS.
Крюки Framer, используемые при создании этого приложения:
- Framer useMotionValue
- Использование FramerTransform
- Использование FramerАнимация
Создание приложения React и установка модуля:
Шаг 1: Создайте приложение React с помощью следующей команды.
npx create-react-app tinder-swipe
Шаг 2: После создания папки проекта, т. е. Tinder-swipe, перейдите к ней с помощью следующей команды.
cd tinder-swipe
Шаг 3: После создания приложения ReactJS установите модули фреймов с помощью следующей команды.
npm install framer
Структура проекта: Дерево структуры нашего проекта должно выглядеть так:
Подход:
- Мы собираемся использовать useMotionValue() для перемещения карты, когда пользователь перетаскивает курсор, поскольку все компоненты движения внутренне используют motionValues для отслеживания состояния и скорости анимируемого значения, которое мы собираемся получить с помощью этого хука.
- Мы собираемся использовать хук useTransform() для поворота карты по мере того, как карта движется при перетаскивании, связывая с ней motionValue карты.
- Кроме того, мы собираемся использовать хук useTransform() для изменения непрозрачности карты при ее перемещении, привязав ее к motionValue.
- useAnimation() — это служебный хук, который используется для создания элементов управления анимацией (animControls), которые можно использовать для ручного запуска, остановки и последовательности анимации на карте.
Пример 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 card const style = { backgroundImage: "URL( 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 ; } |
Шаг для запуска приложения: Запустите приложение с помощью следующей команды из корневого каталога проекта.
npm start
Вывод: теперь откройте браузер и перейдите по адресу http://localhost:3000/ , вы увидите следующий вывод:
Пример 2: Создание колоды карт
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 props const 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 = [ { color: "#55ccff" }, { color: "#e8e8e8" }, { color: "#0a043c" }, { 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" )); |
Шаг для запуска приложения: Запустите приложение, используя следующую команду из корневого каталога проекта:
npm start
Вывод: теперь откройте браузер и перейдите по адресу http://localhost:3000/ , вы увидите следующий вывод: