테마 선택

📚 지식 노트

AI·하드웨어·주변기기·게임·컴퓨터 시스템·이론 컴퓨터 과학·수학·개발과 운영·보안·응용 분야에 대해 알아 두면 좋은 내용을 정리한 노트다. 위에서 분야를 고르고 아래에서 노트를 고른다.

모션과 전환

움직임으로 관계와 변화를 설명하는 법과, 지나친 움직임을 줄이는 법이다.

목차 (12)
  1. 모션이 하는 일
  2. 이징 곡선: 언제 빠르고 언제 느린가
  3. 스프링: 시간 대신 물리로
  4. 지속 시간: 짧을수록 좋지만 0은 아니다
  5. 전환 패턴: 공유 요소, 컨테이너 변형, 공유 축, 페이드 스루
  6. 애니메이션 원칙 가운데 UI에 쓰는 것
  7. 연쇄(stagger): 차례로 들어오기
  8. 성능: transform과 opacity, 프레임 예산
  9. 움직임 줄이기: prefers-reduced-motion과 전정 장애
  10. 게임 UI의 트윈
  11. 흔한 오해
  12. 핵심 자료

모션이 하는 일

화면의 움직임은 장식이 아니라 설명이다. 상태가 한순간에 바뀌면 사람은 앞뒤 화면을 비교해 무엇이 바뀌었는지 스스로 알아내야 한다. 움직임은 그 사이를 이어 "무엇이 어디서 와서 어디로 갔는지"를 보여 준다. 쓰임은 크게 넷이다.

모션이 하는 일 네 가지. 관계는 작은 카드가 점선 화살표를 따라 큰 상세 화면이 되는 모습, 방향은 새 화면이 오른쪽에서 밀려 들어오는 모습, 피드백은 누른 자리에서 퍼지는 원, 주의는 종 모양 아이콘 옆 배지와 흔들림 표시다관계이것이 저것이 됐다방향앞으로 갔다(뒤로 가면 반대로)피드백입력을 받았다주의여기를 보라(한 번만)
모션의 네 쓰임. 관계(이것이 저것이 됐다), 방향(앞으로 갔다), 피드백(입력을 받았다), 주의(여기를 보라).
  • 관계: 목록의 카드가 그대로 커져 상세 화면이 되면, 둘이 같은 것이라는 사실이 설명 없이 전해진다.
  • 방향: 다음 단계는 오른쪽에서 들어오고 뒤로 가면 오른쪽으로 나간다. 사람은 화면들이 어떤 공간에 놓여 있다고 느끼고 길을 잃지 않는다.
  • 피드백: 누른 자리의 작은 변화가 입력을 받았다고 알린다. 이것이 인터랙션과 상태 노트의 "즉시" 피드백이다.
  • 주의: 새 알림 배지가 한 번 흔들리면 눈이 간다. 계속 흔들리면 방해가 되므로 한 번으로 끝낸다.

이 넷 가운데 무엇도 하지 않는 움직임은 지운다. 매번 보는 화면의 화려한 전환은 처음 한두 번만 즐겁고, 그 뒤로는 기다리는 시간이 된다.

이징 곡선: 언제 빠르고 언제 느린가

이징(easing)은 시간에 따라 움직임이 얼마나 진행했는지를 정하는 곡선이다. 현실의 물체는 정지 상태에서 갑자기 최고 속도가 되지 않는다. 일정한 속도(linear)로 움직이는 화면 요소가 기계적으로 보이는 이유다. CSS의 키워드는 모두 3차 베지어 곡선의 줄임말이다. MDN에 따르면 ease는 cubic-bezier(0.25, 0.1, 0.25, 1), ease-in은 (0.42, 0, 1, 1), ease-out은 (0, 0, 0.58, 1), ease-in-out은 (0.42, 0, 0.58, 1)이다.

