手描きインク素描 は何をしますか?
1枚の絵を、セルフ完結型のアニメーションSVGとして描画します。太さが変化するぐにゃぐにゃのインク線、線から少しはみ出すマーカーのにじみ、クリーム色の紙の質感などが特徴です。フラットな2Dで、正面または側面からのビューで描かれます。線は「沸騰」します(2フレームごとにぐにゃつきが描き直されるため)。そのため、静止した被写体でも生きているように見え、t を使って小さな動きを加えることもできます。3Dのアイソメトリック版が必要な場合は、代わりに handdrawn-3d スキルを使用してください。ラベルやタイトルには、ラテン文字とベトナム語をカバーする組み込みの手書きストロークフォントを使用します。
キット: assets/kit.js・レンダラー: assets/render.mjs・全関数: references/kit.md (シーンを書く前に必ず読んでください)・動作例: examples/ (カップ、リンゴ、猫、植物、家、食事)。
セットアップ(一度だけ)
PNG/GIF書き出しには @resvg/resvg-js が必要です。render.mjs が不足していると表示された場合は、このスキルのフォルダで npm install を実行してください。SVG出力には追加のパッケージは不要です。
描く前に
- 描画可能ですか? 抽象的なテーマ(「希望」「生産性」「経済」など)の場合、漠然としたものを描いてはいけません。その旨を伝え、具体的なシーンを1つか2つ提案してください(「舗装の割れ目から芽を出す苗」など)。その後、ユーザーが選んだものを描いてください。
- 図表、チャート、UI、ボタン、インタラクティブなもの: このスキルの対象外です。
- アニメーション: SVGは常にループします(線の沸騰)。被写体に合った小さな動き(湯気、尻尾の振り、まばたき、葉の揺れなど)を、適切な場合やユーザーが求めた場合に1つ追加してください。それ以外の場合は、線の沸騰だけで十分です。ユーザーが静止画を要求した場合(
--still)のみ、1フレームのSVGとして出力します。
ワークフロー
- パーツとビューを決める。 被写体の実際のパーツをリストアップし、ビュー(正面または側面)を選びます。やかんの場合:本体、蓋、つまみ、注ぎ口、取っ手、底;側面図。実際のパーツ(縁、取っ手、蓋、茎、板、タイル)から描き、名前だけの単なる塊として描いてはいけません。
- 配置を決める。 シーンの先頭に、コメントとして小さな表を書きます:パーツ、シェイプ呼び出し、ボックス (x, y, w, h)、色。被写体は用紙の約65~80%を占め、中央に配置し、余白を残します。地面/テーブルの線は、高さの約80~88%の位置にします。
- 後ろから前に向かって描く。
scene.jsでキットを使用します:影 → 後ろのもの → メインボディ → 上部の詳細 → ラベル。既製の部品 (k.cat,k.person,k.tree,k.house,k.window,k.leaf…) を優先し、それらを再描画するのではなくオプションを変更します。ろくろで回せるような丸いもの(カップ、ポット、花瓶、ボトル、ボウル、ランプ)にはk.turnedを使用します。取っ手、茎、尻尾、腕、枝にはk.tubeを使用します。 - レンダリングして確認する:
生成されたnode <skill>/assets/render.mjs scene.js -o out/scene.svg --png out/scene.png --thumb --gridout/scene.pngをReadツールで開き、実際に見てください。--gridオーバーレイは座標を表示するので、実際の位置を読み取ることができます。out/scene-128.pngも確認してください。128ピクセルでも被写体として認識できる必要があります。 - 修正して再レンダリングする。 以下を確認:
- 一目見ただけで、また128ピクセルでも被写体として認識できますか?まずシルエット。輪郭が「やかん」を表していなければ、ディテールで補うことはできません。
- プロポーションと重なり:取っ手は本体に付いているか、物は地面に置かれているか、浮いたりクリッピングしたりしていないか。
- 光源は常に左上から(陰影/ハッチングは右下)。
- ラベルが絵の上に乗っていたり、他の線と交差していないか。
正しくなるまで(通常2~4回)ステップ4~5を繰り返します。その後、
--gridなしで 最終レンダリングを行います。
PNGを見ずに納品してはいけません。 SVG(アニメーション画像)とPNGのパスを納品し、PNGを表示してください。シーンが動く場合は、数フレームも確認してください(アニメーション 参照)。
スタイルルール
- 一貫した外観: インク + フラットなマーカーによるにじみ。テクスチャやグレインはなし。グラデーション、グロー、ドロップシャドウ、ぼかし、不透明度のトリック、SVG
<text>は使用禁止(k.text/k.label/k.titleを使用)。生のSVGを追加しないでください。 - 色: パレット名(
red, coral, orange, ochre, yellow, sage, green, leaf, teal, sky, blue, navy, lilac, plum, pink, wood, brown, chocolate, grey, stone, charcoal, white, cream, sand, skin, tan)。1枚の絵につき3~5色+インク色。16進数は自動的にソフトになりますが、パレット名が最も見栄えが良くなります。 - シェーディング: 主要なボリュームには
shade: true(または 0.15~0.35)。ハッチングは最大で1つか2つの大きなオブジェクトにのみhatch: trueを使用。光源は常に左上から。 - 線の太さ: 輪郭は
'outline'(デフォルト)、内部の詳細は'detail'、小さなマークや引き出し線は'fine'。 - かわいく丸みを帯びた形: 動物や植物は柔らかく丸みを帯び、大きな頭、点目の目、小さなほっぺの楕円を持ちます。シャープでリアルな解剖学は避けてください。
- 構図: 明確な被写体1つ、中央に配置し、用紙の大部分を占めます。何かの上に立っているものの下には地面の影 (
k.shadow) を置きます。 - テキスト: 上部左に任意の
k.title(...)、さらに短い小文字の余白ラベル (k.label) と引き出し線を、空いている余白に配置します。絵の上に浮いたボックスや吹き出しは禁止。ラベルはユーザーの言語で書きます。ベトナム語も完全にサポートされています。 - シート: デフォルトは1000×1000。ワイドなシーンの場合は
export const sheet = { width: 1200, height: 900 }を使用。--transparentで紙の背景を削除します。
シーンテンプレート
// やかん、側面図。パーツ: 本体 (turned)、蓋、つまみ、注ぎ口 (tube)、取っ手 (tube)、影
export const sheet = { seed: 1 };
export function draw(k, t = 0) {
k.shadow(500, 820, 300, 34);
k.tube([[690, 540], [810, 520], [810, 650], [700, 710]], 34, { fill: 'teal' }); // 取っ手(端は本体に隠れる)
k.tube([[330, 640], [250, 560], [200, 470]], [60, 26], { fill: 'teal', shade: 0.3 }); // 注ぎ口
const pot = k.turned([[150, 0], [230, 70], [250, 180], [210, 300], [170, 330]],
{ cx: 500, y: 480, fill: 'teal', hatch: true }); // 本体
k.ellipse(500, 480, 150, 22, { fill: 'teal', weight: 'detail' }); // 蓋
k.blob(500, 445, 30, { squash: 0.8, fill: 'ochre' }); // つまみ
k.label('the good teapot', { x: 640, y: 300, to: [560, 440] });
}
アニメーション(常時オン)
out.svg はデフォルトでループするアニメーションSVGです。CSSでフレームを切り替え、スクリプトは不要で、ブラウザや <img> タグで動作します(CSSアニメーションに対応していないレンダラーではフレーム0が表示されます)。シーンは t ∈ [0, 1) を受け取り、1ループします。シンプルに保ち、自動的な線の沸騰に加えて、せいぜい1つか2つの動くもの(湯気、尻尾の振り、まばたき、葉の揺れ、煙)だけにします。Math.sin(2 * Math.PI * t) を使用して、モーションがシームレスにループするようにします。既製の部品は t を受け取ります: k.steam(x, y, { t })、k.cat(..., { animate: true, t })、k.person(..., { wave: true, t })。
node <skill>/assets/render.mjs scene.js -o out/scene.svg --png out/scene.png # アニメーションSVG + PNG静止画
node <skill>/assets/render.mjs scene.js -o out/scene.svg --gif out/scene.gif # + GIF、どこでも再生可能
node <skill>/assets/render.mjs scene.js -o out/scene.svg --still # 1フレームSVG
--frames 8 --fps 10 --boil 2 --gif-size 560
GIFは、いくつかのフレームを確認してチェックしてください: ffmpeg -i out/scene.gif -vf "select='not(mod(n\,3))',scale=300:-1,tile=4x1" -frames:v 1 out/frames.png(またはPNG静止画でチェック。これはフレーム0です)。GIFは256色です。幅は600px以下にしてください。