🎞️ Framer Motion. Animation

Framer Motion: React-এ দারুণ স্মুথ অ্যানিমেশন 🚀

Framer Motion হলো React-এর জন্য একটি সহজ, শক্তিশালী এবং প্রোডাকশন-রেডি অ্যানিমেশন লাইব্রেরি। এটি দিয়ে খুব সহজেই জটিল UI অ্যানিমেশন ডিক্লেয়ারেটিভ উপায়ে তৈরি করা যায় — CSS এর জটিল কীফ্রেম বা @keyframes নিয়ে ভাবতে হবে না, বরং সহজ props ব্যবহার করেই চমৎকার ইফেক্ট যোগ করা যায়।


১. ইনস্টলেশন

প্রথমে আপনার React প্রজেক্টে Framer Motion ইনস্টল করুন:

npm install framer-motion
# অথবা
yarn add framer-motion

২. বেসিক অ্যানিমেশন

Framer Motion-এর মূল জাদু শুরু হয় motion কম্পোনেন্ট দিয়ে। যে কোনো HTML এলিমেন্টকে অ্যানিমেট করতে চাইলে তার আগে motion. বসাতে হয়।

প্রধান props:

  • initial → শুরুতে কেমন দেখাবে
  • animate → শেষে কেমন হবে
  • transition → কত সময়, কেমন টাইমিং, কীভাবে অ্যানিমেট হবে

উদাহরণ:

import { motion } from "framer-motion";
 
export default function BasicBox() {
  return (
    <motion.div
      className="w-40 h-40 bg-red-500 rounded-lg"
      initial={{ opacity: 0, scale: 0.5 }}
      animate={{ opacity: 1, scale: 1 }}
      transition={{ duration: 0.8 }}
    />
  );
}

৩. Keyframe অ্যানিমেশন

একটা অ্যানিমেশনে একাধিক ধাপ দিতে চাইলে keyframes ব্যবহার করতে হবে। animate প্রপ-এ অ্যারে ([]) হিসেবে মান দিলে সেটি ধাপে ধাপে চলবে।

উদাহরণ:

import { motion } from "framer-motion";
 
export default function KeyframeBox() {
  return (
    <motion.div
      className="w-40 h-40 bg-blue-500"
      animate={{
        scale: [1, 1.5, 1, 1.5, 1],
        rotate: [0, 90, 0, -90, 0],
        borderRadius: ["20%", "50%", "20%", "50%", "20%"],
      }}
      transition={{
        duration: 2,
        ease: "easeInOut",
        times: [0, 0.25, 0.5, 0.75, 1],
        repeat: Infinity,
        repeatDelay: 1,
      }}
    />
  );
}

৪. জেসচার অ্যানিমেশন (ইন্টারঅ্যাকশন বেসড)

ইউজার হোভার বা ক্লিক করলে অ্যানিমেশন চালাতে whileHover এবং whileTap ব্যবহার করা হয়।

উদাহরণ:

import { motion } from "framer-motion";
 
export default function AnimatedButton() {
  return (
    <motion.button
      className="px-6 py-3 bg-gray-800 text-white rounded-lg font-semibold"
      whileHover={{ scale: 1.1, rotate: 3 }}
      whileTap={{ scale: 0.9, rotate: -3 }}
      transition={{ type: "spring", stiffness: 300 }}
    >
      Click Me
    </motion.button>
  );
}

৫. ড্র্যাগ অ্যানিমেশন

Framer Motion-এর আরেকটা অসাধারণ ফিচার হলো drag সাপোর্ট। যেকোনো এলিমেন্ট drag প্রপ দিলে সেটি মাউস দিয়ে সরানো যাবে।

উদাহরণ:

import { motion } from "framer-motion";
 
export default function DragBox() {
  return (
    <motion.div
      className="w-32 h-32 bg-green-500 rounded-lg"
      drag
      dragConstraints={{ top: -50, left: -50, right: 50, bottom: 50 }}
    />
  );
}