이징 곡선 여섯 개. linear는 대각선, ease-in은 처음이 평평하다 끝에서 가파르고, ease-out은 처음이 가파르다 끝에서 평평하며, ease-in-out은 S자, Material 3 standard와 emphasized decelerate는 처음에 빠르게 솟아 길게 감속한다linear기계처럼 일정ease-in천천히 출발: 나갈 때ease-out천천히 멈춤: 들어올 때ease-in-out양 끝이 느림: 화면 안 이동M3 standard(0.2, 0, 0, 1)M3 emph. decelerate(0.05, 0.7, 0.1, 1)각 칸: 가로 = 시간(0→1), 세로 = 진행률(0→1), 점선 = linear
이징 곡선 여섯 개. 곡선이 가파른 구간에서 빠르게, 평평한 구간에서 느리게 움직인다. Material 3 토큰 값은 Material Components 문서에서 가져왔고, 곡선은 계산 함수로 그렸다.
  • 들어올 때는 감속(ease-out 계열): 빠르게 나타나 천천히 자리 잡는다. 사용자는 곧바로 반응을 보고, 끝부분에서 어디에 멈췄는지 읽는다.
  • 나갈 때는 가속(ease-in 계열): 천천히 출발해 빠르게 사라진다. 이미 떠나는 것을 오래 볼 이유가 없다.
  • 화면 안에서 옮길 때는 양쪽(ease-in-out 계열): 출발과 도착이 모두 화면 안에서 보이기 때문이다.

Material 3의 이징 토큰도 같은 생각이다. standard는 (0.2, 0, 0, 1), 들어올 때 쓰는 emphasized decelerate는 (0.05, 0.7, 0.1, 1), 나갈 때 쓰는 emphasized accelerate는 (0.3, 0, 0.8, 0.15)다. 두 곡선을 이어 붙인 emphasized는 한 개의 베지어가 아니라 경로로 정의되어 있다.

이징 단계 그림: 세 줄의 공이 같은 시간에 출발해 같은 시간에 도착하지만, ease-out은 앞쪽에, ease-in은 뒤쪽에 위치 점이 몰려 있다출발도착linearease-outease-in0ms / 300ms (60Hz에서 약 0번째 프레임)50ms / 300ms (60Hz에서 약 3번째 프레임)100ms / 300ms (60Hz에서 약 6번째 프레임)150ms / 300ms (60Hz에서 약 9번째 프레임)200ms / 300ms (60Hz에서 약 12번째 프레임)250ms / 300ms (60Hz에서 약 15번째 프레임)300ms / 300ms (60Hz에서 약 18번째 프레임)
1 / 7

0ms: linear 0%, ease-out 0%, ease-in 0%.

300ms를 여섯 토막으로 나눠 본 세 이징. ease-out은 처음 몇 프레임에 대부분을 가고 천천히 멈춰서, 같은 시간이어도 더 빨리 반응한 것처럼 느껴진다. 위치는 계산 함수로 구했다.
/* 들어올 때: 빠르게 와서 천천히 멈춘다 */
.sheet-enter {
  transition: transform 300ms cubic-bezier(0.05, 0.7, 0.1, 1);
}
/* 나갈 때: 천천히 출발해 빠르게 사라진다, 들어올 때보다 짧게 */
.sheet-exit {
  transition: transform 200ms cubic-bezier(0.3, 0, 0.8, 0.15);
}

스프링: 시간 대신 물리로

베지어 이징은 지속 시간을 먼저 정한다. 스프링은 반대로 강성(stiffness)과 감쇠비(damping ratio)만 정하고, 움직임이 끝나는 시간은 물리 법칙이 정한다. 손가락으로 끌다 놓은 시트처럼 움직이는 도중에 목표가 바뀌거나 처음 속도가 제각각인 경우에 자연스럽다. 감쇠비가 1이면 넘치지 않고 다가가고, 1보다 작을수록 목표를 넘었다가 출렁이며 돌아온다.

강성 700인 스프링 세 개의 위치 곡선. 감쇠비 1은 목표를 넘지 않고 다가가고, 0.9는 거의 넘지 않으며, 0.5는 목표를 16% 넘었다가 출렁이며 자리 잡는다목표출발0ms200ms400ms600ms감쇠비 1넘침 0.0% · 250ms감쇠비 0.9넘침 0.2% · 193ms감쇠비 0.5넘침 16.3% · 331ms강성 700 · 질량 1. 자리 잡는 시간 = 목표의 ±1% 안에 머물기 시작하는 시각
강성 700에서 감쇠비만 바꾼 세 스프링. 0.9는 눈에 거의 안 띄게 넘치고, 0.5는 크게 출렁인다. 질량 1로 놓고 감쇠 진동 공식으로 계산했다.

