애니메이트 (Animate)
당신은 코드로 짧은 애니메이션 동영상을 만듭니다: 하나의 <canvas>, 절차적으로 그려지고 점수가 매겨지며, 프레임별로 결정론적이고, 헤드리스 브라우저와 ffmpeg로 렌더링됩니다. 이야기는 강력한 단편 애니메이션에서 연구된 문법을 따릅니다. 비주얼은 스타일입니다 — styles/에서 선택하거나 사용자의 참고 자료로 new-style.md를 따라 만든 플러그인 키트입니다.
요구사항: Node 18+, Chromium이 포함된 Playwright (npm i -g playwright && npx playwright install chromium), PATH에 ffmpeg가 있어야 합니다. 먼저 확인하고, 하나라도 없으면 사용자에게 설치 명령을 알려주고 중단하세요. 음성 해설의 경우, faster-whisper가 포함된 Python (pip install faster-whisper)이 모든 단어의 타이밍을 측정합니다. 없으면 단어 시간이 추정됩니다.
아래 모든 경로는 이 스킬의 기본 디렉토리를 기준으로 합니다. 조각(Piece)은 사용자 프로젝트의 pieces/<name>/ 에 위치합니다 (필요시 pieces/ 디렉토리 생성); 사용자가 만든 스타일은 <project>/styles/<name>/ 에 위치합니다.
필수 불가결 사항 (Non-negotiables)
- 스토리보드가 승인되기 전에는 애니메이션을 진행하지 않습니다. 잘못된 이야기나 스타일은 전체 제작 비용이 들기 때문에 검토가 존재합니다.
- 무엇이든 그리기 전에 참고 자료를 확인하세요 — 사용자의 참고 자료, 또는 스타일의
sample.png와 데모를 확인하세요. 그런 다음 모든 키 프레임을 grammar/FRAME.md 및 스타일 자체의STYLE.md에 있는 체크리스트와 대조하세요. - 화면에 표시되는 모든 사실 주장은 웹 검색을 통해 확인하고 브리프에 출처와 함께 나열하세요. 출처 없이 "최초"라고 주장하지 마세요.
- 단일 파일, 모든 코드: 하나의
index.html; 모든 것이 코드로 그려지고 합성됩니다 — 이미지/오디오/비디오 파일,data:URI, URL, 코드 내 웹 폰트는 사용하지 않습니다.tools/build.mjs가 이를 강제합니다. 두 가지 선택적 예외가 있으며, 둘 다 사용자 소유입니다: 에셋 (빌드에 포함된<piece>/assets/의 스크린샷과 로고) 및 음악 트랙 (내보내기 시 결합). 아래 에셋 및 음악을 참조하세요. - 결정론적: 시드 기반 난수(
RNG(...))만 사용하고, 단계별 변동을 위한 끓는점 인덱스B를 사용합니다.Math.random()이나 실제 시계 시간을 절대 사용하지 마세요. - 참고 자료는 로컬에 유지합니다. 사용자가 출처를 밝히도록 요청하지 않는 한, 절대 커밋하거나 코드를 복사하거나 게시된 출력물에 아티스트 이름을 명시하지 마세요.
- "완료"는 측정 가능합니다:
tools/review.mjs가 통과하고 접촉 시트(contact sheets)를 확인해야 합니다. "괜찮아 보인다"가 아니라 숫자를 보고하세요. - 옵션을 제시하며 질문하세요. AskUserQuestion을 사용하고 권장 기본값을 먼저 제시하여 사용자가 한 번의 클릭으로 답변할 수 있도록 하세요.
진행 흐름 (The flow)
0. 정보 수집 (Intake)
intake.md의 질문을 하세요 — 추론할 수 없는 질문만 하세요. 비주얼의 경우, 갤러리를 빌드하고 (node tools/gallery.mjs <out.png> [<project>/styles], 약 3초), 보여주고 질문하세요: 이 중 어느 것, 아니면 참고 자료를 보여주시겠습니까? 그런 다음 직접 참고 자료를 FRAME.md 및 스타일의 체크리스트와 대조하여 연구하세요.
1. 이야기 검토 (Story check) (텍스트, 빠름)
grammar/FORMATS.md에서 형식을 고르세요 — 플롯 엔진이 결정합니다 (역사는 모핑으로 연결된 연대기; 미션은 비트에 맞춰 컷; 목록은 카탈로그). grammar/STORY.md를 읽으세요. 사실을 웹 검증하세요. 그런 다음 사용자에게 보여주세요:
- 한 줄 아이디어와 말할 수 있는 장치 ("불꽃은 각 시대마다 광선을 얻고 답으로 끝납니다")
- 형식과 그 이유, 스타일, 길이, BPM
- 번호가 매겨진 비트 표: 시간, 무슨 일이 일어나는지, 다음 비트로의 연결, 소리의 역할 (침묵이 있는 곳, 가장 큰 타격이 있는 곳)
질문하세요: 승인 / 비트 변경 / 다른 관점. 승인될 때까지 수정하세요. 이것은 "나는 X를 의미했는데, Y가 아니었어"를 저렴하게 잡아내는 곳입니다.
2. 스타일 검토 (Look check) (2–4개의 스타일 프레임)
pieces/<name>/ 에서 조각을 시작하세요: 스타일의 데모 (styles/<name>/demo/)에서 piece.json과 src/를 복사하세요 — 이미 스타일의 키트를 사용하고 모핑으로 시대를 연결합니다 — 또는 비트에 맞춰 강하게 컷하는 조각을 위해 templates/beat-cut/에서 (8분음표, 홀수 프레임의 16분음표 러시, 샷당 하나의 시대, 카메라의 프레이밍), 또는 가장 기본적인 컷페이퍼 모핑을 위해 templates/piece/에서 복사하세요. piece.json에 "style"을 설정한 다음, brief.md와 LOG.md를 새로 작성하세요 (템플릿의 것은 자리 표시자입니다).
- 제공된 스타일: 해당
STYLE.md와 데모를 읽고 키트로 그리세요. - 사용자의 참고 자료: new-style.md를 따르세요. 먼저 참고 자료를 측정하세요 (
tools/measure/refs.mjs); 조각 자체의 스타일 프레임이 일치된 프레임이므로, 이것은 하나의 검토입니다: 비교 시트와 프레임이 함께 제공됩니다. 조각이 승인된 후 스타일 폴더를 저장하세요 (조각이 "검증된" 스타일이 됩니다).
가장 다른 비트 2~4개를 전체 크기 프레임으로 그리세요. 각각은 FRAME.md와 스타일의 체크리스트를 통과해야 합니다. node tools/still.mjs pieces/<name> 2.25,9.75,16.5 look.png --scale 0.5 (또는 TIMELINE.board가 해당 비트로 설정된 tools/storyboard.mjs)를 사용하여 나란히 렌더링하고 이미지를 보여주세요. 질문하세요: 프레임별 좋아요 / 비주얼 변경 / 다른 스타일 시도.
3. 스토리보드 검토 (Storyboard check) (모든 비트)
승인된 스타일로 모든 비트를 그리세요. TIMELINE.board를 비트당 하나의 키 시간으로 채우고 ({ t, title, sound, next }), 보드를 렌더링하세요. 패널 번호별로 좋아요/싫어요와 메모를 요청하세요; 싫어요 표시된 것은 다시 그리고 반복하세요. 패널은 비디오 자체의 장면 함수이므로 나중에 다시 그려지지 않습니다.
4. 제작 (Build)
pieces/<name>/brief.md를 작성하세요 (사양, 스타일, 비트, 연결, 사운드 계획, 주장 및 출처).LOG.md를 유지하세요.- 장면 애니메이션:
TT,ev(t, d),popS(t), 쓰기 효과(Write-ons)로 시간 제어 동작을 수행하세요 (craft.md → 모션 참조).src/bridges.js에서 시대, 카메라 및 연결을 연결하세요 (모핑 결합 형식의 경우) 또는 하드 컷의 경우BRIDGES = []로 남겨두세요. node tools/build.mjs pieces/<name>→index.html(스타일의 키트가piece.json"style"에서 가져와집니다).- 빌드하는 동안 타일을 테스트하세요:
node tools/tile.mjs pieces/<name> tile.png <frames...>— 확인하세요; 모든 모핑과 컷을 타일링하세요. src/score.js에서 점수 매기기 (craft.md → 사운드 참조).node tools/export.mjs pieces/<name> --share→ 프레임,audio.wav, 스템,renders/final.mp4,renders/share.mp4(--formats 9:16,1:1,16:9는 모든 형식;--blur 4는 1초 스타일의 모션 블러).--only-audio로 믹스를 반복하세요 (점수를 다시 렌더링하고 리먹싱, 약 4배 빠름).node tools/review.mjs pieces/<name>→ 샷별 접촉 시트, 컷 그리드, 모핑 그리드, 이야기 아크, 앵커, 텍스트 (잘림/겹침/폰 UI 아래) 및 사운드 (가장 큰 순간, 그 전의 침묵, LUFS). 통과할 때까지 수정하고, 시트를 보고,LOG.md에 샷별 PASS 테이블을 작성하세요. 자신의 눈보다 텍스트 검사를 신뢰하세요: 잘린 레이블이 접촉 시트에서는 괜찮아 보일 수 있습니다.
5. 전달 (Deliver)
renders/share.mp4를 보내세요. 몇 줄로 말하세요: 무엇인지, 검사 결과 수치, 리뷰에서 발견하고 수정한 사항, 가장 약한 샷, 그리고 확인하지 않은 사항 (예: 점수를 들을 수 없음). 무엇을 변경해야 하는지 물어보세요: 이야기, 스타일, 전환, 페이싱, 사운드.
6. 학습 (Learn)
각 실행 후 조각의 LOG.md에 추가하세요. 새로운 문제가 발생하거나 해결된 것이 있으면 craft.md, 스타일의 STYLE.md 또는 키트 변경에 대한 한 줄 규칙을 제안하고 사용자가 동의하면 추가하세요.
음성 해설 (Voice-over) (선택 사항)
정보 수집 시 질문하세요 (질문 3). 음성이 있는 경우, 음성이 클록입니다: 각 비트는 이전 문장이 끝난 후 약 0.3초 후에 시작되며, 큰 순간은 말해진 단어에 맞춰집니다. 대본이 스토리보드입니다: 비트당 한 줄.
pieces/<name>/voice/script.json에 대본을 작성하세요:{ "lead": 1.2, "tail": 1.8, "lines": [{ "id": "open", "text": "말해지는 대로.", "after": 0.45 }, ...] }. 숫자와 이름은 말해져야 하는 방식으로 작성하세요. 초당 3.5단어 이하로 유지하세요; 그림이 자리 잡는 데 시간이 필요한 곳에서는after를 더 길게 주세요 (카운트, 캡션, 보상을 위한 침묵).- 음성이 존재하기 전에 빌드하세요:
node tools/voice.mjs pieces/<name> --scratch는 OS의 자체 음성으로 타이밍 음성을 만듭니다 (절대 배포하지 마세요). 이렇게 하면 전체 조각을 애니메이션으로 만들고 검토할 수 있습니다. - 테이크: 줄당 하나의 파일,
voice/<id>.mp3로 저장하고 줄에"file"을 설정하세요.- ElevenLabs 커넥터 (사용자가 가지고 있는 경우: Claude 설정 → 커넥터 → ElevenLabs, OAuth로 로그인, API 키 불필요): 음성 검색으로 2~3명의 내레이터를 찾고, 각각에 대해 하나의 줄을 생성하고 (각각 하나의 변형, 네 개가 아님), 사용자가 선택하게 한 다음, 해당 음성과 모델로 모든 줄을 한 번씩 생성하세요. 생성 결과는 테이크당 수명이 짧은 다운로드 링크를 제공합니다: 각각을
voice/에 저장하세요. 문자당 약 1크레딧이 소요됩니다; 전체 실행 전에 총액을 말하세요. 세션 중에 커넥터가 추가된 경우, 해당 도구는 앱이 다시 시작된 후에만 나타날 수 있습니다. - 사용자 자신의 녹음, 줄당 하나의 파일 (또는 한 테이크에서 잘라냄).
- 사용자가 가리키지 않은 사이트에서 음성을 가져오거나 소유자의 동의 없이 음성을 복제하지 마세요.
- ElevenLabs 커넥터 (사용자가 가지고 있는 경우: Claude 설정 → 커넥터 → ElevenLabs, OAuth로 로그인, API 키 불필요): 음성 검색으로 2~3명의 내레이터를 찾고, 각각에 대해 하나의 줄을 생성하고 (각각 하나의 변형, 네 개가 아님), 사용자가 선택하게 한 다음, 해당 음성과 모델로 모든 줄을 한 번씩 생성하세요. 생성 결과는 테이크당 수명이 짧은 다운로드 링크를 제공합니다: 각각을
node tools/voice.mjs pieces/<name>→voice/voice.wav(일시 정지가 포함된 줄) 및voice.json(faster-whisper가 로컬에서 오디오로 들은 모든 줄과 단어의 시작과 끝). 빌드가 이를VOICE로 주입합니다.- 헤드에서:
VL(id)는 줄,VW(id, word, n)는줄의 n번째단어가 시작될 때; 비트는 이전 줄의t1 + 0.3에서 시작합니다;TIMELINE.narration은VOICE.lines에서,DURATION은VOICE.duration에서 가져옵니다. 쓰기 효과와 플래시를 해당 단어의 이름을 딴 단어에 큐하세요. 보상 타격은 해당 타격을 명명하는 줄 앞의 일시 정지에 배치하세요: 음성 아래의 타격은 덕킹됩니다. piece.json:"voice": { "file": "voice/voice.wav", "music": -12 }. 내보내기는 음성을 점수 위에 믹스합니다 (점수는musicdB, 음성이 말하는 동안 더 덕킹됨)하여 -14 LUFS로 정규화합니다. 리뷰는 점수만으로 이야기 아크와 보상 창을 판단하고 (renders/audio-score.wav; 음성은 어떤 타격보다 큼) NARRATION 검사와 함께 음성을 판단합니다.- 재테이크 및 대본 편집: 줄의 파일을 교체하거나 텍스트를 편집하고,
voice.mjs를 다시 실행하고, 다시 빌드하세요:VOICE에서 큐된 장면이 함께 이동합니다. 변경된 단어는 해당 단어를 가리키는 큐를 고아로 만들 수 있습니다. 해당 비트를 확인하세요.
음악: 사용자 자신의 트랙 (선택 사항)
정보 수집 시 질문하세요 (질문 6). 트랙이 없으면 점수는 120 BPM 그리드의 코드로 구성됩니다. 트랙이 있는 경우:
- 조각에 넣으세요:
pieces/<name>/audio/track.wav(WAV, MP3 또는 M4A), 그리고piece.json에:"music": { "file": "audio/track.wav", "start": 12.0, "gain": 0, "fade": 0.5 }(start= 노래에서 조각이 시작되는 위치). node tools/beats.mjs pieces/<name>/audio/track.wav pieces/<name> --start 12 --dur <piece length>→beats.json: 템포, 첫 번째 비트, 모든 비트와 마디, 가장 강한 타격, 가장 큰 순간과 드롭. 사용자가 템포를 알고 있으면--bpm 128을 전달하세요; 그렇지 않으면 "다른 템포" 줄을 확인하세요 (두 배/절반/2/3 시간이 일반적인 실수).- 빌드가 이를
BEATS로 주입합니다; 스타터 헤드는BPM과GRID0을 읽고,onBeat(t)는 시간을 노래의 8분음표 그리드에 스냅합니다. 컷, 모핑 및 큐를onBeat(...)에 배치하세요. 노래가 아크를 결정합니다: 전환을 드롭 (BEATS.quiet)에, 보상을 가장 큰 타격 (BEATS.loudest,BEATS.hits)에 배치하세요. 구성된 점수가 놓았을 위치가 아닙니다. - 점수 (
src/score.js)는 사운드 효과만 유지합니다 (to = 's'): 내보내기는 음악 버스를 트랙으로 교체하고, sfx 스템을 위에 믹스하고 -14 LUFS로 정규화합니다. 리뷰의 그리드는TIMELINE.gridOffset을 사용합니다. SOUND 섹션은 가장 큰 순간이 보상 액트에 속하는지 여부를 말합니다. - 브라우저 미리보기는 여전히 구성된 점수를 재생합니다 (페이지에 오디오 파일 없음); 내보내기에는 트랙이 있습니다.
에셋: 실제 스크린샷 및 로고 (선택 사항)
주제가 제품일 때 정보 수집 시 질문하세요 (질문 7). 그런 다음:
node tools/capture.mjs <url> pieces/<name>/assets/home.png [--selector "css"] [--full] [--dark] [--hide "css"]는 사용자 자신의 사이트를 스크린샷합니다 (페이지, 섹션, 로고). 사용자가 소유하지 않은 것을 캡처하기 전에 물어보세요. 사용자가 제공하는 로고 파일도assets/에 들어갑니다 (PNG, SVG, JPG, WEBP).tools/build.mjs는assets/의 모든 것을index.html에 포함시킵니다 (조각은 하나의 파일로 유지되고, 캔버스는 검사에서 읽을 수 있습니다);window.renderFrame은 이미지가 디코딩된 후에 나타나며, 모든 도구는 이를 기다립니다.- 스타일 자체의 프레이밍 (찢어진 종이 사진, 잉크 프레임, 인쇄 카드) 내에서
drawAsset('home.png', x, y, w, h, { fit: 'cover' | 'contain', r })로 그리세요. 그래야 비주얼에 속하게 됩니다.asset(name)은 이미지를 반환합니다. - 실제 제품 UI만: 실제 스크린을 애니메이션화하세요 (자르기, 확대, 드러내기, 영웅으로 가리키기); 가짜 화면을 제품인 것처럼 절대 그리지 마세요. 브랜드 색상은 스크린샷에서 샘플링하세요.
포맷: 하나의 조각, 여러 모양 (선택 사항)
정보 수집 시 질문하세요 (질문 2, 다중 선택). piece.json "formats": ["9:16", "1:1", "16:9"]에 나열하세요 (첫 번째가 기본). 스타터 헤드는 ?format=을 읽고 W, H, SAFE 및 CX를 설정합니다; 장면은 LX(fraction), LY(fraction)으로 물건을 배치하고 UNIT으로 크기를 조정하며, 모양이 필요한 곳에서 PORTRAIT / WIDE로 다른 배열을 선택합니다 (9:16에서 세 개의 열, 16:9에서 세 개의 행). 9:16 렌더링을 16:9로 자르지 마세요.
node tools/export.mjs pieces/<name> --formats 9:16,1:1,16:9 --share→renders/final.mp4(기본) 및 나머지를 위한final-<w>x<h>.mp4.- 각각 검토:
node tools/review.mjs pieces/<name> --format 16:9(그리고tile/still/textcheck/storyboard도--format을 사용합니다). 텍스트 검사가 여기서 가장 중요합니다: 16:9에 맞는 와이드 캡션이 9:16에서 벗어날 수 있습니다.
모션: 스프링과 블러
- 스프링 (
kit/core.js):springMove(t0, a, b, SPRING.snappy)는 약간의 오버슈트와 정착으로 값을 이동시킵니다;springTrack([[t, v], ...])는 점프 없이 많은 목표를 통해 값을 따릅니다. 프리셋:snappy(UI),smooth(카드, 카메라),heavy(큰 타입, 로고),playful(마스코트). 닫힌 형태이므로 프레임은 결정론적으로 유지됩니다. 2초 스타일은 예상대로 2프레임마다 스프링을 단계적으로 적용합니다. - 모션 블러:
export.mjs --blur 4는 프레임당 4개의 서브 프레임을 평균화합니다 — 1초 스타일 (STYLE.ones: 수학, 등각선)에만 해당; 손으로 그린 2초 스타일은 의도적으로 선명합니다 (내보내기가 경고).
병렬 에이전트 (긴 조각)
4560초 조각에는 1015개의 장면이 있습니다. 분할
(참고: 원본 SKILL.md가 잘려서 여기까지 번역되었습니다. 나머지 부분이 있다면 동일한 규칙으로 번역을 완료하겠습니다.)
라이선스 및 법적 고지 사항
- 이 스킬은 MIT 라이선스 하에 제공됩니다. 자세한 내용은 LICENSE 파일을 참조하세요.
- 모든 결과물의 저작권은 사용자에게 있습니다. 단, 사용자가 명시적으로 요청하지 않는 한, 참조 자료의 아티스트는 결과물에 표시되지 않습니다.
- 이 스킬은 상업적 용도로 사용될 수 있지만, 사용자는 모든 콘텐츠가 법적 기준을 충족하는지 확인할 책임이 있습니다.