৬. Variants (স্ট্রাকচারড অ্যানিমেশন)

Variants ব্যবহার করে একাধিক অ্যানিমেশন অবস্থা ডিফাইন করে নাম দিয়ে ব্যবহার করা যায়। এটি বড় বা জটিল অ্যানিমেশনের ক্ষেত্রে অনেক কাজে লাগে, বিশেষত parent-child stagger effect-এ।

উদাহরণ:

import { motion } from "framer-motion";
 
const containerVariants = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: { staggerChildren: 0.2 },
  },
};
 
const itemVariants = {
  hidden: { y: 20, opacity: 0 },
  visible: { y: 0, opacity: 1 },
};
 
export default function StaggerList() {
  const items = ["Item 1", "Item 2", "Item 3"];
 
  return (
    <motion.ul
      className="list-none p-0"
      variants={containerVariants}
      initial="hidden"
      animate="visible"
    >
      {items.map((item, i) => (
        <motion.li
          key={i}
          className="p-4 bg-indigo-500 my-2 rounded text-white"
          variants={itemVariants}
        >
          {item}
        </motion.li>
      ))}
    </motion.ul>
  );
}

৭. Scroll-ভিত্তিক অ্যানিমেশন

Framer Motion-এ useScroll এবং useTransform হুক দিয়ে স্ক্রল অনুযায়ী অ্যানিমেশন তৈরি করা যায়।

উদাহরণ:

import { motion, useScroll, useTransform } from "framer-motion";
 
export default function ScrollBox() {
  const { scrollYProgress } = useScroll();
  const scale = useTransform(scrollYProgress, [0, 1], [0.5, 2]);
 
  return (
    <motion.div
      style={{ scale }}
      className="w-40 h-40 bg-pink-500 rounded-lg"
    />
  );
}

৮. React + Framer Motion দিয়ে Animated Counter

🎯 উদ্দেশ্য: React এবং Framer Motion ব্যবহার করে এমন একটি কম্পোনেন্ট তৈরি করা, যেখানে সংখ্যা ০ থেকে ১০০ পর্যন্ত মসৃণভাবে অ্যানিমেট হবে।


ধাপে ধাপে প্রক্রিয়া

1. প্রয়োজনীয় ইম্পোর্ট

import React, { useEffect } from "react";
import { motion, useMotionValue, useTransform, animate } from "framer-motion";

2. Motion Value তৈরি

const count = useMotionValue(0); // 0 থেকে শুরু
const roundedValue = useTransform(count, Math.round); // দশমিক → পূর্ণসংখ্যা

3. অ্যানিমেশন চালু করা

useEffect(() => {
  const animation = animate(count, 100, { duration: 2 }); // ২ সেকেন্ডে ১০০ পর্যন্ত
  return animation.stop; // Cleanup
}, []);

4. UI-তে দেখানো

return (
  <div style={{ fontSize: "3rem", fontWeight: "bold" }}>
    <motion.div>{roundedValue}</motion.div>
  </div>
);

সম্পূর্ণ কোড

import React, { useEffect } from "react";
import { motion, useMotionValue, useTransform, animate } from "framer-motion";
 
const Counter = () => {
  const count = useMotionValue(0);
  const roundedValue = useTransform(count, Math.round);
 
  useEffect(() => {
    const animation = animate(count, 100, { duration: 2 });
    return animation.stop;
  }, []);
 
  return (
    <div style={{ fontSize: "3rem", fontWeight: "bold" }}>
      <motion.div>{roundedValue}</motion.div>
    </div>
  );
};
 
export default Counter;

💡 টিপস:

  • duration পরিবর্তন করে স্পিড নিয়ন্ত্রণ করতে পারেন।

  • Tailwind CSS ব্যবহার করলে inline style-এর বদলে ক্লাস ব্যবহার করুন:

    <div className="text-5xl font-bold">
      <motion.div>{roundedValue}</motion.div>
    </div>

🎯 ৯. Scroll Reveal Animation

