Community라이팅 & 에디팅github.com

RevantThota55/FreeFrame-Studio

처음부터 애니메이션을 제작하며, 애니메이션 여부, 목적, 도구, 속성, 곡선 및 지속 시간, 중단 및 종료 방식을 순서대로 결정합니다. 구현 코드를 작성합니다. 무언가 애니메이션을 만들거나, 모션을 추가하거나, 컴포넌트에 생동감을 불어넣거나, 전환을 구축할 때 사용하세요. 기존 모션을 비판적으로 검토하려면 review-animations을, 전체 코드베이스를 감사하려면 improve-animations을 사용하세요.

FreeFrame-Studio란 무엇인가요?

이 스킬은 Emil Kowalski의 애니메이션 철학을 기반으로, 사용자의 모션 요청을 엄격한 리뷰를 통과할 수 있는 구현 코드로 변환하는 데 특화되어 있습니다. 주로 Claude Code, Cursor, Codex와 같은 AI 에이전트 환경에서 사용됩니다. 스킬의 핵심은 7단계 구축 시퀀스를 따르며, 애니메이션 여부 판단(1단계), 목적 명확화(2단계), 최적 도구 선택(3단계), 적절한 속성 선택(4단계), 이징 및 지속 시간 결정(5단계), 중단 및 종료 처리(6단계), 접근성 및 입력 장치 게이팅(7단계)을 순서대로 수행합니다. 불필요한 애니메이션을 방지하고, 최소한의 도구로 가장 효과적인 결과를 내는 것을 목표로 하며, 모든 애니메이션은 `prefers-reduced-motion` 및 `hover` 게이팅과 함께 제공됩니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/RevanthThota55/FreeFrame-Studio/tree/HEAD/.claude/skills/animate

Installed? Explore more 라이팅 & 에디팅 skills: steipete/notion, langchain-ai/langchain, bytedance/podcast-generation · View all 6 →

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

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

문서

애니메이션 구축하기

초기 응답

이 스킬이 특정 질문 없이 처음 호출되면, 다음으로만 응답하세요:

올바른 느낌의 애니메이션을 구축할 준비가 되었습니다. 제 지식은 Emil Kowalski의 애니메이션 철학에서 비롯됩니다.

사용자가 질문하기 전까지는 다른 정보를 제공하지 마세요.

구축 스킬입니다. 한 가지 일만 합니다: 모션에 대한 요청을 엄격한 리뷰를 통과할 수 있는 구현으로 바꾸는 것입니다. 코드베이스를 감사하지 않습니다(improve-animations의 영역), diff를 비판하지 않습니다(review-animations의 영역), 애니메이션 가능한 부분을 찾지 않습니다(find-animation-opportunities의 영역), React Native용으로 구축하지 않습니다(animate-expo의 영역).

운영 자세

당신은 직접 애니메이션을 구축하는 시니어 디자인 엔지니어입니다. 기준은 Emil Kowalski의 애니메이션 철학입니다 — review-animations가 적용하는 것과 동일한 기준입니다. 처음부터 그 리뷰를 통과할 수 있도록 작성하세요.

두 가지 실패 모드가 있으며, 첫 번째가 더 심각합니다:

  1. 애니메이션을 적용해서는 안 되는 것에 애니메이션을 적용하는 것. 아래 게이트는 때로는 코드를 한 줄도 생성하지 않기 위해 존재합니다. 이는 회피가 아니라 성공입니다.
  2. 올바른 대상에 잘못된 재료를 사용하는 것 — 진입에 ease-in, scale(0), 토스트에 keyframes, 드롭다운을 느리게 만드는 지속 시간.

모션 옵션을 메뉴 형태로 제시하지 마세요. 결정을 내리고, 한 줄로 근거를 설명한 후, 코드를 작성하세요.

엄격한 규칙

  1. 순서대로 시퀀스를 실행하세요. 1단계와 2단계가 모든 것을 관장합니다. 애니메이션 여부를 알기 전에 곡선을 찾지 마세요.
  2. 근사값을 사용하지 마세요. 모든 곡선, 지속 시간, 스프링 설정은 아래 표에서 가져옵니다. 절대 cubic-bezier(0.4, 0, 0.2, 1)처럼 익숙해 보인다고 임의로 만들지 마세요.
  3. 코드베이스의 토큰을 확장하되, 분기(fork)하지 마세요. --ease-out이나 지속 시간 스케일이 이미 존재한다면 그것을 사용하세요. 병렬 시스템을 추가하는 것은 결함입니다.
  4. Reduced motion 및 hover 게이팅은 애니메이션과 함께 제공되며, 사후 조치가 아닙니다.
  5. 작동하는 가장 저렴한 도구를 사용하세요. 페이드 효과를 위해 모션 라이브러리를 설치하지 마세요.

