前回、ブラウザで動くSVGエディタを作りました。
コードを書くとリアルタイムでプレビューが更新され、プレビュー側からも編集できる便利なツールです。
しかし実際に使ってみると、既存のSVGファイルを編集したいときに不便さを感じました。
いったんエディタで表示してからコードをコピー&ペーストするのは手間がかかります。
そこで今回は、SVGファイルを直接読み込める機能を2つ追加しました。
ドラッグ&ドロップとファイル選択ボタンです。

1. なぜファイル読み込み機能が必要だったのか
エディタを実際に使い始めると、すぐに課題が見えてきました。
既存のSVGファイルを編集するとき、まずファイルをテキストエディタで開き、内容を全選択してコピーし、ブラウザに戻ってペーストする必要があります。
この作業を何度も繰り返すうちに、もっと直接的な方法がほしくなりました。
理想は、ファイルをエディタに渡すだけで読み込みが完了することです。
現代のWebアプリケーションでは、ドラッグ&ドロップが標準的なUIになっています。
ファイルをブラウザにドロップすれば開ける。この体験を実現したいと考えました。
2. ドラッグ&ドロップ機能の実装
ブラウザでドラッグ&ドロップを実装するには、3つのイベントを扱います。
dragoverはファイルがエリア上にある状態、dragleaveはエリアから離れた状態、- そして
dropが実際にファイルをドロップした瞬間です。
最初に気をつけたのは、ブラウザのデフォルト動作を止めることでした。
通常、SVGファイルをブラウザにドロップすると、そのファイルを新しいタブで開いてしまいます。
これを防ぐため、各イベントでpreventDefault()を呼びます。
function handleDragOver(e) {
e.preventDefault();
e.stopPropagation();
// 視覚的フィードバック
DOM.codeInput.style.background = '#1a1a1a';
DOM.codeInput.style.opacity = '0.8';
}Code language: JavaScript (javascript)
2.1. 視覚的なフィードバック
ドラッグ中は、コードエリアの背景色を少し明るくしました。
ユーザーは「ここにドロップできる」と視覚的に理解できます。
ファイルがエリアから離れると、元の暗い背景に戻ります。この変化があるだけで、操作の手応えが大きく変わりました。
CSSにはtransitionプロパティを追加し、色の変化を滑らかにしています。
2.2. ファイルの読み込み処理
ドロップされたファイルはe.dataTransfer.filesで取得できます。
まずファイルが本当にSVGかどうかを確認しました。
拡張子が.svgであるか、MIMEタイプがimage/svg+xmlであることをチェックします。
if (!file.name.endsWith('.svg') && file.type !== 'image/svg+xml') {
DOM.errorMessage.textContent = 'SVGファイルのみ対応しています';
DOM.errorMessage.style.display = 'block';
return;
}Code language: JavaScript (javascript)
ファイルの内容を読むにはFileReaderを使います。readAsText()メソッドでファイルをテキストとして読み込み、onloadイベントで結果を受け取ります。
ここで前回実装したupdateSVG()関数を呼ぶと、プレビューが自動的に更新されます。
2.3. SVG2への対応
読み込んだSVGコードには、古い記法が含まれている場合があります。
特にxlink:href属性は、SVG2では単なるhrefに置き換えられました。
互換性を保つため、正規表現で自動的に変換します。
text = text.replace(/xlink:href\s*=/g, 'href=');
text = text.replace(/\s+xmlns:xlink="http:\/\/www\.w3\.org\/1999\/xlink"/g, '');Code language: JavaScript (javascript)
この処理により、古いSVGファイルでもエラーなく読み込めるようになりました。
3. ファイル選択ボタンの追加
ドラッグ&ドロップは直感的ですが、すべてのユーザーがこの操作に慣れているわけではありません。
特にファイルマネージャーを開いていない状態では、ドラッグ&ドロップは使いにくいものです。
そこで従来型のファイル選択ボタンも追加することにしました。
3.1. hidden inputの活用
HTML5の<input type="file">要素は、標準のファイル選択機能を提供します。
しかしデフォルトのデザインは、エディタの見た目と合いません。
そこで、input要素自体はdisplay: noneで隠し、代わりにスタイルを整えたボタンを配置しました。
<input type="file" id="file-input" accept=".svg,image/svg+xml" style="display: none;">
<button class="copy-btn" id="load-file-btn">📁 Load SVG File</button>Code language: HTML, XML (xml)
ボタンをクリックすると、JavaScriptで隠しているinput要素のclick()メソッドを呼びます。
これによりファイル選択ダイアログが開きます。
デザインの自由度を保ちながら、標準機能を活用できる方法です。
3.2. ファイル選択後の処理
input要素のchangeイベントで、選択されたファイルを受け取ります。
処理内容はドラッグ&ドロップと同じです。
SVGファイルかチェックし、FileReaderで読み込み、コードを置き換えてプレビューを更新します。
一つ工夫したのは、処理が終わった後にinput要素の値をリセットすることです。e.target.value = ''を実行すると、同じファイルを再度選択できるようになります。
これがないと、一度選んだファイルをもう一度選ぼうとしてもchangeイベントが発火しません。
3.3. ボタンの配置とフィードバック
新しいボタンは、「Paste & Replace」の左側に配置しました。
左から順に「Load SVG File」「Paste & Replace」「Copy All」と並びます。
ファイル読み込みに成功すると、ボタンのテキストが「✓ Loaded: ファイル名」に変わります。
2秒後に元の表示に戻ります。この一時的な変化により、ユーザーは操作が成功したことを確認できます。
4. 実装して気づいたこと
ファイル操作では、予期しない問題が起きやすいものです。ファイルが壊れている、形式が違う、読み込み権限がない。
さまざまなケースを想定する必要がありました。
エラーメッセージは、画面上部に赤い背景で表示されます。
3秒後に自動的に消えるため、ユーザーの操作を妨げません。
エラーの内容も具体的に伝えるよう心がけました。
「ファイルの読み込みに失敗しました」だけでなく、「SVGファイルのみ対応しています」と書くことで、ユーザーは何が問題だったのかを理解できます。
5. まとめ
既存のSVGエディタに、ファイル読み込み機能を追加しました。ドラッグ&ドロップで直感的に、ボタンで確実に。どちらの方法でもSVGファイルを開けるようになり、実用性が大きく向上しました。
実装自体はシンプルでしたが、細部の配慮が使いやすさを左右することを実感しています。視覚的なフィードバック、エラーメッセージの内容、ボタンの配置。小さな積み重ねが、ツール全体の完成度を高めていきます。
このエディタは、まだまだ改善の余地があります。次は何を追加しようか。使いながら考えるのが楽しみです。