画像の一部をクリック、ホバー出来るようにするクリッカブルマップの作り方です。svg編とpng編の2パターン試してみました。今回はpng編です。
svg編はこちらから
SVG画像:画像の一部をクリック可能にする
完成イメージ
png画像をクリッカブルにしていきます。レスポンシブ対応可能です。

実装手順
- ベースとなるHTMLの記述
- オンラインツールを画像上でクリック可能にしたい場所を指定する
- ツールで吐き出されたコードをHTMLに設定する
- プラグインを導入してレスポンシブ対応させる
1. ベースとなるHTMLの記述
クリッカブルマップにしたいimgタグにusemap属性を設定します。
属性値は何でもOK。
HTML
<p class="img"><img src="./img/town.png" alt="" usemap="#image-map"></p>
2. 画像上でクリック可能にしたい場所を指定する
こちらのサイトでコードを生成してもらいます。
- Select Image form My PC をクリックして使用する画像を選択
- Activeにチェックを入れる
- ShapeやLinkなど各項目を設定
- 範囲を選択
- 必要な分だけ行を増やして繰り返す

最後に Show Me The Code ! をクリックするとコードが表示されるので、mapタグ部分をコピーします。
3. ツールで吐き出されたコードをHTMLに設定。
先ほどコピーしたmapタグをHTMLに貼り付けます。
name属性に最初にimgタグに設定したusemap属性と同じ値を設定します。
HTML
<map name="image-map">
<area target="" alt="title" title="title" href="aaa.html" coords="12,44,86,139" shape="rect">
<area target="" alt="" title="" href="" coords="271,1,230,133,311,133" shape="poly">
<area target="" alt="" title="" href="" coords="381,50,450,137" shape="rect">
</map>
ブラウザで開いて動作確認。
実際にクリックしてみるとアウトラインが表示されるので分かりやすいです。
タブキーでフォーカスを移動して確認してみてください。

4. プラグインを導入してレスポンシブ対応させる。
先ほどのツールが自動生成してくれるソースコードは、あくまで画像の元の大きさを基準にしたものです。そのため、width: 100%; などスタイルでサイズを変更してしまうとクリックできる位置もずれてしまいます。
レスポンシブにも対応できるようにプラグインを読み込みます。
使用するのはこちら。
davidjbradshaw/image-map-resizer
jQuery依存ではないので単体でも使用可能です。
ソースコードをgitからダウンロードし、読み込ませます。
そのあと、一行記述するだけでOK。
HTML
// ソースコードの読み込み
<script src="js/imageMapResizer.min.js"></script>
JavaScript
// jQueryを使用していない時はこちら。
imageMapResize();
// jQueryバージョン。
$('map').imageMapResize();
導入前:width: 70%; にしてみました。クリックエリアが探せていません。笑

導入後:綺麗に合わせてくれています。

おまけ:今回実現したかったスタイル
今回紹介したのは古い方法みたいです。
SVG画像が使えるならそちらの方が簡単綺麗ですが、どうしてもPNG画像しか用意できないこともあると思うので、頭の片隅にでも知識があると良いかなと思いました。
実際に実現したかったのは一番最初に載せてあるアニメーションのようなイメージ。レスポンシブ対応で、画像をホバーしたら吹き出し的な部分の色を変えたいとのこと。
参考までにそちらのソースコードも。
処理の流れ
大まかな処理の流れはこんな感じです。
- ホバーしたマップエリアを識別するためのdata-option属性をつける。
- mouseover() を使用してホバーしたエリアに振った番号(data-option属性の値)を取得。
- 同じ番号の吹き出しにactiveクラスを付与。背景色を変える。
- mouseout()でホバーが外れた時にクラスを取り除く。
function | 役割 |
---|---|
mouseover() | ホバーを検知する。 参考:http://js.studio-kingdom.com/jquery/events/mouseover |
mouseout(): | ホバーが外れたことを検知する。 参考:http://js.studio-kingdom.com/jquery/events/mouseout |
ソースコード
HTML
areaタグにdata-option属性を追加。
<div class="wrapper">
<div class="baloon">
<p class="baloon-01">building A</p>
<p class="baloon-02">building B</p>
<p class="baloon-03">building C</p>
</div>
<div class="background">
<p class="background-01"></p>
<p class="background-02"></p>
<p class="background-03"></p>
</div>
<div>
<p class="img"><img src="./img/town.png" alt="" usemap="#image-map-01"></p>
<map name="image-map-01">
<area target="" alt="" title="" class="item" data-option="01" href="#" coords="10,49,83,139" shape="rect">
<area target="" alt="" title="" class="item" data-option="02" href="#" coords="270,3,228,139,311,137" shape="poly">
<area target="" alt="" title="" class="item" data-option="03" href="#" coords="381,53,447,139" shape="rect">
</map>
<div>
</div>
CSS
長いので一部割愛してます 。
吹き出しのbaloonにactiveクラスがつくと背景色が変わります。
.baloon-01.active{
background-color: goldenrod;
}
.baloon-02.active{
background-color: darkseagreen;
}
.baloon-03.active{
background-color: cornflowerblue;
}
.background{
width: 100%;
height: 100%;
position: absolute;
z-index: 1;
}
.background p{
border-radius: 50%;
opacity: 0;
position: absolute;
}
.background p.active{
transition-property: opacity;
transition-duration: .7s;
opacity: .7;
}
.background p::after{
content: '';
display: block;
width: 105%;
height: 105%;
background-color: transparent;
border-radius: 100%;
box-shadow: 0 0 15px 15px whitesmoke inset;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
}
JavaScript
$(this)
を使用することで、ホバーされた対象のdata-option属性を取り出せます。
取り出した値を目印として同じ番号が降られたbaloonとbackgroundにactiveクラスを付与。
$(function(){
// hoverした時
$('area').mouseover(function(){
$('.hover-area').toggleClass('hover');
let targetNum = $(this).data('option');
let target = $('.baloon-'+targetNum);
let bg = $('.background-'+targetNum);
target.addClass('active');
bg.addClass('active');
})
// hover外れた時
$('area').mouseout(function(){
$('.hover-area').toggleClass('hover');
let targetNum = $(this).data('option');
let target = $('.baloon-'+targetNum);
let bg = $('.background-'+targetNum);
target.removeClass('active');
bg.removeClass('active');
})
})
mouseover()とmouseout()と似ている関数として、mouseenter()とmouseleave()があるのですが、そっちを使った方が良かったかなぁ。。。