Doodle
コードで描くイラストレーションシステム。被写体はジオメトリとして作成され、カメラを通して投影され、シードされた「手」によって描かれたように見えるマークがレンダリングされます。プレーンなHTML + JS、ビルド不要、依存関係なし:ブラウザでページを開くだけです。
セットアップ:作業場所
エンジンはこのスキル内の engine/ (このファイルの隣) に同梱されています。そこで編集しないでください。スキルのアップデートで上書きされます。
LOCAL.mdがこのファイルの隣にある場合は、最初にそれを読んでください。このマシンのワークスペースとツールが指定されており、以下のデフォルト設定よりも優先されます。- それ以外の場合、ワークスペースは現在のプロジェクト内の
./.doodle(隠しファイル) です。存在しない場合は、作成します:cp -R "<このスキルのフォルダ>/engine" ./.doodle。 - 以下のすべてのパス (
src/…、bin/…) はワークスペースからの相対パスです。レンダリングには Chrome または Chromium (CHROME=/pathで上書き) と python3 が必要です。それ以外は不要です。
1つの描画 = bin/new.sh <名前> で、drawings/<名前>.js (draw(S) 内で描画、完全なツールキット、自動フレーム設定) とそれをレンダリングするページが作成されます。1枚の絵の中に複数のものがある場合は1つの描画です。複数の別々の絵は別の名前になります。
例はコードであり、ページではありません。 src/ 内のモジュール (things.js、people.js、trials.js、scapes.js …) には、加工済みの被写体が含まれています。それらを読み、その構造をあなたの描画にコピーしてください。それらに追加したり編集したりしないでください。以下のルーティングテーブルは、どのモジュールを出発点として使用するかを示しています。
画像を納品し、ページではありません。 描画が完成したら、bin/render.sh <名前> を実行します。プロジェクト内に doodles/<名前>/<名前>.png (カラー) と <名前>-line.png (線のみ) が書き込まれ、そのフォルダがユーザーに開かれます。ユーザーにフォルダのパスを伝えてください。ユーザーが要求しない限り、HTMLページ、キャンバス、ダイヤルパネルをビルド、開いたり、ユーザーに指示したりしないでください。
このファイルがすべての契約であり、意図的に短くして全体を読み込めるようにしています。 詳細は references/ にあります (そのまま移動されており、何も削除されていません)。以下のルーティングテーブルは、ジョブのためにどのリファレンスを読むべきかを示しています。それを読むことはジョブの一部であり、オプションではありません。それらのファイル内のすべてのルールは、却下された描画によって代償として得られたものです。
毎回の手順
- フォームとクラスを指定する (以下のテーブル)。フォームはページ、フレーミング、詳細の予算を決定します。クラスはペン、ニブ、塗りつぶし、トーンを決定します。
- ルーティングする。 ルーティングテーブルがあなたの被写体に対して指定しているリファレンスファイルを読み、それが開始点として指定しているモジュールを開いてください。すでにキットが存在する被写体の場合、空白のファイルから始めないでください。
- 描く前に測定する。 リファレンス画像から:プロポーションとパレットを、推測ではなくプローブします。リファレンスがない場合:被写体のプロポーションをモジュールヘッダーに数値として書き留めてください (靴には8つの数値が必要でした。それなしで3回レンダリングに失敗しました)。
references/hand-and-craft.md§ 測定。 - 最初にラインを構築する。 色の前に
?outline=1で判断します。すべての値は、塗りつぶしとしてと線の中の2回運ばれます。詳細はフォーカスからミッドグラウンド、紙へと減少します。references/line-first.md。 - ラインとカラーの両方で、フレームサイズでレンダリングして見る。 コンタクトシートで構図を、大きな単一フレームで線の質を見ます。毎ラウンド、両方とも。
- 被写体ではなく、キットで修正する、問題がヘルパー側にある場合。すべての被写体が完成するまでループします。
bin/check.sh drawings/<名前>.html(引数なし = すべての描画):レンダリング、NaNなし、コンソールエラーなし、クラスのドリフトなし。- 納品:
bin/render.sh <名前>—doodles/<名前>/内のPNG、フォルダが開かれます。 - 学んだことを同じターンでこのスキルに折り畳む (§ 進化)。
ルーティング: 何を読むか、どこから始めるか
| 被写体 | 開始点 | 読むもの |
|---|---|---|
| 任意の落書き、セッションで初めて | n/a | 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 |
| 日常的な物体 (ノートパソコン、はさみ、メガネ、歯ブラシ、ヘアドライヤー、Tシャツ、石鹸、ノート、南京錠、テディベア、ハンガー、バックパック、ボトルなど) | src/things.js def(...) | products.md, geometry.md |
| 人、人物、シーンの中の誰か | 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 布) | 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) をシーンキット上で | 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 |
| クリーン / ベクター / 落書き風ではない | n/a | インストールされていれば clean-illustration スキル |
| セット、ストレステスト | 既存のセットページをテンプレートとして | checking.md |
| レンダリングと位置を合わせる必要がある落書き (スケッチ → 最終消去) | シルエットをトレースし、内部を作成する | registration.md |
| どのページ / ファイルが何をするか | n/a | references/pages-and-files.md |
すべての references/ パスは、このスキルフォルダからの相対パスです。
フォーム
| 依頼内容 | フォーム | 開始例 | 詳細予算 |
|---|---|---|---|
| "マグカップ/椅子を描いて" | subject | src/things.js, src/retro.js | すべて、1つのものを完全な忠実度で |
| "N個作って" | set | アイテムごとに1つの bin/new.sh 描画、各々に共有ヘルパー | 1つのツールキット、詳細はツールキットに存在 |
| "家/店の正面" | elevation | src/houses.js, src/arch.js | 3つのベイ、55% ベタ黒塗り |
| "通り/景色/風景" | scene | src/scapes.js、指定されたフレーム + クリップ | 3段階の奥行きラダー |
| "ブロック全体/小さな世界" | diorama | src/cafe.js | ブロックの端は画像内に収まる |
| "部屋" | interior | src/kitchen.js, src/deskscene.js | 前景は完全に、背景の壁は特徴的に |
| "これをストーリーボードに" | board | src/board.js | 被写体ではなく SHOT SIZE によって設定される |
| "ペンとインク/色なし" | register ink | src/pen.js | トーンは線で運ばれ、塗りつぶしはまったくない |
セットはシーンではありません (1ページ上のものはシート以外は共有しません)、そしてボードはセットではありません (同じ忠実度ではシーケンスが失われます)。判断基準:ものは同じ空間を共有する必要がありますか? そうであれば、それはシーンです。
クラス (src/spec.js; 全文は references/forms-and-classes.md にあります)
| クラス | ペン | ニブ | フィット | 塗りつぶし | トーン |
|---|---|---|---|---|---|
object | 0.30 | firm | .84/.84 | フラット、面の法線で陰影付け | 影はより暗い塗りつぶし、およびその線の双子 |
ink | 0.26 | pen | .90/.88 | なし、紙がオブジェクト | 線のみ; ドットスクリーンは禁止 |
product | 0.30 | firm | .84/.84 | 1つの素材 = 1色 | 折り目は約35°以上のみ |
elevation | 0.30 | firm | .86/.84 | 55% ベタ黒ペイン | 屋根をハッチ、影側 |
plant | 0.30 | firm | .84/.88 | フラット; 淡い色合い .96、その他 .84 | 大量の葉のみランダムな線 |
flower | 0.26 | firm | .92/.90 | フラット | なし |
scene | 0.30 | firm | .96/.94 | フラット; 影はより暗い塗りつぶし | 何も前に立っていない場合のみハッチ |
diorama | 0.22 | firm | .94/.92 | フラット | なし |
panel | 0.26 | firm | .94/.94 | フラット、単独の被写体よりも少ない | 1つの値の地面、1つの空 |
furniture、interior | 0.16 / 0.15 | pen | — | レガシーウェイト; 新しい作業は object を取る | — |
クラスを宣言し、数値を再入力しないでください: Spec.wrap(cls, label, build)。bin/check.sh はすべてのページでドリフトを監査します。クラスは手を所有します。ページは紙を所有します。塗りつぶしまたはトーンのポリシーが実際に異なる場合にのみ、クラスを追加してください。
ハードルール (それぞれは却下された描画です)
ライン優先と忠実度
- 線のみ (
?outline=1) は完成した描画でなければなりません。すべてのページは?outline=1を尊重します。コピーしたページを確認してください (ハードコードされたoutline: falseが1つあります)。 - すべての値は2回運ばれます:暗い素材 = ハッチング; 曲がり = サーフェスに沿って湾曲するリブ; 落ち影 = 輪郭のないハッチング; 物に名前を付けるマーク = 輪郭のあるマーク、決して
w: 0の塗りつぶしではありません。すべてのw: 0を監査してください。 - フォーカスは完全な詳細、ミッドグラウンドは輪郭と2〜3本の線、背景は紙 (被写体が投げかける影のみがそのトーン)。目を細めてください:壁が被写体と同じくらい忙しい場合は、壁を削ってください。
- ハッチングは線としてキューに入れられます (
S.hatch)、決してk.Tトーンではありません。後の塗りつぶしがそれをカットします。gapが値です:2.4 明るい、1.5 中間、1.1 暗い。クロスハッチはフォーカス内の最も暗い1つのものだけにしてください。 - 影側は、形状に沿って湾曲する曲線で囲まれた三日月形であり、決して直線的な半平面のカットではありません (それはオブジェクトが2つに分割されているように見えます)。
ジオメトリとパス構築
- あなたが作成しなかった直線はパスバグです:2つの半分を間違った方向に連結した弦、または
closedでストロークされた開いた形状です。ポイントを出力してください。 - 不透明なボディの周りのバンドは、その手前側の半分のみです。完全な楕円になるのは開いた口だけです。
- 穴は背景色で塗るのではなく、カット (
keyhole) です。 穴が線で表示されるが色では表示されない = そのワインディング。 - 細いもの (手足、チューブ、茎) は、その関節を通る1つのストリップです。側面の輪郭を描き、端を後で描画されるものにプラグインさせます。
- コンテナ:内側 → 遠い縁 → 内容物 → 前壁。内容物は縁の下に沈みます。
- 既知のオブジェクトを描画する前に、プロポーションを数値として測定してください。 間違った形状を引き伸ばしても、間違ったままです (靴)。
- 家具はそれを使用する身体からサイズを決め、逆にしてはいけません。
- 画像と位置を合わせる必要がある落書き:画像のアルファからそのシルエットをトレースし、内部を作成し、フレームを画像に固定し、エクスポート時にクラスのフィットをクロップオフします (
registration.md)。 - 人:
People.figureのみ。 詳細の前にジェスチャー (片足に体重、腰と肩は反対に傾く); ポーズは角度なのでプロポーションは固定されます。家具や保持されているものは、返された関節から導出されます。後ろの髪は体の前にペイントします。 - 柔らかい形状を横切る長い直線の点線 = 三日月ラップバグ (
S.softで修正); 波状の旋盤 = 少ないノット + セグメントごとのイージング:steps: 1で密なプロファイルを使用します。 { dash: true }は機能しません:S.dashを使用してください。フレームオブジェクトは目視ではなく、そのコンテンツのバウンディングボックスに合わせてください。- 「ラフ」= 詳細ではなく構築: フルサイズで1つの被写体を判断してください。輪郭は結合しなければなりません (関節に開いた端がない)、トーンはタイトで規則的または存在しない、ペンの太さはフォームの幅に適合します。
フレーミング
- フレームは導出され、決してタイプされません:ピクチャープレーンキットでは、最初のリージョンの境界です。したがって、最初の呼び出しは
S.panel(<フレーム>)です。カメラを使用する場合、投影から導出されます。何かが見えない?それを大きく再描画する前に、フレーム内にあるか確認してください。clip = trueは指定されたフレームにクリップします。 - すべてのグラウンドレイヤーはフレームの下端 (
FOOT) まで実行されるか、またはより近いレイヤーが沈む場所に空が表示されます。1つのグラウンドルールはシートの両端に到達し、それ以上には到達しません。
シーン、夜、天気
- 奥行きは数値
d(0 近い、1 遠い) であり、ペン、ハッチギャップ、色、詳細はすべてそれを読み取ります。ベンチと同じ重さの山は、平坦な風景の失敗です。 - 夜は値を反転します:空は最も密なハッチング、すべての光は鍵穴のようなギャップ、グローは空よりも明るいです。明るい部分に対する人物は、ハッチングされたシルエットです。
- 雨は最後に描画され、傘の下には存在しません。反射は被写体を反転し、押しつぶし、壊れたバンドで、輪郭はありません。
ページとパレット
- ページは、その被写体が使用するすべてのパレットキーを宣言しなければなりません。未知のキーは一度レンダリングされると自動的に黒になります。
- 並列ヘッドレスChrome実行には、それぞれ別個の
--user-data-dirが必要です。そうしないと、ショットが空白で返ってきます。
検証
cd <ワークスペース> # セットアップを参照
bin/check.sh drawings/<名前>.html # レンダリング、NaNなし、コンソールエラーなし、クラスのドリフトなし
bin/shot.sh "drawings/<名前>.html?outline=1" out.png [1120x700] # 動作ルックアップ。カラーの場合は ?outline=1 を削除
bin/render.sh <名前> # 納品: doodles/<名前>/*.png、フォルダが開く
Chrome/Chromium は bin/chrome.sh によって見つけられます (CHROME=/path で上書き)。各ショットは独自の --user-data-dir を取得するため、並列実行は安全です。すべてのPNGを見てください (開くか、画像を見ることができるなら読んでください)。check.sh がパスすることはレンダリングされたことを証明しますが、それが読めることを証明するわけではありません。
このスキルの進化
ギャップを修正したら、新しいセッションがそれを見つけることができる場所に書き留めてください (このスキルが読み取り専用でインストールされている場合は、これらのメモをワークスペースに保持し、そう伝えてください):
- トピックのリファレンスファイル (
references/<topic>.md): ルールとその症状を、指示として記述します。Cr
…
[翻訳のため省略]