Advance CSS শিখুন বাংলায় (পর্ব ৩) — Advanced Animation: cubic-bezier ও keyframes শিখুন

Advanced Animation - cubic-bezier ও keyframes

আগের পর্বে আমরা BEM দিয়ে CSS সংগঠিত রাখা শিখেছিলাম। এই পর্বে আমরা দেখব কীভাবে অ্যানিমেশনকে আরও প্রফেশনাল আর প্রাণবন্ত বানানো যায় — keyframes বিস্তারিতভাবে আর cubic-bezier কার্ভ দিয়ে।

@keyframes রিক্যাপ ও বিস্তারিত

@keyframes দিয়ে একটা অ্যানিমেশনের একাধিক ধাপ (from-to না, শতাংশ দিয়ে) নির্ধারণ করা যায় — এতে জটিল, বহু-ধাপের অ্যানিমেশন বানানো সহজ হয়।

@keyframes bounce {
  0% {
    transform: translateY(0);
  }
  30% {
    transform: translateY(-30px);
  }
  50% {
    transform: translateY(0);
  }
  70% {
    transform: translateY(-15px);
  }
  100% {
    transform: translateY(0);
  }
}

.ball {
  animation: bounce 1s ease-in-out infinite;
}

শতাংশ (0%, 30%, 100%) দিয়ে অ্যানিমেশনের প্রতিটা মুহূর্তে কী হবে সেটা নিয়ন্ত্রণ করা যায় — শুধু শুরু আর শেষ না, মাঝের যেকোনো পয়েন্টে।

animation প্রপার্টি কাজ
animation-duration কতক্ষণ ধরে চলবে
animation-timing-function গতির ধরন (ease, linear, cubic-bezier)
animation-delay শুরু হওয়ার আগে কত অপেক্ষা করবে
animation-iteration-count কতবার চলবে (সংখ্যা বা infinite)
animation-fill-mode শেষ হওয়ার পর কোন অবস্থায় থাকবে
animation-direction normal, reverse, alternate

cubic-bezier কী?

ব্রাউজারের ডিফল্ট টাইমিং ফাংশনগুলো (ease, ease-in-out) দিয়ে বেশিরভাগ কাজ চলে যায়, কিন্তু নিজের মতো করে গতির "ফিল" ঠিক করতে চাইলে cubic-bezier(x1, y1, x2, y2) ব্যবহার করা হয় — এটা একটা গাণিতিক কার্ভ যেটা নির্ধারণ করে অ্যানিমেশন কখন দ্রুত, কখন ধীরে চলবে।

.smooth {
  transition: transform 0.5s cubic-bezier(0.25, 0.1, 0.25, 1);
}

.bouncy {
  transition: transform 0.6s cubic-bezier(0.68, -0.55, 0.27, 1.55);
}

