🎉

IllustratorのSVGパスからイメージマップの座標に変換する方法

に公開

はじめに

Illustratorで作成したクリッカブルマップをWebで実装する際、SVGパスをイメージマップの座標に変換する必要があります。この記事では、その変換処理をJavaScriptで実装する方法を解説します。

背景

クリッカブルマップの実装方法には主に2つあります:

  1. SVGを直接使用する
  2. HTMLのimage mapを使用する

SVGは優れた選択肢ですが、特にホバーエフェクトを実装する際にはimage mapの方が都合が良い場合があります。そこで、Illustratorで作成したSVGパスをimage mapの座標に変換する必要が出てきます。

実装方法

SVGからImageMap(イメージマップ)に変換ツール
https://gist.github.com/sarap422/5660d5d69fded713db37275af28d7076

image-map-resizer.jsを利用した、hoverの効くクリッカブルマップのサンプル
<iframe height="600" style="width:100%;" scrolling="no" title="image-map-resizer.jsを利用した、hoverの効くクリッカブルマップのサンプル" src="https://codepen.io/sarap422/embed/RwjawVZ?theme-id=25176&amp;default-tab=result&amp;editable=true" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">See the Pen <a href='https://codepen.io/sarap422/pen/RwjawVZ'>image-map-resizer.jsを利用した、hoverの効くクリッカブルマップのサンプル</a> by sarap422 (<a href='https://codepen.io/sarap422'>@sarap422</a>)on <a href='https://codepen.io'>CodePen</a>.</iframe>

1. SVGファイルの構造

Illustratorから書き出されるSVGファイルの構造は以下のようになっています:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 720 584">
  <g id="imgmap-area1">
    <polygon class="cls-7" points="409.5 416.54 420.76 556.99 216.91 556.99 216.91 515.5 409.5 416.54"/>
  </g>
  <!-- 他のエリアも同様の構造 -->
</svg>

2. 変換スクリプト

SVGをimage map形式に変換する核となるコードは以下の通りです:

function parsePathToCoords(path) {
    const points = path.getAttribute('points');
    if (!points) return '';

    const coordinates = points.trim()
        .split(' ')
        .map(point => {
            const [x, y] = point.split(',');
            return `${Math.round(x)}`;
        })
        .join(',');

    return coordinates;
}

3. 変換処理の流れ

  1. SVGファイルをパース
  2. imgmap-areaで始まるID要素を検索
  3. polygon要素のpoints属性を取得
  4. 座標を適切な形式に変換
  5. HTML形式で出力

4. 出力されるHTML

変換後のHTMLは以下のような構造になります:

<dl class="imgmap-wrapper">
  <dt class="imgmap-basis">
    <img src="img/imgmap-basis.png" usemap="#ImageMap1" alt="" />
  </dt>
  <dd class="imgmap-area1">
    <area shape="poly" coords="410,417,421,557,217,557,217,516,410,417" href="#" alt="" />
    <img src="img/imgmap-area1.png" alt="" />
  </dd>
  <!-- 他のエリアも同様の構造 -->
</dl>

実装のポイント

座標の処理

  • SVGのpoints属性はx y形式でスペース区切り
  • イメージマップはx,y形式でカンマ区切り
  • 数値の丸め処理が必要(Math.roundを使用)

エラー処理

// ファイルタイプの確認
function isSVGFile(file) {
    const isSVGMimeType = file.type === 'image/svg+xml';
    const isSVGExtension = file.name.toLowerCase().endsWith('.svg');
    return isSVGMimeType || isSVGExtension;
}

// SVGの内容確認
function isValidSVGContent(content) {
    try {
        const parser = new DOMParser();
        const doc = parser.parseFromString(content, 'image/svg+xml');
        const parserError = doc.getElementsByTagName('parsererror');
        return parserError.length === 0 && doc.documentElement.nodeName === 'svg';
    } catch (e) {
        return false;
    }
}

CSS実装のポイント

変換後のHTMLにホバーエフェクトを実装する際のCSSは以下のようになります:

.imgmap-container {
    display: block; 
    position: relative;
}
.imgmap-wrapper .imgmap-basis {
    display: block; 
    width: 100%;
}
.imgmap-wrapper [class*="imgmap-area"] {
    position: absolute;
    inset: 0;
    margin: auto;
    width: 100%;
    pointer-events: none;
}
.imgmap-wrapper [class*="imgmap-area"]:is(:hover, :focus) {
    filter: brightness(1.08);
    opacity: 0.75;
}

まとめ

この実装により:

  1. Illustratorでの直感的な編集が可能
  2. 自動的にイメージマップ座標に変換
  3. ホバーエフェクトが実装可能
  4. メンテナンス性の高いコード生成

が実現できます。

参考資料

Discussion