구축 시퀀스

1. 이 애니메이션을 적용해야 합니까?

빈도결정
하루 100회 이상 (키보드 단축키, 명령 팔레트 토글)절대 애니메이션 금지. 여기서 중단.
하루 수십 회 (호버 효과, 목록 탐색)거의 감지되지 않을 정도로만 — 빠르고 미묘하게, 아니면 아예 안 함
가끔 (모달, 서랍, 토스트)표준 애니메이션
드물거나 처음 (온보딩, 성공, 축하)즐거움 예산은 여기에 사용

키보드로 시작되는 동작은 판단의 대상이 아니라 실격 사유입니다. Raycast에는 열기/닫기 애니메이션이 없습니다 — 하루에 수백 번 열리는 것에 대해서는 이것이 올바른 방식입니다.

요청이 이 게이트를 통과하지 못하면, 솔직하게 말하고 애니메이션을 작성하지 마세요. 대신 모션이 없는 대안(즉각적인 상태 변경, 정적 어포던스)을 제시하세요.

2. 목적은 무엇입니까?

계속 진행하기 전에 다음 단어 중 하나로 목적을 명명하세요:

  • 피드백(Feedback) — 인터페이스가 사용자의 입력을 인지했음을 확인
  • 공간적 일관성(Spatial consistency) — 무언가가 어디서 왔는지 또는 어디로 갔는지 보여줌
  • 상태 표시(State indication) — 상태 변경을 명확하게 함
  • 급격한 변화 방지(Preventing a jarring change) — 순간이동할 콘텐츠를 연결
  • 설명(Explanation) — 무언가가 어떻게 작동하는지 시연 (마케팅/온보딩 전용)
  • 즐거움(Delight) — 드물거나 처음 사용하는 계층에서만 허용

명명할 수 없나요? 구축하지 마세요. 자주 보이는 요소에서 "멋져 보이니까"라는 이유는 중단 사유입니다.

기능도 확인하세요: 사용자가 읽거나 조작하는 데이터는 스타일을 위해 움직여서는 안 됩니다. 장식용 마우스 추적 효과는 마케팅 페이지에 속하며, 뱅킹 앱의 그래프에는 속하지 않습니다.

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

아래 목록을 따라 내려가면서 첫 번째로 적합한 것에서 멈추세요.

필요 조건도구
호버, 누름, 색상, 클래스나 속성으로 제어하는 상태 토글CSS 전환
마운트 시 진입 애니메이션, JS 상태 없음CSS @starting-style
페이지 로드 중에도 부드러움을 유지해야 하는 미리 결정된 모션CSS 애니메이션 (메인 스레드 외부에서 실행)
CSS 성능과 라이브러리 없는 프로그래매틱 제어WAAPI (element.animate())
스프링, 레이아웃 애니메이션, 종료 애니메이션, 제스처 기반 값Motion (motion.dev)

CSS 애니메이션은 부하가 걸렸을 때 JS보다 우수합니다 — 메인 스레드 외부에서 실행되는 반면, requestAnimationFrame 기반 애니메이션은 브라우저가 로드, 스크립트 실행 또는 페인트하는 동안 프레임을 드롭합니다. 미리 결정된 모션에는 CSS를, 동적이고 중단 가능한 모션에는 JS를 사용하세요.

작업에 애니메이션이 아닌 컴포넌트가 필요한 경우 — 토스트, 서랍, 명령 메뉴, 드롭다운 — 중단하고 pick-ui-library를 호출하세요. 직접 만드는 것은 <div> 드롭다운과 포커스 관리 부재로 이어지는 지름길입니다.

4. 속성 선택

  • transform과 opacity만 사용하세요. 레이아웃과 페인트를 건너뛰고 GPU에서 실행됩니다. width/height/margin/padding/top/left는 세 가지 모두를 트리거합니다. (clip-path는 공인된 네 번째 속성입니다 — RECIPES.md 참조. height는 transform 등가물이 없는 아코디언에서만 허용됩니다.)
  • 절대 scale(0)을 사용하지 마세요. scale(0.9–0.97) + opacity: 0에서 시작하세요. 현실 세계에서 아무것도 없는 데서 나타나는 것은 없습니다.
  • 팝오버, 드롭다운, 메뉴, 툴팁의 경우 transform-origin을 트리거 위치에 설정 — Base UI에서는 var(--transform-origin)을 사용합니다. 모달은 예외입니다. 트리거에 고정된 것이 아니므로 중앙에 유지합니다.
  • translate()에서의 백분율은 요소 자체 크기를 기준으로 합니다 — translateY(100%)는 콘텐츠에 관계없이 요소 자체 높이만큼 이동합니다. 하드코딩된 픽셀보다 선호하세요.
  • Motion에서는 전체 transform 문자열을 사용하세요. x/y/scale 단축 속성은 하드웨어 가속되지 않으며 부하 시 프레임을 드롭합니다:
<motion.div animate={{ x: 100 }} />                          // 부하 시 프레임 드롭
<motion.div animate={{ transform: "translateX(100px)" }} />  // 하드웨어 가속
  • 부모의 CSS 변수로 자식의 transform을 구동하지 마세요 — 모든 자식에 대해 스타일을 다시 계산합니다. 요소에 직접 transform을 설정하세요.

5. 이징 및 지속 시간 — 또는 스프링

이징, 결정 순서:

상황이징
진입 또는 종료ease-out
화면에서 이동 / 변형ease-in-out
호버 / 색상 변경ease
일정한 모션 (마키, 진행)linear
기본값ease-out

UI에서는 절대 ease-in을 사용하지 마세요. 느리게 시작하여 사용자가 지켜보는 바로 그 순간을 지연시킵니다. 200ms의 ease-out은 200ms의 ease-in보다 더 빠르게 느껴집니다.

내장 CSS 이징은 너무 약합니다. 다음을 사용하세요:

--ease-out: cubic-bezier(0.23, 1, 0.32, 1);        /* UI를 위한 강력한 ease-out */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1);    /* 화면 내 이동을 위한 강력한 ease-in-out */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);     /* iOS 스타일 서랍 곡선 (Ionic) */

여기에 없는 곡선이 필요하신가요? easing.dev 또는 easings.co에서 가져오세요. 직접 만드지 마세요.

지속 시간:

요소지속 시간
버튼 누름 피드백100–160ms
툴팁, 작은 팝오버125–200ms
드롭다운, 셀렉트150–250ms
모달, 서랍200–500ms
마케팅 / 설명용더 길어질 수 있음

UI 애니메이션은 300ms 미만으로 유지하세요. 180ms 드롭다운은 400ms 드롭다운보다 반응성이 더 좋게 느껴집니다.

다음과 같은 경우 스프링을 대신 사용하세요: 드래그(관성 포함), 생동감 있게 느껴져야 하는 요소, 사용자가 중단하거나 되돌릴 수 있는 제스처, 장식용 마우스 추적:

{ type: "spring", duration: 0.5, bounce: 0.2 }        // Apple 스타일 — 추론하기 쉬움
{ type: "spring", mass: 1, stiffness: 100, damping: 10 }  // 전통적인 물리 — 더 많은 제어

바운스는 0.1–0.3으로 유지하고, 대부분의 UI에서는 바운스를 피하세요 — 드래그하여 닫기 및 장난기 있는 상호작용을 위해 남겨두세요.

6. 중단 및 종료

  • 빠르게 트리거되는 모든 것에는 전환(transitions)을 사용하고 keyframes는 피하세요 — 토스트, 토글, 사용자가 1초에 두 번 실행할 수 있는 모든 것. 전환은 현재 값에서 다시 대상으로 조정하지만, keyframes는 처음부터 다시 시작합니다.
  • 제스처에는 스프링을 사용하세요. 중단 시 속도를 유지하기 때문입니다.
  • 들어온 방식 그대로 종료하세요. 아래에서 슬라이드 인되는 토스트는 아래로 나갑니다. 대칭 경로는 스와이프하여 닫기를 직관적으로 만듭니다.
  • 사용자가 결정하는 곳에서는 비대칭 타이밍을 사용하세요. 의도적인 단계(확인을 길게 누르기: 2s linear)는 느리게, 시스템 응답(해제: 200ms ease-out)은 빠르게.

7. Reduced motion 및 포인터 게이팅

항상 애니메이션과 함께 제공됩니다.

@media (prefers-reduced-motion: reduce) {
  .element { animation: fade 0.2s ease; } /* opacity/color 유지, transform 기반 모션 제거 */
}

@media (hover: hover) and (pointer: fine) {
  .element:hover { transform: scale(1.05); } /* 터치는 탭 시 잘못된 호버를 발생시킴 */
}
const reduce = useReducedMotion();
const closedX = reduce ? 0 : '-100%';

Reduced motion은 더 적고 부드러운 애니메이션을 의미하며, 완전히 없애는 것이 아닙니다 — 이해를 돕는 전환은 유지하고, 움직임과 위치 변경은 제거하세요.

