Communitygithub.com

GA-MO/iso: 등각 투영 애니메이션 설명 도구

프리미엄 개발 도구 스타일(둥근 슬라브, 레이어 스택, 빛이 흐르는 와이어, 라벨, 반복 설명 동작)로 애니메이션 등각 제품 일러스트레이션을 손수 작성된 SVG + CSS/WAAPI로 그리며, 애니메이션 라이브러리 없이 구현합니다.

iso: 등각 투영 애니메이션 설명 도구란 무엇인가요?

이 스킬은 제품 스토리를 하나의 장면(6~14초 반복)으로 전달하는 등각 투영 애니메이터를 만드는 도구입니다. 개발자는 이를 통해 둥근 슬라브, 레이어 스택, 빛이 흐르는 와이어, 라벨, 설명 동작을 직접 SVG와 HTML 텍스트로 구현할 수 있습니다. Cursor, Claude Code, Codex 등 에이전트 기반 개발 플랫폼에서 활용 가능하며, 모든 장면은 실제 SVG와 HTML 텍스트로 작성되어 박스에 맞게 크기가 조정되고, 화면 밖에서는 일시 정지되며, 축소 동작 설정 시 정지 이미지로 전환됩니다. 이 도구는 `Scene` 빌더(`lib/iso.ts`), WAAPI 런타임(`lib/runtime.ts`), 렌더링 스크립트(`scripts/render.ts`), 성능 측정 스크립트 등을 포함합니다. 주요 기능으로는 드롭인, 핸드오프, 와이어를 통한 빛 이동, 레이어 공개, 선택 회전, 그리드 채우기, 호버 상호작용 등이 있으며, 각 동작은 측정된 타이밍과 완화 함수를 사용합니다. 스토리보드 먼저 작성한 후 모바일 우선으로 컴포지션을 구성하는 것이 핵심 원칙입니다.

지원 대상~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/GA-MO/isokit/tree/HEAD/skill

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

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

문서

iso: 애니메이션 등각 설명 도구

하나의 장면은 6초에서 14초 사이의 루프에서 하나의 제품 스토리를 전달합니다. 요소들이 도착하고, 빛이 요소 사이를 이동하며, 한 번에 한 부분씩 밝아지고, 루프는 첫 프레임으로 돌아갑니다. 흐름은 하나의 형태입니다. 비트 테이블에서 스토리에 필요한 형태를 선택하세요: 레이어를 보여주기 위해 열리는 상자, 두 객체 간의 핸드오프, 채워지는 그리드, 선택지를 회전시키는 스택, 호버로 들어 올리는 타일. 모든 것은 실제 SVG 및 HTML 텍스트이며, 박스에 맞게 크기가 조정되고, 화면 밖에서는 일시 정지되며, 축소 동작 설정 시 정지 이미지로 전환됩니다.

