Communitygithub.com

motioncraft-builder

고객의 실제 세계에서 얻은 하나의 아이디어를 바탕으로 시네마틱하고 수상급 모션 웹사이트나 히어로 섹션(스크롤 기반 three.js 장면, 필름 스타일 히어로, 심도 사진 시차, 합성 사운드, 라이브 3D 콜아웃)을 구축합니다.

motioncraft-builder란 무엇인가요?

이 스킬은 에이전트가 소규모 스튜디오에서 수상작을 출시하는 방식과 동일한 워크플로우로 모션 웹사이트를 제작하도록 가르칩니다: 하나의 아이디어 → 글로 작성된 계획 → 회색 상자로 기능 메커니즘 구현 → 디자인 입히기 → 엄격한 검토 및 수정 패스. 전체 프로세스는 참조 문서를 기반으로 하며, 기본 스택은 가져오기 맵을 통한 three.js 0.170, 순수 HTML/CSS/자바스크립트 모듈을 사용하며 빌드 단계가 없습니다. 주요 단계는 고객의 실제 세계(물건, 소리, 행동 동사)에서 하나의 아이디어를 도출하고(Step 1), 페이지 아키텍처와 비트 시트(스토리보드)를 작성하고(Step 2-3), 회색 상자로 3D 메커니즘을 증명한 후(Step 4), 레퍼런스 기법 인덱스에서 레시피를 가져와 드레싱하고(Step 5), 마지막으로 motion-review 및 motion-analytics 스킬을 통해 엄격한 QA와 성능 검토를 수행합니다(Step 6). 모든 페이지는 WebGL이 꺼져도 완전히 읽히고 작동해야 하며, 단일 클록 루프, 원본 스크롤 유지, 접근성(축소 모션, 포즈 컨트롤)을 핵심 원칙으로 합니다.

지원 대상✓Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/iboss21/regescore-motioncraft-skills/tree/main/plugins/motioncraft/skills/motioncraft-builder

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

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

문서

MotionCraft Builder

이 스킬은 에이전트가 소규모 스튜디오에서 수상작을 출시하는 방식으로 모션 웹사이트를 제작하도록 가르칩니다: 하나의 아이디어, 글로 작성된 계획, 회색 상자로 동작하는 메커니즘, 그다음 드레싱, 그리고 엄격한 검토와 수정 패스. 모든 결과물은 참조 문서에 기반합니다. 이 파일이 워크플로우입니다.

기본 스택: 의미론적 HTML, CSS, 바닐라 자바스크립트 모듈, 가져오기 맵을 통한 three.js 0.170, 빌드 단계 없음. GSAP나 Lenis는 레시피에서 필요한 경우에만 추가합니다. 모든 페이지는 WebGL이 꺼진 상태에서도 작동하고, 읽히고, 전환되어야 합니다.

<script type="importmap">
{
  "imports": {
    "three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js",
    "three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/"
  }
}
</script>

워크플로우

다음 단계를 순서대로 실행하세요. 효과로 건너뛰지 마세요. 각 단계에는 다음 단계로 넘어가기 전에 고객에게 보여줄 수 있는 결과물이 있습니다.

1단계. 하나의 아이디어 찾기

브리프를 읽고 고객의 실제 세계를 나열하세요: 그들이 다루는 물건, 출력하는 문서, 현장의 소리, 직원들이 하루 종일 사용하는 동사. 그런 다음 한 문장을 작성하세요:

[브랜드]은(는) 사용자가 [그들의 세계에 있는 물건]을(를) [동사]하면 [그들이 판매하는 가치]를(를) 보여주는 사이트입니다.

가상 브랜드 예시:

  • Cinderford Coffee Roasters: 사용자가 하나의 원두를 로스팅 과정(녹색 → 퍼스트 크랙 → 풀 시티)을 스크롤하면, 색상이 변함에 따라 로스트 로그에 풍미 노트가 인쇄됩니다.
  • Lakemont Bike Fitters: 사용자가 라이더의 안장 높이를 드래그하면 실시간 측면 보기에 무릎 각도 아크가 다시 그려집니다.
  • Halvorsen Tide Charters: 사용자가 조석 시계를 스크롤하면 보트가 실제 부두에 맞춰 오르내립니다.