Material 3는 스프링도 토큰으로 둔다. 위치·크기처럼 공간을 바꾸는 spatial 스프링은 감쇠비 0.9(기본 강성 700), 색·투명도처럼 넘치면 안 되는 effects 스프링은 감쇠비 1(기본 강성 1600)이다. 문서의 설명대로 배경의 투명도가 100%를 넘어 출렁일 수는 없기 때문이다. 감쇠비 0.9의 넘침은 계산하면 약 0.15%라 "살아 있는 느낌"만 남고, 0.5처럼 16%나 넘치는 탄성은 게임이나 장난스러운 브랜드가 아니면 과하다.

지속 시간: 짧을수록 좋지만 0은 아니다

너무 빠르면 움직임을 알아채지 못하고, 너무 느리면 기다리게 한다. NN/g는 대부분의 UI 애니메이션을 복잡도와 이동 거리에 따라 100–500ms 안에 두라고 한다. 체크박스나 토글 같은 단순한 피드백은 약 100ms면 즉각적으로 느껴지고, 모달이 나타나는 것 같은 큰 화면 변화는 200–300ms, 큰 화면을 가로지르는 이동은 400ms까지 쓴다. 500ms쯤부터는 질질 끄는 느낌이 든다.

0에서 1000밀리초 눈금 위에 Material 3 지속 시간 토큰 16개가 short, medium, long, extra long 네 묶음으로 찍혀 있고, 아래에 NN/g가 든 쓰임별 시간 구간이 있다Material 3 지속 시간 토큰short 1–4medium 1–4long 1–4extra long 1–401002003004005006007008009001000ms · 60Hz에서 100ms = 6프레임, 300ms = 18프레임체크박스·토글: 약 100ms모달 등장 같은 큰 변화: 200–300ms큰 화면을 가로지르는 이동: 400ms500ms부터는 질질 끄는 느낌들어올 때를 나갈 때보다 조금 길게(예: 나타남 300ms, 사라짐 200–250ms)
Material 3의 지속 시간 토큰(50ms~1000ms, 16개)과 NN/g가 든 쓰임별 구간. 작은 요소일수록 짧고, 움직이는 거리와 면적이 클수록 길다.
  • 크기와 거리에 비례: 작은 아이콘의 색 변화는 short(50–200ms), 카드 펼치기는 medium(250–400ms), 화면 전체 전환은 long(450–600ms) 쪽이다. 토큰 값은 Material Components 문서의 표에 있다.
  • 들어올 때가 조금 길다: NN/g의 예처럼 팝업은 나타날 때 300ms, 사라질 때 200–250ms로 둔다.
  • 자주 볼수록 짧게: 하루에 수백 번 여닫는 메뉴는 처음 보는 온보딩 화면보다 짧아야 한다.
  • 토큰으로 고정한다: 지속 시간과 이징을 화면마다 새로 고르면 제품 전체의 리듬이 흩어진다. 몇 개의 이름(짧음·보통·김)으로 묶어 디자인 시스템에 둔다(디자인 시스템 노트).

전환 패턴: 공유 요소, 컨테이너 변형, 공유 축, 페이드 스루

화면이 바뀔 때의 움직임은 두 화면의 관계에 맞춰 고른다. Material의 전환 패턴은 넷이다. 컨테이너 변형은 카드가 상세 화면으로, 떠 있는 버튼이 화면으로 커지는 것처럼 테두리 있는 요소 사이의 전환이다. 공유 축은 단계의 앞뒤나 탭처럼 공간·탐색 관계가 있는 화면을 같은 축(가로·세로·깊이)으로 함께 민다. 페이드 스루는 하단 탭을 바꿀 때처럼 서로 관계없는 화면에서 앞 화면이 사라진 뒤 새 화면이 나타난다. 페이드는 대화상자·메뉴·스낵바처럼 화면 안에서 나타나고 사라지는 요소에 쓴다.

전환 패턴 네 가지. 컨테이너 변형은 작은 카드가 화면 전체로 커지고, 공유 축은 두 화면이 같은 가로축을 따라 함께 밀리며, 페이드 스루는 앞 화면이 사라진 뒤 새 화면이 나타나고, 페이드는 화면 안에서 대화상자가 나타난다컨테이너 변형카드 → 상세FAB → 화면공유 축단계 앞뒤탭 좌우페이드 스루관계없는하단 탭 전환페이드화면 안에서나타남·사라짐사라짐→ 나타남
전환 패턴 넷. 두 화면 사이에 관계가 강할수록 왼쪽(같은 요소가 변한다), 약할수록 오른쪽(그냥 바뀐다)에 가깝다.