이 키트는 이 파일 옆에 있습니다:

  • lib/iso.ts: Scene 빌더(투영, 슬라브, 면, 와이어, 펄스, 라벨, 모션 트랙), scene.exportSvg(), responsive() 및 lazyBox().
  • lib/runtime.ts: WAAPI로 렌더링된 장면을 재생하고, 장면의 40% (또는 높은 장면의 경우 화면 높이의 절반)가 보이면 인트로를 시작하고, 화면 밖에서는 일시 정지하며, 화면에서 절반 이상 멀어지면 애니메이션을 제거했다가 돌아오기 전에 같은 프레임으로 복원하고, 축소 동작 설정 시 정지하며, window.isoSeek(t)를 노출합니다.
  • scripts/render.ts: 장면 모듈(기본 내보내기 Page)을 런타임이 인라인된 하나의 독립적인 HTML 파일로 렌더링합니다.
  • scripts/shots.mjs: 선택한 시간과 너비에서 페이지를 스크린샷으로 찍고 sheet.png를 작성합니다.
  • scripts/check.ts: 디스크 어디에든 있는 장면 파일을 키트에 대해 엄격한 타입 검사합니다 (bun scripts/check.ts scene.ts).
  • scripts/page-idle.mjs: 여러 장면이 있는 페이지를 한 번 스크롤한 후 0%, 20%, 35%, 50%, 60%, 80%에서 멈추고 각 지점에서 메인 스레드 시간을 출력하며, CPU는 1배 및 4배로 설정합니다 (node scripts/page-idle.mjs page=<url> width=393 dpr=3 scroll=4). 장면이 여러 개 있는 페이지에서 실행하세요.
  • scripts/perf.mjs: Chrome에서 전화기 너비로 CPU를 제한하여 페이지를 재생하고 (node scripts/perf.mjs page=<out.html> width=393 throttle=4 seconds=20) 프레임 속도, 프레임 시간 백분위수, 늦은 프레임, 긴 작업 및 메인 스레드 시간을 출력합니다. 30개 이상의 움직이는 객체가 있는 장면에서 실행하세요.
  • scripts/contrast.mjs, scripts/render-all.ts: 렌더링된 페이지의 모든 텍스트를 정지 프레임과 추가로 네 순간에서 해당 글리프 바로 뒤의 픽셀에 대해 측정하고 4.5:1 미만이면 실패합니다 (node scripts/contrast.mjs <out.html>; bun scripts/render-all.ts <dir>는 먼저 모든 카탈로그 예제를 작성합니다). 모든 장면에서 실행한 후 완료했다고 말하세요.
  • scripts/study-rive.mjs, scripts/compare-rive.mjs: 자신의 .riv 애니메이션을 프레임별로 연구하고 키트 장면과 비교하기 위한 선택적 도구입니다. 둘 다 runtime=<canvas_advanced.mjs 및 rive.wasm이 있는 폴더>가 필요합니다.
  • examples/: 가상 제품을 위한 64개의 장면, 각 파일은 example (제목, 스토리, 프롬프트, 수준, 카테고리, 레이아웃, 상호작용 및 art: 컴팩트 및 와이드 장면 art(compact, wide, breakpoint))과 기본 Page를 내보내므로 scripts/render.ts가 이 중 하나를 렌더링할 수 있습니다. spot 장면은 하나의 작은 장면, art(compact)입니다. hero.ts는 hero (Art)를 내보내고 material-gallery.ts는 galleries (각 마감 패밀리당 하나의 Art)를 내보내며, 각각 기본 Page가 있습니다. examples/shared.ts는 표면, 색상 램프, paints, 글꼴 및 fitX()를 보유하며, 이는 가장 좁은 카드 안에 라벨을 장면 내에 유지합니다.

스토리에 가장 가까운 예제를 선택하고 그리기 전에 읽으세요:

예제수준보여주는 내용
notifications.ts간단최소 파일: 하나의 코어가 세 타일로 퍼져나가고, 펄스, 도착 플래시 및 홉. 먼저 읽으세요
ci-deploy.ts간단체인을 따라 홉하는 패키지, 착지 시 스쿼시, 마지막에만 상태 색상
file-upload.ts간단진행 표시줄을 채우는 청크, 그런 다음 가장자리 지점으로 퍼지는 복사본; 빈 슬롯의 행진 대시
db-branching.ts간단실선이 되는 점선 유령, 뒤로 미끄러져 병합되는 변경 타일
service-map.ts간단호버: 레이블이 호버 또는 탭 시 드러나는 9개의 slab({ hover }) 타일, 여전히 스토리를 전달하는 루프 포함
auth-flow.ts중간세로 panel() 전화기, 입력된 텍스트, 토큰을 운반하는 핸드오프 유령
etl-pipeline.ts중간와이어를 따라 코어로 공급되는 소스 타일, 함께 이동하도록 그 위에 있는 슬래브와 그룹화된 오버레이
queue-workers.ts중간빌드가 검증하는 이벤트 테이블에 의해 구동되는 슬롯 큐 (오버플로우 없음, 빈 큐에서 가져오지 않음)
search-index.ts중간밝은 페이지의 선화 타일, 입력된 쿼리, 일치 강조, 오름차순으로 정렬된 결과
feature-flags.ts중간재생: 라벨의 실제 <button>과 seek으로 한 루프 단계를 재생하는 인라인 스크립트
agent-tools.ts복잡위성과 함께하는 코어, 호출 및 응답 펄스, 입력되는 답변 카드
checkout-payment.ts복잡점선 반환 경로와 크로스페이드 상태 표시줄이 있는 단계 링
edge-cache.ts복잡동일한 요청 두 번: 오리진에 대한 웜 미스, 그런 다음 엣지에서 콜 히트
observability.ts복잡세 가지 신호 모양 (대시, 점, 스팬), heightTo가 있는 prism 막대, 경고 및 복구
keycard-slot.ts, battery-charge.ts, tile-loader.ts, empty-box.ts스팟기능 목록, 로더 또는 빈 상태를 위한 하나의 작은 객체; 슬롯 입구에서 잘린 세로 panel() 카드, heightTo 셀, 대각선 드롭 웨이브, 행진 대시
sync-loop.ts, inbox-fill.ts, alert-stack.ts, table-scan.ts스팟평면에 압착된 화살표, 유리 앞면 트레이, 맨 위 카드를 타고 가는 카운트 배지가 있는 스택 위로 미끄러지는 카드, 행별로 미끄러지는 렌즈
audit-ledger.ts, dns-resolve.ts, cron-jobs.ts간단봉인과 함께 쌓이는 페이지, 한 번에 하나씩 응답과 함께 홉, 작업을 트리거하는 다이얼
vault-rotate.ts, firewall-filter.ts, zero-trust.ts중간슬롯 패턴을 사용한 키 교환, 되돌아오는 거부된 패킷, 모든 요청에 스탬프
workload-scheduler.ts, autoscale.ts, health-check.ts중간작은 규칙 테이블에서 배치, 새 노드를 위한 공간 만들기, 제거되었다가 다시 합류하는 노드
blue-green.ts, snapshot-restore.ts중간목표가 변경된 와이어, 타임라인을 따라 뒤로 미끄러지는 커서
embedding-clusters.ts, training-loss.ts, recs-rerank.ts, ab-test.ts중간클러스터로 정착하는 포인트, 떨어지는 prism 막대, 재정렬되는 슬롯 선반, 승자가 있는 분할
data-erasure.ts, rag-answer.ts복잡카운터와 함께 여섯 시스템으로 퍼져나가는 하나의 요청, 모델로 날아가는 검색된 카드와 입력되는 답변
hero.ts복잡하나의 프롬프트가 1, 5, 15, 40 계층으로 시스템을 성장시킴: 턴테이블 스핀인 및 가중치 드롭, 아래에서 밀려나오는 출력, 팝, 그리드 채우기로 드롭인되는 풀, 끝없는 요청, 정지 상태에서 마우스 방향으로 기울임; fill로 플래시되고 <use>로 반복되는 타일은 저렴함; SVG text()만 사용하므로 exportSvg()가 작동함
funnel-live.ts, billing-cycle.ts, parcel-delivery.ts, test-shards.ts중간, 복잡layout: 'wide': 3:1 스트립을 왼쪽에서 오른쪽으로 읽음 (좁아지는 단계, 점프 없이 이동하는 월 스트립, 상자를 운반하는 차량, 차선에서 경주하고 병합되는 샤드)
kanban-move.ts, stock-sync.ts, diff-merge.ts, refund-flow.ts간단~복잡layout: 'diagonal': 하나의 등각 축을 따라 이동하는 카드 또는 토큰, 녹색으로 변하는 게이트, 두 번째 색상으로 같은 경로를 따라 역으로 실행되는 환불
live-cursors.ts, two-approvals.ts, design-comments.ts, translate-six.ts간단, 중간layout: 'panels': 서로 마주보는 세로 panel()들; 입력하는 커서, 자물쇠를 여는 두 개의 체크 표시, 핀과 스레드, 태국어 및 일본어 글꼴 스택의 여섯 언어로 된 하나의 메시지
cms-publish.ts, sensor-gateway.ts, smart-home.ts, currency-convert.ts간단, 중간layout: 'radial': 다섯 채널로 복사 하나, 읽기 후 층파 내보내기, 차례로 상태를 변경하는 장치, 링 와이어를 한 바퀴 도는 하나의 펄스
ota-rollout.ts, build-cache.ts, calendar-booking.ts, load-slider.ts간단~복잡layout: 'field': 중단 및 재시도와 함께 장치 필드를 가로지르는 웨이브, 종속성 테이블에서 계산된 캐시 히트, 충돌을 건너뛰는 회의; load-slider는 드래그 컨트롤 (실제 범위 입력, 마우스, 터치 및 키)로, 주변 트래픽이 계속 이동하는 동안 루프를 탐색함
video-transcode.ts, image-resize.ts, fraud-gauge.ts, data-lineage.ts, drill-down.ts간단~복잡layout: 'exploded': 분리되어 인코딩되는 렌디션, 벗겨지는 크기, 선을 넘어 쌓이는 위험 레이어, 레이어를 통해 아래로 조명되는 업스트림 경로; drill-down은 실제 버튼에서 해당 부분의 루프 세그먼트를 탐색하여 레이어로 열림
materials-*.ts, material-gallery.ts여섯 패밀리 (금속, 유리, 자연, 기술 패턴, 레트로, 생성)의 49가지 측면 마감재를 (scene) => Material 팩토리로, 패밀리당 라벨 없는 갤러리 하나씩. 생성 마감재는 시드를 사용함. 마감재를 직접 발명하지 말고 복사하세요

