area要素で地図をホバーした時に色を付ける方法

今回やりたいこと

ここに来て初めて直面した実装なのですが、例えば日本地図があってその地図の東京都をクリックしたら東京都のページに移動するようなページってよくありますよね。でもこれボタンをホバーするならいいのですが、日本地図の東京都をホバーした時に東京都にだけ色(ホバーアニメーション)が付けば、すごくユーザーにとって分かりやすいです。

そもそも今回紹介するやり方がこの時代に最新の正しい方法なのかは置いておいて、とりあえず実装はできたので記事に残しておきます。

画像を用意

47都道府県の日本地図の場合、48枚の画像を用意する必要があります。ホバーしたタイミングで日本地図の一枚絵を丸ごと切り替えるイメージです。つまりどこにも色がついていない日本地図の画像1枚+それぞれの都道府県に色を付けた画像47枚が必要です。容量をとってしまうので可能であればgif形式で保存した方がいいかもしれません。その辺の配慮は適宜適当にお願いします。

エリアを作成する

今回紹介するものはレスポンシブ非対応です。画像のサイズは縦横きっちりpxで固める必要があります。これはarea要素でエリアを指定する数値が絶対値だからです。

ではこのarea要素を作成していきます。もちろんこんなの手書きで測ってられないので、Web上の便利なツールを使います。

今回私が使用したのはこちらのサービスです。

ここにドラッグドロップする画像はホバーアニメーションがない画像です。この画像がHTML上に最初に乗る画像になるので間違えないようにご注意ください。

画像をドラッグドロップしたら右上にある図形を描くをクリックし、形を作っていきましょう。図の形に応じて適した形を使用して下さい。

確定「escキー」、削除「deleteキー」です。確定するたびに右側にHTMLコードが生成されるので、すべて囲い終わったらHTMLコードを丸ごとコピーしてHTMLに貼り付けてしまいましょう。

HTMLコードを編集する

特に修正する必要はないのですが、付与されているIDなどがすべてデフォルトになっているので分かりやすいようにカスタマイズすると良いです。


<img src="画像のパス" usemap="#ImageMap" alt="" id="mapimg" />
<map name="ImageMap">
	<area shape="poly" coords="988,3,982,1,954,132,1001,159,1012,144,1046,75,1079,93,1095,1,1095,1,1095,1,1095,1,1095,1,1095,1,1095,1,1093,0" href="#" alt="宮城県" id="map_miyagi" />
	<area shape="poly" coords="944,292,1001,306,996,451,964,427,931,443,879,402,879,402,879,398,879,398" href="#" alt="茨城県" id="map_ibaraki" />
	<area shape="poly" coords="879,412,1007,466,942,552,895,508,888,581,939,548,906,518,906,518,906,518" href="#" alt="千葉県" id="map_chiba" />
	<area shape="poly" coords="761,428,812,389,869,401,888,451,843,457,764,437,764,437,764,437" href="#" alt="埼玉県" id="map_saitama" />
	<area shape="poly" coords="789,447,846,494,894,463,892,459,885,462,885,462" href="#" alt="東京都" id="map_tokyo" />
	<area shape="poly" coords="807,547,786,508,809,477,885,491,873,549,869,547" href="#" alt="神奈川県" id="map_kanagawa" />
</map>

今回私はこのようにIDを指定しました。

jsを記述する際に使用するものになりますので、もちろんclassでもOKですが、ここで使用するものはすべてユニーク(被りがない)ものになるので、今回はIDにしています。

※img要素につけたID = img要素のsrcを書き換える記述をするときに必要。

※各area要素につけたID = そのエリアをホバーしたら~という記述をするときに必要。

このエリアにさらにボタンを置きたい時

このエリアにその都道府県名のボタンを置きたいときもあると思います。その場合はこのコピーしてきた要素一式を、1つのdiv要素で囲って、この要素一式の下にボタン一式のコードを書きましょう。それらをposition: absolute;で絶対値で配置するとよいです。この画像サイズは固定なのでpx指定で問題ありません。


<div class="index-map">
	<img src="画像のパス" usemap="#ImageMap" alt="" id="mapimg" />
	<map name="ImageMap">
		<area shape="poly" coords="988,3,982,1,954,132,1001,159,1012,144,1046,75,1079,93,1095,1,1095,1,1095,1,1095,1,1095,1,1095,1,1095,1,1093,0" href="#" alt="宮城県" id="map_miyagi" />
		<area shape="poly" coords="944,292,1001,306,996,451,964,427,931,443,879,402,879,402,879,398,879,398" href="#" alt="茨城県" id="map_ibaraki" />
		<area shape="poly" coords="879,412,1007,466,942,552,895,508,888,581,939,548,906,518,906,518,906,518" href="#" alt="千葉県" id="map_chiba" />
		<area shape="poly" coords="761,428,812,389,869,401,888,451,843,457,764,437,764,437,764,437" href="#" alt="埼玉県" id="map_saitama" />
		<area shape="poly" coords="789,447,846,494,894,463,892,459,885,462,885,462" href="#" alt="東京都" id="map_tokyo" />
		<area shape="poly" coords="807,547,786,508,809,477,885,491,873,549,869,547" href="#" alt="神奈川県" id="map_kanagawa" />
	</map>
	<div class="index-map__btn--left">
		<a href="#" class="index-map__btn" id="btn_saitama">埼玉県</a>
		<a href="#" class="index-map__btn" id="btn_tokyo">東京都</a>
		<a href="#" class="index-map__btn" id="btn_kanagawa">神奈川県</a>
	</div>
	<div class="index-map__btn--right">
		<a href="#" class="index-map__btn" id="btn_miyagi">宮城県</a>
		<a href="#" class="index-map__btn" id="btn_ibaraki">茨城県</a>
		<a href="#" class="index-map__btn" id="btn_chiba">千葉県</a>
	</div>
