2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

キーボードで全操作できる SVG マインドマップエディタを作った

2
Last updated at Posted at 2026-05-01

作ったもの

Mind Maphttps://sen.ltd/portfolio/mind-map/

スクリーンショット

  • SVG ベースのレンダリング、自動ツリーレイアウト
  • キーボードファースト: Tab で子、Enter で兄弟、Del で削除、F2 で編集、矢印でナビゲーション
  • Undo / Redo(50 ステップ履歴)
  • パン & ズーム
  • エクスポート: SVG / PNG / Markdown / OPML / JSON
  • インポート: Markdown / OPML / JSON
  • localStorage 自動保存

vanilla JS、ゼロ依存、ビルド不要node --test で 54 ケース。

シンプルなツリーレイアウト

各ノードの x = 深さ、y = 子の平均:

function layoutNode(node, depth, yOffset) {
  node.x = depth * HORIZONTAL_SPACING;
  if (node.children.length === 0) {
    node.y = yOffset.current;
    yOffset.current += VERTICAL_SPACING;
    return;
  }
  node.children.forEach(c => layoutNode(c, depth + 1, yOffset));
  node.y = (node.children[0].y + node.children.at(-1).y) / 2;
}

葉ノードから順に y を割り当て、内部ノードは子の中心に配置。Reingold-Tilford ほど厳密ではないが、数百ノードまではきれいに収まる。

SVG foreignObject でインライン編集

SVG の <text> は入力を受け付けない。<foreignObject> で HTML <input> を埋め込めば任意座標で編集可能。F2 で切り替え、Enter or blur で戻す。

キーボード主導

Tab で子追加、Enter で兄弟追加、F2 で編集、矢印でナビゲーション、Ctrl+Z で undo。e.preventDefault() を忘れると Tab で SVG からフォーカスが飛ぶ。

Markdown エクスポート

アウトライン形式は Markdown のインデントリストそのまま:

function walk(node, depth) {
  lines.push('  '.repeat(depth) + '- ' + node.text);
  node.children.forEach(c => walk(c, depth + 1));
}

シリーズ

100+ 公開ポートフォリオ シリーズの #58 です。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?