React, Tailwind CSS, এবং Framer Motion ব্যবহার করে এমন একটি স্ক্রল রিভিল (Scroll Reveal) অ্যানিমেশন তৈরি করা, যেখানে ইউজার স্ক্রল করলে বক্সগুলো সুন্দরভাবে fade-in + slide-in হবে।


🛠 ধাপ ১ — কম্পোনেন্ট কাঠামো

আমরা দুটি কম্পোনেন্ট তৈরি করব:

  1. ScrollReveal — মূল কন্টেইনার যেখানে একাধিক বক্স থাকবে
  2. Box — প্রতিটি বক্সের ডিজাইন ও অ্যানিমেশন হ্যান্ডেল করবে
// src/components/ScrollReveal.jsx
import React from "react";
import { motion } from "framer-motion";
 
// বক্স কম্পোনেন্ট
const Box = ({ text }) => {
  return (
    <motion.div className="w-32 h-32 m-4 rounded-sm bg-pink-300 flex items-center justify-center">
      <span className="text-black text-xl">{text}</span>
    </motion.div>
  );
};
 
// মূল কম্পোনেন্ট
const ScrollReveal = () => {
  const greetings = ["Hello", "Holla", "Welcome", "Namaste", "Come In"];
 
  return (
    <div className="flex flex-col items-center py-10">
      {greetings.map((greeting, index) => (
        <Box key={index} text={greeting} />
      ))}
    </div>
  );
};
 
export default ScrollReveal;

🛠 ধাপ ২ — অ্যানিমেশন যুক্ত করা

Framer Motion-এর motion.div-এ অ্যানিমেশন প্রপস যোগ করব:

const Box = ({ text }) => {
  return (
    <motion.div
      className="w-32 h-32 m-4 rounded-sm bg-pink-300 flex items-center justify-center"
      initial={{ opacity: 0, x: -50 }} // শুরুর অবস্থা
      whileInView={{ opacity: 1, x: 0 }} // ভিউপোর্টে এলে অবস্থা
      transition={{ duration: 1 }} // সময়কাল
    >
      <span className="text-black text-xl">{text}</span>
    </motion.div>
  );
};

🛠 ধাপ ৩ — একবারের জন্য অ্যানিমেশন চালানো

যাতে প্রতিবার স্ক্রল করলে রিপিট না হয়, আমরা viewport={{ once: true }} ব্যবহার করব।

const Box = ({ text }) => {
  return (
    <motion.div
      className="w-32 h-32 m-4 rounded-sm bg-pink-300 flex items-center justify-center"
      initial={{ opacity: 0, x: -50 }}
      whileInView={{ opacity: 1, x: 0 }}
      transition={{ duration: 1 }}
      viewport={{ once: true }}
    >
      <span className="text-black text-xl">{text}</span>
    </motion.div>
  );
};

📄 চূড়ান্ত কোড

// src/components/ScrollReveal.jsx
import React from "react";
import { motion } from "framer-motion";
 
const Box = ({ text }) => {
  return (
    <motion.div
      className="w-32 h-32 m-4 rounded-sm bg-pink-300 flex items-center justify-center"
      initial={{ opacity: 0, x: -50 }}
      whileInView={{ opacity: 1, x: 0 }}
      transition={{ duration: 1 }}
      viewport={{ once: true }}
    >
      <span className="text-black text-xl">{text}</span>
    </motion.div>
  );
};
 
const ScrollReveal = () => {
  const greetings = ["Hello", "Holla", "Welcome", "Namaste", "Come In"];
 
  return (
    <div className="flex flex-col items-center py-10">
      {greetings.map((greeting, index) => (
        <Box key={index} text={greeting} />
      ))}
    </div>
  );
};
 
export default ScrollReveal;

ফলাফল এই সেটআপ দিয়ে আপনার পেজে প্রতিটি বক্স স্ক্রল করলে একবার করে fade + slide-in হবে, যা ভিজ্যুয়ালি অনেক স্মুথ ও প্রফেশনাল লাগবে।


