مقدمه‌ای بر Framer Motion در React

آفلاین
user-avatar
عرفان حشمتی
14 شهریور 1400, خواندن در 6 دقیقه

این مقاله به نحوه ایجاد انیمیشن با React می‌پردازد. Framer Motion یک کتابخانه آماده برای ایجاد انیمیشن با استفاده از ری‌اکت است. به عنوان یک توسعه دهنده وب برای خود من بسیار هیجان انگیز است، زیرا می‌توانم با استفاده از فناوری‌هایی که قبلا با آنها آشنا هستم، انیمیشن بسازم.

بنابراین در این مقاله Framer Motion را همراه با ویژگی‌های اصلی و مثال‌های آن با React، React Hooks و Styled Components مورد بررسی قرار می‌دهیم.

شروع کار با Framer Motion

Framer Motion با انواع انیمیشن‌های مختلف مانند انیمیشن‌های spring، keyframeها و gestureها همراه است و شما می‌توانید به راحتی از این ترکیب‌های اساسی برای ایجاد انیمیشن‌های پیچیده استفاده کنید.

بنابراین بیایید همه چیز را با اضافه کردن Framer Motion به پروژه React خود شروع کنیم.

توجه: Framer-Motion مستلزم استفاده از React نسخه 16.8 یا بالاتر است.

برای نصب Framer Motion که بیش از 400 هزار دانلود در هفته دارد، می‌توانید از NPM استفاده کنید:

npm install framer-motion

بله، شما Framer Motion را با موفقیت در پروژه React خود نصب کردید. اکنون درباره سینتکس‌های اساسی Framer Motion با چند مثال بحث خواهیم کرد.

انیمیشن‌های ساده

کامپوننت‌های حرکتی یکی از عناصر اصلی در Framer Motion هستند و بیشتر انیمیشن‌ها در Framer Motion از طریق خصوصیت انیمیشن انعطاف پذیر کامپوننت حرکتی کنترل می‌شوند.

خصوصیت Animate

می‌توانید با استفاده از خصوصیت animate یک کامپوننت را متحرک کنید تا موقعیت، مقیاس، چرخش، رنگ یا تیرگی آن را به راحتی تغییر دهید.

برای استفاده از این خصوصیت فقط باید کامپوننت motion را از کتابخانه Framer Motion ایمپورت کنید. بسته به نیاز خود می‌توانید از پراپ animate به طرق مختلف استفاده کنید:

<motion.div animate={{ x: 100, scale:1.5, rotate:90 }} />

در مثال بالا تگ div به راست 100px حرکت می‌کند، 1.5 برابر اندازه اصلی خود بزرگتر شده و 90 درجه می‌چرخد.

خصوصیت Transition

از پراپ animate به ندرت تنها استفاده می‌شود و معمولا همراه با خصوصیت transition می‌آید.

پراپ transition به شما امکان می‌دهد انواع مختلف انیمیشن را با عبور از یک نوع ترنزیشن مانند tween، spring یا inertia تنظیم کنید.

خصوصیات فیزیکی مانند x و scale به طور پیش فرض از طریق spring متحرک می‌شوند، در حالی که مقادیری مانند opacity و color با tween متحرک می‌شوند. برای تغییر خصوصیاتی مانند duration، delay و stiffness انیمیشن نیز می‌توانید از transition استفاده کنید.

<motion.div
  animate={{ y: [0, 150, 150, 0], rotate: 90 }}
  transition={{ duration: 3, repeat: Infinity }}
/>

در مثال بالا متوجه خواهید شد که من برای انیمیشن محور "y" از یک آرایه به جای مقدار واحد استفاده کرده‌ام. این مقادیر به عنوان keyframeها عمل می‌کنند و به شما امکان می‌دهد از طریق هر مقدار در آرایه المان‌ها را متحرک کنید. duration و repeat برای نگه داشتن انیمیشن در یک حلقه با مدت زمان 3 ثانیه استفاده می‌شود.

همچنین من کامپپوننت متحرک شده را با استفاده از Bit توسعه داده و به اشتراک گذاشته‌ام. شما نیز می‌توانید آن را بررسی کنید، به صورت پکیج نصب کنید یا کلون را به فضای کاری Bit خود ایمپورت کنید.

خصوصیت Varients

اگر می‌خواهید انیمیشن‌هایی ایجاد کنید که در سرتاسر DOM انتشار یابند، می‌توانید از varients برای تنظیم دقیق آنها استفاده کنید.