.snappy {
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
ডিফল্ট নাম সমতুল্য cubic-bezier
ease cubic-bezier(0.25, 0.1, 0.25, 1)
linear cubic-bezier(0, 0, 1, 1)
ease-in-out cubic-bezier(0.42, 0, 0.58, 1)

টিপস: কার্ভের মান y1 বা y2 ১-এর বেশি বা ০-এর কম হলে অ্যানিমেশন সীমা ছাড়িয়ে "ওভারশুট" করে — এতেই বাউন্সি বা স্প্রিং-এর মতো ইফেক্ট পাওয়া যায় (উপরের .bouncy ক্লাসে যেমন হয়েছে)।

লাইভ ডেমো — বিভিন্ন টাইমিং ফাংশনের পার্থক্য

নিচের বাটনে চাপো — তিনটা বল একই সময়ে চলবে, কিন্তু ভিন্ন টাইমিং ফাংশন দিয়ে। পার্থক্যটা লক্ষ্য করো।

linear

ease

cubic-bezier bouncy

একাধিক অ্যানিমেশন একসাথে

একটা এলিমেন্টে একাধিক অ্যানিমেশন কমা দিয়ে আলাদা করে একসাথে চালানো যায়:

@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes slideUp {
  from { transform: translateY(20px); }
  to { transform: translateY(0); }
}

.card {
  animation:
    fadeIn 0.5s ease-out,
    slideUp 0.5s ease-out;
}

এখানে fadeIn আর slideUp একসাথে চলবে — কার্ড একইসাথে স্বচ্ছ থেকে দৃশ্যমান হবে আর নিচ থেকে উপরে উঠবে।

SCSS দিয়ে অ্যানিমেশন ভ্যারিয়েবল

আগের পর্বগুলোতে শেখা SCSS ভ্যারিয়েবল দিয়ে অ্যানিমেশনের টাইমিংও পুনর্ব্যবহারযোগ্য করা যায়:

$ease-bounce: cubic-bezier(0.68, -0.55, 0.27, 1.55);
$ease-smooth: cubic-bezier(0.25, 0.1, 0.25, 1);
$duration-fast: 0.2s;
$duration-normal: 0.4s;

.modal {
  transition: transform $duration-normal $ease-bounce;
}

.tooltip {
  transition: opacity $duration-fast $ease-smooth;
}

পারফরম্যান্স টিপস

সব CSS প্রপার্টি সমানভাবে দ্রুত অ্যানিমেট হয় না। ব্রাউজার transform আর opacity-কে GPU দিয়ে দ্রুত হ্যান্ডেল করতে পারে, কিন্তু width, top, margin অ্যানিমেট করলে পেজের পুরো লেআউট বারবার হিসাব করতে হয় — এতে অ্যানিমেশন কাঁপা কাঁপা (janky) লাগে।

/* ❌ ধীর — লেআউট বারবার হিসাব হয় */
.box:hover {
  width: 200px;
  margin-left: 20px;
}

/* ✅ দ্রুত — GPU-accelerated */
.box:hover {
  transform: scale(1.1) translateX(20px);
}

একটা সম্পূর্ণ উদাহরণ — লোডিং স্পিনার

চলো একটা প্রফেশনাল-লুকিং লোডিং স্পিনার বানাই, keyframes আর cubic-bezier মিলিয়ে।

<!DOCTYPE html>
<html lang="bn">
<head>
  <meta charset="UTF-8" />
  <title>লোডিং স্পিনার</title>
  <style>
    @keyframes pulse-ring {
      0% {
        transform: scale(0.8);
        opacity: 1;
      }
      100% {
        transform: scale(1.5);
        opacity: 0;
      }
    }

    .spinner-wrap {
      position: relative;
      width: 60px;
      height: 60px;
      margin: 60px auto;
    }

    .spinner-dot {
      width: 60px;
      height: 60px;
      border-radius: 50%;
      background: #2563eb;
      position: absolute;
    }

    .spinner-ring {
      position: absolute;
      width: 60px;
      height: 60px;
      border-radius: 50%;
      border: 3px solid #2563eb;
      animation: pulse-ring 1.2s cubic-bezier(0.25, 0.1, 0.25, 1) infinite;
    }
  </style>
</head>
<body>
  <div class="spinner-wrap">
    <div class="spinner-dot"></div>
    <div class="spinner-ring"></div>
  </div>
</body>
</html>

এই ডিজাইনে একটা স্থির বিন্দুর চারপাশে pulse-ring অ্যানিমেশন দিয়ে একটা রিং বড় হতে হতে মিলিয়ে যায় — এটাই "pulse" ইফেক্টের বেসিক টেকনিক, যা অনেক মডার্ন অ্যাপে নোটিফিকেশন বা লাইভ স্ট্যাটাস দেখাতে ব্যবহার হয়।

নিজে চেষ্টা করো

Exercise:

  1. উপরের বাউন্স ডেমো নিজে বানাও, কিন্তু cubic-bezier-এর মান পাল্টে নিজের মতো একটা "ফিল" তৈরি করো।
  2. একটা বাটনে হোভার করলে transform: scale() আর box-shadow একসাথে অ্যানিমেট করো।
  3. Pulse ring স্পিনারটা রঙ পাল্টে নিজের ব্র্যান্ড কালার (Pathok Ghor বা ArifStack-এর থিম কালার) দিয়ে বানাও।
  4. একটা এলিমেন্টে width আর transform: scaleX() দুই রকম দিয়ে একই ভিজুয়াল ইফেক্ট বানিয়ে DevTools-এর Performance ট্যাবে পার্থক্য দেখো।

পরের পর্বে যা থাকছে

পরের পর্বে আমরা শিখব CSS Grid এডভান্সড প্যাটার্নgrid-template-areas দিয়ে কীভাবে জটিল লেআউট সহজে সংজ্ঞায়িত করা যায়।

একটি মন্তব্য পোস্ট করুন

নবীনতর পূর্বতন

যোগাযোগ ফর্ম