emotional-journey
طراحی موشن هماهنگ با احساس کاربر در تمام مراحل تجربه
این Skill احساس کاربر را در مسیرهایی مثل کنجکاوی، تعامل، تمرکز، سردرگمی، موفقیت و ناکامی مدل میکند و برای هر حالت، الگوی حرکتی مناسب پیشنهاد میدهد. با استفاده از state machine، انتقالهای معتبر و پروفایلهای موشن، تجربهای منسجم و قابلپیشبینی میسازید.
برای طراحی onboarding، checkout، بازیابی خطا و تجربههای تعاملی پیچیده کاربرد دارد. این Skill شدت، زمانبندی، easing و واکنشهای بصری را با استانداردهایی مانند Russell's Circumplex، Material Design 3 و W3C DTCG هماهنگ میکند و reduced motion را نیز در نظر میگیرد.
چه چیزی میگیرید
- نقشهی state machine برای حالات احساسی و انتقالهای معتبر
- پروفایل موشن برای حالتهایی مانند curious، engaged، frustrated و accomplished
- الگوهای آماده برای onboarding، checkout، بازیابی خطا و deep work
- پیشنهاد duration، easing، intensity و بازخورد بصری برای هر انتقال
- راهنمای پیادهسازی با GSAP، Framer Motion و TypeScript بههمراه پشتیبانی از reduced motion
برای چه کاری خوب است
- طراحان محصول و توسعهدهندگانی که برای flowهای چندمرحلهای سیستم موشن طراحی میکنند
- تیمهایی که میخواهند انیمیشنها احساس پیشرفت، موفقیت یا بازیابی از خطا را بهدرستی منتقل کنند
- محصولات SaaS، onboarding، فرمهای حساس و تجربههای تعاملی که به بازخورد رفتاری منسجم نیاز دارند
برای چه کاری نیست
- صفحههایی که فقط به یک انیمیشن تزئینی مستقل و بدون جریان کاربر نیاز دارند
- پروژههایی که state machine یا مدلسازی حالتهای احساسی برایشان بیش از حد پیچیده است
- موشنهای صرفاً سینمایی یا تبلیغاتی که با تعامل کاربر و وضعیت محصول ارتباطی ندارند
دربارهٔ این اسکیل
Emotional Journey
Map user emotional states and valid transitions to create journey-coherent motion. Ensures animations reflect and support the user's evolving emotional state.
Standards Reference
| Standard | Documentation |
|---|---|
| W3C DTCG | designtokens.org |
| Russell's Circumplex | Arousal-valence emotion model |
| Material Design 3 | m3.material.io/styles/motion |
Quick Reference
Load from: tokens/emotional-journey.tokens.json
Journey States
| State | Arousal | Valence | Motion Profile | Stable? |
|---|---|---|---|---|
| neutral | low | neutral | minimal | Yes |
| curious | medium | positive | inviting | No |
| engaged | medium-high | positive | responsive | No |
| focused | medium | neutral | minimal (reduced) | No |
| confused | medium | negative | clarifying | No |
| frustrated | high | negative | recovery | No |
| accomplished | medium-high | positive | rewarding | No |
| delighted | high | positive | celebratory | Transient |
| anticipating | medium | neutral | progressive | No |
State Machine
┌───────────────────────────────────────┐
│ │
┌─────────▼──────────┐ ┌──────────────────┐│
│ NEUTRAL │◄───────│ DELIGHTED ││
│ (stable rest) │ │ (transient) ││
└────────┬───────────┘ └────────▲─────────┘│
│ │ │
┌────────▼───────────┐ ┌────────┴─────────┐│
│ CURIOUS │◄──────►│ ACCOMPLISHED │├─┐
│ (exploring) │ │ (completed) ││ │
└────────┬───────────┘ └────────▲─────────┘│ │
│ │ │ │
┌────────▼───────────┐ │ │ │
│ ENGAGED ├─────────────────┘ │ │
│ (participating) │ │ │
└────────┬───────────┘ │ │
│ │ │
┌─────────────┼─────────────┐ │ │
│ │ │ │ │
┌───▼────┐ ┌────▼────┐ ┌────▼─────┐ │ │
│FOCUSED │ │CONFUSED │ │FRUSTRATED│────────────────────┘ │
│(deep) │ │(lost) │ │(blocked) │──────────────────────┘
└────────┘ └─────────┘ └──────────┘
State Transitions
Valid Transitions
| From | To | Trigger Event | Motion Response |
|---|---|---|---|
| neutral | curious | new-content-discovered | reveal |
| neutral | engaged | task-started | guide |
| curious | engaged | task-started | guide |
| curious | confused | complexity-encountered | clarify |
| engaged | accomplished | action-success | confirm |
| engaged | frustrated | action-failed | warn |
| engaged | focused | deep-work-entered | indicate |
| engaged | anticipating | loading-started | indicate |
| focused | accomplished | action-success | confirm |
| frustrated | engaged | recovery-offered | guide |
| frustrated | clarified | help-requested | clarify |
| accomplished | delighted | milestone-reached | celebrate |
| accomplished | engaged | continue-task | guide |
| anticipating | accomplished | async-complete | confirm |
| anticipating | frustrated | async-failed | warn |
Journey Archetypes
Onboarding Journey
neutral → curious → engaged → accomplished → delighted
Motion strategy: Progressive revelation
// Onboarding flow with emotional journey
const onboardingSteps = [
{ state: 'neutral', motion: 'minimal' },
{ state: 'curious', motion: 'reveal', intent: 'reveal' },
{ state: 'engaged', motion: 'responsive', intent: 'guide' },
{ state: 'accomplished', motion: 'rewarding', intent: 'confirm' },
{ state: 'delighted', motion: 'celebratory', intent: 'celebrate' }
];
function getMotionForStep(stepIndex, event) {
const currentState = onboardingSteps[stepIndex].state;
const motionProfile = onboardingSteps[stepIndex].motion;
return {
duration: getStateDuration(currentState),
easing: getStateEasing(currentState),
intensity: getStateIntensity(currentState)
};
}
Checkout Journey
engaged → focused → anticipating → accomplished
Motion strategy: Clear confirmation
// Checkout with minimal distraction during focused state
const checkoutMotion = {
engaged: { intensity: 0.6, duration: 1.0 },
focused: { intensity: 0.3, duration: 0.8 }, // Reduced motion
anticipating: { intensity: 0.4, duration: 1.0 },
accomplished: { intensity: 0.8, duration: 1.2 }
};
Error Recovery Journey
engaged → frustrated → clarified → engaged → accomplished
Motion strategy: Calm guidance
// Error recovery with calming transition
function handleError() {
// 1. WARN: Show error
gsap.to('.form', {
x: 10,
duration: 0.08,
repeat: 3,
yoyo: true
});
// 2. Brief pause (let frustration register)
gsap.delayedCall(0.5, () => {
// 3. GUIDE: Show recovery path
gsap.to('.help-panel', {
opacity: 1,
y: 0,
duration: 0.3,
ease: 'power2.out'
});
});
}
Deep Work Journey
engaged → focused → accomplished
Motion strategy: Minimal distraction
// Deep work: 50% reduced motion intensity
const deepWorkModifier = 0.5;
const focusedMotion = {
confirm: {
duration: 200 * deepWorkModifier,
scale: 1 + (0.05 * deepWorkModifier), // Subtle
opacity: 1
}
};
State Motion Profiles
Neutral
const neutralProfile = {
motion: 'none',
intensity: 0.1,
secondary: false,
ambient: 'allowed' // Subtle background motion OK
};
Curious
const curiousProfile = {
motion: 'inviting',
intensity: 0.5,
easing: 'emphasized-decelerate',
patterns: ['reveal', 'highlight', 'pulse'],
encouragement: true
};
// Framer Motion
const curiousVariants = {
hidden: { opacity: 0, y: 20, scale: 0.95 },
curious: {
opacity: 1,
y: 0,
scale: 1,
transition: {
duration: 0.4,
ease: [0.05, 0.7, 0.1, 1]
}
}
};
Engaged
const engagedProfile = {
motion: 'responsive',
intensity: 0.6,
easing: 'standard',
feedback: 'immediate',
patterns: ['confirm', 'guide']
};
// Quick, satisfying feedback
const engagedVariants = {
tap: {
scale: 0.98,
transition: { duration: 0.05 }
},
release: {
scale: 1,
transition: { type: 'spring', stiffness: 400, damping: 20 }
}
};
Frustrated
const frustratedProfile = {
motion: 'recovery',
intensity: 0.7, // Clear but not overwhelming
maxDwellTime: 3000, // Must resolve within 3s
requiresResolution: true,
patterns: ['warn', 'guide'],
calmingTransition: {
delay: 500,
easing: 'ease-out'
}
};
// Show error, then guide to resolution
const frustratedSequence = gsap.timeline()
.to('.error-indicator', {
opacity: 1,
scale: 1.1,
duration: 0.15
})
.to('.error-indicator', {
scale: 1,
duration: 0.3,
ease: 'power2.out'
})
.to('.help-suggestion', {
opacity: 1,
y: 0,
duration: 0.3,
delay: 0.3
}, '-=0.1');
Delighted
const delightedProfile = {
motion: 'celebratory',
intensity: 1.0,
transient: true, // Auto-exits after duration
duration: 2000,
patterns: ['celebrate', 'particle', 'glow'],
secondary: true
};
// Full celebration with particles
const delightedAnimation = async () => {
await gsap.to('.success-icon', {
scale: 1.3,
duration: 0.3,
ease: 'back.out(2)'
});
triggerConfetti();
await gsap.to('.success-icon', {
scale: 1,
duration: 0.4,
ease: 'power2.out'
});
// Auto-transition to accomplished
transitionTo('accomplished');
};
Transition Motion
Positive Transitions (toward positive valence)
const positiveTransition = {
easing: 'emphasized-decelerate',
durationMultiplier: 1.1,
secondaryEffects: true
};
// frustrated → engaged (recovery)
gsap.to('.interface', {
filter: 'saturate(1)',
duration: 0.3,
ease: 'power2.out'
});
Negative Transitions (toward negative valence)
const negativeTransition = {
easing: 'emphasized-accelerate',
durationMultiplier: 0.9,
secondaryEffects: false
};
// engaged → frustrated
gsap.to('.interface', {
filter: 'saturate(0.8)',
duration: 0.2,
ease: 'power2.in'
});
Implementation
State Manager
type EmotionalState =
| 'neutral' | 'curious' | 'engaged' | 'focused'
| 'confused' | 'frustrated' | 'accomplished'
| 'delighted' | 'anticipating';
interface JourneyManager {
currentState: EmotionalState;
transition(event: TransitionEvent): void;
getMotionProfile(): MotionProfile;
}
const validTransitions: Record<EmotionalState, EmotionalState[]> = {
neutral: ['curious', 'engaged'],
curious: ['engaged', 'confused', 'neutral'],
engaged: ['accomplished', 'frustrated', 'focused', 'anticipating', 'curious'],
focused: ['accomplished', 'frustrated', 'engaged'],
confused: ['curious', 'engaged', 'frustrated', 'clarified'],
frustrated: ['neutral', 'engaged', 'clarified'],
accomplished: ['engaged', 'delighted', 'neutral', 'curious'],
delighted: ['accomplished', 'engaged', 'neutral'],
anticipating: ['engaged', 'frustrated', 'delighted', 'accomplished']
};
function canTransition(from: EmotionalState, to: EmotionalState): boolean {
return validTransitions[from]?.includes(to) ?? false;
}
Reduced Motion
For prefers-reduced-motion: reduce:
| State | Full Motion | Reduced Motion |
|---|---|---|
| curious | Reveal animation | Instant appear |
| engaged | Spring feedback | Opacity pulse |
| frustrated | Shake + guide | Icon + message |
| delighted | Celebration | Checkmark only |
| anticipating | Loading animation | Static indicator |
Cross-References
- See
emotion-mapping/for emotion-to-parameter mapping - See
intent/for intent-emotion affinity - See
narrative-arc/for arc phase to emotional state mapping - See
consequence/for emotion-triggered chains
References
references/state-transitions.md— Complete transition tablereferences/journey-archetypes.md— Common journey patterns