아이디어 규칙 (참조: 제작 규칙 1~3 참조):

  • 하나의 물건, 하나의 동사, 하나의 세계. "그리고"를 두 번 사용해야 한다면 두 개의 아이디어입니다. 하나를 선택하세요.
  • 은유는 고객의 세계에서 와야 하며, 절대 트렌드에서 가져오지 않습니다. 정비소는 수리 지시서로 말하고, 식료품점은 주간 전단지로, 교통 기관은 노선도로 말합니다.
  • 강조 색상은 하나의 역할만 부여하세요. 빨간색이 "결함 발견"을 의미한다면, 페이지의 다른 어떤 곳에서도 다른 의미로 사용하지 마세요.
  • 로더, 커서, 내비게이션, 호버 상태, 전환, 404 페이지 모두 동일한 언어를 사용합니다.

결과물: 문장, 동사, 강조 색상과 그 의미, 그리고 각각이 탈락된 이유를 한 줄씩 적은 세 개의 기각된 아이디어.

2단계. 페이지 아키텍처 선택

page-architecture.md를 열고 아이디어와 동일한 세계에서 나온 내비게이션 아키텍처, 히어로 구성 및 섹션 시퀀스를 선택합니다. 이전 프로젝트의 뼈대를 절대 재사용하지 마세요. 선택한 내용을 프로젝트 README에 기록하여 다음 빌드에서 피할 수 있도록 합니다.

결과물: 사용한 명명된 패턴을 포함한 짧은 아키텍처 카드(내비게이션, 히어로, 섹션 목록, 푸터, 404).

3단계. 비트 시트 작성

코드를 작성하기 전에 시나리오를 먼저 작성하세요. beat-sheet.md의 템플릿을 사용하세요. 각 비트는 스크롤 범위, 방문자가 보는 내용, 움직이는 요소, 카피, 카메라, 전화기 프레이밍, 축소 모션 버전 및 비용을 명시합니다. 실제 예제는 요구되는 상세 수준을 보여줍니다.

결과물: 작성된 비트 시트. 이후의 모든 결정은 이 비트 시트에 대해 검증됩니다. 섹션이 1단계의 문장을 제공하지 않으면, 비용이 적게 드는 여기서 삭제하세요.

4단계. 메커니즘 회색 상자 구현

자리 표시자 지오메트리와 자리 표시자 카피로 모션을 구축하세요. 이 단계는 어떤 에셋이 존재하기 전에 타이밍, 카메라 및 상호작용을 증명합니다.

  1. DOM을 먼저 작성하세요: 실제 제목, 실제 카피 블록, 실제 버튼과 폼, 각 비트당 하나의 <section class="shot">. 스크립트가 꺼진 상태에서 페이지가 위에서 아래로 읽혀야 합니다.
  2. DOM 뒤에 하나의 고정 캔버스와 하나의 렌더 루프를 추가하세요. 스크롤, 포인터, 오디오 및 렌더는 해당 루프를 공유합니다(규칙 8).
  3. 스크롤을 비트를 세는 단일 부동 소수점 t에 매핑하고, 스무드스텝 홀드가 있는 샷 목록을 통해 카메라를 이동시킵니다(스크롤 및 카메라 레시피).
  4. 모든 객체에 회색 상자, 구체 및 평면을 사용하세요. 스토리가 회색으로 작동하지 않으면 드레싱이 저장하지 않습니다.
  5. 일시 중지 컨트롤과 축소 모션 분기를 지금 추가하세요. 마지막이 아닌 지금입니다(상호작용 레시피).

그레이박스 시작 코드. 페이지에는 위의 가져오기 맵, 고정 캔버스 및 SHOTS의 각 항목당 하나의 .shot 섹션이 필요합니다:

<style>
  #gl { position: fixed; inset: 0; width: 100%; height: 100%; z-index: -1; display: block; }
  .shot { min-height: 100svh; display: grid; align-items: center; padding: 16px 6vw; }
  .no-gl #gl { display: none; }
</style>
<canvas id="gl" aria-hidden="true"></canvas>
<main>
  <section class="shot" id="top"><h1>Headline from beat 0</h1></section>
  <section class="shot" id="detail"><h2>Beat 1</h2></section>
  <section class="shot" id="side"><h2>Beat 2</h2></section>
</main>
<script type="module" src="main.js"></script>

main.js:

import * as THREE from "three";

const canvas = document.getElementById("gl");
let renderer = null;
try { renderer = new THREE.WebGLRenderer({ canvas, antialias: true, powerPreference: "high-performance" }); }
catch { document.body.classList.add("no-gl"); } // DOM 페이지는 독립적으로 작동합니다

