মোশন

  • কাস্টম জ্যামিতিক রিভিল ও স্মুথ ফেড-আউটের জন্য clip-path ও mask-image ব্যবহার করুন।
  • JS লিসনারের পরিবর্তে স্ক্রল-বাউন্ড এফেক্টের জন্য স্ক্রল-চালিত অ্যানিমেশন (animation-timeline: scroll()) ব্যবহার করুন।
  • জটিল লেআউট স্টেটের মধ্যে মসৃণভাবে অ্যানিমেট করতে ভিউ ট্রানজিশন ব্যবহার করুন।

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

.popover-reveal {
  /* Transition discrete display and top-layer overlay alongside opacity */
  transition:
    opacity ease-out,
    display,
    overlay;
  transition-duration: 0.2s;
  transition-behavior: allow-discrete;
}

অ্যাক্সেসিবিলিটি

যেসব ব্যবহারকারী ভারী মোশন বন্ধ রাখতে চান তাদের জন্য prefers-reduced-motion মিডিয়া কোয়েরি ব্যবহার করুন।

  • পজ করার মেকানিজম প্রদান করা: ব্যবহারকারীদের অটো-রানিং ক্যারোজেল, ব্যানার বা অন্যান্য স্থায়ী অ্যানিমেশন বন্ধ করার অনুমতি দিন।
  • স্ট্যাটিক ভিউ ডিফল্ট হিসেবে সেট করা: স্ট্যাটিক স্টেট ডিফল্ট হিসেবে সেট করার কথা বিবেচনা করুন এবং ব্যবহারকারীদের মোশন চালু করার অনুমতি দিন।
  • ফ্ল্যাশ দেখানোর সীমা (প্রতি সেকেন্ডে তিনবার) অতিক্রম করবেন না: দ্রুত আলো থেকে অন্ধকার ফ্ল্যাশ করার মতো দৃশ্য কখনও অন্তর্ভুক্ত করবেন না। এই ধরনের এফেক্ট খিঁচুনি সৃষ্টি করতে পারে।

animation-duration: 0.01ms; গ্লোবাল লেভেলে প্রয়োগ করবেন না কারণ এর ফলে কিছু অ্যানিমেশন আরও বেশি ঝাঁকুনিযুক্ত হয়ে যেতে পারে। পরিবর্তে, দুটি পদ্ধতির মধ্যে একটি ব্যবহার করে কেস-বাই-কেস ভিত্তিতে মোশন সংক্রান্ত পছন্দ ম্যানেজ করুন, নিয়মের মধ্যে @media কোয়েরি নেস্ট করুন যাতে দুটি ভার্সনই একসাথে রাখা যায়:

  • ডিফল্ট হিসেবে চালু থাকা অ্যানিমেশন দিয়ে শুরু করুন এবং @media (prefers-reduced-motion: reduce) ব্যবহার করে সেগুলির টোন ডাউন করুন:
/* Good: Dampen spin states or slow down animations for reduced motion */
.spinner {
  animation: spin 1s linear infinite;
  @media (prefers-reduced-motion: reduce) {
    animation: none;
    opacity: 0.5;
  }
}

progress:not([value]) {
  animation: slide 1s infinite linear;
  @media (prefers-reduced-motion: reduce) {
    animation-duration: 20s;
  }
}
  • ডিফল্ট হিসেবে কোনও অ্যানিমেশন ছাড়াই শুরু করুন এবং @media (prefers-reduced-motion: no-preference) ব্যবহার করে সেগুলি চালু করুন:
/* Good: Default to static or gentle states and opt-in to full motion */
.spinner {
  opacity: 0.5;
  @media (prefers-reduced-motion: no-preference) {
    opacity: 1;
    animation: spin 1s linear infinite;
  }
}

progress:not([value]) {
  animation: slide 20s infinite linear;
  @media (prefers-reduced-motion: no-preference) {
    animation-duration: 1s;
  }
}

জাভাস্ক্রিপ্টে অ্যানিমেশন এবং ট্রানজিশন ইভেন্ট নিয়ে কাজ করা

AnimationEvent (animationstart, animationiteration, animationend, animationcancel) এবং TransitionEvent (transitionrun, transitionstart, transitionend, transitioncancel) ইন্টারফেস, দুটিতেই event.target আপনাকে অরিজিনেটিং DOM এলিমেন্ট দেয়। ইভেন্ট ট্রিগার করেছে এমন নির্দিষ্ট Animation অবজেক্ট (Animation, CSSAnimation বা CSSTransition) অ্যাক্সেস করতে, readonly event.animation প্রপার্টি ব্যবহার করুন।

event.animation উপলভ্য না থাকলে, আপনি সাধারণত event.target.getAnimations() কল করে এবং event.animationName (বা ট্রানজিশনের জন্য event.propertyName) দ্বারা ফিল্টার করে Animation ইনস্ট্যান্স খুঁজে পেতে পারেন। তবে, সরাসরি event.animation ব্যবহার করা ভালো, যাতে এমন অনেক পরিস্থিতি এড়ানো যায় যেখানে event.target.getAnimations() ফিল্টার করা এই ফলব্যাক প্রত্যাশা অনুযায়ী কাজ করে না:

  • Web Animations API (element.animate()) অ্যানিমেশনে কোনও animationName নেই, তাই event.target.getAnimations() ফিল্টার করার সময় নাম দিয়ে সেগুলি ম্যাচ করা যাবে না।
  • একই এলিমেন্টে একই নামের একাধিক অ্যানিমেশন অ্যাটাচ করা থাকলে, AnimationEvent-এর জন্য animationName অনুযায়ী ফিল্টার করা অস্পষ্ট হয়ে যায়।
    • মনে রাখবেন যে TransitionEvent-এর জন্য transitionProperty-এ ফিল্টার করা কাজ করে কারণ প্রতিটি ট্রানজিশন প্রপার্টির জন্য শুধুমাত্র একটি ইভেন্ট আছে।
  • event.target সবসময় মূল DOM এলিমেন্টকে পয়েন্ট করে, তাই এটি এলিমেন্টে চলা অ্যানিমেশন এবং এর কোনও একটি ছদ্ম-এলিমেন্টের মধ্যে পার্থক্য করে না — যেখানে event.animation.effect.pseudoElement সরাসরি টার্গেট ছদ্ম-এলিমেন্টকে দেখায়।
// Works in most basic CSS animation cases, but fails for WAAPI animations,
// duplicate animation names on the same element, or pseudo-elements.
document.addEventListener('animationstart', (event) => {
  const animation = event.target
    .getAnimations()
    .find((anim) => anim.animationName === event.animationName);
  console.log(animation);
});

// PREFERRED: Directly access the exact Animation object via event.animation
document.addEventListener('animationstart', (event) => {
  const animation = event.animation;
  console.log(animation);
});

আপনি 'animation' in AnimationEvent.prototype (বা 'animation' in TransitionEvent.prototype) ব্যবহার করে ফিচার-ডিটেক্ট সাপোর্ট করতে পারবেন।