Varients مجموعه‌ای از اشیا هدف از پیش تعریف شده است که با استفاده از پراپ varients به کامپوننت‌های حرکتی منتقل می‌شود.

با استفاده از varients می‌توانید به پراپ‌های transition اضافی مانند when ، delayChildren و staggerChildren دسترسی پیدا کنید که به کامپوننت‌های والد اجازه می‌دهد تا اجرای انیمیشن‌های فرزند را ترتیب دهند.

بیایید نگاهی به مثالی از انیمیشن ساید منو (منوی کناری) بیندازیم که با خصوصیت variants ساخته شده است.

import * as React from "react";
import { motion } from "framer-motion";

const variants = {
 open: {
  transition: { staggerChildren: 0.07, delayChildren: 0.2 }
 },
 closed: {
  transition: { staggerChildren: 0.05, staggerDirection: -1 }
 }
};
export const Navigation = () => (
  <motion.ul variants={variants}>
    {itemIds.map(i => (
      <MenuItem i={i} key={i} />
    ))}
  </motion.ul>
);
const itemIds = [0, 1, 2, 3, 4];

در مثال بالا از پراپ‌های staggerChildren و delayChildren برای به تأخیر انداختن انتقال آیتم‌های منو استفاده می‌شود. علاوه بر این از پراپstaggerDirection  برای تعیین جهت متناوب استفاده می‌گردد.

به همین ترتیب پراپ‌های بسیاری در Framer Motion موجود است که در کمترین زمان می‌توانید از آنها برای افزودن انیمیشن و انتقال به پروژه React خود استفاده کنید.

Gestureها

Framer Motion شامل یک سیستم تشخیص حرکت پیشرفته برای مرورگر است.

این مجموعه اصلی شنوندگان رویداد را با شناسههای رابط کاربر گسترش میدهد تا حرکاتی مانند hover، focus، tap و drag را تشخیص دهد.

Hover

وقتی نشانگر روی یک کامپوننت قرار می‌گیرد، می‌توانید از حرکات hover برای ایجاد انیمیشن استفاده کنید. سه پراپ  hoverدر دسترس است: whileHover ، onHoverStart و onHoverEnd.

در مثال زیر از propHaveHover استفاده کرده‌ام. وقتی کاربری روی کامپوننت قرار بگیرد، مقیاس بندی می‌شود و میزان opacity را روی 1 تنظیم می‌کند.

<motion.div whileHover={{ scale: 1.2, opacity: 1 }}>
  Hover Over Me!
</motion.div>

 

Focus

زمانی که کامپوننت‌ها فوکوس می‌شوند، می‌توانید از پراپ focus برای متحرک‌سازی فیلد‌های ورودی استفاده کنید. whileFocus تنها پراپ موجود برای حرکت فوکوس است و می‌تواند به طور مشابه با whileHover استفاده شود. 

<motion.input whileFocus={{ scale: 1.2 }} />

Tap

هنگامی که نشانگر را روی یک کامپوننت کلیک کرده و سپس آن را رها می‌کنید، می‌توانید از پراپ tap استفاده کرده و آن را متحرک کنید.

4 پراپ tap موجود است:

  • whiletap - برای متحرک سازی هنگام کلیک روی کامپوننت:
<motion.div whileTap={{ scale: 0.5 }} />
  • onTap - هنگامی که حرکت tap با موفقیت پایان یابد، فراخوانی می‌شود.
function onTap(event, info) { ... } 
<motion.div onTap={onTap} />
  • onTapStart - هنگام شروع حرکت tap فراخوانی می‌شود.
function onTapStart(event, info) { ... }
<motion.div onTapStart={onTapStart} />
  • onTapCancel - هنگامی که tap لغو شد، فراخوانی می‌شود.
function onTapCancel(event, info) { ... }
<motion.div onTapCancel={onTapCancel} />

Drag

حرکت drag اجازه می‌دهد تا عمل درگ کردن یک کامپوننت متحرک شود. می‌توانید drag را بر روی محور "x"، محور "y" یا هر دو فعال کنید.

برای فعال کردن drag در امتداد محور "x" می‌توانید از drag=“x” استفاده کنید. بیایید به یک نمونه از پراپ drag با برخی از ویژگی‌های اضافی آن نگاه کنیم.

در مثال زیر drag برای هر دو جهت x و y فعال است. اگر می‌خواهید فقط به جهت x محدود شود، می‌توانید مقدار خاصیت درگ را روی "x" تنظیم کنید: drag=“x”

