Mapbox Newsletter WEEKLY TIPSの解説 -「ボタンでレイヤーの色を変更」
はじめに
この記事は、先日配信されたMapbox NewsletterのWEEKLY TIPSで紹介されていた「ボタンでレイヤーの色を変更」についての解説です。このサンプルでは動的にPaintプロパティを変更する方法を例示しています。また、Newsletterの購読はこちらからお申し込みいただけます。
コードを確認
まずExamplesのコードを見に行きましょう。
日本語サイト
英語サイト
基本的に同じコードですが、英語版はスタイルがMapbox Light v11にアップグレードされているのでこちらを使用します。Mapbox Light v10ではデフォルトのプロジェクションがWebメルカトルであるのに対し、Mapbox Light v11ではGlobe(3D表示された地球)なので、印象がかなり異なります。
今回はコードが少し長めでドキッとしますが、順番に見ていけば大丈夫です。
HTML/CSS
まずHTMLを見ていきましょう。
以下は地図を表示するエレメントです。
<div id="map"></div>
以下は左上に表示されているコントロール部分です。
<div class="map-overlay top">
<div class="map-overlay-inner">
<fieldset>
<label>Select layer</label>
<select id="layer" name="layer">
<!-- Each value matches a layer ID. -->
<option value="water">Water</option>
<option value="building">Buildings</option>
<option value="triangles">Triangles</option>
</select>
</fieldset>
<fieldset>
<label>Choose a color</label>
<div id="swatches"></div>
</fieldset>
</div>
</div>
CSSはコントロール部分のスタイリングなので省略します。
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', // style URL for Mapbox Light
center: [12.338, 45.4385],
zoom: 18
});
load
イベントでレイヤーを一つ作っています。このレイヤーは川の中にいくつかある黒い三角形を表現しているレイヤーです。いつもはaddSource
で先にソースを登録していますが、ここではaddLayer
内で直接sourceを定義する方法を採用しています。
map.on('load', () => {
// Add a custom layer that uses
// a vector tileset source.
map.addLayer({
id: 'triangles',
source: {
type: 'vector',
url: 'mapbox://examples.ckv9z0wgf5v7c27p7me2mf0l9-9wrve' // custom tileset
},
'source-layer': 'triangles',
type: 'fill'
});
});
次はコントロール部分のコードです。
swatches
は"Choose a color"の下に表示されているdev
タグ(カラーパレット)の部分です。
const swatches = document.getElementById('swatches');
layer
は"Select layer"の下のselect
タグの部分です。
const layer = document.getElementById('layer');
dev
タグ(カラーパレット)に表示する色の定義です。
const colors = [
'#ffffcc',
'#a1dab4',
'#41b6c4',
'#2c7fb8',
'#253494',
'#fed976',
'#feb24c',
'#fd8d3c',
'#f03b20',
'#bd0026'
];
定義された色でループを回します。各色に対応したボタンを作成(document.createElement('button')
)し、そのボタンがクリックされたときの挙動(swatch.addEventListener('click',()=>{})
)を定義しています。このサンプルで最も大事なコードがこのクリックイベントの中で呼ばれているMap#setPaintProperty
です。このメソッドはレイヤーのPaintプロパティの値を動的に変更します。第一引数にレイヤーID、第二引数にプロパティ名、第三引数に値を設定します。ここでは第一引数はlayer.value
となっていますが、これはselect
タグで選択された値(water
, building
, triangles
)が格納されています。第二引数はfill-color
なのでポリゴンの塗りつぶしの色を指定してます。第三引数はcolor
なのでボタンの色がそのまま入ります。
for (const color of colors) {
const swatch = document.createElement('button');
swatch.style.backgroundColor = color;
swatch.addEventListener('click', () => {
map.setPaintProperty(layer.value, 'fill-color', color);
});
swatches.appendChild(swatch);
}
サンプルは長めでしたが本当に言いたいことはmap.setPaintProperty(layer.value, 'fill-color', color);
の一行でした。
まとめ
Map#setPaintProperty
を使うと動的にレイヤーのPaintプロパティを変更できることがわかりました。
Discussion