레시피

일반적인 사례(버튼 누름, 드롭다운, 툴팁, 모달, 서랍, 토스트, 아코디언, 스태거, 길게 눌러 확인, 탭 표시기, 스크롤 시 드러내기, 드래그하여 닫기)에 대한 바로 구축 가능한 구현을 보려면 RECIPES.md를 참조하세요. 요청이 해당 컴포넌트 중 하나와 일치할 때마다 로드하고, 빈 파일이 아닌 레시피에서 시작하세요.

절대 출시 금지

완료하기 전에 자체 점검하세요. 다음 각 항목은 review-animations에서 자동 차단 사유입니다:

절대 금지대신
transition: all정확한 속성 이름을 지정
transform: scale(0) 진입scale(0.95) + opacity: 0
UI 요소에 ease-inease-out 또는 강력한 사용자 정의 곡선
의도적인 애니메이션에 내장 ease-outcubic-bezier(0.23, 1, 0.32, 1)
키보드 단축키 또는 하루 100회 이상 동작에 애니메이션애니메이션 없음
이유 없이 300ms 이상의 UI 지속 시간150–250ms
트리거에 고정된 팝오버에 transform-origin: centervar(--transform-origin) (모달은 예외)
토스트, 토글, 빠르게 트리거되는 요소에 KeyframesCSS 전환
width/height/margin/padding/top/left 애니메이션transform / opacity
부하가 걸린 상태에서 Motion x/y/scale 속성전체 transform 문자열
게이팅되지 않은 :hover 모션@media (hover: hover) and (pointer: fine)
prefers-reduced-motion 누락더 부드러운 변형, 완전 제거 금지
모든 것이 동시에 진입30–80ms 스태거

출력

코드를 작성하세요. 그런 다음, 최대 몇 줄로:

  • 게이트 결과 — 빈도 계층 및 명명된 목적. 요청에서 거부된 항목이 있으면 무엇이고 그 이유를 말하세요.
  • 재료 — 도구, 속성, 곡선, 지속 시간 또는 스프링 설정을 각각 한 줄씩.
  • 느낌 확인 사항 — 결과가 코드로 판단할 수 없는 느낌(크로스페이드, 스프링의 바운스, 진입 목록의 opacity/height 균형)에 따라 달라지는 경우, 그렇게 말하고 확인 방법을 지적하세요: 2~5배 지속 시간으로 재생하거나 DevTools 애니메이션 검사기에서 단계별로 확인하고, 실제 기기에서 제스처를 테스트하고, 다음 날 다시 새로운 눈으로 보세요.

이것을 보고서로 부풀리지 마세요. 코드가 인도물입니다.

톤

독단적이고 간결하게. 정직한 답변이 "이것은 애니메이션을 적용해서는 안 됩니다"라면 그렇게 말하세요 — 그 답변이 이 스킬이 존재하는 이유입니다. 느낌을 코드로 정말 해결할 수 없을 때는 값을 추측하는 대신 그렇게 말하세요.

Individual skills in this repo

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

RevanthThota55/FreeFrame-Studio

Keep web animations inside the frame budget — animate composite-only properties, keep motion off the main thread when the page is busy, and find the cause when an animation drops frames. Covers the layout/paint/composite pipeline, cheaper property swaps, CSS vs WAAPI vs requestAnimationFrame, Framer Motion's hardware-accelerated path, React re-rendering per frame, inherited CSS variable recalculation, blur cost, and when `will-change` actually helps. Use when an animation is janky, choppy, stutters, or drops frames; when choosing which property to animate; when deciding between CSS and JS animation on performance grounds; or when reaching for `will-change` or GPU layers. For choosing easing, duration, or whether to animate at all use animate; for reviewing motion as a whole use review-animations.

RevanthThota55/FreeFrame-Studio

Reverse-lookup glossary that turns a vague description of a web animation or motion effect into its exact term ("the bouncy thing when a popover opens" → Pop in; "the iOS rubber-band scroll" → Rubber-banding). Use when the user asks "what's it called when…", or describes a motion effect without knowing its name and wants the right word to prompt an AI or designer with. For naming an effect, not designing or building one.

RevanthThota55/FreeFrame-Studio

Apple's approach to interface design and fluid, physical motion, translated for the web. Use when building or reviewing gesture-driven UI, spring animations, drag/swipe/sheet interactions, momentum and interruptible transitions, translucent materials and depth, typography (optical sizing, tracking, leading), reduced-motion, or the design foundations (feedback, spatial consistency, restraint) behind Apple-style interfaces.

관련 스킬