<motion.div
  drag
  dragTransition={{
    min: 0,
    max: 100,
    bounceStiffness: 100
  }}
>
 Drag Me!
</motion.div>

انیمیشن‌هایLayout 

با استفاده از Framer Motion می‌توانید با بهره گیری از پراپ layout هرگونه تغییر طرح در یک کلامپوننت را متحرک کنید.

با تنظیم پراپ layout به true می‌توانید تغییرات طرح بندی مانند تغییر استایل کامپوننت، مرتب سازی مجدد لیست، تغییر فلکس باکس یا گرید و... را متحرک کنید.

در مثال زیر layout با تغییر محتوای justify بین flex-start و flex-end و تغییر رنگ پس زمینه متحرک می‌شود.

const divStyle = {
  background: "#6F3C8E",
  padding: 0,
  margin: 0,
  height: "100vh",
  display: "flex",
  justifyContent: "center",
  alignItems: "center",
};

const switchStyle = {
  width: "160px",
  height: "85px",
  backgroundColor: "rgba(255, 255, 255, 0.4)",
  display: "flex",
  justifyContent: "flex-start",
  borderRadius: "50px",
  padding: "10px",
  cursor: "pointer",
};

const switchStyle2 = {
  width: "160px",
  height: "85px",
  backgroundColor: "rgba(188, 252, 151, 0.884)",
  display: "flex",
  justifyContent: "flex-end",
  borderRadius: "50px",
  padding: "10px",
  cursor: "pointer",
};

const toggleStyle = {
  width: "80px",
  height: "80px",
  backgroundColor: "white",
  borderRadius: "40px",
};
export function LayoutAnimation() {
  const [isOn, setIsOn] = useState(false);

  const toggleSwitch = () => {
    setIsOn(!isOn);
    console.log(isOn);
  };

  return (
    <div style={divStyle}>
      <div
        style={isOn ? switchStyle : switchStyle2}
        data-isOn={isOn}
        onClick={toggleSwitch}
      >
        <motion.div style={toggleStyle} layout transition={spring} />
      </div>
    </div>
  );
}

const spring = {
  type: "spring",
  stiffness: 700,
  damping: 30,
};

توجه: انیمیشن‌های layout تأثیری در کامپوننت‌های display: inline یا کامپوننت‌های SVG ندارند.

انیمیشن‌های Shared Layout

با استفاده از کامپوننت‌های سازنده AnimateSharedLayout می‌توانید انیمیشن‌های shared layout را پیاده سازی کنید.

تمام کاری که باید انجام دهید این است که کامپوننت AnimateSharedLayout را ایمپورت کرده و تمام کامپوننت‌های layout مورد نیاز برای اشتراک گذاری انیمیشن را استفاده کنید. سپس هنگامی که یکی از کامپوننت‌های layout در AnimateSharedLayout طرح خود را تغییر می‌دهد، تمام کامپوننت‌های layout دیگر بر این اساس متحرک می‌شوند.

<AnimateSharedLayout>
  <motion.ul layout initial={{ borderRadius: 25 }}>
   {items.map(item => (
    <Item key={item} />
   ))}
  </motion.ul>
</AnimateSharedLayout>

اکنون شما درک خوبی از نحوه کار Framer Motion و چگونگی ساخت انیمیشن با استفاده از آن دارید. دانشی که در این مقاله جمع آوری کرده‌اید مطمئنا به شما کمک می‌کند تا با Framer Motion شروع به کار کنید.

اما اگر می‌خواهید که از این انیمیشن‌ها در سطح تولید استفاده کنید، باید تجربه عملی کار با Framer Motion داشته باشید. بنابراین شما را تشویق می‌کنم که این مثال‌ها را خودتان انجام دهید و ببینید چه اتفاقی می‌افتد.

منبع

چه امتیازی به این مقاله می دید؟
خیلی بد
بد
متوسط
خوب
عالی

دیدگاه‌ها و پرسش‌ها

برای ارسال دیدگاه لازم است، ابتدا وارد سایت شوید.

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

آفلاین
user-avatar
عرفان حشمتی @heshmati74
مهندس معماری سیستم های کامپیوتری، طراح و توسعه دهنده وب سایت
دنبال کردن

گفتگو‌ برنامه نویسان

بخشی برای حل مشکلات برنامه‌نویسی و مباحث پیرامون آن وارد شو