Communitygithub.com

caceresfjulian/motion-figure

이동하거나 사용자 입력에 반응하는 피규어를 세 가지 계층으로 제작합니다: 수업 내 SMIL 애니메이션 및 슬라이더 위젯, 실제 시스템의 명명된 부품을 보여주고 계산된 결과를 제공하는 대화형 메커니즘 피규어, 코스 팔레트의 질서 정연한 디더 밴드.

motion-figure란 무엇인가요?

이 스킬은 수업, 독립형 페이지, 또는 페이지 머리글에서 사용할 수 있는 동적이고 대화형 피규어를 생성합니다. 세 가지 계층으로 구성되어 있습니다: 계층 1은 선언적 SMIL 애니메이션 또는 슬라이더 위젯(ES5로 제한되며 특정 SMIL 규칙을 따름)을 통해 수업 내에서 사용됩니다. 계층 2는 독립형 HTML 패널로, 실제 시스템 부품을 표시하고 사용자가 하나의 컨트롤을 조작하여 계산된 결과를 확인할 수 있습니다. 계층 3은 WebGL 기반 디더 필드로, 코스 색상을 사용하고 여러 시드 모션을 지원합니다. 이 스킬은 Claude, Cursor, Codex, OpenClaw, Hermes 등 SKILL.md를 읽는 모든 에이전트와 함께 사용할 수 있습니다. 주의: 계층 1은 애니메이션 지속 시간(2.5~6초), 요소 수 제한(55개 이하), 특정 속성(예: 기하학 속성은 한 번만 재생)에 대한 엄격한 규칙을 준수해야 하며, `setInterval`이나 `requestAnimationFrame`을 사용할 수 없습니다.

지원 대상✓Claude Code✓Codex CLI✓Cursor
npx skills add https://github.com/caceresfjulian/ai-engineering-from-scratch/tree/HEAD/.claude/skills/motion-figure

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

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

문서

모션 피규어

이 스킬은 이동하거나 입력에 반응하는 피규어를 만듭니다. 세 가지 계층으로 구성되어 있습니다. Claude, Cursor, Codex, OpenClaw, Hermes 또는 SKILL.md를 읽는 모든 에이전트와 함께 이 스킬을 사용하세요.

