الرسومات المتحركة هي ما يجعل من المواقع البسيطة تتحول إلى تجارب مشوقة ولا تنسي على المدى الطويل. إنها تعطي موقعك جزءًا من الشخصية والفريدة وتترك الزائر يعجب بالجمال العام للموقع.

من الواضح أن البشر يحبون الأشياء الجميلة. نحن جميعًا نحب المنتجات التي تبدو سهلة النظر.

في هذا المقال سنتعلم كيفية إنشاء رسومات تدهش المستخدمين باستخدام Framer motion و React-Router-Dom.

الأحداث الملازمة

لكي نتمكن من تتبع ما نقوم به في هذا المقال، يجب أن يكون لديك بعض المعرفة بReact، Framer motion و React-Router-DOM.

لتعلم Framer motion بشكل أفضل، يمكنك البحث في دورياتهم.

Node.js يجب أيضًا أن يكون مثبتًا على نظامك، ويجب أن يكون لديك محرر كود يعمل. سأستخدم VS Code.

كيفية إعداء المشروع

سنستعمل Vite لإنشاء بيئة تطوير React لمشروعنا.

  1. افتح السجل الفوري في VScode. يمكنك استخدام Ctrl + backtick(`)

  2. في سجلك، أدخل الأمر التالي:

npm create vite@latest
  1. تتبع التقاءات لتسمي مشروعك وتختار قاعدة تطويرك المرغوب فيها. في حالتنا ، نستخدم React. سيكون هذا مشروع لJavaScript.

  2. أذهب إلى دليل مشروعك واستخدم npm i في المحرر.

  3. لتشغيل مشروعك قم باستخدام npm run dev.

  4. أتذكر أن تنظف مشروعك بإزالة البرمجيات في App.js وficeros الCSS في المجلد src.

كيفية تشغيل Framer Motion و React-Router-DOM

  1. لتثبيت Framer-motion في مشروعك أفتح المحرر وأدخل:
npm i framer-motion
  1. لتثبيت React-Router-DOM في مشروعك أفتح المحرر وأدخل:
npm i react-router-dom

كيفية إنشاء مكونات وتوجيه بسيط بواسطة React-Router-DOM

دعونا نستعمل مكوناتنا والصفحات التي سنتوجيه إليها لهذا المشروع.

  1. في src، قم بإنشاء مجلد جديد يدعى components.

  2. سنضيف أربع ملفات في هذا المجلد وسيكون لأسماءها Home.jsx، About.jsx، Projects.jsx و Navbar.jsx.

  3. في الثلاثة أولى، سنصنع مكون وظيفي لـ React. قم بتغيير محتوى العلامة h1 في كل مكون:

const Home = () => {
 return (
    <div>
     <h1>Home</h1>
    </div>
 )
 }

 export default Home
  1. في Navbar، سنقوم بإستيراد Link من React-Router-DOM لإنشاء عناصر الرابط. ومن ثم سنقوم بإنشاء حاوية تحتوي على شعارنا وروابط القائمة. سيشكل الشعار الرابط الذي يشير إلى صفحتنا الرئيسية.
import {Link} from "react-router-dom"

const Navbar () => {
 return (
     <div className="nav">
      <div className="logo">
         <Link className="nav-link" to="/">Lennythedev</Link>
     </div>
     <div>
        <div className="nav-links">
           <div className="nav-item">
            <Link className="nav-link" to="/">Home</Link>
           </div>
           <div className="nav-item">
            <Link className="nav-link" to="/">About</Link>
           </div>
           <div className="nav-item">
            <Link className="nav-link" to="/">Projects</Link>
           </div>
     </div>
     </div>
     </div>
  )
 }
  1. الآن دعونا نذهب إلى ملف index.js أو main.js. الهدف هو تغليف كل تطبيقنا بـ BrowserRouter الذي سيتمكن النظام من التنقل داخل تطبيقنا.
import React from "react"
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <Router>
      <Routes>
        <Route path='/*' element={<App />} />
      </Routes>
    </Router>
  </React.StrictMode>,
)
  1. الآن في App.js، سنقوم بخطوة الإنهاء الأخيرة لتكويننا. سنقوم بإستيراد مكوناتنا، وبعض المزايا من React-Router-DOM ونقوم بعرض مكوناتنا. من خلال استخدام ميزة useLocation من React-Router-DOM، يمكننا تعيين موقع التنقل الحالي للمسارات عن طريق تعيين المفتاح للمسار الحالي.
import './App.css'
import { Routes, Route, useLocation } from 'react-router-dom'
import NavBar from './components/NavBar';
import Home from './components/Home';
import Projects from './components/Projects';
import About from './components/About';

function App() {
  const location = useLocation();
  return (
    <>
       <NavBar />
       <AnimatePresence mode='wait'>
       <Routes location={location} key={location.pathname}>
        <Route index element={<Home />} />
        <Route path='/projects' element={<Projects />}/>
        <Route path='/about' element={<About />}/>
       </Routes>
       </AnimatePresence>
    </>
  )
}

export default App
  1. الآن يمكننا إضافة تنسيقنا في App.css:
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  color: white;
  font-family: "Fira Sans Condensed", sans-serif;
}

html,
body {
  font-family: "Fira Sans Condensed", sans-serif;
  background: rgb(0, 162, 255);
}

.nav {
  position: fixed;
  width: 100%;
  display: flex;
  justify-content: space-between;
}

.nav-links {
  display: flex;
  cursor: pointer;
}

.logo, .nav-item {
  margin: 2em;
  font-weight: 400;
  font-size: 1.5vw;
}

h1{
  width: 80%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  text-align: center;
  font-weight: 500;
  font-size: 10vw;
  line-height: 1;
  text-transform: uppercase;
}

a {
  text-decoration: none;
  font-weight: 500;
}
  1. بعد تتبع جميع الخطوات، يجب أن يبدو تطبيقك كما هو الآتي:

صفحة مصممة بدون تحريك

كيفية إنشاء التحولات باستخدام Framer Motion

والان دعونا نصنع رسماً للانتقالات بين الصفحات.

  1. أنشأ ملفاً في المكونات يسمى Box.jsx و import motion from framer-motion.

  2. يمكننا بعد ذلك إرجاع قسمين من الdivs مع classNames من slide-in و slide-out واحد للدخول المتحرك وآخر للخروج المتحرك.

  3. نضع رسماً ما بين هذه الdivs بمساعدة Framer Motion:

import { motion } from "framer-motion"

export default function Box() {
  return(
    <div>
     <motion.div
        className="slide-in"
        initial={{ scaleY: 0 }}
        animate={{ scaleY: 0 }}
        exit={{ scaleY: 1 }}
        transition={{ duration: 1, ease: [0.22, 1, 0.36, 1] }}
     />
     <motion.div
     className="slide-out"
        initial={{ scaleY: 1 }}
        animate={{ scaleY: 0 }}
        exit={{ scaleY: 0 }}
        transition={{ duration: 1, ease: [0.22, 1, 0.36, 1] }}
     />
    </div>
  )
}
  1. من ثم نضع أساساً تشكيلاتنا في ملفنا الCSS لـ slide-in و slide-out في ملفنا الـ App.css
.slide-in {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  background: #0f0f0f;
  transform-origin: bottom;
}

.slide-out {
  position: fixed;
  top: 0;
  left: 0;
  height: 100vh;
  background: #0f0f0f;
  transform-origin: top;
}
  1. وأخيرًا ، الخطوة الأخيرة هي استخدام AnimatePresence من Framer Motion في ملفنا الـ App.js وتغلق بالكامل التطبيق في AnimatePresence وتحدد الوضع كـ wait. إذا كنت تريد تعلم المزيد عن AnimatePresence يمكنك زيارة وثيقات Framer Motion.
import './App.css'
import { Routes, Route, useLocation } from 'react-router-dom'
import NavBar from './components/NavBar';
import Home from './components/Home';
import Projects from './components/Projects';
import About from './components/About';
import { AnimatePresence } from 'framer-motion';

function App() {
  const location = useLocation();
  return (
    <>
       <NavBar />
       <AnimatePresence mode='wait'>
       <Routes location={location} key={location.pathname}>
        <Route index element={<Home />} />
        <Route path='/projects' element={<Projects />}/>
        <Route path='/about' element={<About />}/>
       </Routes>
       </AnimatePresence>
    </>
  )
}

export default App
  1. وأخيرًا ، ينبغي أن يبدو عملنا ب exact مثل الفيديو أسفل:

ختام

إن إنشاء الرسومات المتعددة الصفحات مع Framer Motion و React-Router-Dom يحسن التجربة المستخدمية عن طريق توفير الانتقالات الناعمة.

تقوم هذه التكامل بتعزيز قدرات إنتاج الرسوم المتحركة في Framer Motion مع ميزات نقل المسارات في React-Router-Dom، مما ينتج عن تطبيقات ويب ديناميكية وتفاعلية.