78
83

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

HTML5 SVG + CSS + JS で柔軟なマウス領域を実現

Posted at

HTML5でサポートした <svg> 要素と、CSS、JavaScriptを組合せて、マウス処理する複雑な形の領域を作ります。次のような関東地方の地図のデモを作成しました。都道府県の形に沿ってマウスイベントが発火するのが、確認できるかと思います。

kanto.png
Kanto SVG map - CodePen

はじめに

HTML5でサポートした <svg> 要素により、HTMLドキュメント内にSVGを描画できるようになり、従来の矩形(<div>など)だけでは難しかった複雑な形の要素も配置できるようになりました。SVG画像を描画するだけでなく、<svg> ... </svg> 内の要素(<path><rect>)に、これまでのHTML文章同様、CSSによるスタイルの指定や、JavaScriptによる要素の変更、イベントリスナの登録が可能となります。

これまで <area> タグで指定していたマウスの処理の範囲も、SVGから作成することができます。SVGだとInkscapeのような視覚的にわかりやすいツールを使って、パスを作成できます。

HTMLの記述

HTMLに埋め込むSVGを用意するのは、Inkscapeを使うのが手っ取り早いです。SVGで適当なパスを作成し、出力ファイル形式をPlain SVGとしてファイルに書き出します。Plain SVGはInkscapeが使用するデータを削除したSVG形式です。しかしそれでも不要なメタ情報などが付与されるので、テキストエディタで削除してからHTMLに貼り付けます。

<!DOCTYPE html>
<html>
  <body>
    <svg width='240' height='262' >
      <path data-name='Ibaraki'  d='...' />
      <path data-name='Chiba'    d='...' />
      <path data-name='Tokyo'    d='...' />
      <path data-name='Kanagawa' d='...' />
      <path data-name='Tochigi'  d='...' />
      <path data-name='Gumma'    d='...' />
      <path data-name='Saitama'  d='...' />
    </svg>
  </body>
</html>

各要素に指定される style 属性も、今回はCSSにから一括で指定するので削除します。InkscapeにはXMLエディタもついており、描画結果を確認しながら不要な要素の掃除もできて便利です。

data-name属性には都道府県名を記述して、後にJavaScriptから参照します。

CSSの記述

続いてCSSでスタイルを記述します。CSSを使用すると他の要素と同様に、セレクタを指定してスタイルを設定できます。

path {
  fill: #5fd35f;
  stroke: #165016;
  stroke-width: 1;
  transition-duration: 200ms;
  cursor: pointer;
}
path:hover {
  fill: #2ca02c;
}

ここで fillstroke など、普段見ないプロパティ名がたくさんあることに気づきます。これはSVGで使用するスタイルです。その他の使用可能なプロパティはW3Cから確認できます。

そして通常のHTMLドキュメント同様、path:hover セレクタや transition-duration プロパティも使用できます。これでCSSのみで、ホバー時に色の変化をつけることができました。

JavaScriptの記述

JavaScriptの記述も、従来のHTML要素と同じようにSVG内の要素を扱うことができます。

function alertName(e) {
  alert('Welcome to ' + e.target.getAttribute('data-name'));
}

window.onload = function() {
  paths = window.document.querySelectorAll('path');
  for (i = 0; i < paths.length; ++i) {
    paths[i].onclick = alertName;
  }
};

window.onload 時に、すべての <path> 要素に対して、クリック時のイベントを記述しています。このイベント内では、ターゲットのdata-name 内のデータ参照し、 alert で表示しています。

おわりに

SVGを使うことで、<area> タグに変わる方法で、柔軟かつ容易にマウス処理の範囲を指定することができました。

ただ、CodePenで動作は確認できたのですが、HTMLの仕様として合法かどうかまでは確認できていないんので、仕様書をもう一度確認する必要があります。

78
83
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
78
83

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?