if (renderer) {
  const scene = new THREE.Scene();
  scene.background = new THREE.Color(0x111114);
  scene.add(new THREE.HemisphereLight(0xffffff, 0x222233, 1.4));
  const camera = new THREE.PerspectiveCamera(35, 1, 0.1, 100);
  // 비트 시트가 승인될 때까지 히어로 객체의 회색 대체물
  scene.add(new THREE.Mesh(new THREE.BoxGeometry(2, 1, 1.2), new THREE.MeshStandardMaterial({ color: 0x8a8a8a, roughness: 0.6 })));

  const V = (x, y, z) => new THREE.Vector3(x, y, z);
  const SHOTS = [
    { pos: V(4, 3, 8), at: V(-1.5, 0, 0) },  // 히어로: 객체는 헤드라인 오른쪽
    { pos: V(0, 9, 0.1), at: V(0, 0, 0) },   // 탑뷰 디테일
    { pos: V(-6, 1.2, 3), at: V(1.5, 0, 0) }, // 낮은 측면, 카피는 오른쪽
  ];
  const sections = [...document.querySelectorAll(".shot")];
  let centers = [];
  const measure = () => { centers = sections.map((s) => s.offsetTop + s.offsetHeight / 2); };
  const smooth = (a, b, x) => { const k = Math.min(1, Math.max(0, (x - a) / (b - a))); return k * k * (3 - 2 * k); };
  function scrollT() {
    const c = scrollY + innerHeight / 2;
    if (!centers.length || c <= centers[0]) return 0;
    for (let i = 0; i < centers.length - 1; i++) if (c < centers[i + 1]) return i + (c - centers[i]) / (centers[i + 1] - centers[i]);
    return centers.length - 1;
  }
  function resize() {
    renderer.setPixelRatio(Math.min(devicePixelRatio, innerWidth < 760 ? 1.5 : 1.75));
    renderer.setSize(innerWidth, innerHeight, false);
    camera.aspect = innerWidth / innerHeight;
    camera.updateProjectionMatrix();
    measure();
  }
  addEventListener("resize", resize);
  document.fonts?.ready.then(measure);
  resize();

  const pos = new THREE.Vector3(), at = new THREE.Vector3();
  let raf = 0;
  function frame() {
    raf = requestAnimationFrame(frame);
    const t = scrollT(), i0 = Math.floor(t), i1 = Math.min(SHOTS.length - 1, i0 + 1);
    const f = smooth(0.15, 0.85, t - i0); // 각 샷에서 유지, 중간에서 이동
    pos.lerpVectors(SHOTS[i0].pos, SHOTS[i1].pos, f);
    at.lerpVectors(SHOTS[i0].at, SHOTS[i1].at, f);
    camera.position.copy(pos);
    camera.lookAt(at);
    renderer.render(scene, camera);
  }
  raf = requestAnimationFrame(frame);
  document.addEventListener("visibilitychange", () => {
    cancelAnimationFrame(raf); // 두 개의 루프가 실행되지 않도록 함
    if (!document.hidden) raf = requestAnimationFrame(frame);
  });
}

4단계 종료 기준: 모든 비트를 앞뒤로 스크롤했을 때 카메라가 양방향 동일하게 도착합니다. 모든 샷은 해당 카피를 위한 공간을 남깁니다. 전화기 프레이밍이 390 x 844에서 작동합니다. 일시 중지 컨트롤이 모든 연속 모션을 중지합니다. WebGL이 비활성화된 상태에서 페이지가 읽힙니다.

5단계. 드레싱하기

이제 회색을 실제 세계로 교체합니다. 기법 인덱스에서 레시피를 가져옵니다. 각 레이어 후 비트 시트를 확인하면서 다음 순서로 드레싱합니다:

  1. 형태: 프리미티브, glTF, 필름 또는 심도 사진으로 제작된 히어로 객체.
  2. 조명: 키, 림 및 하나의 동기가 있는 강조 조명. 표면에 놓인 모든 것 아래에 접촉 그림자를 추가합니다.
  3. 재질 및 텍스처: 사진 텍스처보다 먼저 캔버스로 그린 레이블과 전면판. 선명하고 작으며 편집 가능합니다.
  4. 타이포그래피: 최대 두 개의 서체. 헤드라인 모션은 페이지의 리듬에 연결되며, 절대 일반적인 페이드 인이 아닙니다.
  5. 사운드: 선택 사항, 옵트인, Web Audio로 합성하여 바이트 비용이 들지 않습니다.
  6. 작은 보상: 하나의 숨겨진 제스처, 유휴 상태, 브랜드 언어의 404 페이지.