계층만드는 것위치
1. 수업 피규어선언적 SMIL 애니메이션 또는 SVG를 다시 그리는 슬라이더 위젯. 둘 다 `figure 펜스 안에서 마운트됩니다.코스 수업
2. 메커니즘 피규어시스템의 명명된 부품을 보여주는 HTML 패널. 사용자가 하나의 컨트롤을 조작하고 계산된 결과를 읽습니다.독립형 페이지, README, 에세이, 수업 외 코스 사이트
3. 디더 필드용지, 강조, 잉크 색상으로 질서 정연한 디더 점의 WebGL 밴드. 네 가지 시드 모션 포함.페이지 머리글 및 섹션 구분

계층 1에는 가장 많은 규칙이 있습니다. 수업 런타임에 하드 제한이 있기 때문입니다. 계층 2와 3에는 자체 참조 파일이 있습니다.

사용 시기

  • 수업이 시간에 따라 변화하는 프로세스를 설명할 때: 단계를 거치는 토큰, 채워지는 큐, 반복되는 루프.
  • 수업이 하나의 입력이 출력을 변경하는 공식을 설명할 때: 학습률, 온도, 청크 크기, 배치 크기.
  • 작성자가 "이 피규어에 애니메이션 적용", "슬라이더 추가", 또는 "다이어그램을 대화형으로 만들기"라고 말할 때.
  • 페이지에 사용자가 한 가지를 변경하고 시스템(캐시, 큐, 컨텍스트 창, 라우터)의 결과를 볼 수 있는 데모가 필요할 때. 계층 2를 사용하세요.
  • 페이지에 코스 색상의 천천히 움직이는 헤더가 필요할 때. 계층 3을 사용하세요.

사용하지 말아야 할 때

  • 아이디어가 시간 축이나 입력이 없는 고정 구조인 경우. 정적 SVG 피규어를 만드세요. 자매 스킬 blueprint-figure가 정적 피규어를 다룹니다.
  • 페이지가 자체 상태 모델과 머신 지오메트리를 가진 전체 설명 페이지인 경우. 자매 스킬 isometric-explainer가 이를 다룹니다.
  • 팔레트, 글꼴 또는 산문 규칙만 필요한 경우. 자매 스킬 course-style이 이를 보유합니다. 이 스킬은 필요한 부분을 references/tokens.md로 복사합니다.

방법

  1. 피규어가 보여주는 단일 변경 사항을 명명하는 한 문장을 작성하세요. 두 문장이 필요하면 두 개의 피규어를 만드세요.

  2. 계층을 선택하세요. 수업 내에서는 계층 1을 사용하세요. 계층 2의 경우 references/mechanism-figures.md를 읽고 templates/mechanism.html에서 시작하세요. 계층 3의 경우 references/dither-fields.md를 읽고 templates/dither.js를 복사하세요. 아래 단계는 계층 1에 대한 것입니다. 계층 1에서는 시간이 변수일 때 애니메이션 피규어를 사용하세요. 숫자가 변수일 때 슬라이더 위젯을 사용하세요.

  3. 케밥 케이스로 이름을 선택하세요(예: request-path 또는 context-budget). 먼저 레지스트리에서 해당 이름을 검색하세요. 나중에 동일한 이름을 등록하는 모듈은 이전 피규어를 대체합니다.

  4. 코드를 figures-<주제>.js라는 모듈 파일에 넣으세요. IIFE로 감싸고 window.LF를 읽은 후 없으면 조기에 반환하세요.

  5. function (host, cfg) 피규어 함수를 작성하세요. host에 하나의 .lf 카드를 추가하고 dispose 함수를 반환할 수 있습니다.

  6. 카드를 빌드하세요: 대문자 .lf-label과 짧은 힌트가 있는 .lf-head, .lf-body, 캡션이 있는 .lf-cap.

  7. SVG에 viewBox="0 0 520 H"를 사용하세요. 대부분의 코스 피규어는 200에서 250 사이의 H를 사용합니다. 단일 막대는 더 적게 필요합니다.

  8. 렌더 함수 외부에서 한 번 생성하는 id를 가진 <title>과 <desc>를 추가하세요.

  9. 애니메이션 피규어의 경우, 먼저 항목을 추가한 다음 하나의 느린 루프를 추가하세요. references/smil-rules.md를 한 줄씩 따르세요.

  10. 슬라이더 위젯의 경우, LF.slider 또는 LF.select를 호출하기 전에 state._render를 정의하세요. 그런 다음 마지막에 state._render()를 한 번 호출하세요.

  11. 모듈 끝에서 LF.register({ 'your-name': fn })을 호출하세요.

  12. 수업 Markdown에서 펜스를 추가하세요. 첫 번째 줄에 이름을 넣고 선택적 JSON 구성을 그 뒤에 넣으세요:

    ```figure
    context-budget {"windowK": 32}
    ```
    
  13. "완료 전 확인"의 검사를 실행하세요. 밝은 테마, 어두운 테마, 375px 너비, 그리고 축소된 모션 켜짐 상태에서 피규어를 보세요.

페이지가 피규어를 마운트하는 방법

  • Markdown 파서는 펜스를 <div class="lesson-figure" data-figure="name {json}">로 변환합니다.
  • 사이트 빌드는 수업 Markdown에서 펜스 이름을 스캔합니다. 인용된 이름을 포함하는 모듈 파일을 찾고 매니페스트를 작성합니다. 제공자가 없는 펜스 이름은 빌드를 중단시킵니다.
  • 페이지는 수업에 필요한 모듈만 고정된 순서로 로드합니다. 새 모듈 파일은 나열된 파일 뒤에 알파벳 순서로 들어갑니다.
  • 마운트 함수는 첫 번째 단어를 이름으로 읽고 나머지를 JSON으로 구문 분석합니다. 잘못된 JSON은 빈 cfg를 제공합니다.
  • 피규어 함수가 오류를 발생시키면 런타임은 호스트를 비우고 경고를 기록합니다. 수업의 나머지 부분은 계속 렌더링됩니다.
  • 마운트 후 런타임은 제목, 설명, role="img", 그리고 누락된 경우 컨트롤 레이블을 추가합니다. 피규어에 SMIL 애니메이션이 있는 경우 일시 정지 버튼을, 애니메이션이 한 번 재생되는 경우 재생 버튼을 추가합니다.
  • 런타임은 피규어가 뷰포트를 벗어나거나, 탭이 숨겨지거나, 사용자가 일시 정지를 누르면 애니메이션을 일시 중지합니다. 축소된 모션 또는 인쇄 모드에서는 정적 프레임을 표시합니다.

references/toolkit.md는 모든 런타임 함수를 설명하고 두 개의 완전한 예제 모듈을 포함합니다.

규칙

애니메이션 피규어:

  1. <animate>, <animateTransform>, <animateMotion>만 사용하세요. 피규어에서 setInterval 또는 requestAnimationFrame을 사용하지 마세요.
  2. 각 피규어를 55개 이하의 SVG 요소로 유지하세요.
  3. 항목은 opacity 0과 scale 0.95에서 opacity 1과 scale 1로 시작하세요. scale을 0에서 시작하지 마세요.
  4. 항목은 calcMode="spline"과 keySplines="0.23 1 0.32 1"을 사용하세요. 항목 지속 시간은 0.5~0.6초입니다.
  5. 항목 시작을 0.05~0.4초 간격으로 지연시키세요. 종료는 항목보다 짧습니다.
  6. 루프는 2.5~6초 동안 지속되며 repeatCount="indefinite"를 사용하세요. 루프에 fill="freeze"를 설정하지 마세요. 런타임이 한 번만 재생하기 때문입니다.
  7. 각 keyTimes 목록은 values만큼의 항목을 가집니다. 0에서 시작하여 1에서 끝나며 절대 감소하지 않습니다.
  8. 각 keySplines 목록은 keyTimes보다 하나 적은 항목을 가집니다. calcMode="spline"에서만 사용하세요.
  9. keyPoints와 함께 animateMotion을 사용하는 경우 calcMode="linear"를 사용하세요. keyPoints 수는 keyTimes 수와 같습니다. values는 없습니다.
  10. 애니메이션 fill 또는 stroke 값에 var()를 넣지 마세요. 대상 색상을 가진 두 번째 요소의 opacity를 애니메이션하세요.
  11. 루프는 opacity, transform, stroke-dashoffset 또는 경로를 따른 모션만 애니메이션합니다. 런타임은 x, y, x1, y1, x2, y2, width, height, r, cx, cy, rx, ry의 애니메이션을 한 번만 재생합니다.
  12. 호스트의 data-static-time(기본값 1.5초)에서의 프레임은 완전하고 읽을 수 있어야 합니다. 나중 순간이 전체 상태를 보여줄 때 호스트에 속성을 설정하세요.
  13. 요소를 중심을 기준으로 크기 조정하세요. 그룹의 내용을 (0, 0) 주위에 그리고 translate로 그룹을 이동하세요. additive="sum"으로 크기 조정을 추가하세요.

슬라이더 위젯:

  1. ES5만 작성하세요: var, 함수 표현식, 문자열 연결. 화살표 함수, let, const 또는 템플릿 리터럴을 사용하지 마세요.
  2. 첫 번째 LF.slider 또는 LF.select 호출 전에 state._render를 정의하세요. 슬라이더는 생성 시 렌더 함수를 래핑합니다.
  3. state._render에서 모든 SVG 자식을 제거하고 다시 추가하세요. 노드를 제자리에서 편집하지 마세요.
  4. state._render 외부에서 id를 한 번 생성하세요. 런타임은 새 노드가 가지고 있지 않은 속성(id 포함)을 제거합니다.
  5. 막대를 길이 또는 경로의 stroke-dasharray로 늘리세요. 조정된 노드가 중심에서 크기 조정되므로 막대를 크기 조정으로 늘리지 마세요.
  6. 각 슬라이더 레이블을 짧고 소문자로 유지하고 단위를 대괄호 안에 넣으세요(예: chunk size (tokens)).

두 종류 모두:

  1. 모든 색상을 밝은 테마 값을 기본값으로 하는 CSS 변수에서 가져오세요(예: var(--blueprint,#3553ff)). 변수가 작동하지 않을 때만 리터럴 16진수를 사용하세요.
  2. 주요 주제에 대해 최대 하나의 강조 색상(--blueprint)을 사용하고 두 번째 상태에 대해 --warn을 사용하세요. 나머지는 잉크 및 규칙 토큰을 사용하세요.
  3. SVG 텍스트를 12단위 이상으로 설정하고 var(--font-mono)를 사용하세요. 레이블이 더 작아야 하는 경우 SVG에 최소 너비 500px를 주고 옆으로 스크롤되도록 하세요.
  4. 휴대폰에서 레이블 크기를 측정하세요. 375px 화면에서 카드 내부의 520단위 SVG는 279px 너비로 그려졌습니다. 12단위 레이블은 약 6.4px로 그려졌습니다.
  5. 캡션을 평이한 기술 영어로 작성하세요. 각 색상이 의미하는 바를 명명하세요. 문장을 25단어 이하로 유지하세요.
  6. .lf-label의 레이블을 대문자로, 2~4단어로 제공하세요.

메커니즘 피규어 (계층 2):

  1. 실제 이름과 실제 숫자를 표시하세요: 파일 이름, 키, 토큰 수. 절대 item 1이나 이름이 없는 회색 막대를 사용하지 마세요.
  2. 사용자에게 하나의 컨트롤을 제공하세요: 단계, 슬라이더, 토글, 재생 또는 부품 정지.
  3. 본문의 숫자에서 계산된 텍스트의 결과 줄로 끝내세요. 고정된 결과를 작성하지 마세요.
  4. 피규어의 35%가 보일 때 한 번 실행하고 재생 버튼을 추가하며 절대 반복하지 마세요.
  5. cubic-bezier(0.23, 1, 0.32, 1)로 transform과 opacity만 애니메이션하세요. 누르기 120160ms, 드러내기 200300ms, 접기 380~500ms.
  6. 처음 8개 항목에 대해서만 항목당 30~70ms 간격으로 목록을 지연시키세요.
  7. 모든 프레임에서 모든 레이블을 온전하게 유지하세요: 줄임표 없음, 겹침 없음, 점 위에 텍스트 없음. 텍스트 11px 이상, 결과 12.5px 이상.
  8. 320px에서 패널을 한 열로 쌓고 각 컨트롤에 40px 터치 대상을 제공하세요.
  9. 사이트의 다른 페이지에서 사용하지 않는 메커니즘을 사용하고 사이트의 메커니즘 테이블에 추가하세요.

디더 필드 (계층 3):

  1. --bg, --blueprint, --ink에서 색상을 읽고 data-theme이 변경될 때 다시 그리세요.
  2. 초당 최대 30프레임으로, 밴드가 보이는 동안에만 그리세요.
  3. 축소된 모션에서는 하나의 정적 프레임을 그리세요. WebGL이 없으면 정적 해치를 표시하세요.
  4. 밴드를 aria-hidden="true"로 표시하고 레이블 칩을 제외한 점 위에 텍스트를 넣지 마세요.

완료 전 확인

  • 펜스 이름이 등록된 이름과 정확히 일치하며, 다른 모듈이 이를 등록하지 않습니다.
  • 모듈에 =>, let, const 또는 백틱 문자열이 없습니다.
  • 모듈에 setInterval 및 requestAnimationFrame이 없습니다.
  • references/smil-rules.md의 검증기가 마운트된 호스트에 대해 빈 목록을 반환합니다.
  • 각 애니메이션 피규어는 55개 이하의 SVG 요소를 가집니다.
  • 모든 루프는 2.5~6초의 지속 시간을 가집니다.
  • 어떤 루프도 규칙 11의 지오메트리 속성을 애니메이션하지 않습니다.
  • 축소된 모션이 켜져 있을 때 피규어는 완전한 그림을 보여주고 누락된 요소가 없습니다.
  • 어두운 테마에서 모든 선과 레이블이 보입니다.
  • 375px 너비에서 모든 레이블을 읽을 수 있고 피규어 외부에 페이지가 옆으로 스크롤되지 않습니다.
  • 위젯의 경우 각 슬라이더를 최소 및 최대로 이동해도 NaN, 음수 너비 또는 콘솔 오류가 발생하지 않습니다.
  • SVG에는 하나의 제목과 하나의 설명이 있으며, 슬라이더가 이동한 후에도 해당 id가 동일하게 유지됩니다.
  • 캡션은 피규어가 사용하는 모든 색상을 명명합니다.
  • 계층 2: references/mechanism-figures.md 끝에 있는 체크리스트의 모든 항목이 통과합니다.
  • 계층 3: references/dither-fields.md 끝에 있는 체크리스트의 모든 항목이 통과합니다.

파일

  • references/smil-rules.md: 12가지 SMIL 규칙 전체, 각 규칙이 방지하는 내용, 브라우저 콘솔에서 실행할 수 있는 검증기.
  • references/toolkit.md: LF 함수 및 마운트 시퀀스. 또한 완전한 슬라이더 위젯, 완전한 SMIL 피규어 및 코스 사이트 외부에서 사용하기 위한 미리보기 페이지를 포함합니다.
  • references/tokens.md: 밝은 테마 및 어두운 테마용 색상 토큰, 글꼴, 모션 타이밍 값.
  • references/mechanism-figures.md: 계층 2. 실제 이름, 거부된 피규어, 메커니즘 모양, 해부학, 결과, 모션 예산 및 검사.
  • references/dither-fields.md: 계층 3. 셰이더 그리는 방법, 네 가지 모션, 마크업, 규칙, 디더 막대 및 검사.
  • templates/mechanism.html: 완전한 계층 2 피규어, 크기 컨트롤이 있는 LRU 캐시, 모든 브라우저에서 열림.
  • templates/dither.js: 완전한 계층 3 스크립트. 로드하고 <div class="dither" data-seed="...">를 추가하세요.

AI Engineering from Scratch 저장소 내에서 런타임에 대한 site/lesson-figures.js와 더 많은 피규어에 대한 site/figures-*.js도 참조하세요.

관련 스킬