컨테이너 변형은 공유 요소 전환(shared element transition)의 대표적인 형태다. 앞 화면의 요소와 뒤 화면의 요소를 같은 것으로 짝지어, 위치와 크기를 이어 움직인다. 안의 내용은 앞 화면 것이 먼저 흐려지고 뒤 화면 것이 나중에 나타나서, 두 내용이 겹쳐 지저분해 보이지 않는다.

컨테이너 변형 단계 그림: 목록 속 카드가 점점 커지며 화면 전체를 채우고, 카드의 글은 흐려지고 상세 화면의 내용이 나타난다제주 3박 4일제주 3박 4일일정 · 숙소 · 지도제주 3박 4일제주 3박 4일일정 · 숙소 · 지도제주 3박 4일제주 3박 4일일정 · 숙소 · 지도제주 3박 4일제주 3박 4일일정 · 숙소 · 지도제주 3박 4일제주 3박 4일일정 · 숙소 · 지도시간 0 → 400ms변화내용은 앞 절반에 사라지고 뒤 절반에 나타난다
1 / 5

0ms: 목록 속 카드. 누르면 이 카드 자체가 상세 화면이 된다.

카드가 상세 화면으로 커지는 컨테이너 변형. 왼쪽은 화면, 오른쪽은 쓰인 이징(M3 emphasized decelerate) 위의 지금 위치다. 400ms는 예로 든 길이이고, 크기와 위치는 계산 함수로 구했다.

웹에서는 View Transition API가 이것을 맡는다. document.startViewTransition()에 화면을 바꾸는 함수를 넘기면 브라우저가 앞뒤 화면을 찍어 이어 주고, 앞뒤 화면의 요소에 같은 view-transition-name을 주면 그 요소가 따로 이어 움직인다. 여러 페이지로 된 사이트는 두 문서 모두 @view-transition으로 참여를 밝힌다.

// 같은 이름을 붙인 요소끼리 앞뒤 화면에서 이어 움직인다
card.style.viewTransitionName = 'trip-hero';
document.startViewTransition(() => showDetail(trip));

애니메이션 원칙 가운데 UI에 쓰는 것

디즈니 애니메이터 프랭크 토머스와 올리 존스턴은 1981년 책 『The Illusion of Life』에 캐릭터 애니메이션의 12원칙을 정리했다(위키백과 정리). 캐릭터를 위한 원칙이지만 몇 가지는 화면 요소에도 그대로 쓴다.

애니메이션 원칙 여섯 칸. 느리게 시작·끝내기는 양 끝에 점이 몰린 줄, 예비 동작은 오른쪽으로 가기 전 왼쪽으로 조금 물러나는 화살표, 따라오는 동작은 목표를 조금 넘었다 돌아오는 화살표, 무대 연출은 어두운 배경 위 밝은 카드 하나, 호는 휘어진 이동 경로, 찌그러짐과 늘어남은 바닥에 닿아 납작해진 공이다느리게 시작·끝내기거의 모든 이동예비 동작당기기 전 살짝 반대로따라오는 동작멈출 때 조금 넘었다 복귀무대 연출중요한 것만 밝게호(arc)날아가는 아이콘의 길찌그러짐과 늘어남눌림·튕김을 과장할 때목표
12원칙 가운데 UI에서 자주 보는 여섯. 느리게 시작·끝내기 칸의 점은 ease-in-out을 같은 시간 간격으로 찍은 위치라 양 끝에 몰린다.
원칙원래 뜻UI에서
느리게 시작·끝내기(slow in and slow out)동작의 처음과 끝에 그림을 더 많이 둬 가속·감속을 흉내 낸다이징 곡선 그 자체
예비 동작(anticipation)점프 전에 무릎을 굽히듯 동작을 미리 알린다당겨서 새로 고침 전에 화살표가 돌기 시작, 버튼이 눌리며 살짝 작아짐
따라오는 동작(follow through)몸이 멈춰도 느슨한 부분은 조금 더 움직인다멈출 때 살짝 넘었다 돌아오는 스프링
무대 연출(staging)가장 중요한 것에 시선이 가게 배치·조명을 정한다모달 뒤 배경을 어둡게, 한 번에 한 가지만 움직이기
호(arc)자연스러운 움직임은 곡선 경로를 따른다장바구니로 날아가는 상품 아이콘
찌그러짐과 늘어남(squash and stretch)부피는 그대로 두고 모양을 바꿔 무게와 탄성을 보인다게임·장난스러운 UI에서 눌림과 튕김을 과장할 때

