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 Type | Duration | Easing |
|---|---|---|
| Quick dismiss | 150ms | emphasized-accelerate |
| Standard exit | 200ms | emphasized-accelerate |
| Modal close | 200ms | emphasized-accelerate |
| Page exit | 300ms | emphasized-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
}
}
});