1仕組みと動作原理
実装全体の基盤となるのは輝度ランプ:sRGB知覚輝度(0..1)をインク濃度に合致する文字インデックスへマッピングする
Map luminance (0..1) to a character whose ink density matches. Order characters dark-to-light.
文字セルのアスペクト比約0.5を最大の落とし穴として定義:サンプリング行数は列数より少なく設定しなければならず、さもなければ画像が縦に引き伸ばされる
Correct by sampling **fewer rows than columns**: for a target of `cols` characters wide, use `rows = Math.round(cols * (imgH / imgW) * fontAspect)` where `fontAspect ≈ 0.5`.
レンダリングパイプラインを負荷コストに応じて階層化:<pre>+textContent(シンプル)、canvas fillText(1文字ずつの着色/大型グリッド/60fps)、Three.js AsciiEffect(シーン全体のアスキーアート化)
**Canvas `fillText`**: needed for per-character color, larger grids, or 60fps.
端末側ではANSIエスケープシーケンスを用いた自前描画のフレームループを採用:カーソル非表示、原点復帰、12〜24fpsのスロットリング、終了時の復元を行い、画面クリアよりも原点復帰の方が低コストであることを明記
Use `ESC + '2J'` to clear the whole screen, `ESC + 'H'` for home (cheaper per frame than clearing).
再現性の担保:注入可能な時間パラメータと固定シード値でフレームを駆動し、?t=Nで1フレームのみ描画することで、スクリーンショットを確定的なエビデンスとする
Drive frames from an **injectable time** (not `Date.now()`/`performance.now()` directly) and seed any randomness, so a frame is reproducible.
2コア機能
3外部依存関係
| Kind | Dependency / Endpoint |
|---|---|
| package | sharp(自带脚本的依赖:解码 PNG/JPG/WebP 并缩放到字符网格) |
| package | three(可选:AsciiEffect 走 three/addons,交付页可从 CDN 取) |
| api | 浏览器与终端原语:canvas 2D getImageData、requestAnimationFrame、ANSI 转义序列、process.stdout |
| cli | npx / Playwright(宿主侧截图工具;SKILL.md 在 verify 段示范) |
| cli | scripts/seek-shot.sh + scripts/contact-sheet.sh + ffmpeg(仓库根打包助手,被 SKILL.md 的 Packaged helper 段点名) |
4推奨統制措置と判定根拠
- scripts/: ローカルスクリプトまたはコマンドの実行: node skills/ascii-animation/scripts/img-to-ascii.mjs <image> [--cols N] [--
- 网络端点: 外部ネットワークアクセスの宣言: スクリプト自体による外部送信はゼロ。npm i sharp(インストール時のnpmレジストリ取得)および成果物ページでの任意のthree CDN読み込みはホスト環境または成果物実行時のものであり、判定対象外。
- 本地工作目录: ファイル読み書きと成果物出力: 同梱スクリプトは一切のファイル書き込みを行わない(stdoutのみ)。
5二重目の独立検証
- [ok] 自带脚本是否真的没有网络、凭证与写盘面 — img-to-ascii.mjs 全文 64 行逐行读过:import 只有 sharp;用 process.argv 解析参数;sharp(file).metadata() 与 .resize().removeAlpha().raw().toBuffer() 读像素;结果只经 process.stdout.write 输出。无 fetch、无 http 模块、无 fs 写、无 process.env,也无 shell 调用。
- [discrepancy] 坡道「16 级中等坡道被截断」的指引是否自洽 — SKILL.md 的 Common ramps 段在 Medium (16) 之后写 truncated — see table below,但该段下方最近的表是 Quick reference(无坡道表);完整 16 级坡道实际在 references/rendering.md 的 ### 16-level extended (balance)。指向错位,照抄 SKILL.md 拿不到完整坡道。
- [discrepancy] Packaged helper 的路径基准与适用性 — SKILL.md 写 scripts/seek-shot.sh anim.html 0 1.5 3,scripts/ 实际在仓库根;且本 skill 的终端形态本就不适用 ?t=N 冻结(SKILL.md 自己注明终端件需另法验收),该 helper 只覆盖浏览器形态。
- [ok] willReadFrequently 与 AsciiEffect 的取舍是否与参考文件一致 — SKILL.md 的 <pre> 与 canvas 取舍、willReadFrequently 用法、AsciiEffect 必须 effect.render 的注意事项,在 references/rendering.md 的 #### <pre> vs canvas 与 Three.js AsciiEffect 两节均可定位,前后无矛盾。
6結論
b1d5e8b21e57db26…