나머지 원칙 가운데 타이밍(그림 수, 곧 지속 시간이 무게와 분위기를 정한다)과 과장(현실보다 조금 크게)은 위 절들에 이미 들어 있다. UI는 캐릭터보다 절제한다. 과장이 지나치면 정보보다 움직임이 먼저 보인다.

연쇄(stagger): 차례로 들어오기

목록 항목을 한꺼번에 나타내지 않고 조금씩 늦춰 차례로 들어오게 하는 것을 연쇄(stagger)라고 한다. 눈이 위에서 아래로 따라가며 읽는 순서와 묶음이 드러난다. 위의 따라오는 동작(겹치는 동작)을 여러 요소로 나눈 셈이다.

목록 항목 여섯 개가 50밀리초 간격으로 차례로 나타나는 시간표. 아래에는 항목이 12개일 때 같은 간격이면 750밀리초, 간격을 줄이면 500밀리초 안에 끝난다는 비교가 있다항목 1+0ms항목 2+50ms항목 3+100ms항목 4+150ms항목 5+200ms항목 6+250ms0100200300400500600700800ms한 항목 200ms, 간격 50ms항목 12개를 같은 간격으로:750ms간격을 27.3ms로 줄이면:500ms아래 두 막대는 위 눈금의 절반 비율. 연쇄는 짧고 일정하게, 전체 시간에 상한을 둔다
한 항목 200ms, 간격 50ms인 연쇄. 항목이 12개면 같은 간격으로는 750ms가 걸려, 전체를 500ms 안에 끝내려면 간격을 줄여야 한다. 시간은 계산 함수로 구했다.
  • 전체 시간에 상한을 둔다: 간격 × (항목 수 − 1) + 한 항목 시간이 전체다. 항목이 늘면 간격을 줄인다. 예에서 12개를 500ms에 맞추려면 간격이 27.3ms가 된다.
  • 보이는 것만: 화면 밖 항목까지 연쇄에 넣으면 스크롤했을 때 이미 지난 애니메이션을 기다리게 된다. 첫 화면의 몇 개에만 쓴다.
  • 처음 한 번만: 목록을 다시 정렬하거나 새로 고칠 때마다 연쇄를 다시 틀면 내용을 가린다.

성능: transform과 opacity, 프레임 예산

매끄러운 움직임은 매 프레임이 제때 나와야 가능하다. web.dev에 따르면 60Hz 화면에서 브라우저는 프레임 하나를 16.7ms 안에 만들어야 하고, 브라우저 자신의 일이 있어 페이지의 일은 약 10ms 안에 끝내야 한다. 120Hz 화면이면 프레임 하나가 8.3ms다. 모바일 앱의 프레임 예산은 모바일 개발 노트에 있다.

위는 바꾸는 속성별로 다시 거치는 렌더링 단계. 크기·위치는 레이아웃부터 전부, 색과 그림자는 페인트부터, transform과 opacity는 합성만 다시 한다. 아래는 60Hz 한 프레임 16.7밀리초 가운데 페이지의 일에 쓸 수 있는 약 10밀리초를 보인 막대다width·top·leftJS스타일레이아웃페인트합성color·box-shadowJS스타일건너뜀페인트합성transform·opacityJS스타일건너뜀건너뜀합성60Hz 한 프레임 = 16.7ms페이지의 일: 약 10ms브라우저 몫넘치면 그 프레임을 건너뛰어 끊겨 보인다(jank). 120Hz면 한 프레임이 8.3ms로 더 빠듯하다
바꾸는 속성에 따라 브라우저가 다시 하는 일. 크기·위치를 바꾸면 레이아웃부터 다시 하고, transform·opacity는 합성만 다시 한다. 아래는 60Hz 한 프레임의 예산이다.
  • transform과 opacity만 움직인다: web.dev의 애니메이션 안내는 애니메이션을 이 둘로 제한하라고 한다. width·top·left를 움직이면 매 프레임 레이아웃과 페인트를 다시 한다. 위치는 translate, 크기는 scale로 바꾼다.
  • will-change는 아껴 쓴다: 같은 안내는 성능 문제가 실제로 생겼을 때만 쓰라고 한다. 미리 잔뜩 붙이면 레이어가 늘어 다른 문제가 생긴다.
  • 메인 스레드를 비운다: 애니메이션 도중에 무거운 스크립트가 돌면 예산을 넘겨 프레임을 건너뛴다(끊김, jank). 데이터 처리는 애니메이션이 끝난 뒤나 다른 스레드로 미룬다.

