Mapbox Newsletter WEEKLY TIPSの解説 -「マーカーインスタンスにポップアップを添付」
はじめに
この記事は、本日配信されたMapbox NewsletterのWEEKLY TIPSで紹介されていた「マーカーインスタンスにポップアップを添付」についての解説です。また、Newsletterの購読はこちらからお申し込みいただけます。
コードを確認
まずExamplesのコードを見に行きましょう。
日本語サイト
英語サイト
基本的に同じコードですが、英語版はスタイルがMapbox Streets v12にアップグレードされているのでこちらを使用します。Mapbox Streets v11ではデフォルトのプロジェクションがWebメルカトルであるのに対し、Mapbox Streets v12ではGlobe(3D表示された地球)なので、印象がかなり異なります。
HTML/CSS
まずHTMLを見ていきましょう。以下は地図を表示するエレメントです。
<div id="map"></div>
次はCSSです。このサンプルではMarkerとPopupを使用しているため、それぞれCSSを設定します。以下はMarkerのCSSです。画像を使用し、角を丸めて円形にしています。
#marker {
background-image: url('https://docs.mapbox.com/mapbox-gl-js/assets/washington-monument.jpg');
background-size: cover;
width: 50px;
height: 50px;
border-radius: 50%;
cursor: pointer;
}
以下はPopupのCSSです。このクラス名はサンプルコード中には出てきませんが、Popupクラス内部で使用されるクラス名です。Popupクラスは内部的にdiv
エレメントを作成し、それに対してmapboxgl-popup
というクラス名を設定しています。詳細はこちらのコードをご参照ください。
.mapboxgl-popup {
max-width: 200px;
}
Mapの作成
次にJavaScriptのコードを見ていきます。以下のコードはいつも通り、Mapオブジェクトを作成しています。container
で地図を表示するHTMLエレメントのidを指定します。
const map = new mapboxgl.Map({
container: 'map',
// Choose from Mapbox's core styles, or make your own style with Mapbox Studio
style: 'mapbox://styles/mapbox/light-v11',
center: monument,
zoom: 15
});
Popupを作成します。setText
で文字列を指定すると、その文字列からテキストノードを作成し、div
エレメントが作成されます。詳細はこちらのコードをご参照ください。また、オフセットを設定することで、PopupがMarkerに重ならないようにしています。
const popup = new mapboxgl.Popup({ offset: 25 }).setText(
'Construction on the Washington Monument began in 1848.'
);
次にMarkerを作成します。ここではdiv
エレメントを明示的に作成し、Markerとして使用しています。idを指定して先程のCSSをあてています。これにより標準の青いピンではなく、CSSに設定されている画像がマーカーとして表示されます。また、後ほど説明しますがsetPopup
メソッドでPopupオブジェクトと関連付けることで、Merkerクリック時にPopupを表示するといった連携動作が可能になります。
// create DOM element for the marker
const el = document.createElement('div');
el.id = 'marker';
// create the marker
new mapboxgl.Marker(el)
.setLngLat(monument)
.setPopup(popup) // sets a popup on this marker
.addTo(map);
MarkerとPopupの連携
PopupはMarkerと連携することで利便性が増します。ここではMarkerのsetPopup
メソッドとaddTo
メソッドの処理内容を確認し、どのようにMarkerとPopupが連携するのかを見てみます。
setPopup
Popupのoffset
以下のコードを見るとMarkerがデフォルト(水色のピン)のときは自動的にPopupのoffsetが設定されます。これはデフォルトを使用しているときはアイコンの高さが既知なのでPopupが重ならないoffsetが計算できるからですね。今回のサンプルでは独自のMarkerに変更しているので明示的にoffset: 25
を設定しています。
Popupの座標の設定
以下のコードでPopupの座標を設定しています。そのため、Popup作成時に座標を設定する必要はありませんでした。
addTo
Popupのトグル
Markerをクリックすると自動的にPopupが表示されます。これは以下のコードでクリックイベント発生時にtogglePopup
を実行しているためです。
togglePopup
の処理は以下のとおりです。
const popup = this._popup;
if (!popup) {
return this;
} else if (popup.isOpen()) {
popup.remove();
this._element.setAttribute('aria-expanded', 'false');
} else if (this._map) {
popup.addTo(this._map);
this._element.setAttribute('aria-expanded', 'true');
}
Popupが表示されていないときはPopup#addTo
を使用してMapオブジェクトに登録し、逆に表示されているときはPopup#remove
で削除しています。
これにより、表示するときだけPopupのdivエレメントを作成し、非表示時にはエレメントそのものが削除されるので効率的です。
まとめ
このサンプルでは独自のMarkerの表示方法や、MarkerとPopupの連携方法について確認しました。
Discussion