📜  如何使用 React 和 framer-motion 创建 Tinder 刷卡手势?

📅  最后修改于: 2022-05-13 01:56:55.227000             🧑  作者: Mango

如何使用 React 和 framer-motion 创建 Tinder 刷卡手势?

我们可以使用 ReactJS 中的Framer模块使用以下方法创建一个简单的 tinder 应用程序,例如滑动手势。

先决条件:

  1. JavaScript(ES6)知识
  2. 熟悉 HTML/CSS。
  3. ReactJS 的基础知识。

用于构建此应用程序的 Framer 挂钩是:

  1. 成帧器使用MotionValue
  2. 成帧器使用变换
  3. 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(
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 (
    
       {           // 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 });           }         }}       />     
  ); };    ReactDOM.render(, 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;
}


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 (
    
       {                      // 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 });           }         }}       />     
  ); };    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 (     
             {/* Traversing through cards arrray using map function       and populating card with different image and color */}                {cards.map((card) => (                ))}     
  ); };    ReactDOM.render(, document.getElementById('root'));


索引.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 (
    
       {                      // 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 });           }         }}       />     
  ); };    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 (     
             {/* Traversing through cards arrray using map function       and populating card with different image and color */}                {cards.map((card) => (                ))}     
  ); };    ReactDOM.render(, document.getElementById('root'));

运行应用程序的步骤:从项目的根目录使用以下命令运行应用程序:

npm start

输出:现在打开浏览器并转到http://localhost:3000/ ,您将看到以下输出:

可滑动的纸牌