모션
요소의 등장과 퇴장에 사용하는 시간과 곡선입니다.
사용 기준
움직임은 무엇이 나타나고 사라졌는지 설명할 때 사용합니다. 같은 동작에는 같은 시간과 곡선을 적용합니다.
시간과 곡선의 원본 값은 Roblox 공개 토큰에서 가져왔습니다. 용도별 조합, 확대 비율과 이동 거리는 이 프로젝트에서 정한 규칙입니다. 레이어는 부드럽게 나타나고, 입력·선택은 짧게 반응하도록 구분합니다.
곡선 비교
곡선은 움직임의 속도가 시간에 따라 어떻게 바뀌는지 나타냅니다. 등장 곡선은 앞부분에서 빠르게 움직이고 끝에서 부드럽게 멈춥니다. 퇴장 곡선은 움직이기 시작한 뒤 빠르게 화면을 벗어납니다.
같은 시간으로 재생해 속도 차이를 비교하세요. 1000ms는 차이를 살펴보기 위한 값이며 토스트에 적용하는 시간은 아닙니다.
| 곡선 | CSS 토큰 | 값 | 용도 |
|---|---|---|---|
| 등장 | --rbx-ease-standard-out | cubic-bezier(0.2, 0, 0, 1) | 나타난 요소가 제자리에서 멈출 때 |
| 퇴장 | --rbx-ease-standard-in | cubic-bezier(0.8, 0, 0.4, 1) | 요소가 화면에서 사라질 때 |
| 일정한 속도 | --rbx-ease-linear | cubic-bezier(0, 0, 1, 1) | 일정한 진행을 보여줄 때 |
원본의 expressive-in, expressive-out은 범위를 벗어나거나 튀는 움직임을 포함합니다. 현재 토스트에는 사용하지 않습니다.
시간과 이동
| 동작 | 시간 | 곡선 | 토스트의 변화 |
|---|---|---|---|
| 등장 | 300ms | standard-out | 97.5% → 100%, 아래 4px → 제자리, 투명 → 불투명 |
| 퇴장 | 200ms | standard-in | 100% → 97.5%, 아래 4px로 이동, 불투명 → 투명 |
| 교체 | 퇴장 200ms / 등장 300ms | 각각의 곡선 | 이전 알림의 퇴장과 새 알림의 등장을 함께 재생 |
자동 닫힘까지 기다리는 5초·10초와 모션의 200ms·300ms는 별도 값입니다. 표시 시간을 늘려도 모션이 느려지지는 않습니다.
컴포넌트별 적용
| 대상 | 등장 / 퇴장 | 움직임 |
|---|---|---|
| 문서 사이드바, Sidebar | 500ms / 500ms | 가장자리에서 이동. 문서의 접힘·펼침과 모바일 탐색에도 적용 |
| Dialog, Alert Dialog | 300ms / 200ms | 중심을 유지하며 97.5% → 100%, 투명도 전환 |
| Menu, Context Menu, Menubar, Select, Combobox, Autocomplete, Popover, Preview Card, Navigation Menu | 200ms / 100ms | 연결된 요소를 기준으로 97.5% → 100%, 투명도 전환 |
| Tooltip | 100ms / 100ms | 작은 확대와 투명도 전환 |
| Drawer | 300ms / 200ms | 아래에서 이동. 스와이프 중에는 손가락 위치를 즉시 반영 |
| Accordion, Collapsible | 200ms / 200ms | 실제 내용 높이로 펼침·접힘 |
| Button, Icon Button, 입력, 선택 항목 | 100ms | 배경·테두리·글자색 전환 |
| Switch, Tabs, Progress, Meter | 100–300ms | 기존 상태 표시의 이동과 색상 변화에 공통 시간 적용 |
| Card | 200ms | 클릭 가능한 이미지의 기존 호버 움직임에 공통 시간 적용 |
텍스트, 표, 구분선처럼 상태 변화가 없는 콘텐츠에는 등장 효과를 일괄 적용하지 않습니다. Slider처럼 드래그 중인 컨트롤은 포인터를 바로 따라갑니다.
사이드바 500ms
--rbx-time-500 원본 값에 --rbx-motion-duration-sidebar라는 용도별 이름을 연결했습니다. 등장과 퇴장 모두 500ms를 사용합니다. 위 비교 예제에서 500ms를 선택해 곡선을 확인할 수 있습니다.
코드와 조정 위치
src/styles/motion.css에서 원본 토큰을 용도별 이름으로 연결합니다. 공통 theme.css가 이 파일을 불러오며, 모든 컴포넌트 설치에 함께 포함됩니다.
:root {
--rbx-motion-duration-enter: var(--rbx-time-200);
--rbx-motion-duration-exit: var(--rbx-time-100);
--rbx-motion-ease-enter: var(--rbx-ease-standard-out);
--rbx-motion-ease-exit: var(--rbx-ease-standard-in);
--rbx-motion-distance-toast: 4px;
--rbx-motion-duration-sidebar: var(--rbx-time-500, 500ms);
--rbx-motion-duration-panel: var(--rbx-time-300);
--rbx-motion-duration-panel-exit: var(--rbx-time-200);
--rbx-motion-duration-feedback: var(--rbx-time-100);
--rbx-motion-scale-overlay: 0.975;
}기본 CSS를 불러온 다음 변수를 재정의하면 적용한 컴포넌트의 모션을 함께 조정할 수 있습니다. 원본 스냅샷과 생성된 tokens.css를 직접 수정하지 않습니다.
움직임 감소
prefers-reduced-motion: reduce에서는 컴포넌트의 이동과 전환을 생략합니다. 알림 내용, 작업 버튼, 표시 시간은 유지합니다. 비교 예제에서도 움직임 없이 끝 위치를 표시합니다.
실제 동작
Toast 문서에서 설명, 액션, 연속 알림의 등장과 퇴장을 확인할 수 있습니다.
탭 콘텐츠 전환
Tabs.Panels 안에서는 기존 내용의 퇴장 200ms → 새 내용의 등장 300ms 순서로 재생합니다. --rbx-motion-delay-tabs는 생략되어 추가 간격이 0ms입니다. 간격이 필요하면 시간 토큰을 연결합니다. --rbx-motion-distance-tabs는 24px입니다. 선택한 탭의 방향에 따라 퇴장과 등장 방향이 반대가 됩니다. 움직임 감소 설정에서는 전환과 간격을 생략합니다.
탭 콘텐츠는 퇴장과 등장 모두 standard-in 곡선을 사용합니다. 끝으로 갈수록 빨라지는 움직임으로 통일합니다.