AI에게 화면 움직임을 맡기면서 이렇게 쓴 적이 있습니다.

카드가 부드럽게 나타나게 해 줘

나온 것은 부드럽긴 한데 어딘가 굼떴습니다. 다시 "좀 더 경쾌하게"라고 했더니 이번엔 너무 팔랑거렸습니다. 몇 번을 주고받다가 알았습니다. 부드러움은 결과지 지시가 아닙니다.

그래서 모션을 말로 시킬 때 쓰는 용어를 하나씩 정리해 보려고 합니다. 이 글이 첫 번째, 이징입니다. 나머지 스무 개가 전부 이 위에 얹히기 때문에 여기서 시작합니다.

이징이 무엇인가

맨 위 그림을 보십시오. 점 네 개가 같은 거리를 같은 시간에 갑니다. 동시에 출발해서 동시에 도착합니다. 그런데 가는 동안의 위치는 서로 다릅니다.

다른 것은 속도 곡선뿐입니다. 이 곡선을 고르는 일이 이징입니다.

이름어떻게 가나어디에 쓰나
linear처음부터 끝까지 같은 속도회전, 무한 루프, 진행 막대
ease-out튀어나가 천천히 멈춘다등장, 열기, 펼치기
ease-in천천히 떠나 빨라진다퇴장, 닫기, 사라지기
ease-in-out양끝이 느리고 가운데가 빠르다자리 옮기기, 화면 전환

linear가 기계처럼 보이는 이유가 여기 있습니다. 현실에서 속도가 일정한 물체는 거의 없습니다. 던진 공도, 닫히는 문도, 멈추는 차도 전부 가감속이 있습니다.

들어올 때와 나갈 때는 반대입니다

같은 카드가 두 번 등장하는 애니메이션. 왼쪽은 ease-out 으로 빠르게 올라와 부드럽게 멈추고, 오른쪽은 ease-in 으로 느리게 출발했다가 끝에서 갑자기 빨라져 부딪히는 것처럼 보입니다

이것 하나만 지켜도 절반은 됩니다.

  • 들어오는 것은 ease-out — 빠르게 들어와 부드럽게 멈춥니다
  • 나가는 것은 ease-in — 천천히 떠나 빠르게 사라집니다

왜 그런가. 눈이 보는 것은 도착입니다. 도착이 느려야 "도착했다"로 읽히고, 도착이 빠르면 "부딪혔다"로 읽힙니다. 반대로 퇴장은 시작이 보이고 끝은 안 봐도 되니, 천천히 떠나 빠르게 치우는 편이 답답하지 않습니다.

위 그림의 오른쪽이 ease-in으로 등장한 경우입니다. 꾸물대다 끝에서 튀어서, 부드럽기는커녕 벽에 부딪힌 것처럼 보입니다.

그래서 프롬프트에 무엇을 적나

"부드럽게" 대신 곡선과 시간을 적습니다.

이렇게 쓰면 — 카드가 부드럽게 나타나게 해 줘 이렇게 씁니다 — 카드가 아래에서 20px 올라오면서 나타나게 해 줘. ease-out, 320ms. 사라질 때는 ease-in, 180ms로 더 빠르게.

셋만 정해 주면 됩니다.

  1. 무엇이 변하나 — 위치, 크기, 투명도
  2. 얼마나 변하나 — 20px, 0.96배, 0 → 1
  3. 어떤 곡선으로 얼마 동안 — ease-out, 320ms

이 셋이 없으면 AI는 기본값을 고르고, 기본값은 대개 ease(살짝 ease-in-out)입니다. 그래서 시킨 것마다 비슷하게 흐물거립니다.

cubic-bezier 를 읽는 법

정해진 이름 네 개로 부족하면 숫자로 직접 씁니다.

cubic-bezier(0.16, 1, 0.3, 1)
자리값무엇을 정하나
첫째·둘째0.16, 1출발 쪽 제어점
셋째·넷째0.3, 1도착 쪽 제어점