এখানে আপনার দেওয়া Framer Motion "Stagger" অ্যানিমেশন টিউটোরিয়ালটি আমি আরও ক্লিন, সংক্ষিপ্ত, এবং ধাপে ধাপে সাজিয়ে দিচ্ছি—যাতে নতুন বা অভিজ্ঞ যে কেউ সহজে বুঝতে পারে এবং কোড কপি করেই রান করতে পারে।


🎯 ১০. Framer Motion Stagger Animation

1. Stagger Animation কী?

Stagger অ্যানিমেশন এমন একটি টেকনিক যেখানে একাধিক এলিমেন্ট (যেমন লিস্ট আইটেম বা ইমেজ) একসাথে না এসে নির্দিষ্ট সময় ব্যবধানে একের পর এক আসে। এটি ইউজারের জন্য আরও স্মুথ ও ভিজ্যুয়ালি আকর্ষণীয় ইফেক্ট তৈরি করে।

উদাহরণ: মেনুর আইটেমগুলো একসাথে না এসে একের পর এক স্লাইড হয়ে আসা।


2. Framer Motion-এ কিভাবে কাজ করে?

  • Parent Container: এখানে আমরা staggerChildren সেট করি, যা বলে দেয় প্রতিটি চাইল্ডের অ্যানিমেশনের মধ্যে কত সময় গ্যাপ থাকবে।
  • Child Elements: প্রত্যেকটি চাইল্ডের জন্য আলাদা variants থাকে যা তাদের আসা-যাওয়ার স্টাইল ডিফাইন করে।

3. Variants সেটআপ

// প্যারেন্টের জন্য Variants
const containerVariants = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: {
      staggerChildren: 0.2, // প্রতিটি চাইল্ডের মধ্যে ০.২ সেকেন্ড
    },
  },
};
 
// চাইল্ডের জন্য Variants
const itemVariants = {
  hidden: { y: 20, opacity: 0 }, // নিচে এবং অদৃশ্য
  visible: { y: 0, opacity: 1 }, // উপরে উঠে দৃশ্যমান
};

4. React কম্পোনেন্টে প্রয়োগ

import React from "react";
import { motion } from "framer-motion";
 
const containerVariants = {
  hidden: { opacity: 0 },
  visible: {
    opacity: 1,
    transition: { staggerChildren: 0.2 },
  },
};
 
const itemVariants = {
  hidden: { y: 20, opacity: 0 },
  visible: { y: 0, opacity: 1 },
};
 
export default function StaggeredList() {
  const items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5"];
 
  return (
    <motion.ul
      className="list-none p-0 m-0"
      variants={containerVariants}
      initial="hidden"
      animate="visible"
    >
      {items.map((item, i) => (
        <motion.li
          key={i}
          className="bg-purple-500 text-white p-4 my-2 rounded"
          variants={itemVariants}
        >
          {item}
        </motion.li>
      ))}
    </motion.ul>
  );
}

5. রান করলে যা হবে

  • পুরো লিস্ট প্রথমে হিডেন থাকবে।
  • তারপর প্রতিটি আইটেম ০.২ সেকেন্ড ব্যবধানে নিচ থেকে উঠে আসবে।
  • এটি ইউজারের জন্য সুন্দর ও ডাইনামিক ইফেক্ট তৈরি করবে।

6. চ্যালেঞ্জ (Practice Task)

একই কনসেপ্ট ব্যবহার করে লিস্ট আইটেমের বদলে ইমেজ ব্যবহার করে একটি Image Gallery বানান যেখানে ছবিগুলো stagger ইফেক্ট দিয়ে লোড হবে।

💡 টিপস:

  • items অ্যারের বদলে ইমেজের src অ্যারে ব্যবহার করুন।
  • Tailwind দিয়ে গ্যালারির লেআউট গ্রিড আকারে সাজিয়ে নিন।
  • চাইলে hover এ zoom-in বা fade-in ইফেক্টও যোগ করতে পারেন।