움직임 줄이기: prefers-reduced-motion과 전정 장애

몸의 균형을 맡는 전정 기관에 장애가 있는 사람에게 화면의 움직임은 실제 증상을 일으킨다. W3C의 설명에 따르면 꼭 필요하지 않은 움직임이 어지럼, 메스꺼움, 두통을 부르고, 심하면 누워서 쉬어야 할 정도다. MDN은 큰 물체를 확대하거나 패닝하는 움직임을 대표적인 방아쇠로 든다.

왼쪽은 기본 설정에서 새 화면이 작게 시작해 커지며 날아오고 배경이 다른 속도로 움직이는 전환, 오른쪽은 움직임 줄이기 설정에서 제자리에서 앞 화면이 흐려지고 새 화면이 나타나는 전환이다no-preference배경은 다른 속도로(시차)확대·패닝·시차: 전정 장애가 있으면어지럼·메스꺼움의 방아쇠가 된다reduce흐려짐나타남같은 자리, opacity만움직임 대신 페이드로 바꾼다. 상태가바뀌었다는 정보는 그대로 남는다
같은 화면 전환을 두 설정에서. 기본은 확대하며 날아오고 배경이 시차로 움직인다. 움직임 줄이기 설정에서는 제자리에서 교차 페이드만 한다(오른쪽 두 상자는 실제로는 같은 자리에 겹친다).

운영체제는 움직임 줄이기 설정을 둔다. iOS는 설정 › 손쉬운 사용 › 동작, 안드로이드 9 이상은 설정 › 접근성 › 애니메이션 삭제, Windows 11은 설정 › 접근성 › 시각 효과 › 애니메이션 효과다. 웹은 이 설정을 prefers-reduced-motion 미디어 쿼리로 읽는다. 값은 no-preference와 reduce 둘이다.

@media (prefers-reduced-motion: reduce) {
  /* 확대·이동 대신 제자리 페이드 */
  .page-enter {
    animation: fade-in 200ms ease-out both;
  }
  .parallax {
    transform: none;
  }
}
  • 지우지 말고 바꾼다: 움직임이 상태 변화를 알려 주던 것이라면 그 정보는 남겨야 한다. 이동·확대를 짧은 페이드로 바꾸는 것이 MDN 예제의 방식이다.
  • 기준: WCAG 2.3.3(상호작용에서 나온 애니메이션, AAA)은 상호작용이 부른 움직임을 끌 수 있게 하라고 하고, 2.2.2(일시 정지·정지·숨기기, A)는 저절로 시작해 5초 넘게 이어지는 움직임에 멈출 방법을 두라고 한다. 2.3.1(세 번 깜빡임, A)은 1초에 세 번 넘게 번쩍이는 것을 금한다.
  • 설정 화면에도 둔다: 운영체제 설정을 모르는 사람도 있으므로, 앱 안에 "애니메이션 줄이기" 스위치를 두면 더 많은 사람이 쓴다. 게임 접근성은 게임 UX 노트에 있다.

게임 UI의 트윈

게임은 UI 모션을 더 과감하게 쓴다. 대신 원리는 같다. 값이 바뀐 사실을 숨기지 않고, 그 변화를 읽을 시간을 준다. 게임 엔진에서는 값을 시작점에서 끝점까지 시간에 따라 채워 넣는 것을 트윈(tween, between에서 나온 말)이라 부른다. Godot의 Tween은 곡선 모양(전이 종류: 선형, 사인, 2·3·4·5제곱, 지수, 원, 탄성, 튕김, 뒤로 물러남, 스프링)과 곡선을 어디에 적용할지(이징 종류: 천천히 시작, 천천히 끝, 양 끝이 느림, 양 끝이 빠름)를 따로 고른다. CSS의 ease-in·ease-out과 같은 생각이다.