한 번 설정: cd <this dir>/scripts && bun install && bunx playwright install webkit (스크린샷은 설치된 Google Chrome을 Chromium으로 사용함). 타입 검사: scripts/node_modules/.bin/tsc -p <this dir>.

1. 그리기 전에 스토리보드 작성

먼저 recipes.md를 여세요. 모든 측정된 모션 및 컴포지션 패턴 (도착, 연결, 스트림, 비교, 선택, 유휴, 상호작용, 완화, 표면)이 숫자와 키트 호출과 함께 들어 있습니다. 해당 레시피에서 스토리를 구성하고 타이밍을 유지하세요.

먼저 타임라인 테이블로 스토리를 작성하세요: 뷰어가 이해해야 할 내용, 이를 보여주는 3~6개의 비트, 각 비트에 대해 어떤 요소가 어떻게, 언제, 얼마나 오래 움직이는지. 비트당 하나의 아이디어. 설명하는 데 문단이 필요한 비트는 두 개의 비트이거나 잘못된 그림입니다.

입증된 비트 모양과 측정된 타이밍:

비트내용타이밍
도착조각이 하나씩 떨어지고, 약간 오버슛하고, 안착함dropIn: 각 0.55초, 83ms 지연, 46px 낙하
핸드오프타일의 유령 윤곽선이 한 객체에서 다른 객체로 미끄러짐유령 4개, 0.22초 간격, 각 1.2초, ease.io
이동짧은 광선 펄스가 와이어를 따라 흐름; 대상이 도착 시 깜빡임270px/초, 펄스 와이어의 0.120.16, 상승 0.1초, 페이드 0.6초
레이어 공개단색 상자가 투명해짐; 내부 레이어가 라벨과 함께 하나씩 켜짐켜짐 0.23초, 유지 ~1초, 꺼짐 0.2초, 다음은 마지막이 끝날 때 시작
선택 회전스택이 한 슬롯 위로 이동함; 활성 카드가 강조 색상으로 변함3초마다 0.9초 이동, 느린 시작, 긴 이즈아웃
채우고 비우기그리드가 타일별로 채워지고, 유지되고, 다시 비워짐들어올 때 7프레임 (0.12초) 간격, 나갈 때 2프레임 간격
당기기와이어가 줄어들거나 늘어날 때, 연결된 상자가 와이어를 따라 약 6px 당겨지고, 유지된 후 천천히 돌아와 와이어에 장력이 있는 것처럼 보임0.23초 당김, 0.25초 유지, 0.65초 복귀 (긴 이즈아웃)
호버 리프트타일이 16px 올라가고 브랜드 색상을 취하며, 이름이 나타남slab({ hover }): 켜짐 270ms, 꺼짐 325ms, ease.out

