営業の枠から飛び出せ!
営業の枠から飛び出せ!
2019.04.22
#187
それいけ!フロントエンド

infobox.jsを使って、画像なしで連番のオリジナルマーカーを作ってみよう!

はっちゃん

こんにちは、フロントエンドエンジニアのはっちゃんです。

Google Maps APIをつかってオリジナルのマーカーを置くとき、連番にしたいことってありますよね? ですが、デフォルトの機能だと代替えの画像を置くことしかできないので、
連番のマーカー画像を作成するしかありません。

今回はそんな悩みを解決すべく、infobox.jsを使って数字部分に画像を使わないオリジナルマーカーを作成しようと思います。

準備するもの

Googlemapのinfowindowをカスタマイズする「infobox.js」

基本的な使い方については、以前別の記事で書いているので参考にしてください。

本稿のinfobox.jsの使い方は、吹き出しだけでなく、マーカーもオリジナルのDOMで作って、テキストも自由に置けるようにしてしまおうというものです。

機能を洗い出してみよう!

まずテキストで必要な機能をざっくり並べてみましょう。

  • googlemapのインスタンスを作成
  • infoboxを作成
    • ショップ情報を配列で用意
    • 配列をfor文で回す
      • マーカーのDOMを作成
      • 吹き出しのDOMを作成
      • マーカーを全て表示する
      • マーカーにクリックイベントを紐づける
  • 全infoboxを非表示にする関数を用意

あとはこれにそってコードをガンガン描いていくだけです!

HTML、CSS、JSコーディング

ではコーディングしていきましょう。

HTML

<div id="js-gmap" class="gmap" data-latitude="35.710260" data-longitude="139.757228" data-title="株式会社LIG"></div>
<script src="//maps.googleapis.com/maps/api/js?key={key名}"></script> <script src="https://82mou.github.io/infobox/lib/infobox.js"></script>

CSS

* {
  box-sizing: border-box;
}
.gmap {
	margin-top: 30px;
	height: 450px;
}
.gmap-info-window {
	position: relative;
	width: 250px;
	padding: 25px 30px;
	border: 2px solid #EC492C;
	background-color: #fff;
}
.gmap-info-window:before {
	display: inline-block;
	position: absolute;
	left: 50%;
	bottom: -10px;
	width: 20px;
	height: 10px;
	transform: translate(-50%, 0);
	background: url(https://82mou.github.io/infobox/img/gmap-info-window-frame-point.png) no-repeat 0 0;
	content: '';
}
.gmap-info-window-title {
	color: #EC492C;
	font-size: 16px;
	font-weight: bold;
	text-align: center;
}
.gmap-info-window-address {
	margin-top: 10px;
	font-size: 12px;
	font-weight: bold;
}
.infobox-marker {
  	width: 30px;
  	height: 30px;
  	padding: 4px 0 5px;
  	border-radius: 50%;
  	background-color: #fff;
  	border: 2px solid #F6411B;
  	text-align: center;
  	span {
		font-weight: bold;
		line-height: 1;
  	}
}

JS

const infobox = []; // 全てのinfoboxオブジェクトを格納する配列を用意する
const $map = document.querySelector('#js-gmap');
const latitude = $map.dataset['latitude']; // 緯度
const longitude = map.dataset['longitude'] // 経度
const title = $map.dataset['title']; // タイトル
const targetLatlng = new google.maps.LatLng(latitude, longitude);
const myOptions = {
  zoom: 15, // 拡大比率
  center: targetLatlng, // 表示枠内の中心点
  mapTypeId: google.maps.MapTypeId.ROADMAP // 表示タイプの指定
};
const map = new google.maps.Map($map, myOptions);

function hiddenAll() {
  for(let i = 0; i < infobox.length; i++) {
    infobox[i].close(map);
  }
}

function makeInfobox() {
  const obj = [
    {
      name: 'ショップ1',
      discription: 'ショップ1の説明',
      position: {
        lat: 35.710260,
        lng: 139.777228
      }
    },
    {
      name: 'ショップ2',
      discription: 'ショップ2の説明',
      position: {
        lat: 35.711260,
        lng: 139.767228
      }
    },
    {
      name: 'ショップ3',
      discription: 'ショップ3の説明',
      position: {
        lat: 35.712260,
        lng: 139.757228
      }
    },
    {
      name: 'ショップ4',
      discription: 'ショップ4の説明',
      position: {
        lat: 35.713260,
        lng: 139.747228
      }
    },
    {
      name: 'ショップ5',
      discription: 'ショップ5の説明',
      position: {
        lat: 35.714260,
        lng: 139.737228
      }
    }
  ];
  
  for(let i = 0; i < obj.length; i++) {
  
  // markerのDOMを生成
  let infoboxMarkerElem = `<div id="js-marker-${i + 1}" class="infobox-marker"><span>${i + 1}</span></div>`;
  
  // infobox用のDOMを生成
  let infoboxElem = `<div class="gmap-info-window-inner">
						<p class="gmap-info-window-title">${obj[i].name}</p>
						<p class="gmap-info-window-address">${obj[i].discription}</p>
					</div>`;
					
  let markerLatlng = new google.maps.LatLng(obj[i].position);
  
  // infoboxのオプション
  let infoMarkerOptions = {
  	content: infoboxMarkerElem,//生成したDOMを割り当てる
	pixelOffset: new google.maps.Size(0, 0), // オフセット値
	alignBottom: true, // 位置の基準
	position: markerLatlng, // 位置の座標
	boxClass: "gmap-info-window-marker", // 生成したDOMをラップするdivのclass名
	closeBoxURL: ''
  };
  
  // infoboxのオプション
  let infoboxOptions = {
   	content: infoboxElem, // 生成したDOMを割り当てる
	pixelOffset: new google.maps.Size(-110, -40), // オフセット値
	alignBottom: true, // 位置の基準
	position: markerLatlng,// 位置の座標
	boxClass: "gmap-info-window", // 生成したDOMをラップするdivのclass名
	closeBoxMargin: "-15px -20px 0px 0px", // 閉じるボタンの位置調整
	closeBoxURL: 'https://82mou.github.io/infobox/img/close.png' // 閉じるボタンの画像パス
 };
 
 // infoboxを生成して表示
 let infoboxMarker = new InfoBox(infoMarkerOptions);
 	infobox[i] = new InfoBox(infoboxOptions);
	
	// infoboxを表示
	infoboxMarker.open(map);
	
	// googlemapのタイルが表示されたら実行
	map.addListener('tilesloaded', () => {
		let $marker = document.querySelector(`#js-marker-${i + 1}`);
		
		// マーカーにイベントをバインド
		google.maps.event.addDomListener($marker, 'click', (event) => {
			hiddenAll(); infobox[i].open(map);
		});
	});
  }
}

$(window).on('load', function() {
 makeInfobox();
});

完成

See the Pen
Google Map Api Original Number Marker
by k_hatsushi (@hatsushi_kazuya)
on CodePen.

操作方法
マーカーをクリックしてみよう!

まとめ

いかがでしたか? マーカーに番号を振りたいときって多々あると思いますが、このやり方ってわりと知らない人多いんじゃないかな……と記事にまとめた次第です。これでGooglemapマスターへの道、一歩前進ですね! それではまた。

LIGにWeb制作について相談してみる