왼쪽 그래프는 체력이 100에서 60으로 줄 때 앞 막대는 100밀리초에 바로 떨어지고, 잔상 막대는 400밀리초까지 머물다 800밀리초까지 부드럽게 따라 내려오는 모습이다. 오른쪽은 네 시점의 체력 막대 모양이다1006000ms250ms500ms750ms1000ms맞음앞 막대: 즉시잔상: 300ms 머문 뒤 400ms 트윈50ms250ms600ms900ms숫자는 즉시 정확하게, 움직임은 그 변화를 읽을 시간을 준다
체력이 100에서 60으로 줄 때. 앞 막대는 곧바로 정확한 값이 되고, 뒤의 잔상 막대가 잠깐 머문 뒤 부드럽게 따라 내려와 얼마나 잃었는지 보여 준다. 값은 계산 함수로 구했다.
# 맞은 순간: 앞 막대는 바로, 잔상 막대는 0.3초 뒤 0.4초 동안
front_bar.value = hp
var tween = create_tween()
tween.tween_interval(0.3)
tween.tween_property(ghost_bar, "value", hp, 0.4) \
    .set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT)
  • 정확한 값은 즉시: 체력·탄약처럼 판단에 쓰는 숫자는 바로 바꾸고, 움직임은 그 옆의 보조 정보(잔상, 숫자 튀어 오름)에 맡긴다. 트윈이 끝날 때까지 실제 값을 모르면 조작이 늦어진다.
  • 획득과 손실을 다르게: 점수가 오를 때는 숫자가 빠르게 올라가는 카운트업, 잃을 때는 잔상과 흔들림처럼 성격이 다른 움직임으로 구분한다.
  • 시간 배율을 따로: 게임을 일시 정지하거나 느리게 하는 동안에도 메뉴 UI는 움직여야 한다. UI 트윈은 게임 시간과 분리된 시계로 돌린다.

피격 반응, 화면 흔들림 같은 "손맛"은 게임 UX 노트에서, HUD 정보 배치는 게임 UI 노트에서 다룬다.

흔한 오해

  • "애니메이션은 꾸밈이라 나중에 넣는다" — 관계와 방향을 설명하는 움직임은 정보 설계의 일부다. 무엇을 움직일지는 화면 흐름을 정할 때 함께 정한다.
  • "느리게 움직여야 부드러워 보인다" — 부드러움은 이징과 프레임이 만든다. 길이는 대부분 100–500ms 안이고, 길수록 기다림이 된다.
  • "linear가 가장 정직한 움직임이다" — 현실의 물체는 가속하고 감속한다. 진행 막대처럼 값 자체를 보여 줄 때가 아니면 기계적으로 보인다.
  • "움직임 줄이기는 애니메이션을 모두 끄는 것" — 상태 변화의 정보는 남기고 이동·확대를 페이드 같은 덜 자극적인 것으로 바꾸는 것이다.
  • "left·top으로 움직여도 요즘 기기는 빠르다" — 매 프레임 레이아웃을 다시 하게 되고, 저사양 기기나 120Hz 화면에서 가장 먼저 끊긴다. transform을 쓴다.
  • "스프링은 늘 튕긴다" — 감쇠비가 1이면 넘치지 않는다. Material의 공간 스프링도 감쇠비 0.9로 거의 넘치지 않는다.

핵심 자료

요지는 직접 정리한 한 줄이다.

자료한 줄 요지
Material Components — Motion지속 시간 토큰 16개, 이징 곡선, 스프링 토큰, 전환 패턴 넷의 값과 쓰임.
NN/g — Animation Duration대부분 100–500ms. 단순한 피드백은 약 100ms, 큰 변화는 200–300ms.
MDN — <easing-function>ease·ease-in·ease-out의 cubic-bezier 값과 linear()·steps().
web.dev — Rendering performance픽셀 파이프라인 다섯 단계와 60fps 프레임 예산(약 10ms).
MDN — prefers-reduced-motion운영체제의 움직임 줄이기 설정을 CSS에서 읽는 법과 전정 장애 주의.
W3C — Animation from Interactions상호작용이 부른 움직임을 끌 수 있어야 한다는 AAA 기준과 그 이유.
Godot — Tween게임 UI 값을 트윈하는 API. 전이 종류와 이징 종류를 따로 고른다.