Communitygithub.com

nkurunziza-saddy/motion

제품 UI를 위한 모션을 구축합니다. 요소가 움직여야 하는지 여부, 움직임의 목적, 도구(CSS 트랜지션, WAAPI, Motion, 스프링), 속성, 커브, 지속 시간, 인터럽션, 종료 및 감소된 모션 경로를 결정하고 코드를 작성합니다. 스태거, 안무, 제스처(드래그, 플릭, 시트), 모션 토큰 및 애니메이션 성능도 다룹니다.

motion란 무엇인가요?

이 기술은 제품 UI를 위한 모션을 설계하고 구현하는 포괄적인 가이드와 의사 결정 트리를 제공합니다. CSS 전환, WAAPI, Motion 라이브러리 등 다양한 도구 중에서 가장 효율적인 옵션을 선택하는 방법을 안내하며, 성능과 사용자 경험에 미치는 영향을 신중하게 고려합니다. 또한 스태거와 안무, 드래그 및 플릭과 같은 제스처, 모션 토큰 사용, 애니메이션 성능 최적화에 대한 세부 지침을 포함합니다. Claude Code, Cursor, Codex와 같은 AI 에이전트와 함께 사용하여 모션 관련 코드를 자동 생성하고 검증할 수 있습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/nkurunziza-saddy/hmm-interfaces/tree/HEAD/motion

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

motion은(는) 무엇을 하나요?

이 기술은 모션을 구축합니다. product-ui/references/values.md의 모션 섹션을 확장하며, 해당 파일에는 확정된 숫자(이징 커브, 누르기 스케일, 바운스, 스태거, 지속 시간 표, 토스트 및 레이아웃 지속 시간, 이동 거리, 종료 대 진입 비율)가 포함되어 있습니다. 이러한 숫자는 여기에 반복되지 않습니다. 이 기술은 결정 순서, 토큰, 레시피 및 실패 모드를 추가합니다.

결정을 내리기 전에 product-ui §1(취향 저널 및 우선 순위)과 §5(각 기술이 소유하는 것)를 적용합니다.

결정 순서

이 지침을 위에서 아래로 따르십시오. 각 단계에서 작업을 종료할 수 있습니다. 애니메이션 라인이 0개여도 유효한 결과이며, 그렇게 명시합니다.

1. 움직여야 하는가? 빈도 게이트

한 사용자가 하루에 이 요소를 몇 번 보는지 묻습니다. 등급은 values.md에 있습니다. 실제로:

  • 키보드에 의해 시작되거나 하루에 100회 이상 보이는 경우: 움직임 없음. 이유: 반복적인 움직임은 지연으로 바뀝니다.
  • 하루에 수십 회 보이는 경우(호버, 탭 전환, 행 선택): 없음 또는 즉각적인 색상 변경.
  • 사용자가 읽거나 작업 중인 데이터(테이블의 숫자, 라이브 대시보드의 차트)는 스타일을 위해 절대 움직이지 않습니다. 이유: 움직임은 읽고 있는 것에서 시선을 돌립니다.
  • 게이트가 '아니오'라고 말하면 애니메이션을 작성하지 마십시오. 어떤 등급에 해당하는지 말하고 정적 대안(즉각적인 상태 변경)을 제시하십시오.

2. 목적 이름 지정

한 단어를 고르십시오: 공간적(어디에서 왔거나 갔는지), 상태(이것이 변경됨), 피드백(들었습니다), 연속성(점프를 방지함), 설명(드문 순간에만). 이름을 지정할 수 없으면 중단하십시오. 이유: 빈번한 요소에 대해 "멋져 보인다"는 느린 UI의 주요 원인입니다.

3. 도구 선택: 작동하는 가장 저렴한 것

필요도구
클래스, 속성, 호버 또는 누름으로 전환되는 상태CSS 전환
display: none, 팝오버 또는 대화상자에서 진입@starting-style + transition-behavior: allow-discrete
일회성 시퀀스, 스태거 또는 페이지가 바쁜 동안 실행되어야 하는 모션CSS @keyframes
JS가 시점을 결정, 취소, 역방향, finished 또는 FLIP 필요WAAPI el.animate()
스프링, 속도 핸드오프, 마운트 해제되는 React 노드의 종료, 공유 레이아웃Motion (motion/react)

요소가 전체 컴포넌트(메뉴, 토스트, 드로어)인 경우 포커스 처리를 제공하는 라이브러리를 사용하고 pick-library를 요청하십시오. 페이드를 위해 Motion을 설치하지 마십시오. 이유: CSS는 메인 스레드에서 실행되지 않으며 번들을 소모하지 않습니다.

