Hamdy Tabsissi
日本語

Mindmap 本番稼働中 個人プロジェクト

考えを広げても、いまいる場所を見失わない

小さな惑星のような形をしたマインドマップ。メモを開くと、その下のメモが周りに現れ、全体像も見えたままです。

ニーズ

多くのマインドマップツールでは、枝を開くと画面がごちゃごちゃになるか、別のページに移ってしまい、どこから来たのかがわからなくなります。

アイデア

おなじみのアイデアの木構造はそのままにして、その中の移動のしかただけを変えること。

つくったもの

  • 各メモの下位メモが、その周りの小さな球の上に現れ、上の階層は画面に残り続けるナビゲーション。
  • 快適さを基準に選んだ操作:ホイールで拡大・縮小、ドラッグで回転、Alt + ドラッグで視点を移動、スマートフォンではより大きなタップ領域。
  • 以前の2つのバージョン(平面の図と、クリックのたびに場面が切り替わる3D版)は、使う人が方向を見失うため置き換えました。
  • 小さな公開データフィードを通じて、このウェブサイトのプロジェクトも自動で地図に載せています。

成果

  • 3試したナビゲーション、採用は1つ
  • 22編集保護を回避しようとした試み(すべて遮断)
  • 2プロジェクト全体の依存パッケージ数
  • 2026年9月5日公開開始

公開中の地図は、このナビゲーションが実際に動くデモです。変更は自動テストに合格したときだけ本番に反映されます。

画面で見る

公開中の Mindmap:星空を背景にしたワイヤーフレームの地球儀と、光る2つのメモ「Bienvenue」と、このサイトのプロジェクトを載せた枝「Sur le site」
公開中の Mindmap:星空を背景にしたワイヤーフレームの地球儀と、光る2つのメモ「Bienvenue」と、このサイトのプロジェクトを載せた枝「Sur le site」

学んだこと

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フレームになりました。

まだ足りない点

  • 編集できるのは私だけ(意図的な設計)
  • タッチ操作はまだ調整中