Doodle
코드로 그리는 일러스트레이션 시스템. 주제는 기하학으로 작성되고, 카메라를 통해 투영되며, 시드(seed) 기반의 "손"에 의해 렌더링되어 손으로 그린 듯한 선을 만듭니다. 일반 HTML + JS, 빌드 도구 불필요, 종속성 없음: 브라우저에서 페이지를 열면 됩니다.
설정: 작업 환경
엔진은 이 스킬 안의 engine/ (이 파일과 같은 위치)에 있습니다. 절대 그곳에서 편집하지 마세요; 스킬이 업데이트되면 덮어쓰여집니다.
LOCAL.md가 이 파일 옆에 있다면 먼저 읽으세요: 이 컴퓨터의 작업공간과 도구를 명시하며, 아래 기본값을 재정의합니다.- 그렇지 않으면 작업공간은 현재 프로젝트의
./.doodle(숨김 폴더)입니다. 존재하지 않으면 생성합니다:cp -R "<이 스킬의 폴더>/engine" ./.doodle. - 아래의 모든 경로 (
src/…,bin/…)는 작업공간을 기준으로 합니다. 렌더링에는 Chrome 또는 Chromium (CHROME=/path로 재정의)과 python3이 필요하며, 다른 것은 필요하지 않습니다.
그림 한 개 = bin/new.sh <name>, 이것은 drawings/<name>.js (내용을 draw(S) 안에 그리고, 전체 도구 키트를 사용하며, 자동으로 프레임이 잡힘)와 이를 렌더링하는 페이지를 만듭니다. 하나의 그림에 여러 개체가 있으면 하나의 드로잉입니다. 여러 개의 별도 그림은 여러 개의 이름입니다.
예제는 코드이지 페이지가 아닙니다. src/의 모듈 (things.js, people.js, trials.js, scapes.js …) 에는 작업된 주제들이 있습니다: 읽고 그 구성을 드로잉에 복사하세요. 절대 추가하거나 편집하지 마세요. 아래 라우팅 테이블은 어떤 모듈에서 시작할지 지정합니다.
이미지를 전달하고, 페이지를 전달하지 마세요. 드로잉이 완성되면 bin/render.sh <name>를 실행하세요: 프로젝트에 doodles/<name>/<name>.png (컬러)와 <name>-line.png (선만)을 쓰고, 사용자에게 해당 폴더를 엽니다. 폴더 경로를 알려주세요. 사용자가 요청하지 않는 한 HTML 페이지, 캔버스 또는 다이얼 패널을 빌드하거나 열거나 사용자에게 가리키지 마세요.
이 파일은 전체 계약서이며, 전체를 로드할 수 있도록 의도적으로 짧습니다. 세부 사항은 references/ (그대로 옮겨졌으며, 아무것도 삭제되지 않음)에 있습니다. 아래 ROUTING 테이블은 작업에 대해 어떤 참조를 읽어야 하는지 알려줍니다. 읽는 것은 선택 사항이 아니라 작업의 일부입니다: 해당 파일들의 모든 규칙은 거부된 드로잉으로 대가를 치렀습니다.
절차, 매번
- FORM(형태)과 CLASS(클래스)를 지정합니다 (아래 표). 형식은 페이지, 프레이밍 및 세부 예산을 결정합니다. 클래스는 펜, 펜촉, 채움 및 색조를 결정합니다.
- 라우팅. 라우팅 테이블이 주제에 대해 지정한 참조 파일을 읽고, 시작점으로 지정된 모듈을 엽니다. 해당 주제에 대한 키트가 이미 존재할 때 빈 파일에서 주제를 시작하지 마세요.
- 그리기 전에 측정하세요. 참조 이미지가 있는 경우: 비율과 팔레트를 조사하고, 기억에 의존하지 마세요. 참조 이미지가 없는 경우: 주제의 비율을 모듈 헤더에 숫자로 기록하세요 (신발은 8개의 숫자가 필요했습니다; 숫자 없이 3번의 렌더링이 실패했습니다).
references/hand-and-craft.md§ Measurement. - LINE(선)을 먼저 구축하세요. 색상보다
?outline=1을 먼저 판단하세요. 모든 값은 채움과 선 두 가지로 표현됩니다. 세부 사항은 초점에서 중간 지대, 종이 순으로 줄어듭니다.references/line-first.md. - 렌더링하고 보고, 선과 색상 모두 프레임 크기로 확인하세요. 구성을 위한 연락처 시트, 선 품질을 위한 큰 단일 프레임. 매 라운드마다 둘 다 확인하세요.
- 중단이 도우미 기능인 경우 주제가 아닌 KIT(키트)에서 수정하세요. 모든 주제가 읽힐 때까지 반복하세요.
bin/check.sh drawings/<name>.html(인수 없음 = 모든 드로잉): NaN 없이, 콘솔 오류 없이, 클래스 드리프트 없이 렌더링합니다.- 전달:
bin/render.sh <name>—doodles/<name>/디렉토리에 PNG 파일, 폴더 열림. - 배운 내용을 동일한 턴(turn)에 이 스킬에 통합하세요 (§ Evolving).
라우팅: 읽을 내용, 시작 위치
| 주제 | 시작 위치 | 읽을 내용 |
|---|---|---|
| 모든 낙서(doodle), 세션에서 처음 | 해당 없음 | references/line-first.md, references/forms-and-classes.md |
| 일상적인 물건 (전화기, 열쇠, 병, 천, 안경 …) | src/things.js (가장 가까운 20개; cam, S.prism, S.on, S.dash) | things.md |
| 제품, 기기, 가젯, 가전제품 | src/retro.js (Retro._kit) | products.md, geometry.md |
| 둥근 물체 (컵, 꽃병, 과일, 병) | src/stilllife.js 스테이지 (lathe, ball) 또는 src/still.js | still-life.md, geometry.md (경로 구축) |
| 정물 / 배열 / 사진에서 | src/stilllife.js | still-life.md |
| 가구 | src/furniture3.js, src/kitchen.js | products.md |
| 일상적인 물건 (노트북, 가위, 안경, 칫솔, 헤어드라이어, 티셔츠, 비누, 공책, 자물쇠, 테디베어, 옷걸이, 배낭, 병…) | src/things.js def(...) | products.md, geometry.md |
| PERSON(사람), 사람들, 장면 속 누군가 | src/people.js People.figure; 절대 Trials._figure (죽은 코드) | people.md |
| 동물 | src/trials.js (cat) | figures-and-trials.md |
| 유리, 액체, 투명도 | src/trials.js (glass) | figures-and-trials.md |
| 자전거, 프레임, 얇은 튜브로 된 모든 것 | src/trials.js (bicycle), S.limb | figures-and-trials.md |
| 신발, 의복, 천 | src/trials.js (sneaker, fruit cloth) | figures-and-trials.md |
| 식물, 꽃, 잎 | src/plants3.js, src/flowers.js; 구멍 뚫린 잎: trials.js monstera | plants.md, figures-and-trials.md |
| 건물, 집, 정면 | src/houses.js, src/arch.js, src/arch2.js | architecture.md, geometry.md |
| 풍경, 야외 전망 | src/scapes.js (장면 키트) | landscapes.md |
| 밤, 어둠, 날씨, 비 | src/trials.js (night, rain) on the scene kit | figures-and-trials.md, landscapes.md |
| 거리, 디오라마, 카페 | src/cafe.js, src/scenes.js | landscapes.md, geometry.md |
| 방 / 실내 | src/kitchen.js, src/deskscene.js | geometry.md, landscapes.md (충실도) |
| 펜과 잉크, 색상 없음 | src/pen.js | line-first.md (톤), forms-and-classes.md (ink) |
| 스토리보드 / 시퀀스 | src/board.js | storyboards.md |
| 글자, 표지판 | src/letter.js | pages-and-files.md |
| 화면, UI, 터미널 (어두운 배경에 밝은 텍스트) | src/letter.js + 톤 색상 선 | pages-and-files.md (letter.js 항목) |
| 움직이게 만들기 (Rive) | Rive 내보내기 도구 (번들되지 않음; 파일 참조) | animation.md |
| 그리는 과정 보기, 밑그림 | ?draw=<key>, ?sketch=1 | hand-and-craft.md |
| 깔끔한 / 벡터 / 낙서 스타일이 아님 | 해당 없음 | 설치된 경우 clean-illustration 스킬 |
| SET(세트), 스트레스 테스트 | 기존 세트 페이지를 템플릿으로 | checking.md |
| 렌더링과 일치해야 하는 낙서 (스케치 → 최종 지우기) | 실루엣 추적, 내부 작성 | registration.md |
| 어떤 페이지/파일이 무엇을 하는지 | 해당 없음 | references/pages-and-files.md |
모든 references/ 경로는 이 스킬 폴더를 기준으로 합니다.
형태 (Forms)
| 말한 내용 | 형태 | 시작 예시 | 세부 예산 |
|---|---|---|---|
| "머그잔/의자를 그려줘" | subject(주제) | src/things.js, src/retro.js | 모든 것, 하나의 사물을 완전한 충실도로 |
| "그것들을 N개 만들어줘" | set(세트) | 항목당 하나의 bin/new.sh 드로잉, 각 항목에 공유 도우미 | 하나의 도구 키트, 세부 사항은 키트에 있음 |
| "집/상점 정면" | elevation(입면도) | src/houses.js, src/arch.js | 세 개의 베이, 55% 검은색 채움 |
| "거리/전망/풍경" | scene(장면) | src/scapes.js, 명시된 프레임 + 클립 | 3단계 깊이 사다리 |
| "전체 블록/작은 세계" | diorama(디오라마) | src/cafe.js | 블록의 가장자리가 그림 안에 유지 |
| "방" | interior(실내) | src/kitchen.js, src/deskscene.js | 전경 전체, 뒷벽 특징적 |
| "이걸 스토리보드로 만들어줘" | board(보드) | src/board.js | 주제가 아닌 SHOT SIZE에 의해 설정됨 |
| "펜과 잉크/색상 없음" | ink 등록 | src/pen.js | 선으로 전달되는 톤, 채움 없음 |
set(세트)은 scene(장면)이 아닙니다 (한 페이지의 사물들은 시트 외에는 공유하는 것이 없음), 그리고 board(보드)는 set(세트)이 아닙니다 (동일한 충실도는 시퀀스를 잃게 함). 차이점: 사물들이 SAME SPACE(동일한 공간)을 공유해야 합니까? 그렇다면 scene(장면)입니다.
클래스 (src/spec.js; 전체 텍스트는 references/forms-and-classes.md)
| 클래스 | 펜 | 펜촉 | fit | 채움 | 톤 |
|---|---|---|---|---|---|
object | 0.30 | firm | .84/.84 | flat, 면 법선으로 음영 처리 | 그림자는 더 어두운 FILL(채움)과 그 선 twin |
ink | 0.26 | pen | .90/.88 | NONE, 종이가 객체 | 선만; 점 스크린 금지 |
product | 0.30 | firm | .84/.84 | 하나의 재질 = 하나의 색상 | ~35° 이상의 주름만 |
elevation | 0.30 | firm | .86/.84 | 55% 검은색 창문 패널 | 지붕 해칭, 그림자 쪽 |
plant | 0.30 | firm | .84/.88 | flat; 옅은 음영 .96, 나머지 .84 | 덩어리 잎만 스크리블 |
flower | 0.26 | firm | .92/.90 | flat | 없음 |
scene | 0.30 | firm | .96/.94 | flat; 그림자는 더 어두운 채움 | 앞에 아무것도 서 있지 않은 곳만 해칭 |
diorama | 0.22 | firm | .94/.92 | flat | 없음 |
panel | 0.26 | firm | .94/.94 | flat, 단독 주제보다 적음 | 하나의 값 지면, 하나의 값 하늘 |
furniture, interior | 0.16 / 0.15 | pen | — | LEGACY(레거시) 가중치; 새 작업은 object 사용 | — |
클래스를 선언하고, 숫자를 다시 입력하지 마세요: Spec.wrap(cls, label, build). bin/check.sh는 모든 페이지에서 드리프트를 감사합니다. 클래스는 손을 소유하고, 페이지는 종이를 소유합니다. 채움 또는 톤 정책이 실제로 다른 경우에만 클래스를 추가하세요.
엄격한 규칙 (각각은 거부된 드로잉입니다)
선 우선 및 충실도
- 선만 (
?outline=1)은 FINISHED(완성된) 드로잉이어야 합니다. 모든 페이지는?outline=1을 존중합니다. 복사한 페이지를 확인하세요 (하드코딩된outline: false가 있을 수 있음). - 모든 값은 두 번 전달됩니다: 어두운 재질 = 해칭; 회전 = 표면과 함께 휘는 리브; 투영 그림자 = 외곽선 없는 해칭; 사물을 NAMING(명명)하는 표시 = 외곽선이 있는 표시, 절대
w: 0채움이 아님. 모든w: 0을 감사하세요. - 초점은 전체 세부 사항, 중간 지대는 윤곽선 + 2–3개 선, 배경은 PAPER(종이) (주제가 던지는 그림자만이 유일한 톤). 눈을 가늘게 뜨고 보세요: 벽이 주제만큼 복잡하면 벽을 줄이세요.
- 해칭은
S.hatch로 QUEUED(대기열)되며, 절대k.T톤이 아닙니다. 나중 채움은 해칭을 자릅니다.gap이 값입니다: 2.4 밝음, 1.5 중간, 1.1 어두움. 크로스 해칭은 초점에서 가장 어두운 ONE(하나)의 사물에만 적용하세요. - 그림자 쪽은 형태와 함께 휘는 곡선으로 경계 지어진 CRESCENT(초승달) 모양이며, 절대 직선 반평면 절단이 아닙니다 (그것은 사물이 둘로 나뉜 것으로 읽힘).
기하학 및 경로 구축
- 작성하지 않은 직선은 경로 버그입니다: 두 반쪽을 잘못된 방향으로 연결한 현(chord), 또는
closed로 스트로크된 열린 모양. 점들을 출력하세요. - 불투명한 몸체 주위의 띠는 NEAR(가까운) 반쪽만입니다; 열린 입만이 완전한 타원입니다.
- 구멍은 CUT(절단) (
keyhole)이며, 절대 배경색으로 칠해지지 않습니다. 구멍은 선에서는 보이지만 색상에서는 보이지 않음 = 권선 방향. - 얇은 것들 (팔다리, 튜브, 줄기)은 관절을 통해 ONE(하나)의 스트립입니다; 측면을 외곽선으로 그리고 끝은 나중에 그려질 것에 연결되도록 하세요.
- 용기: 내부 → 먼 테두리 → 내용물 → 앞 벽. 내용물은 가장자리 아래로 잠깁니다.
- 알려진 사물을 그리기 전에 비율을 숫자로 측정하세요. 잘못된 모양을 늘리면 계속 잘못됩니다 (신발).
- 가구 크기는 그것을 사용하는 신체에서 결정하며, 절대 그 반대가 아닙니다.
- 이미지와 일치해야 하는 낙서: 이미지의 알파에서 실루엣을 추적하고, 내부를 작성하고, 프레임을 이미지로 고정하고 내보내기 시 클래스 fit을 자릅니다 (
registration.md). - 사람:
People.figure만 사용하세요. 세부 사항보다 몸짓 우선 (한쪽 다리에 체중, 엉덩이와 어깨는 반대로 기울어짐); 포즈는 ANGLES(각도)이므로 비율이 고정됨; 가구와 잡은 물건은 반환된 관절에서 파생됩니다. 뒷머리카락은 몸보다 먼저 칠해집니다. - 부드러운 모양을 가로지르는 긴 직선 점선 = crescent-wrap 버그 (
S.soft에서 수정됨); 물결 모양의 선반(lathe) = 적은 매듭 + 세그먼트당 이징:steps: 1과 함께 조밀한 프로파일을 사용하세요. { dash: true }는 아무것도 하지 않습니다:S.dash를 사용하세요. 프레임 객체는 내용 bbox에 맞추고, 눈대중으로 하지 마세요.- "Scrappy"는 구축이지 세부 사항이 아닙니다: ONE(하나) 주제를 전체 크기로 판단하세요; 외곽선은 JOIN(연결)되어야 함 (관절에 열린 끝이 없음), 톤은 빡빡하고 규칙적이거나 없어야 함, 펜 두께는 형태의 너비에 맞아야 함.
프레이밍
- 프레임은 DERIVED(파생)되며, 절대 직접 입력되지 않습니다: 그림 평면 키트에서는 FIRST(첫 번째) 영역의 경계이므로 첫 번째 호출은
S.panel(<the frame>)입니다. 카메라가 있는 경우 투영에서 파생됩니다. 보이지 않는 것이 있습니까? 더 크게 다시 그리기 전에 프레임 안에 있는지 확인하세요.clip = true는 명시된 프레임으로 클리핑됩니다. - 모든 지상 레이어는 프레임 하단 (
FOOT)까지 실행되거나, 그렇지 않으면 더 가까운 레이어가 낮아지는 곳에 하늘이 보입니다. 하나의 지면 규칙은 시트의 양쪽 가장자리에 도달하며, 그 너머로는 가지 않습니다.
장면, 밤, 날씨
- 깊이는 숫자
d(0 가까움, 1 멂)이며 펜, 해칭 간격, 색상 및 세부 사항 모두가 이를 읽습니다. 벤치와 같은 무게의 산은 THE 평지 풍경 실패입니다. - 밤은 값을 반전시킵니다: 하늘은 가장 조밀한 해칭, 모든 빛은 keyholed gap; 빛남은 하늘보다 LIGHTER(더 밝음). 빛을 배경으로 한 인물은 해칭된 실루엣입니다.
- 비는 마지막에 그려지며, 우산 아래에는 없습니다; 반사는 주제를 뒤집고, 짜부라뜨리고, 끊어진 띠로, 외곽선 없이 그려집니다.
페이지 및 팔레트
- 페이지는 해당 주제가 사용하는 모든 팔레트 키를 선언해야 합니다. 알려지지 않은 키는 한 번 렌더링되면 검은색으로 조용히 표시됩니다.
- 병렬 헤드리스 Chrome 실행은 각각 별도의
--user-data-dir이 필요합니다. 그렇지 않으면 스크린샷이 빈 상태로 반환됩니다.
확인
cd <workspace> # 설정 참조
bin/check.sh drawings/<name>.html # 렌더링, NaN 없음, 콘솔 오류 없음, 클래스 드리프트 없음
bin/shot.sh "drawings/<name>.html?outline=1" out.png [1120x700] # 작업 상태 확인; 컬러는 ?outline=1 제거
bin/render.sh <name> # 전달: doodles/<name>/*.png, 폴더 열림
Chrome/Chromium은 bin/chrome.sh에서 찾습니다 (CHROME=/path로 재정의). 각 스크린샷은 고유한 --user-data-dir을 받으므로 병렬 실행이 안전합니다. 모든 PNG를 보세요 (열거나, 이미지를 볼 수 있다면 읽으세요). check.sh 통과는 렌더링이 되었음을 증명하지만 읽힌다는 것을 증명하지는 않습니다.
이 스킬 발전시키기
갭을 발견하면 새로운 세션에서 찾을 수 있는 곳에 기록하세요 (이 스킬이 읽기 전용으로 설치된 경우 작업 공간에 이 노트를 보관하고 그렇게 말하세요):
- 주제의 참조 파일 (
references/<topic>.md): 규칙, 증상과 함께, 명령문으로 작성합니다.
…
[번역 잘림]