【JavaScript 入門講座】JavaScriptで作る!SVGベクターアーカイブと簡易ベジェエディタ構想

はじめに:仕事でベジェ曲線と過ごした日々

過去に仕事で、Illustratorなどのベクターデータ作成ツールを使い、看板用のベクターデータを作成してた時期があります。

主に看板製作の仕事で、デフォルトでは文字を切る事が多いですが、画像からベクターデータを作る作業にハマってしまい、昼休みも休日もずっと制作に没頭してた時期があります。

AIにJavaScriptで同様の事が出来るかどうか聞くと、ライブラリがあり出来るようなので勉強を兼ねて試してみた学習・備忘録メモです。

作品制作の裏側(写真付き)

ファイル数の多さ(スクショ画像)

AIに記事を書くよう促されて、一部貼って見ますが、狂ったように作り続けていたので作品の数は膨大な数になっています。 総数は1335個なので、今見ても異常な数ですね…。

完全手作業、1つ1つが一点物

トレースデータから切り絵のように切っていくので、量産は不可能で、製作のズレはどうしてもおきますので、そういう意味では作品は1点ものです。

デスクトップPCや依頼作品など、過去作を紹介

これは、依頼を受けて制作した者ですが、何となく自作PCのケースを購入した際にサイズを測ってそれに合わせてデータを作成してカットした物です。

データの作成から、カッティングまで、1つの作品を作るまでかなり時間がかかっています。

切り絵を作る際に、元の画像データをそのままトレースしたのでは、味気ない絵になってしまう為、どうしたらいいのか色々考えるようになり、 プロの方は影を付けるのが凄く上手で、Youtubeで添削動画などをよく見て勉強もしました。

線の太さや影を自分で考えて作るようになり、最後は、ゼロからベジェ曲線を自分で書くに至るまでになってました。

今、JavaScriptでゲーム制作を土日も休まずやっていますが、当時もそれと同じぐらいやってて、狂人の域に達していたと思います。

兎に角いい作品を作りたいというそれだけを元に作品作りに没頭してました。

3. JavaScriptで再現するという野望

過去作品を見せて、当時の思い出話をして、JavaScriptで同じことができか聞くと、製作可能なようなので今回の記事制作に至っています。

SVGで曲線が描けるって本当?

答えは「Yes」。
SVG(Scalable Vector Graphics)は、名前の通り“拡大しても劣化しない”ベクター形式の画像。
その構成要素は、<path>タグをはじめとする図形命令で成り立っています。

特に <path> に含まれる M(移動)L(直線)C(ベジェ曲線) などは、まさにあのカッティングソフトで何度も目にしたあの構文と似ています。

<path d="M 10 10 C 50 0, 50 100, 100 100" stroke="black" fill="none"/>

JavaScriptなら、このSVGを動的に生成したり、Canvasに描いたり、アニメーションさせたりすることもできます。


Path2D や BezierCurveTo()、あるいは svg.js などの選択肢

Canvas APIでは、Path2Dcontext.bezierCurveTo() を使えば、簡単にベジェ曲線が描けます。

const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.bezierCurveTo(50, 0, 50, 100, 100, 100);
ctx.stroke();

でも、この方法では「後から編集ができない」=リアルタイムなパス操作が難しいという弱点もあります。

そこで、選択肢として浮上するのが:

特に svg.jsPaper.js は、パスの編集やアニメーションなどが得意。GUIでハンドルを動かしてベジェ曲線を調整するような処理も、比較的簡単に実装できそうです。


「トレース機能を持つベクターエディタを自作したい」構想

本当のところを言えば、「過去に作ったあの作品たちを、今の自分のコードで復活させたい」 ただの回顧ではなく、「自分の手で、技術で、形にしたい」という願いに近い。

かつて何時間もかけて線を引き、影を作り、魂を込めた作品。

あれをベクター形式でアーカイブし、Web上で、誰でも見て、編集して、再利用できるようにしたい。(そこまで思ってはいない)

それが今の自分の“カッティング魂”の延長線上にあると感じています。

🖋️ そのために必要な機能は:

  • 画像を読み込み、輪郭を自動検出(OpenCV.jsやPotrace風アルゴリズム)
  • ラフなパスをもとに、ベジェ曲線の制御点をGUIで修正
  • SVGとして出力・保存
  • 過去作との互換性(gstudio形式の変換も…?)

