考えを広げても、いまいる場所を見失わない
小さな惑星のような形をしたマインドマップ。メモを開くと、その下のメモが周りに現れ、全体像も見えたままです。
ニーズ
多くのマインドマップツールでは、枝を開くと画面がごちゃごちゃになるか、別のページに移ってしまい、どこから来たのかがわからなくなります。
アイデア
おなじみのアイデアの木構造はそのままにして、その中の移動のしかただけを変えること。
つくったもの
- 各メモの下位メモが、その周りの小さな球の上に現れ、上の階層は画面に残り続けるナビゲーション。
- 快適さを基準に選んだ操作:ホイールで拡大・縮小、ドラッグで回転、Alt + ドラッグで視点を移動、スマートフォンではより大きなタップ領域。
- 以前の2つのバージョン(平面の図と、クリックのたびに場面が切り替わる3D版)は、使う人が方向を見失うため置き換えました。
- 小さな公開データフィードを通じて、このウェブサイトのプロジェクトも自動で地図に載せています。
成果
- 3試したナビゲーション、採用は1つ
- 22編集保護を回避しようとした試み(すべて遮断)
- 2プロジェクト全体の依存パッケージ数
- 2026年9月5日公開開始
公開中の地図は、このナビゲーションが実際に動くデモです。変更は自動テストに合格したときだけ本番に反映されます。
画面で見る
学んだこと
3つのバージョンを通して、データはほとんど変わらず、変わったのは移動のしかただけでした。この2つを分けておいたおかげで、データに触れずに表示を2回作り直せました。
技術的な詳細 技術スタック、アーキテクチャ、設計判断(技術職の方向け)
技術スタック
- Three.js
- 素の JavaScript
- Node.js + Express
- SQLite (node:sqlite)
- Cloudflare Tunnel + Access
- systemd
- GitHub Actions
仕組み
- 再帰的なテーブルひとつ notes(id, parent_id, x, y, title, content)。x と y は、親メモの球面上の経度と緯度(度)です。
- ブラウザが読み込むライブラリは Three.js のみ。約760行の自作 JavaScript が、配置・ナビゲーション・編集を担当します。カメラは OrbitControls を使わず、球面座標を直接制御しています。
- 子の球の半径は親の0.46倍。ナビゲーション中にシーングラフを作り直すことはありません。
- 閲覧は公開、書き込みは前段の Cloudflare Access で保護し、サービスはトンネルの背後で 127.0.0.1 のみに待ち受けます。回避の試み22件(大文字・小文字の変更、二重スラッシュ、「..」を含むパス、URL エンコード、ほかの HTTP メソッド)は、すべてログインページに行き着きました。
- 攻撃者の視点で行ったレビューで、本物の欠陥が2つ見つかり、その日のうちに修正しました。すべてのルートに組み込んだ JSON パーサーのせいで匿名の訪問者がシステムログに書き込めたこと、そしてネットワークの読み込みが1回失敗しただけでナビゲーションが固まったことです。
- GitHub Actions による継続的デプロイ。テストに合格したときだけ本番が更新されます。
発生した問題と対処
- スマートフォンでは、小さなメモの目印(6〜10 px)へのタップがよく外れていました。22 px のタッチ許容範囲を設け、次の階層を先読みしたことで、シミュレーションでのタップ成功が 12/17 から 17/17 になりました。
- 光のにじみ効果(bloom)が、スマートフォンでのボトルネックでした。スマートフォンではこれをオフにしたことで、複数の階層をまたぐカメラの移動が毎秒20フレームから37フレームになりました。
まだ足りない点
- 編集できるのは私だけ(意図的な設計)
- タッチ操作はまだ調整中