네 숫자는 제어점 두 개의 좌표입니다. 전부 외울 필요는 없고 규칙 하나만 알면 됩니다.

  • 두 번째 숫자가 1보다 크거나 1에 가까우면 출발이 급합니다 → 튀어나갑니다
  • 네 번째 숫자가 1에 가까우면 도착이 완만합니다 → 부드럽게 멈춥니다

그래서 cubic-bezier(.16, 1, .3, 1)은 확 나갔다가 길게 안착하는 곡선입니다. 등장에 잘 맞습니다.

이 사이트가 실제로 쓰는 값

말만 하면 공허하니 실물을 적습니다. 이 사이트의 스타일시트에는 모션 값이 딱 둘입니다.

--m-swap:   180ms ease;
--m-reveal: 620ms cubic-bezier(.16, 1, .3, 1);
  • --m-swap은 색이 바뀌거나 상태가 바뀌는 것에 씁니다. 짧아야 합니다
  • --m-reveal은 스크롤에 맞춰 나타나는 것에 씁니다. 길고 끝이 완만합니다

값을 두 개만 둔 것은 게을러서가 아닙니다. 값이 늘어나면 화면마다 리듬이 달라져서 같은 사이트로 안 읽힙니다.

시간은 얼마나

관행으로 굳은 범위가 있습니다. 규칙이 아니라 출발점입니다.

무엇대략
색·테두리 같은 상태 변화120~200ms
작은 것의 등장·퇴장200~350ms
큰 판이 움직이는 전환400~600ms
그보다 길면대개 "느리다"고 느낍니다

거리가 멀수록 시간이 길어야 합니다. 같은 300ms라도 20px 움직이는 것은 경쾌하고 800px 움직이는 것은 순간이동처럼 보입니다.

안 되는 것도 적습니다

  • 모든 것에 ease-in-out을 쓰면 전부 흐물거립니다. 가장 무난해 보여서 제일 많이 남용됩니다
  • linear는 틀린 게 아닙니다. 회전이나 무한 스크롤처럼 시작과 끝이 없는 움직임에는 오히려 맞습니다
  • prefers-reduced-motion을 켠 사람에게는 이 모든 것이 꺼져야 합니다. 어지럼증 때문에 꺼 둔 사람에게 부드러운 곡선은 위로가 안 됩니다. 이 글의 그림 두 장도 그 설정에서는 멈춘 채로 나옵니다

확인하지 못한 것

여기 적은 시간 범위는 널리 쓰이는 관행이지 측정값이 아닙니다. 실제로 사람이 어느 구간에서 답답하다고 느끼는지는 화면 크기와 기기 성능, 그 사람의 기대에 따라 달라집니다. 저도 재 보지 않았습니다.

정리

  • 이징은 같은 거리·같은 시간을 어떤 속도로 가느냐입니다
  • 들어오는 것은 ease-out, 나가는 것은 ease-in. 눈이 보는 것은 도착입니다
  • 프롬프트에는 무엇이 · 얼마나 · 어떤 곡선으로 얼마 동안 셋을 적습니다
  • cubic-bezier는 두 번째 숫자가 출발의 급함, 네 번째가 도착의 완만함입니다
  • 값은 적게 두십시오. 많으면 같은 사이트로 안 읽힙니다

---

이 연재에서 다룰 것

모션 용어 스물한 개를 여덟 편에 나눠 적습니다. 매번 실제로 움직이는 그림과 함께 올립니다.

  1. 이징 ← 지금 글
  2. 예비동작 · 팔로스루 · 오버랩
  3. 스쿼시 앤 스트레치 · 아크
  4. 스태거 · 홀드 · 비트 싱크
  5. 매치컷 · 줌 스루 · 휩 팬 · 아이리스
  6. 패럴랙스 · 푸시 인
  7. 마스크 리빌 · 모션 블러 · 세컨더리 액션
  8. 키네틱 타이포 · 카운트업 · 루프

이어서 읽을 것

이징은 나머지 전부가 그 위에 얹히는 바닥이라 첫 편으로 뒀습니다. 바로 다음 편인 예비동작 · 팔로스루 · 오버랩이 그 위에 시간을 붙이는 이야기입니다. 연재 전체 목록과 아직 안 나온 편의 차례는 프롬프트 연구에 있습니다.