もし完成すれば、それはただのツールではなく、 **「記憶と技術の再接続装置」**と呼んでもいいかもしれません。


次のセクションでは、技術的な検証をしながら、実際に“画像から線を取る”という挑戦について、掘り下げてみます。 果たして、JavaScriptはどこまで“あの感覚”に近づけるのか──?

4. 技術検証:画像から線を取る(ラフ実験)

ここからは、夢物語ではなく現実の実装に一歩踏み込みます。 つまり「画像から線を取る」ための実験と、得られた気づきについて。

「自動で輪郭抽出できたら楽かも」…と思うのは誰しもが一度は通る道ですが、現実は甘くありません。実際に試してみると、理想と現実のギャップが見えてきます。

🖼️ Canvas によるエッジ検出

まずは基本から。 HTML5の<canvas>要素を使えば、画像を読み込み、ピクセル単位で加工ができます。

const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);

この imageData から、モノクロ化、閾値処理、Sobelフィルタによるエッジ検出なども可能。

// エッジ検出のイメージ
const getGray = (r, g, b) => 0.3 * r + 0.59 * g + 0.11 * b;

ただ、正直なところ「絵をトレースしたい」目的に対しては、この方法は細かすぎる。 結果として、ザラザラした線やノイズが大量に残り、カッティング用途にはまったく向きません。


📦 Tracingライブラリの検証

(例:Potrace風JSライブラリ、Vectorizerなど)

そこで次に試したのが、既存のトレースライブラリです。

有名なライブラリの例:

特に imagetracerjs は、HTMLとCanvasだけで完結し、出力もSVG形式で扱いやすいです。

ImageTracer.imageToSVG(imageElement, function(svgString) {
  document.body.innerHTML += svgString;
});

ただし、線の滑らかさやパスの美しさには限界がある。 AIで生成されたイラストや写真には効果的ですが、ベクターに求める“意図した曲線美”とはやや違うのです。


🤔 自動ではダメ、結局手で描きたい → ベジェUIの検討

何度も試してみて、結局ここにたどり着きました。 **「やっぱり、手で描いたほうが早い」**と。

とはいえ、手で描くといっても紙ではなく、 **「制御点を持つベジェ曲線を、GUIで直感的に編集できる」**という意味です。

例えば:

  • アンカーポイント(点)をマウスで配置
  • ハンドル(制御点)をドラッグで調整
  • 点と点の間に、Cubic Bezierで滑らかに接続
  • 曲線を一時保存、レイヤーで整理

これらは、svg.jsPaper.js などのライブラリで実装可能ですし、 ベースだけならVanilla JSでも実装できます。


✍️ 技術面の気づきまとめ:

項目 メリット デメリット
Canvas処理 細かい画像処理が可能 ノイズが多く、手作業向きでない
自動トレース系ライブラリ SVG化が楽、APIも豊富 線がガタつく、意図しないパスが多い
手描きベジェUI 制御しやすく思い通りに描ける 実装の手間がやや大きい

「自動」と「手描き」の中間が理想── つまり「トレースの補助には自動を使い、最終調整は手でやる」という構成がベストに思えます。

これはまさに、かつてIllustratorで何時間も曲線を磨いた日々と重なります。 当時も、オートトレースでは納得できず、結局全部描き直していました。


次のセクションでは、いよいよ「実際に描くためのエディタUI」について構想をまとめます。 トレース補助、ベジェ編集、レイヤー制御…それらをJavaScriptでどう実現できるか。

→ [5. Webベースの簡易ベクターエディタ構想] へ続く

5. Webベースの簡易ベクターエディタ構想

「トレースは自動だけでは足りない」「自分の手で曲線を描きたい」。 そんな思いを叶えるには、ベジェ曲線を自在に描けるWebエディタを作るのが一番早い。 つまり──「自分だけのIllustrator」をJavaScriptで作ってしまおうという話です。


✒️ 最低限ほしい機能

✅ ベジェ曲線の作成・編集

  • アンカーポイントの追加/移動/削除
  • ハンドルで制御点を調整
  • 線の閉じる/開く(多角形 or 曲線)

✅ 描画エリアの操作

  • キャンバスのズーム/スクロール
  • スナップ(格子に吸着)やガイドの表示
  • 複数レイヤーの制御(塗り/カット用の分離)