একটি প্রোজেক্ট করুন Image Gallery Stagger Animation!


১১. Framer Motion: Exit Animation + AnimatePresence (React + React Router)

কেন দরকার Exit Animation?

React ডিফল্টভাবে যখন রুট পরিবর্তন হয়, তখন পুরনো কম্পোনেন্টকে সাথে সাথেই DOM থেকে সরিয়ে দেয় — ফলে স্ক্রিন থেকে উধাও হওয়ার কোনো অ্যানিমেশন হয় না। Exit Animation এই সমস্যার সমাধান করে: কম্পোনেন্টকে আনমাউন্ট করার আগে একটি "বিদায়ী ট্রানজিশন" দেখায়।


AnimatePresence কী করে?

<AnimatePresence> পুরনো কম্পোনেন্টকে সাথে সাথে সরিয়ে না দিয়ে, তার exit অ্যানিমেশন শেষ হওয়া পর্যন্ত DOM-এ রেখে দেয়। React Router-এর সাথে ব্যবহার করলে smooth পেজ ট্রানজিশন হয়।


ধাপে ধাপে সেটআপ

1. AnimatePresence দিয়ে Routes র‍্যাপ করা

// App.js
import { Routes, Route, useLocation } from "react-router-dom";
import { AnimatePresence } from "framer-motion";
import HomePage from "./HomePage";
import AboutPage from "./AboutPage";
 
function App() {
  const location = useLocation();
 
  return (
    <AnimatePresence mode="wait">
      <Routes location={location} key={location.pathname}>
        <Route index element={<HomePage />} />
        <Route path="/about" element={<AboutPage />} />
      </Routes>
    </AnimatePresence>
  );
}
 
export default App;

নোট:

  • useLocation + key ব্যবহার করা জরুরি যাতে রুট পরিবর্তন সঠিকভাবে শনাক্ত হয়।
  • mode="wait" নিশ্চিত করে যে নতুন পেজ আসার আগে পুরনো পেজের exit অ্যানিমেশন শেষ হয়।

2. পেজ কম্পোনেন্টে exit Variant যোগ করা

// HomePage.jsx
import { motion } from "framer-motion";
import { Link } from "react-router-dom";
 
const pageVariants = {
  initial: { opacity: 0, x: "-100vw" }, // শুরুতে বাম দিকে বাইরে
  animate: { opacity: 1, x: 0, transition: { type: "spring", stiffness: 50 } },
  exit: { opacity: 0, x: "100vw", transition: { ease: "easeInOut" } }, // ডান দিকে সরে বিদায়
};
 
const HomePage = () => {
  return (
    <motion.div
      variants={pageVariants}
      initial="initial"
      animate="animate"
      exit="exit"
      style={{ position: "absolute", width: "100%" }}
    >
      <h1>Home Page</h1>
      <Link to="/about">Go to About</Link>
    </motion.div>
  );
};
 
export default HomePage;

Variant ব্যাখ্যা

  • initial: লোড হওয়ার সময় কম্পোনেন্ট কোথায় থাকবে
  • animate: স্ক্রিনে আসার অ্যানিমেশন
  • exit: স্ক্রিন থেকে চলে যাওয়ার অ্যানিমেশন

ফলাফল: পেজ ট্রানজিশন হবে মসৃণ, প্রফেশনাল, এবং আরও ইন্টারঅ্যাকটিভ। ✨ AnimatePresence + exit ভ্যারিয়েন্ট = React অ্যাপের প্রাণ।


১২. উপসংহার

Framer Motion শেখা মানে React UI-তে প্রাণ দেওয়া। এখানে আমরা শিখলাম:

  • Basic Animation
  • Keyframes
  • Gesture Animations
  • Drag Support
  • Variants & Stagger
  • Scroll-based Effects

আপনি চাইলে এইগুলোর মিক্স ব্যবহার করে অসাধারণ অ্যানিমেটেড UI তৈরি করতে পারবেন।


© 2025 React JS Bangla Tutorial.