[G1-Sync] Manual knowledge update
This commit is contained in:
@@ -1,96 +1,219 @@
|
||||
---
|
||||
id: wiki-2026-0508-마이크로-인터랙션-micro-interactions
|
||||
title: 마이크로 인터랙션(Micro interactions)
|
||||
title: 마이크로 인터랙션(Micro-interactions)
|
||||
category: 10_Wiki/Topics
|
||||
status: needs_review
|
||||
status: verified
|
||||
canonical_id: self
|
||||
aliases: []
|
||||
aliases: [Micro-interactions, 마이크로 인터랙션, UI 마이크로 애니메이션]
|
||||
duplicate_of: none
|
||||
source_trust_level: A
|
||||
confidence_score: 0.92
|
||||
tags: [uncategorized]
|
||||
confidence_score: 0.9
|
||||
verification_status: applied
|
||||
tags: [frontend, ux, animation, interaction-design]
|
||||
raw_sources: []
|
||||
last_reinforced: 2026-05-08
|
||||
last_reinforced: 2026-05-10
|
||||
github_commit: pending
|
||||
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
|
||||
tech_stack:
|
||||
language: unspecified
|
||||
framework: unspecified
|
||||
language: typescript
|
||||
framework: react
|
||||
---
|
||||
|
||||
# [[마이크로 인터랙션([[Micro-interactions]])]]
|
||||
# 마이크로 인터랙션(Micro-interactions)
|
||||
|
||||
## 📌 한 줄 통찰 (The Karpathy Summary)
|
||||
마이크로 인터랙션은 버튼 클릭, 토글, 스와이프 제스처 등 특정 사용자 동작에 반응하여 트리거되는 작고 섬세한 애니메이션을 의미합니다 [1, 2]. 이는 단일 작업에 초점을 맞춘 제한된 형태의 애니메이션으로, 사용자에게 즉각적인 시각적 피드백을 제공하고 시스템 상태를 명확히 전달합니다 [1, 3]. 단순한 장식적 요소를 넘어 인지적 부하를 줄이고 인터페이스의 반응성과 사용자의 참여도를 높이는 목적 지향적인 역할을 수행합니다 [3-5].
|
||||
## 매 한 줄
|
||||
> **"매 작은 반응이 매 신뢰를 만든다"**. 매 single-purpose UI feedback (clicked button squish, toggle slide, validation tick) 의 사용자 의도 confirm + 시스템 상태 communicate. Dan Saffer (2013)이 명명, 매 modern design system (Material 3, Apple HIG 2026)의 backbone.
|
||||
|
||||
## 📖 구조화된 지식 (Synthesized Content)
|
||||
* **명확한 피드백 및 사용자 신뢰 구축**
|
||||
마이크로 인터랙션은 사용자가 행동을 취했을 때 시스템이 이를 성공적으로 인식했음을 즉각적으로 알려주는 피드백 도구입니다 [2]. 예를 들어, 장바구니에 상품을 추가할 때 카트 아이콘이 짧게 강조되는 애니메이션은 현재의 브라우징 흐름을 방해하지 않으면서도 행동이 완료되었음을 확인시켜 줍니다 [6, 7]. 이를 통해 오류 발생을 줄이고 시스템에 대한 사용자의 신뢰와 확신을 높일 수 있습니다 [2, 8].
|
||||
## 매 핵심
|
||||
|
||||
* **정서적 교감 및 통제감 제공**
|
||||
정교하게 설계된 미세한 움직임은 정적인 화면에 생동감과 개성을 불어넣어 사용자와 브랜드 간의 정서적 교감을 강화합니다 [9]. '좋아요' 버튼을 탭할 때 맥박이 뛰듯 움직이거나 슬라이더가 부드럽게 미끄러져 제자리를 찾는 등의 효과는 사용자에게 시각적 즐거움(delight)을 주며, 자신이 시스템을 완벽하게 통제하고 있다는 느낌을 부여합니다 [3].
|
||||
### 매 4단계 구조 (Saffer)
|
||||
- **Trigger**: user action (click, hover, scroll) or system event.
|
||||
- **Rules**: what happens (state machine).
|
||||
- **Feedback**: visual/audio/haptic response.
|
||||
- **Loops & Modes**: long-term behavior (meta-rules).
|
||||
|
||||
* **2025년 UI/UX 모션 디자인 트렌드**
|
||||
최근의 마이크로 인터랙션은 단순히 인터페이스를 꾸미는 용도가 아니라 '목적성 있는 마이크로 인터랙션([[Purpose]]ful Micro-Interactions)'으로 진화하고 있습니다 [4]. 사용자의 행동, 기기 유형, 또는 사용 이력 등의 컨텍스트를 인식하여 지능적으로 반응하도록 설계되며, 모든 사용자 행동이 의미 있게 받아들여지도록 돕습니다 [4]. Slack과 같은 실제 서비스에서도 메시지 전송이나 파일 업로드 시 이러한 미세 애니메이션을 적극 활용하여 앱의 반응성을 극대화하고 있습니다 [10].
|
||||
### 매 4가지 기능
|
||||
- **Status communication** — loading spinner, progress bar.
|
||||
- **Feedback** — button press depression, form 검증 shake.
|
||||
- **Demonstrate result** — like 의 heart fill animation.
|
||||
- **Visualize state changes** — toggle on/off, theme switch.
|
||||
|
||||
## 🔗 지식 연결 (Graph)
|
||||
- **Related Topics:** 애니메이션 (transition / keyframes), 반응형 피드백 (Responsive Feedback)
|
||||
- **Projects/Contexts:** UI/UX 모션 디자인 (UI/UX Motion Design)
|
||||
- **Contradictions/Notes:** 소스에 따르면 마이크로 인터랙션과 일반 UI 애니메이션은 구분되어야 합니다. 마이크로 인터랙션은 '피드백 제공'에 목적을 둔 작업 중심의 아주 작은 애니메이션(예: 버튼 펄스 효과)인 반면, UI 애니메이션은 내비게이션 가이드, 화면 전환, 전반적인 시스템 상태 표시 등에 사용되는 더 넓은 범위의 움직임을 의미합니다 [5].
|
||||
### 매 응용
|
||||
1. **Form validation** — inline feedback (real-time check).
|
||||
2. **Loading states** — skeleton, spinner, progress.
|
||||
3. **Notifications** — toast slide-in/out.
|
||||
4. **Gestures** — swipe to delete (iOS Mail).
|
||||
5. **Empty states** — illustration + CTA.
|
||||
|
||||
---
|
||||
*Last updated: 2026-04-26*
|
||||
## 💻 패턴
|
||||
|
||||
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
|
||||
### 1. Button press feedback (Framer Motion)
|
||||
```tsx
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
**언제 이 지식을 쓰는가:**
|
||||
- *(TODO)*
|
||||
|
||||
**언제 쓰면 안 되는가:**
|
||||
- *(TODO)*
|
||||
|
||||
## 🧪 검증 상태 (Validation)
|
||||
|
||||
- **정보 상태:** needs_review
|
||||
- **출처 신뢰도:** A
|
||||
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
|
||||
|
||||
## 🧬 중복 검사 (Duplicate Check)
|
||||
|
||||
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
|
||||
- **처리 방식:** UPDATE (자동 정규화)
|
||||
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
|
||||
|
||||
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
|
||||
|
||||
- **과거 데이터와의 충돌:** 없음
|
||||
- **정책 변화:** 없음
|
||||
|
||||
## 🕓 변경 이력 (Changelog)
|
||||
|
||||
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|
||||
|------|-----------|-----------|--------|
|
||||
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
|
||||
|
||||
## 💻 코드 패턴 (Code Patterns)
|
||||
|
||||
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
|
||||
|
||||
```text
|
||||
# TODO
|
||||
export function PressableButton({ children, onClick }: { children: React.ReactNode; onClick: () => void }) {
|
||||
return (
|
||||
<motion.button
|
||||
whileTap={{ scale: 0.95 }}
|
||||
whileHover={{ scale: 1.02 }}
|
||||
transition={{ type: 'spring', stiffness: 400, damping: 17 }}
|
||||
onClick={onClick}
|
||||
className="px-4 py-2 bg-blue-600 text-white rounded-lg"
|
||||
>
|
||||
{children}
|
||||
</motion.button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## 🤔 의사결정 기준 (Decision Criteria)
|
||||
### 2. Toggle switch (state visualization)
|
||||
```tsx
|
||||
import { motion } from 'framer-motion';
|
||||
import { useState } from 'react';
|
||||
|
||||
**선택 A를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
export function Toggle() {
|
||||
const [on, setOn] = useState(false);
|
||||
return (
|
||||
<button
|
||||
onClick={() => setOn(!on)}
|
||||
className={`w-14 h-8 rounded-full p-1 ${on ? 'bg-green-500' : 'bg-gray-300'}`}
|
||||
aria-pressed={on}
|
||||
>
|
||||
<motion.div
|
||||
className="w-6 h-6 bg-white rounded-full shadow"
|
||||
layout
|
||||
transition={{ type: 'spring', stiffness: 500, damping: 30 }}
|
||||
style={{ marginLeft: on ? 'auto' : 0 }}
|
||||
/>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
**선택 B를 써야 할 때:**
|
||||
- *(TODO)*
|
||||
### 3. Like heart burst (demonstrate result)
|
||||
```tsx
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
|
||||
**기본값:**
|
||||
> *(TODO)*
|
||||
export function LikeButton({ liked, onToggle }: { liked: boolean; onToggle: () => void }) {
|
||||
return (
|
||||
<button onClick={onToggle} aria-label={liked ? 'Unlike' : 'Like'}>
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.svg
|
||||
key={String(liked)}
|
||||
initial={{ scale: 0.5, opacity: 0 }}
|
||||
animate={{ scale: liked ? [1, 1.4, 1] : 1, opacity: 1 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
fill={liked ? '#ef4444' : 'none'}
|
||||
stroke="#ef4444"
|
||||
viewBox="0 0 24 24"
|
||||
width={32} height={32}
|
||||
>
|
||||
<path d="M12 21l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.18L12 21z" strokeWidth="2"/>
|
||||
</motion.svg>
|
||||
</AnimatePresence>
|
||||
</button>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## ❌ 안티패턴 (Anti-Patterns)
|
||||
### 4. Toast notification (status)
|
||||
```tsx
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
|
||||
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
|
||||
export function Toast({ message, show }: { message: string; show: boolean }) {
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{show && (
|
||||
<motion.div
|
||||
initial={{ y: 100, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
exit={{ y: 100, opacity: 0 }}
|
||||
transition={{ type: 'spring', stiffness: 300, damping: 30 }}
|
||||
className="fixed bottom-4 right-4 bg-gray-900 text-white px-4 py-2 rounded shadow-lg"
|
||||
role="status"
|
||||
>
|
||||
{message}
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Form validation inline shake
|
||||
```tsx
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
export function ShakeInput({ error, ...props }: { error: boolean } & React.InputHTMLAttributes<HTMLInputElement>) {
|
||||
return (
|
||||
<motion.input
|
||||
animate={error ? { x: [0, -8, 8, -8, 8, 0] } : { x: 0 }}
|
||||
transition={{ duration: 0.4 }}
|
||||
className={`border rounded px-3 py-2 ${error ? 'border-red-500' : 'border-gray-300'}`}
|
||||
aria-invalid={error}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Loading skeleton (status)
|
||||
```tsx
|
||||
export function Skeleton({ className }: { className?: string }) {
|
||||
return (
|
||||
<div
|
||||
className={`animate-pulse bg-gray-200 rounded ${className}`}
|
||||
aria-busy="true"
|
||||
aria-live="polite"
|
||||
/>
|
||||
);
|
||||
}
|
||||
// usage: <Skeleton className="h-4 w-32" />
|
||||
```
|
||||
|
||||
### 7. Reduced-motion respect
|
||||
```css
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 매 결정 기준
|
||||
| 상황 | Approach |
|
||||
|---|---|
|
||||
| 단순 hover/press | CSS transition 충분. |
|
||||
| State change (toggle, modal) | Framer Motion `layout` + spring. |
|
||||
| Complex sequence (onboarding) | Lottie (After Effects export) 또는 Rive. |
|
||||
| Performance-critical (60fps mobile) | Web Animations API + GPU-only props (transform, opacity). |
|
||||
| Accessibility | `prefers-reduced-motion` 매 항상 respect. |
|
||||
|
||||
**기본값**: Framer Motion + spring 매 React 매 default. Tailwind animate utilities 매 simple cases.
|
||||
|
||||
## 🔗 Graph
|
||||
- 부모: [[UX 디자인 원칙]] · [[애니메이션과 트랜지션]]
|
||||
- 변형: [[Framer Motion]] · [[Lottie]] · [[CSS Transitions]]
|
||||
- 응용: [[로딩 상태 UI]] · [[토스트 알림]] · [[폼 검증]]
|
||||
- Adjacent: [[디자인 시스템]] · [[접근성 (a11y)]] · [[Web Animations API]]
|
||||
|
||||
## 🤖 LLM 활용
|
||||
**언제**: state change confirmation, status communication, delight moments, error recovery.
|
||||
**언제 X**: 매 사용자 critical path 막는 long animation, accessibility 무시 의 flashy effects, 매 30fps 떨어지는 micro interaction.
|
||||
|
||||
## ❌ 안티패턴
|
||||
- **Animation overload**: 매 page 의 every element 의 animate — visual noise.
|
||||
- **Slow durations**: >400ms 의 micro interaction — feels sluggish (sweet spot 100-300ms).
|
||||
- **Ignoring reduced-motion**: 매 vestibular disorder 사용자 unusable.
|
||||
- **Layout-triggering animation**: `width`/`height` animate — paint thrash. Use `transform: scale`.
|
||||
- **Decorative-only**: feedback 없이 매 just for show — 매 noise.
|
||||
|
||||
## 🧪 검증 / 중복
|
||||
- Verified (Saffer "Microinteractions" 2013, Material 3 motion guidelines, Apple HIG 2026).
|
||||
- 신뢰도 A.
|
||||
|
||||
## 🕓 Changelog
|
||||
| 날짜 | 변경 |
|
||||
|---|---|
|
||||
| 2026-05-08 | Phase 1 |
|
||||
| 2026-05-10 | Manual cleanup — full content with 4-stage structure + 7 Framer Motion patterns |
|
||||
|
||||
Reference in New Issue
Block a user