✅ 入出力

  • SVG形式でのエクスポート
  • JSONで保存して後から編集
  • 背景に画像を読み込んでトレース補助に

✅ 補助機能

  • Undo/Redo(履歴管理)
  • トグル式の色切り替え(線/塗り)
  • カスタムショートカットキーの設定

🔧 技術選定とライブラリ候補

SVG × JavaScript のベース

SVGをDOMとして扱えるため、編集もスタイル適用も直感的。

<svg width="100%" height="100%">
  <path d="M10 80 C 40 10, 65 10, 95 80" />
</svg>

有力ライブラリ候補:

ライブラリ 特徴
svg.js SVGをDOM的に扱える軽量ライブラリ。拡張も豊富。
Paper.js 2Dベクターグラフィックに強く、ベジェも得意。
Two.js 描画・アニメーションに優れるがUIは手作りが必要。
独自実装(Vanilla JS) 学習・拡張の自由度は高いが実装工数も高い。

💡 UIレイアウト案(構想)

┌────────────┬────────────────────────────┐
│ 左パネル     │        作業キャンバス(SVG)        │
│────────────│                            │
│ レイヤー一覧 │                            │
│ 選択ツール   │                            │
│ 描画ツール   │                            │
│ 色/モード   │                            │
└────────────┴────────────────────────────┘
・右下に「SVG出力」ボタン
・背景画像のON/OFF切り替え

今まで自分で使ってきたUIや操作性をベースに、 「欲しかった機能だけを詰め込んだシンプルな設計」にするのがポイントです。


🌀 実現できたら…どうなるか?

  • 📁 旧作アーカイブをWebで再利用可能に
  • 🖱️ カッティングデータの調整・再利用がブラウザで完結
  • ✍️ スキマ時間に作業、依頼にもすぐ対応可能
  • 🤝 他の人に見せたり共有したりするのも簡単

かつて作っていた「一点物の作品たち」も、 このエディタで“再呼吸”させられるかもしれません。


🔚 結論:これは遊びであり、回復である

技術検証の延長でも、アーカイブ整理でもない。 これは、かつての自分が見ていた線や影を、今の自分の手で再びなぞるという時間です。

「開発と表現の交差点」に、もう一度足を踏み入れてもいいのではないでしょうか。


6. アーカイブ再生:作品ビューアの可能性

大量に残された .svg やベクターデータ、当時のスクリーンショット、そして完成品の写真たち。 それらは、もはや単なる作業ファイルではなく、自分の歴史のアーカイブです。

ベクターデータは老朽化しない。 だからこそ、それらを“見る”という体験そのものに価値があると思うのです。


🖼️ ビューアという「展示空間」

構想としては、以下のようなWebベースの作品ビューアが考えられます:

機能 説明
🔍 SVG/JSONの読み込み 手元の作品ファイルをアップロード/選択して表示
🗂️ タグ分類・検索 キャラクター名、シリーズ、時代背景などでフィルタ
🖱️ 拡大・回転 拡大・縮小・回転、全体表示、元に戻す等の操作性
🎨 レイヤー分解表示 アウトライン/影/カット層のON/OFF切り替え
💬 メモ・補足表示 当時の作業メモやコメントを紐付けて表示可能

単なる画像の「閲覧」ではなく、再発見と再構築の場を目指すものです。


📂 アーカイブデータの整理形式(例)

{
  "title": "霧雨魔理沙",
  "tags": ["東方", "魔法", "カッティング", "旧作"],
  "layers": {
    "base": "marisa_base.svg",
    "shadow": "marisa_shadow.svg",
    "outline": "marisa_outline.svg"
  },
  "note": "影レイヤーに苦労した記憶あり。特に帽子の部分。",
  "created_at": "2013-11-20"
}

JSONで管理すれば、作品のメタ情報+SVGパスのセットで構成できます。 そこからインタラクティブなビューアを構築することで、博物館的な体験に近づけるかもしれません。


🏷️ タグと検索の重要性

作品数が多いと、必ず必要になるのが検索性

たとえば:

  • キャラクター:"霧雨魔理沙""西行寺幽々子"
  • テーマ:"幻想", "和風", "SF"
  • 作成時期:"2012年春", "コロナ自粛中"

タグをベースに、一人だけのアート図録を作ることが可能です。