4. 속성

  • transform 및 opacity를 애니메이션 처리하고, filter는 ≤ 2px 스왑 블러에만 사용합니다. 모든 속성의 이름을 지정하고 절대 transition: all을 사용하지 마십시오.
  • 높이 및 레이아웃 변경: references/recipes.md(그리드 행, FLIP)를 참조하십시오. 무언가를 움직이기 위해 width, top, left 또는 margin을 절대 애니메이션 처리하지 마십시오. 이유: 각각은 모든 프레임에서 레이아웃을 강제합니다.
  • 절대 box-shadow를 애니메이션 처리하지 마십시오. 대신 의사 요소의 opacity를 페이드하십시오.
  • translate 백분율은 요소 자체 크기에 상대적이므로 translateY(100%)는 모든 높이의 드로어와 토스트에 적합합니다.

5. 커브 및 지속 시간, 사용법에 따라 일치

추측에 가장 가까운 숫자를 선택하지 마십시오. 사용법("메뉴 닫기", "아이콘 교체")을 명시한 다음 references/tokens.md에서 해당 행을 가져오십시오. 사용법과 일치하는 행이 없으면 사용법의 이름을 딴 새 토큰을 추가하고 기존 토큰을 구부리지 마십시오. 이유: 토큰은 모션이 무엇을 위한 것인지에 대한 진술이므로 잘못된 사용법이 있는 비슷한 숫자는 잘못된 토큰입니다.

  • 진입 또는 종료: --ease-out. 화면에서 이동: --ease-in-out. 드로어: --ease-drawer. 색상: ease. 스피너: linear. 절대 ease-in을 사용하지 마십시오.
  • 드래그 가능하거나 비행 중 인터럽트 가능한 모든 것은 커브가 아닌 스프링을 사용합니다. 이유: 커브는 사용자의 손이 가진 속도를 받아들일 수 없습니다.
  • 느낌이 느린 경우: 먼저 지속 시간을 줄인 다음 거리를 줄이고, 마지막으로 커브를 수정합니다.

6. 인터럽션

  • 사용자가 1초에 두 번 트리거할 수 있는 모든 것은 전환 또는 스프링이어야 하며 절대 @keyframes가 아닙니다. 이유: 전환은 현재 값에서 대상을 다시 지정하지만 키프레임은 다시 시작하여 점프합니다.
  • WAAPI: 현재 값을 읽은 후 이전 애니메이션을 취소하고 그 값에서 새 애니메이션을 시작합니다(references/recipes.md).
  • 10번 스팸으로 토글된 것은 점프 없이 올바른 상태로 끝나야 합니다. 테스트하십시오.

7. 종료

  • 기본 종료는 페이드이며 진입보다 짧습니다(토큰 파일에 각 쌍이 있습니다).
  • 방향이 있는 것(드로어, 시트, 스와이프된 토스트)은 왔던 길로 떠납니다.
  • 종료되는 요소는 즉시 공간을 차지하지 않으므로 형제 요소가 페이드되는 동안 간격을 닫습니다.
  • 종료는 동시에 이루어지며 절대 스태거되지 않습니다. 이유: 사용자는 이미 떠나기로 결정했습니다.

8. 감소된 모션, 애니메이션과 함께 제공

불투명도와 색상은 유지됩니다. 슬라이드, 스케일, 블러 및 바운스는 사라지고 슬라이드는 페이드가 되고 바운스는 0이 됩니다. 모션을 유일한 신호로 사용하지 마십시오. 패턴은 references/recipes.md에 있습니다.

안무

타이밍을 정하기 전에 모든 움직이는 요소에 역할을 지정하십시오:

역할처리
리드(주목해야 할 하나)먼저 움직이고, 가장 많이 이동
서포트따라가고, 덜 이동
장식제자리에서 페이드 또는 아무것도 하지 않음
정적(컨테이너, 크롬)절대 움직이지 않음
  • 컨테이너당 하나의 진입. 패널이 슬라이드 인하면 콘텐츠는 이미 거기에 있습니다. 이유: 두 개의 계층적 진입은 사용자가 두 번 기다리게 만듭니다.
  • DOM 순서가 아닌 중요도 순서로 정렬합니다. 지연은 values.md 단계(항목 간 40ms, 제목, 텍스트 및 작업 간 100ms)를 유지합니다. 지연보다는 역할에 따라 거리와 지속 시간을 변경합니다.
  • 목록 스태거를 인덱스 6(마지막 지연 240ms)으로 제한하고 그 이후의 항목은 그 지연을 공유합니다. 재생 중에 입력이 작동합니다.
  • 메뉴, 명령 팔레트, 탭 콘텐츠 또는 열린 반복을 절대 스태거하지 마십시오.
  • 가만히 있음: 사용자가 클릭하려는 것, 페이지가 다시 로드될 때 이미 화면에 있는 것, 마지막 업데이트 후 150ms 이내에 도착하는 업데이트(종료 상태로 점프).
  • 방향은 의미를 따릅니다: 다음은 오른쪽에서 진입하고 뒤로는 왼쪽에서 진입하며 사용자가 트리거한 것은 트리거에서 바깥쪽으로 커집니다.

