exit-patterns

الگوهای سریع و طبیعی برای خروج، حذف و dismiss عناصر رابط کاربری

این Skill برای طراحی انیمیشن خروج عناصر از صفحه، از fade و slide تا scale و dismiss با gesture استفاده می‌شود. الگوها بر اساس راهنمای M3 و timing استاندارد تنظیم شده‌اند.

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

چه چیزی می‌گیرید

  • الگوهای آماده برای fade out، slide down و scale out
  • تنظیمات duration و emphasized-accelerate easing بر اساس M3
  • نمونه‌ی dismiss با swipe و خروج به سمت مقصد
  • راهنمای staggered exit برای حذف چندعنصری
  • الگوی جایگزین برای prefers-reduced-motion

برای چه کاری خوب است

  • توسعه‌دهندگان رابط کاربری که برای modal، toast، کارت یا آیتم فهرست exit animation می‌سازند
  • پروژه‌های React و Framer Motion با نیاز به dismiss یا swipe-to-dismiss
  • طراحی سیستم‌هایی که timing و رفتار motion آن‌ها باید با Material Design 3 هماهنگ باشد

برای چه کاری نیست

  • ساخت انیمیشن‌های ورود، loading یا transitionهای پیچیده‌ی صفحه
  • پروژه‌هایی که به جلوه‌های سینمایی یا موشن‌گرافیک ویدیویی نیاز دارند
  • مواردی که حذف عنصر باید بدون هیچ حرکت یا تأخیر بصری انجام شود

دربارهٔ این اسکیل

Exit Patterns

Patterns for elements leaving the viewport.

Core Principle

Elements exiting should use:

  • Easing: emphasized-accelerate (0.3, 0, 0.8, 0.15)
  • Duration: Shorter than entrance (short-3 to short-4)
  • Faster than entrance — Don't make users wait

Basic Exit

Fade Out

.fade-out {
  animation: fadeOut 200ms cubic-bezier(0.3, 0, 0.8, 0.15) forwards;
}

@keyframes fadeOut {
  to { opacity: 0; }
}

Slide Down + Fade

.slide-down {
  animation: slideDown 200ms cubic-bezier(0.3, 0, 0.8, 0.15) forwards;
}

@keyframes slideDown {
  to {
    opacity: 0;
    transform: translateY(16px);
  }
}

Scale Out + Fade

.scale-out {
  animation: scaleOut 200ms cubic-bezier(0.3, 0, 0.8, 0.15) forwards;
}

@keyframes scaleOut {
  to {
    opacity: 0;
    transform: scale(0.95);
  }
}

Exit Direction

Exit Toward Destination

Elements should exit toward where they're going.

// Dismiss to trash — exit toward trash icon
<motion.div
  exit={{ x: trashPosition.x, opacity: 0 }}
  transition={{ duration: 0.2, ease: [0.3, 0, 0.8, 0.15] }}
/>

Exit Opposite of Entrance

If element entered from left, exit to left (or opposite).

Gesture-Based Exit

Swipe to Dismiss

const swipeConfidenceThreshold = 10000;
const swipePower = (offset, velocity) => Math.abs(offset) * velocity;

<motion.div
  drag="x"
  dragConstraints={{ left: 0, right: 0 }}
  onDragEnd={(e, { offset, velocity }) => {
    if (swipePower(offset.x, velocity.x) > swipeConfidenceThreshold) {
      onDismiss();
    }
  }}
  exit={{ x: 300, opacity: 0 }}
  transition={{ duration: 0.2, ease: [0.3, 0, 0.8, 0.15] }}
/>

Duration Guidelines

Exit TypeDurationEasing
Quick dismiss150msemphasized-accelerate
Standard exit200msemphasized-accelerate
Modal close200msemphasized-accelerate
Page exit300msemphasized-accelerate

Exit vs Entrance Timing

Exits should be faster than entrances:

  • Entrance: medium-1 (250ms)
  • Exit: short-4 (200ms)

This ratio (~80%) feels natural — users don't want to wait for dismissals.

Staggered Exit

When multiple items exit:

const containerExit = {
  exit: {
    transition: {
      staggerChildren: 0.03, // Faster stagger than entrance
      staggerDirection: -1   // Reverse order often feels better
    }
  }
};

const itemExit = {
  exit: {
    opacity: 0,
    y: -8,
    transition: {
      duration: 0.15,
      ease: [0.3, 0, 0.8, 0.15]
    }
  }
};

Reduced Motion Alternative

const getExitVariant = (prefersReducedMotion) => ({
  exit: {
    opacity: 0,
    y: prefersReducedMotion ? 0 : -8,
    transition: {
      duration: prefersReducedMotion ? 0.1 : 0.2
    }
  }
});

دانلود ZIP