🧭 「見る」ことで思い出す

かつての作品を眺めることで、

  • 当時の技術的こだわり
  • 作り方の癖や変遷
  • なぜそのキャラを選んだか

…といった記憶が自然と蘇ります。 それはまるで自分の手で記憶を再編集する作業です。


💡 応用案:プレゼン or 公開モード

  • 🖥️ 全画面モードで1枚ずつスライド表示
  • 🌐 ローカルビューア → 自分用Webギャラリーへ(公開も視野に)
  • 💾 .gstudio のような独自形式による再利用設計

🔚 結び:データは「蘇る」

作品は、保存されている限り、いつでも再演可能です。 そして、今のJavaScript環境でそれを再構築する力があなたにはある。

かつて手作業で積み重ねてきたものが、 今の知識とコードの力で蘇る瞬間こそ、最高のご褒美かもしれません。


🧪 7. 簡易ビューアのプロトタイプ制作(構想)

✅ 目的:

手元にある .svg(または .json)を読み込んで、 ブラウザ上で確認/拡大縮小/レイヤー切替/メモ表示できる「一人用アーカイブビューア」を構築。


🖥️ プロトタイプUI(レイアウト案)

┌────────────┬────────────────────────┐
│ 📂 ファイル一覧(JSON or SVG) │        🔍 表示エリア(SVG)        │
│ タグ検索 / メタ表示               │                                │
│ レイヤー切替 [✔]base [✔]shadow...│                                │
│ メモ表示(作者メモ)              │                                │
└────────────┴────────────────────────┘

🔧 JavaScriptでの機能設計(最小構成)

機能 実装案
ファイル選択 <input type="file" multiple>FileReader
SVG表示 SVG文字列を<div id="viewer">へ挿入
ズーム・パン viewBoxで拡大/panzoom.jsで操作対応可
レイヤーON/OFF SVGグループ(例:<g id="shadow">)を切り替え
メタ表示 JSONファイルに紐づいたtitle, tags, noteなどをHTML表示
タグフィルタ JavaScriptで作品一覧を動的に絞り込み

🧩 使用するライブラリ(軽量)

  • panzoom:SVGを拡大縮小+ドラッグ移動
  • marked.js:メモにMarkdownを使うなら

📁 ファイル構成ルールの提案

📦 1作品ごとのフォルダ構成(例)

作品名(霧雨魔理沙)/
├── meta.json              ← メタ情報+ファイル定義
├── base.svg               ← ベース部分
├── shadow.svg             ← 影部分
├── outline.svg            ← アウトライン
├── thumb.png              ← サムネイル画像(省略可)

🧾 meta.json 例

{
  "title": "霧雨魔理沙",
  "tags": ["東方", "魔法", "カッティング"],
  "note": "この影レイヤー、帽子と髪の接続に苦労した。",
  "layers": {
    "base": "base.svg",
    "shadow": "shadow.svg",
    "outline": "outline.svg"
  }
}

🚀 開発プラン(段階的)

ステップ 内容
Step 1 単一SVG表示ビューア(ファイル読み込み→表示)
Step 2 JSONメタ付き表示(タイトル・タグ・メモを反映)
Step 3 複数作品の管理とタグフィルタUI
Step 4 レイヤー分解・ON/OFF切替機能
Step 5 エクスポート/保存(必要であれば)

🎁 デモコード一部(Step1用)

<input type="file" id="fileInput" accept=".svg">
<div id="viewer"></div>

<script>
  document.getElementById("fileInput").addEventListener("change", function(e) {
    const file = e.target.files[0];
    const reader = new FileReader();
    reader.onload = function(evt) {
      document.getElementById("viewer").innerHTML = evt.target.result;
    };
    reader.readAsText(file);
  });
</script>

💬 次の選択肢:

  • 🧪 この構成で実装を始める(HTMLテンプレートご用意可能)
  • 🗃️ 既存ベクター作品を整理 → JSON+SVGに変換支援
  • 🔄 P2PまたはIndexedDBでの保存・共有と連携(応用編)

## 終わりに

JavaScriptで、画像データから、ベクターデータを作成する企画を考えてたのですが、方向性がズレてしまいましたがこれはこれで役に立つもしれないので記事にしてみます。

ゲーム制作が忙しいので別企画をするゆとりはないですが、時間が出来たら何かやってみるかもしれません。