필요할 때 로드

  • references/tokens.md: 정확한 지속 시간, 거리, 스케일, 블러, 이징 또는 스프링 값과 기존 코드베이스를 토큰화할 때 로드합니다.
  • references/recipes.md: 메뉴, 팝오버, 대화상자, 드로어, 토스트, 목록 진입, 아이콘 교체, 높이 변경, 탭 표시기 또는 숫자 변경을 구축할 때 로드합니다.
  • references/gestures.md: 드래그, 스와이프, 플릭, 시트 또는 포인터를 따르는 모든 것에 대해 로드합니다.
  • references/performance.md: 모션이 프레임을 드롭할 때, will-change를 사용하기 전, 그리고 업데이트가 빠르게 도착할 때 로드합니다.

쌍

깨짐수정됨이유
.menu { transition: all 300ms ease-in }transition: opacity 200ms, transform 200ms var(--ease-out)명명된 속성, ease-in은 느림, 메뉴 ≤ 200ms
scale(0)에서 scale(1)scale(0.95) 및 opacity: 0에서 1무에서 나타나는 것은 없음
팝오버가 중심에서 스케일transform-origin: var(--transform-origin)트리거에서 바깥쪽으로 커져야 함
.open { animation: slide-in 300ms }토글된 상태의 transition: transform키프레임은 인터럽트될 때 스냅됨
모든 행 animation-delay: i * 120msmin(i, 6) * 40ms마지막 행이 300ms 이내에 도착
드로어가 슬라이드 인 후 페이드 아웃왔던 길로 다시 슬라이드 아웃방향이 설명임
고정된 ease-out에서 드래그 릴리스릴리스 속도로 시드된 스프링손의 운동량이 계속됨
pointermove에서 setY(y)el.style.transform = ...프레임당 리렌더링 없음

마치기 전에

diff를 검색한 다음 확인하십시오.

검색 대상수정
transition: all, *의 will-change, ease-in명명된 속성, 제거, --ease-out
scale(0), 팝오버의 transform-origin: center0.95, 트리거 원점(대화상자는 중앙 유지)
토글되는 클래스의 @keyframes전환
tokens.md의 행보다 긴 지속 시간 또는 tokens.md에 없는 숫자사용법의 토큰
keydown 핸들러 또는 팔레트의 모션제거
전환의 width, height, top, left, box-shadowtransform, opacity 또는 레시피
prefers-reduced-motion 경로 없음추가

실행 중인 앱에서 확인: 4배속으로 재생(DevTools 애니메이션 패널 또는 지속 시간 곱하기), 토글 스팸, 감소된 모션을 켠 상태에서 테스트, CPU 4배 스로틀. 실행할 수 없었던 것을 말하십시오.

Individual skills in this repo

This repo contains 4 individual skills — each has its own dedicated page.

nkurunziza-saddy/break

Stress-tests a piece of UI with worst-case data and every reachable state, then reports what broke with a numbered fix for each. Use it when the user types /break, or asks to "break this", "stress-test", "try the worst case", "what happens with long names", "check the empty and error states" or "find the edge cases" on a component or screen.

nkurunziza-saddy/layout

Structure and space in product UI on the web. It sets the spacing scale, grouping, alignment, density (compact or comfortable), hit areas, app shells (sidebar, toolbar, content, inspector), max widths, container-query responsiveness, dropdown and popover sizing, room for long and translated text, layout stability (no shift on load) and sticky elements that must not cover focus.

nkurunziza-saddy/pick-library

Picks the right library for a frontend task from a curated, status-checked list, instead of hand-rolling it or installing an abandoned package. Use it when the user asks "what should I use for…", "is there a library for…", or names a package, and when you are about to build a toast, command menu, drawer, date picker, table, virtual list, drag and drop, chart, OTP input, animated number, theme switch, form validation…

nkurunziza-saddy/surfaces

What product UI is made of on the web. It sets elevation levels with exact shadow recipes for light and dark mode, when to use a shadow and when a border, the transparent border for forced-colours mode, a small radius scale with concentric nesting, image outlines, every interactive state as a surface change (hover, pressed, selected, disabled, focus-visible), icons (one set, currentColor, outline and fill, stroke tha…

관련 스킬