연결 규칙: 와이어는 양쪽 끝이 모두 화면에 있는 동안에만 표시됩니다. 루프 중간에 도착하는 것에 연결된 와이어는 펄스와 함께 그려집니다 (wire({ dash: '1 1' }), 그런 다음 at(id, 'strokeDashoffset', t, d, 1, 0, ease.linear)), 그리고 연결된 대상과 함께 사라집니다. 이러한 와이어를 인트로에 절대 배치하지 마세요. 와이어는 상자의 윗면을 절대 교차하지 않습니다: 연결하는 객체 앞에 추가하고 (객체 위에 그려지도록) 상자의 중심이 아닌 가장자리에서 시작하세요.

루프 규칙: 마지막 프레임은 첫 번째 프레임과 같습니다. 루프 중에 변경되는 모든 것은 끝나기 전에 다시 변경됩니다. 인트로 전용 모션은 intro()에 들어갑니다; 루프는 인트로가 끝날 때 시작되며, 인트로는 루프가 시작하는 것과 동일한 그림으로 끝나야 합니다. 인트로가 없는 요소는 인트로 중에 루프의 시작 값을 표시하며, 이는 루프 세그먼트의 마지막 to 값입니다.

페인트 순서는 고정되어 있습니다: 나중에 추가된 것이 항상 먼저 추가된 것을 덮습니다. 누가 누구를 덮는지 변경하는 모션 (카드가 스택 맨 위에서 맨 아래로 이동하는 것)은 대신 슬롯으로 그려집니다. 각 요소는 한 단계씩 이동하고 이웃처럼 페이드 또는 리컬러되는 슬롯이며, 모든 세그먼트는 슬롯의 휴식 값에서 다시 시작하므로 모든 슬롯이 함께 점프하지만 그림은 동일하게 보입니다. 각 슬롯에 옵션당 하나의 라벨을 제공하고 활성 슬롯 옆에 표시되는 라벨을 크로스페이드하세요.

2. 레이아웃을 선택한 다음, 먼저 전화기용으로 구성

모든 예제는 layout에서 컴포지션 이름을 지정합니다: wide (왼쪽에서 오른쪽으로 읽는 긴 스트립; 와이드 장면은 약 3:1, 예: 1200x400, 중단점 720, 쇼케이스는 전체 너비 카드로 표시), diagonal (등각 축을 따른 긴 행), panels (서로 마주보는 세로 panel()들), radial (링 위에 물건이 있는 코어), field (높은 곳에서 본 많은 타일; 약간 더 가파른 ratio가 도움이 됨), exploded (수직으로 분리된 레이어) 또는 object (기능 목록 또는 빈 상태를 위한 하나 또는 두 개의 객체). 그리기 전에 스토리에 필요한 것을 선택하세요; 다양한 장면이 있는 페이지가 더 잘 읽힙니다.

뷰어가 재생할 수 있는 장면 (interaction: 'play' | 'drag' | 'explore')은 art()의 head에 작은 인라인 모듈 스크립트를 제공합니다: label({ html })의 실제 <button> 또는 `<input type=

관련 스킬