# KODY Typography

**方向性タイピング・ポスター・エディタ。** HTML 1ファイル、キーボード駆動、モノクローム。

🇬🇧 [English version](./README.md)

---

## コンセプト

キャンバスをクリック。マウスで方向を決める。キーを打つ。

1キー = 1文字。その文字はマウスが指している方向に配置され、walker（次の文字の起点）が前進する。
マウスを動かし続ければ、文字列は曲線・ジグザグ・螺旋・弧、どんな軌跡にも沿って流れる。
画像ファイルをドロップすれば、自動でモノクロ化されて配置され、ドラッグで移動・拡大縮小できる。
文字と画像の重なりは `mix-blend-mode: difference` で自動反転。
予想しなかった図像が、偶然のように立ち上がる。

右下に住むピクセル・マスコット「KODY」は、起動直後に一度だけ挨拶したあと、
延々と目をぎょろぎょろさせている。選択したレイヤーを彼の近くで離すと、
レイヤーは彼の口に吸い込まれるように縮んで消える — いわば息をする、ごみ箱。

## 構成

```
kody_typography/
├── index.html       — ランディングページ
├── app.html         — エディタ本体
├── README.md        — 英語版
└── README.ja.md     — 本ファイル
```

## 起動

ビルド不要。`index.html` を開くか、エディタへ直行するなら `app.html`：

```bash
open index.html                 # macOS
# あるいはローカルサーバ：
python3 -m http.server 8080
```

初回のみ React・Tailwind・Google Fonts を CDN から取得するためオンライン接続が必要。

## 操作一覧

| 操作                              | 動作                                                 |
| --------------------------------- | ---------------------------------------------------- |
| 空のキャンバスをクリック           | 始点を設置・タイピング開始                          |
| マウスを動かす                    | 次の文字の進行方向（角度）を決める                  |
| キーを打つ                        | walker の位置に 1文字 配置（日本語 IME 対応）        |
| `Enter`                           | 現在の文字列を 1つのレイヤーとして確定              |
| `Backspace`（入力中）             | 最後の 1文字を戻す                                  |
| `Backspace`（レイヤー選択中）     | 選択中のレイヤーを削除                              |
| レイヤーをクリック                | 選択 → そのままドラッグで移動                        |
| 画像の右下ハンドルをドラッグ      | 画像のみ：サイズ変更                                |
| 画像ファイルを D&D                | 自動モノクロ化して配置                              |
| レイヤーを KODY に重ねて離す      | KODY が食べて、そのレイヤーを削除                    |
| `−` / `+`                         | フォントサイズ − / +                                |
| `I`                               | 背景 黒 ⇄ 白 反転                                    |
| `C`                               | キャンバス全消去                                    |
| `S`                               | PNG 保存（背景透過）                                 |
| `V`                               | SVG 保存（ベクター・背景透過）                      |
| `?` / `Esc`                       | ヘルプを開く / 閉じる                               |

## 技術スタック

- **React 18** — import map + `esm.sh` 経由で CDN ロード
- **Babel Standalone** — `data-type="module"` でブラウザ内 JSX → ESM 変換
- **Tailwind CSS** — Play CDN、JIT（任意値対応）
- **lucide-react** — タイトル横の装飾アイコン 1 個
- **Noto Sans JP 900** / **Space Mono 700** — Google Fonts

ランタイム完結。バンドラー・`npm install` 不要。

## 改変ポイント

`app.html` 冒頭に意図的に露出させた定数群：

- `FONT_FAMILY` / `FONT_WEIGHT` — 書体の声
- `DEFAULT_FONT_SIZE` / `FONT_MIN` / `FONT_MAX` / `FONT_STEP` — サイズ境界
- `IMG_FILTER` — 画像のモノクロ変換パイプライン（CSS filter 文字列）
- `KODY_SIZE` / `KODY_MARGIN` / `KODY_EAT_RADIUS` — マスコットの位置と捕食範囲
- `exportPNG` / `exportSVG` — 書き出しロジック

ステートは極小：文字レイヤーは `{ ch, pos, angle, advance, fontSize }` の 2D 配列、
画像レイヤーは `{ x, y, w, h, src }`。自由に fork 可能。

## KODY について

KODY は立方体型のピクセル・キャラクター（明るい顔面・左右にブロック状の目玉）。

- 初回起動のヘルプオーバーレイが消えたタイミングで吹き出しが出て
  「僕はKODYだよ」と挨拶する（1セッションに一度だけ）
- その後はずっと目をぎょろぎょろ。左右の瞳は独立した周期で不定にふらつく
- ドラッグ中のレイヤーが捕食半径に入ると瞳が小刻みに揺れ、体がやや膨らむ（空腹モード）
- レイヤーを近くで離すと口を開けて wobble し、レイヤーを吸い込む
- レイヤーは KODY の中心に向かって縮小＋回転しながら不透明度 0 へ → 削除

## 設計メモ

- **1 run per type-session** — 入力中の文字列はステートに保持され、`Enter` で初めて
  `layers` に確定する。誤入力は Backspace で遡れる。
- **Walker の記帳** — 各文字は自身の `angle` と `advance` を保持。次の walker は
  直前の文字の tail から算出される。
- **カーソル `mix-blend-mode: difference`** — 黒背景・白背景・画像どの上でも常に可視。
- **PNG 書き出し** は `fillRect(bg)` を省略し、text を `fg` で直接描画。
  他のレイアウトや SNS 背景に乗せても浮く。
- **SVG 書き出し** は本物の `<text>` 要素で出力 — Illustrator 等で再編集可能。
  画像は base64 埋め込みの `<image>` とし、グレースケール filter を適用。回転は各字ごとに保存。

## ブラウザ要件

ネイティブ import map 対応：Chrome 89+ / Safari 16.4+ / Firefox 108+。

## 思想

> 余計な装飾を削ぎ落とし、機能そのものが美しさを定義する。

—

© kinoshita studio
