필사 모드: 모션·애니메이션 2025 완전 정복: View Transitions API, Motion One, Framer Motion, GSAP, Scroll-driven Animations, Reduced Motion, 60fps 성능, 토스 사례, AI 생성 애니메이션 — Season 6 Ep 4
한국어프롤로그 · 정지된 UI는 죽은 UI다
좋은 UI와 위대한 UI의 차이는 **모션**에 있다. 같은 기능, 같은 레이아웃, 같은 컬러라도 전환·피드백·미세한 반응이 있느냐 없느냐로 체감이 달라진다.
- 토스 앱을 열면 숫자가 카운트업으로 올라간다
- 쿠팡 상품 이미지를 열면 확대 전환(shared element) 되어 들어간다
- Linear에서 티켓을 옮기면 부드럽게 미끄러진다
- Stripe 체크아웃이 매끄럽게 페이지를 전환한다
이 모든 것의 공통점:
> **"사용자가 '부드럽다'고 느끼는 순간, 제품의 품질에 대한 신뢰가 형성된다."**
2024-2025년은 웹 모션의 **네이티브화**가 결정적으로 진행된 해였다. View Transitions API·Scroll-driven Animations·@starting-style이 모두 브라우저에 들어왔다. 이번 글은 그 전체 지도.
1장 · 모션의 목적 5가지
장식이 아닌 **기능적** 모션만이 가치 있다.
(1) Orientation — 어디로 갔는지 알려주기
- 페이지 전환 시 어디서 어디로 이동했는지
- 예: iOS Slide 전환, Shared Element Transition
(2) Feedback — 반응 확인
- 버튼 눌림, 토글 스위치, 체크 완료
- "내가 한 행동에 반응이 있다"
(3) Status — 진행 상황
- 로딩·저장·동기화 중
- Progress Bar, Spinner
(4) Hierarchy — 구조 전달
- Hero 요소 강조
- 연관된 요소 동시 움직임
(5) Delight — 즐거움
- 브랜드 Personality
- 토스 코인 굴리기 같은 마이크로 인터랙션
나쁜 모션의 공통점
- **목적 불분명**: 이유 없이 움직임
- **과도한 화려함**: 집중 분산
- **너무 느림**: 300ms 이상 기다림
- **접근성 배제**: 멀미·민감성 무시
2장 · View Transitions API — 2024-2025 게임체인저
왜 혁명적인가
과거엔 페이지 간 전환 애니메이션이 **거의 불가능**했다. SPA 내 라우트 전환은 가능했지만 MPA(다중 페이지)는 깜빡임이 기본. 2024-2025년 **View Transitions API**가 이를 해결.
2가지 모드
**(1) Same-document (SPA)**
- 한 페이지 내 DOM 변경에 전환
- Chrome 111+ 안정, Safari 18+, Firefox 진행 중
**(2) Cross-document (MPA)**
- 페이지 간 하드 네비게이션에 전환
- Chrome 126+ (2024), Safari 18.2+
- 서로 다른 페이지끼리도 부드러운 전환
기본 사용법
// Same-document
document.startViewTransition(() => {
// DOM 업데이트
updateContent();
});
/* 전환 커스터마이징 */
::view-transition-old(root) {
animation: fade-out 0.3s ease-out;
}
::view-transition-new(root) {
animation: fade-in 0.3s ease-in;
}
Shared Element Transition
같은 요소가 페이지 간 이동할 때 **부드럽게 이어지는** 효과.
.thumbnail {
view-transition-name: hero-image;
}
다음 페이지의 큰 이미지에도 같은 `view-transition-name`을 부여하면 자동으로 morph.
MPA에서 한 줄로
@view-transition {
navigation: auto;
}
이 한 줄로 사이트 전체 페이지 전환이 기본 fade로 부드러워진다.
지원 현황 (2025 4월)
- **Chrome 126+**: Same + Cross-doc 모두 안정
- **Safari 18.2+**: 주요 기능 지원
- **Firefox**: Same-doc 플래그, Cross-doc 개발 중
- **Edge**: Chrome 기반 지원
Astro / Next.js 통합
- **Astro**: `ClientRouter` 컴포넌트로 한 줄 활성화
- **Next.js**: App Router에서 직접 사용 가능, 실험적 통합 기능도
3장 · Scroll-driven Animations — CSS로 스크롤 연동
배경
스크롤 위치에 따라 애니메이션을 실행하는 건 전통적으로 JS가 필요했다 (Intersection Observer + 수동 계산). 2024년 **CSS scroll-driven animations**가 네이티브화.
주요 함수
**(1) `scroll()` timeline**
@keyframes reveal { from { opacity: 0 } to { opacity: 1 } }
.card {
animation: reveal linear;
animation-timeline: scroll();
animation-range: 20vh 80vh;
}
**(2) `view()` timeline**
- 요소가 뷰포트에 들어오는 범위 기준
.image {
animation: fade-in linear;
animation-timeline: view();
animation-range: entry 0% entry 50%;
}
사용 사례
- **Parallax** 헤더
- 스크롤에 따라 **Progress Bar**
- 텍스트가 한 단어씩 나타남
- 긴 페이지의 **애피소드 전환**
지원 현황
- Chrome 115+, Edge 115+: 안정
- Safari: 개발 중 (2025 하반기 예상)
- Firefox: 플래그
**폴백**: `@supports (animation-timeline: scroll())` 로 감싸고, 지원 안 되면 JS 또는 무모션
4장 · CSS Animation 2025 — 새 기능 모음
@starting-style (2024)
요소가 **처음 렌더될 때의 상태** 정의. 진입 애니메이션이 편해짐.
dialog {
opacity: 0;
transition: opacity 0.3s;
}
dialog[open] {
opacity: 1;
@starting-style {
opacity: 0;
}
}
`transition-behavior: allow-discrete`
`display: none` 같은 **비연속(discrete) 속성**도 transition 가능. Popover·Dialog 숨김·노출에 핵심.
`@keyframes` 보간 개선
- `@keyframes`에 `!important` 지원
- `initial`·`unset` 키워드 사용 가능
CSS Nesting + Container Queries 결합
- 애니메이션을 컨테이너 크기에 따라 다르게
- "작은 화면엔 애니메이션 끄기"
`@property` 사용자 정의 속성
@property --angle {
syntax: '<angle>';
initial-value: 0deg;
inherits: false;
}
이제 `--angle`을 **실제 애니메이션 가능한 속성**으로 선언. 그라디언트 회전 등이 부드러워짐.
5장 · Motion One — 표준 지향 경량 엔진
철학
- **Web Animations API**(WAAPI) 기반
- 순수 JS 5kb, 프레임워크 중립
- Framer Motion의 창립자 Matt Perry가 만든 경량 대안
특징
animate('.card', { opacity: [0, 1], y: [20, 0] }, { duration: 0.4 });
- CSS 변수·Transforms 자동 최적화
- Stagger·Timeline 지원
- Scroll·Spring·Gesture 플러그인
Framer Motion vs Motion One
| 항목 | Framer Motion | Motion One |
|---|---|---|
| 크기 | ~30kb | ~5kb |
| React 전용 | 예 | 아님 (바닐라) |
| 기능 폭 | 더 넓음 | 핵심 위주 |
| 성능 | 좋음 | 더 좋음(WAAPI) |
| 선택 이유 | Layout·AnimatePresence | Bundle 중요·바닐라 |
2025 현황
- Motion One이 v10 → Framer Motion과 **API 통합** 방향
- React용 래퍼 `motion/react` 도입
6장 · Framer Motion — React 생태계 표준
강력한 이유
**(1) Declarative API**
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.3 }}
/>
**(2) Layout Animations**
- `layout` prop 하나로 FLIP 애니메이션 자동
- 리스트 재정렬 부드럽게
**(3) AnimatePresence**
- 컴포넌트 언마운트 시 exit 애니메이션 실행
**(4) Variants**
- 상태 집합을 미리 정의, Staggered 전환
2024-2025 트렌드
- Motion 5.0에서 번들 감소
- **motion/react**로 이름 정리
- **Scroll Variants** 지원 강화
실전 팁
- **Layout 애니메이션은 성능 비싸다** — 30개 이상 요소엔 View Transitions API 고려
- **AnimatePresence는 key 필수** — React key 관리 중요
- **`layoutId`로 shared element** 구현
7장 · GSAP — 고급 타임라인의 최강자
언제 GSAP?
- 복잡한 **타임라인**(sequence, sync)
- **SVG 애니메이션**
- **ScrollTrigger**로 복합 스크롤 경험
- **크리에이티브 웹** (광고·포트폴리오)
2024년 GSAP 3.12 / 2025년 무료화
- 2024년 Webflow가 GSAP 인수
- 2025년 주요 플러그인 **상용 프로젝트 무료** 공개 (ScrollTrigger, SplitText 등)
- 업계 환영
예시
gsap.timeline()
.from('.hero', { y: 100, opacity: 0 })
.from('.cta', { scale: 0, ease: 'back.out' }, '-=0.3')
.to('.bg', { rotation: 360, duration: 20, repeat: -1 }, 0);
적합한 경우
- 포트폴리오·캠페인·인터랙티브 내러티브
- Webflow·Framer·No-code 사이트
부적합한 경우
- 일반 제품 UI의 마이크로 인터랙션 — 너무 무겁고 과할 수 있음
8장 · React Spring·Motion Layout·기타
React Spring
- Spring Physics 기반
- 부드러운 자연스러움
- 모바일 제스처·gesture 훅 (`@use-gesture/react`)
Auto-animate (FormKit)
- `<ul auto-animate>` 한 줄로 리스트 애니메이션
- Zero-config
Svelte Motion·Solid Motion
- 각 프레임워크 네이티브 모션
- 번들 작음, 학습 쉬움
CSS만으로 가능한 것
- 대부분의 마이크로 인터랙션
- Hover·Focus·Active·Click 전환
- **2025년 `@starting-style`·Scroll-driven 추가로 CSS만으로 충분한 범위 확장**
9장 · 60fps 성능과 GPU
애니메이션 성능의 기본
**GPU 가속되는 속성**
- `transform` (translate·rotate·scale)
- `opacity`
- `filter`
**GPU 미가속 (피해야)**
- `width`, `height`, `top`, `left` — Reflow·Repaint 유발
- `box-shadow`, `border-radius` 변화 — 주의
will-change·`transform: translateZ(0)`
- GPU 레이어 승격 힌트
- 남용 금지 (메모리·배터리 ↑)
CSS Containment
- `contain: layout paint` 로 렌더링 격리
- 큰 리스트 스크롤 성능↑
content-visibility: auto
- 오프스크린 요소를 **렌더링 스킵**
- 긴 페이지 FCP 개선
측정 도구
- **Chrome DevTools Performance**
- **Paint Flashing** (DevTools Rendering)
- **FPS meter**
- **Lighthouse**의 Performance 점수
모바일 주의사항
- Low-end Android는 60fps 쉽지 않음
- 프로퍼티 수를 최소화, `will-change` 신중
- **battery-aware**: 저전력 모드일 때 애니메이션 최소화
10장 · 접근성 — prefers-reduced-motion
멀미·민감성 문제
전정계 장애·편두통·난독 스펙트럼 사용자는 과도한 모션에 **실제 멀미·고통**. 개인 설정에서 "Reduce Motion" 활성화.
CSS 기본 구현
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
scroll-behavior: auto !important;
}
}
Framer Motion
const shouldReduce = useReducedMotion();
원칙
- **"없애기"가 아니라 "줄이기"**: 구조 전달에 필요한 최소 모션 유지
- 중요한 상태 변화는 **비모션 방식**(색·아이콘)으로 대체
- **스크롤 연동 패럴랙스**는 특히 위험 — 대안 필수
WCAG 2.2 준수
- 3번 이상/초 점멸 금지 (발작 유발)
- 자동 재생 제어 (5초 이상 애니메이션엔 pause)
11장 · 모바일 제스처 애니메이션
주요 라이브러리
- **@use-gesture/react** (React)
- **Framer Motion drag**
- **React Spring use-gesture**
- **Pan/Pinch/Swipe** 감지
대표 패턴
**(1) Swipe to Dismiss**
- 카드·알림 옆으로 밀기
**(2) Pull to Refresh**
- 상단에서 아래로 당겨 새로고침
**(3) Bottom Sheet**
- 아래에서 올라오는 모달, 드래그로 조절
**(4) Shared Element**
- 썸네일 → 상세 확대 (iOS·Android 표준)
성능 주의
- `touch-action: manipulation` 으로 지연 제거
- 60fps 유지 (GPU 속성만 사용)
- 관성(inertia)·Rubber banding 구현
12장 · Apple / Material Motion 가이드라인
Apple Human Interface Guidelines
- **자연스러움**: 물리 법칙 존중 (ease·관성·scale)
- **빠름**: 기본 0.3-0.4초
- **일관성**: 같은 요소는 같은 방식
- **iOS Spring Curve**: `cubic-bezier(0.42, 0, 0.58, 1)` + spring
Material Design 3 Motion
- **Easing**: Standard (cubic-bezier(0.2, 0, 0, 1)), Emphasized·Decelerated·Accelerated
- **Duration**: Short(100-200ms) · Medium(300-450ms) · Long(500-900ms)
- **Container Transform**: 요소가 "열리는" 느낌
- **Shared Axis**: 계층간 이동
- **Motion Tokens**: Material 3에서 모션도 토큰화
13장 · 토스의 모션 문화 — 한국 사례
토스가 유명한 이유
- **모든 숫자가 Count-up**
- 페이지 전환의 부드러움
- **햅틱+모션** 결합
- 마이크로 인터랙션에 극도의 집착
토스의 원칙 (SLASH·블로그에서 언급)
- "모션은 화려함이 아니라 **자연스러움**"
- "프로덕트 성격에 맞는 Personality를 모션으로 드러낸다"
- "60fps 모바일 성능을 지키기 위한 엔지니어링 투자"
구현 기반
- React Native + Reanimated 2/3
- 자체 디자인 토큰·모션 라이브러리
- 디자이너·엔지니어 페어 작업
한국 타 기업
- **쿠팡**: 이커머스에 맞는 간결하고 빠른 모션
- **네이버**: 검색·지도의 함축적 모션
- **카카오**: 캐릭터·이모티콘 기반 정서 모션
- **당근**: 중고거래 맞춘 친근한 마이크로 인터랙션
14장 · AI 생성 애니메이션 도구 (2025)
도구들
**(1) Rive**
- 런타임 가벼운 벡터 애니메이션
- 2024-2025 웹·모바일 통합 강력
- 디자이너가 Lottie 대체로 선택
**(2) Lottie / After Effects**
- 여전히 표준이나 파일 무거움
- **Lottie Light·Skottie** 대안
**(3) v0·Bolt·Lovable의 모션 생성**
- 프롬프트로 애니메이션 포함 UI
- 아직 품질은 기본 수준
**(4) Figma Smart Animate + AI**
- Figma Variables + Motion 플러그인
- 프로토타입의 AI 생성 확장
**(5) Motion Copilot (Motion One 생태)**
- 프롬프트 → 애니메이션 코드
- 실험 단계
2025년 현실
- AI가 **디자이너를 대체하는** 건 아직 멀다
- 그러나 **퀵 프로토타입·초안 생성**에선 유용
- 최종 디테일은 여전히 사람 손
15장 · 실전 - "카드 스택 인터랙션" 만들기
Tinder 스타일 스와이프 카드 스택.
요구사항
- 카드 여러 장 적층
- 위 카드 드래그로 좌/우로 던지기
- 임계값 넘으면 다음 카드 등장
- `prefers-reduced-motion` 대응
구현 (Framer Motion + use-gesture)
'use client';
export function CardStack({ items }) {
const [cards, setCards] = useState(items);
return (
{cards.slice(-3).map((c, i) => (
))}
);
}
function SwipeCard({ card, onSwipe }) {
const x = useMotionValue(0);
const rotate = useTransform(x, [-200, 200], [-15, 15]);
return (
drag="x"
style={{ x, rotate }}
onDragEnd={(_, info) => {
if (Math.abs(info.offset.x) > 150) onSwipe();
}}
className="absolute inset-0 bg-white rounded-2xl shadow-xl"
>
{card.title}
);
}
세부 UX
- `whileDrag` 로 그림자·회전 강화
- 놓으면 중앙으로 복귀(없다면 spring)
- Swipe 직후 다음 카드 Scale up
16장 · 다음 글 예고 — Season 6 Ep 5: "웹 플랫폼의 새 기능들"
모션을 다뤘다면 다음은 **2024-2025 웹 플랫폼** 전반의 새 기능들.
- Container Queries (@container)
- CSS Nesting 네이티브화
- :has() selector
- CSS Subgrid
- Popover API·Dialog element
- Anchor Positioning
- Web Components 2025 현주소
- WebGPU의 현재
- File System Access API
- WebAssembly WASI
- Speculative Loading
- 100% 호환성 Baseline 2024·2025
**"플랫폼이 커지면 프레임워크는 가벼워진다."**
다음 글에서 만나자.
에필로그 · 체크리스트 12
1. 모든 애니메이션이 **목적(5가지 중 하나)** 을 가지는가?
2. **60fps** 유지를 위해 GPU 가속 속성만 쓰는가?
3. **prefers-reduced-motion** 이 전역 적용되는가?
4. 페이지 전환에 **View Transitions API** 고려했는가?
5. 스크롤 연동이 필요하면 **CSS scroll-driven** 을 먼저 검토했는가?
6. 라이브러리 선택이 **목적에 맞는가** (Framer/Motion/GSAP)?
7. 번들에 **불필요한 모션 라이브러리**가 없는가?
8. 모바일 제스처가 **관성·rubber band** 를 포함하는가?
9. **공식 가이드라인(HIG·Material)** 의 duration·easing을 참고했는가?
10. **AI 생성 애니메이션 도구**를 초안에 활용했는가?
11. **접근성 리뷰** (WCAG 2.2) 가 모션에도 적용되는가?
12. 제품의 **Motion Personality**가 일관되는가?
> **"모션은 보이지 않는 디자이너다.**
> **사용자는 의식 못 하지만, 모션의 품질이 제품의 감성을 결정한다."**
— Season 6 Ep 4, Fin.
현재 단락 (1/310)
좋은 UI와 위대한 UI의 차이는 **모션**에 있다. 같은 기능, 같은 레이아웃, 같은 컬러라도 전환·피드백·미세한 반응이 있느냐 없느냐로 체감이 달라진다.