</div>

一応コードを置いておくとこんな感じです。CSSは省略します。以下に記述するjQueryはこちらのコードをベースに記述してます。

jQueryの記述

すごく初歩的なjQueryの記述だけで今回やりたいことの実装が可能です。まずコードは以下のようになります。


$(function() {
  {
    $("#map_miyagi, #btn_miyagi").hover(//宮城県のエリア、宮城県のボタンをホバーした時
      function() {
        $("#mapimg").attr("src", "assets/images/map_miyagi.jpg"); // img要素のsrcを""内のパスに置き換える
        $(this).addClass("is-hover"); // 宮城県のエリアに"is-hover"クラスを付与する
        $("#btn_miyagi").addClass("is-hover"); // 宮城県のボタンに"is-hover"クラスを付与する
      },
      function() {
        $("#mapimg").attr("src", "assets/images/map.jpg");
        $(this).removeClass("is-hover");
        $("#btn_miyagi").removeClass("is-hover");
      }
    );
    $("#map_ibaraki, #btn_ibaraki").hover(
      function() {
        $("#mapimg").attr("src", "assets/images/map_ibaraki.jpg");
        $(this).addClass("is-hover");
        $("#btn_ibaraki").addClass("is-hover");
      },
      function() {
        $("#mapimg").attr("src", "assets/images/map.jpg");
        $(this).removeClass("is-hover");
        $("#btn_ibaraki").removeClass("is-hover");
      }
    );
    $("#map_chiba, #btn_chiba").hover(
      function() {
        $("#mapimg").attr("src", "assets/images/map_chiba.jpg");
        $(this).addClass("is-hover");
        $("#btn_chiba").addClass("is-hover");
      },
      function() {
        $("#mapimg").attr("src", "assets/images/map.jpg");
        $(this).removeClass("is-hover");
        $("#btn_chiba").removeClass("is-hover");
      }
    );
    $("#map_saitama, #btn_saitama").hover(
      function() {
        $("#mapimg").attr("src", "assets/images/map_saitama.jpg");
        $(this).addClass("is-hover");
        $("#btn_saitama").addClass("is-hover");
      },
      function() {
        $("#mapimg").attr("src", "assets/images/map.jpg");
        $(this).removeClass("is-hover");
        $("#btn_saitama").removeClass("is-hover");
      }
    );
    $("#map_tokyo, #btn_tokyo").hover(
      function() {
        $("#mapimg").attr("src", "assets/images/map_tokyo.jpg");
        $(this).addClass("is-hover");
        $("#btn_tokyo").addClass("is-hover");
      },
      function() {
        $("#mapimg").attr("src", "assets/images/map.jpg");
        $(this).removeClass("is-hover");
        $("#btn_tokyo").removeClass("is-hover");
      }
    );
    $("#map_kanagawa, #btn_kanagawa").hover(
      function() {
        $("#mapimg").attr("src", "assets/images/map_kanagawa.jpg");
        $(this).addClass("is-hover");
        $("#btn_kanagawa").addClass("is-hover");
      },
      function() {
        $("#mapimg").attr("src", "assets/images/map.jpg");
        $(this).removeClass("is-hover");
        $("#btn_kanagawa").removeClass("is-hover");
      }
    );
  }
});

1つ1つ記述しているのでコードが長く見えますが1ブロック取って説明するととてもシンプルで簡単です。

“is-hover”クラスでCSSでスタイルを適用しています。これでボタンをホバーしたときのスタイルを記述すればOKです。

いかがでしたでしょうか。若干手間で面倒くさいですが、地道な作業な末に使いやすい地図リンクを作成することができました。

もっと良い方法があれば是非教えて頂きたく宜しくお願いします。

related article

2021/02/19 JavaScript

ユーザーエージェントを判定してスマホ用サイトに飛ばす

2019/11/15 JavaScript

Youtubeをポップアップで再生させる方法

2019/11/08 JavaScript

1個開けると他は閉じるアコーディオンメニュー

2021/07/19 JavaScript

lazyload.jsとスピナーアイコンを組み合わせる