아무도 눈치채지 못하는 물리 효과보다는 상호작용에 프레임 시간을 사용하세요. 비용이 많이 드는 것은 가짜로 만듭니다(규칙 17).

6단계. 검토 및 수정

검토하기 전까지는 완료되지 않았습니다. 페이지를 motion-review 스킬(../motion-review/SKILL.md)에 전달하여 평가 기준, QA 체크리스트 및 데스크톱/전화기 크기의 섹션 스크린샷을 받고, motion-analytics 스킬(../motion-analytics/SKILL.md)에 프레임 시간, 무게 및 참조 비교 평가를 위해 전달하세요. 그런 다음 가장 심각한 문제를 먼저 수정하고 다시 검토합니다. 완료된 것으로 간주하는 모든 작업에 대해 최소 두 번의 전체 검토 및 수정 패스를 수행합니다.

공식 검토 전 빠른 자체 확인:

  • 아래로 스크롤한 후 다시 맨 위로 스크롤합니다. 모든 리빌이 깔끔하게 역전되어야 합니다.
  • 모션 중간에 일시 중지 컨트롤을 누릅니다. 모든 연속적인 움직임이 중지되어야 하며, 페이지는 여전히 구성된 상태로 보여야 합니다.
  • OS에서 축소 모션을 켭니다. 페이지가 스틸 이미지로도 동일한 스토리를 전달해야 합니다.
  • 콘솔을 엽니다. 오류가 없어야 하며, 사용자가 발생시킨 경고도 없어야 합니다.
  • 전화기 너비 390px: 11px 미만의 텍스트, 44px 미만의 탭 대상, 가로 스크롤이 없어야 합니다.

7단계. 출시

페이지 폴더(index.html, style.css, main.js 및 모듈, assets/), 한 문장 아이디어가 포함된 README, 아키텍처 카드, 비트 시트, 라이선스가 포함된 에셋 목록, 그리고 변경할 가치가 있는 튜닝 값을 제공하세요. 전체 페이지를 10MB 미만으로 유지하세요.

확고한 원칙

  • 아래에는 실제 HTML이 있습니다. 콘텐츠, 내비게이션 및 폼은 DOM에 있습니다. WebGL은 no-gl 폴백이 있는 향상된 기능입니다.
  • 하나의 클록. 프레임별 값을 프레임워크 상태에 절대 넣지 마세요. 일반 변수, 유니폼 및 CSS 사용자 정의 속성을 사용하세요.
  • 5초 이상 실행되는 모든 모션에 대해 표시 가능한 일시 중지 컨트롤과 완전한 prefers-reduced-motion 분기가 있어야 합니다.
  • 스크롤은 절대 하이재킹되지 않습니다. 기본 스크롤바가 작동하고, 키보드 스크롤이 작동하며, 앵커 링크가 점프합니다.
  • 데모에는 가상의 브랜드와 창작된 사람들을 사용하세요. 참조 사이트의 코드, 텍스트, 에셋 또는 히어로 컨셉을 절대 복사하지 마세요. 아이디어를 연구하고 직접 작성하세요.
  • 페이지의 모든 숫자(가격, 시간, 통계)는 그럴듯하고 일관되며 고객의 로케일에 맞아야 합니다.

참조 맵

파일사용 시기
references/craft-rules.md취향 관련 결정을 내릴 때. 구체적인 값이 포함된 30개의 규칙.
references/beat-sheet.md스토리 계획 시. 템플릿 및 실제 예제 포함.
references/page-architecture.md템플릿 획일성을 피하면서 내비게이션, 히어로 및 섹션을 선택할 때.
references/techniques/INDEX.md필요, 비용 또는 와우 요소별로 레시피를 찾을 때.
techniques/scroll-and-camera.md스크롤 매핑, 카메라 샷, 전화기 프레이밍, 모드 값.
techniques/scene-craft.mdthree.js 드레싱: 콜아웃, 모프, 도시, 하늘, 레이블, 그림자.
techniques/film-and-photo.md비디오 히어로, 루프, 필름 타이밍 카피, 추적 핫스팟, 심도 사진.
techniques/sound-and-rhythm.mdWeb Audio 보이스, 스케줄링, 비트 동기화 비주얼.
techniques/interaction-and-access.md일시 중지 컨트롤, 앵커, 홀드 게이트, 드래그 뷰, 품질 계층.

RegesCore AI MotionCraft Skills의 일부, LIKE A KING INC 제작. 무료 모션 템플릿 및 전체 카탈로그는 animatedwebs.com에서 확인하세요.

Individual skills in this repo

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

관련 스킬