かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

Google map Maps JavaScript API 画像のカスタムマーカーを retina 対応 (2x) したい

Maps JavaScript API を使って google map を作成していて、オリジナルの Marker (ピン) を作成していました。
SVG 画像を使えれば問題がなかったのですが、諸事情で png で Marker を作成することになったのですが、retina ディスプレイだと荒くなってしまうから 2x の画像にしたいという要望があり対応してみたので備忘録として

画像の Marker を作成

画像の Marker をマップに加える場合は次のような感じで icon に画像のパスを渡せばOK

const MARKER_POSITION = {
  lat: xx.xxxx,
  lng: xx.xxxx,
};
const MARKER_IMAGE = '/path/to/marker-image@2x.png';

function initMap() {
  const map = google.maps.Map(document.getElementById(MAP_DIV_ID), {
    center: MAP_POSITION,
    zoom: ZOOM,
    // スクロールで自動 zoom させない設定
    gestureHandling: 'cooperative',
  });

  const marker = new google.maps.Marker({
    position: MARKER_POSITION,
    title: 'MY MARKER TITLE',
    icon: MARKER_IMAGE,
    map: map,
  });
}

// webpack する場合は window のプロパティにしておくと global から呼び出せる
window.initMap = initMap;

この方法は指定した、画像のサイズのまま Marker として表示されます。
SVG の場合は width, height 属性がないと大きなサイズで表示されてしまうので注意!

2x な状態で表示するには、次のいずれかの方法が実現できれば可能そうです。

  1. srcset 属性で 2x の設定を行う
  2. <img> タグに width, height を設定する
  3. CSSのクラス名を付けるなどして、CSSwidth, height を指定する

scaledSize: new google.maps.Size(25, 25) パラメーターを使う

API ドキュメントを見ていても srcsetCSS のクラスを設定することはできなそうでした。(可能ならこれがシンプルで良かったのですが…)
代わりに icon にオブジェクトを渡して Marker を指定する方法があり、その中に表示するサイズを指定できる scaledSize というプロパティがありました。

Icon interface

  • scaledSize (Type: Point): The size of the entire image after scaling, if any. Use this property to stretch/shrink an image or a sprite.
  • url (Type: string): The URL of the image or sprite sheet.

cf. Marker  |  Maps JavaScript API  |  Google Developers

2倍サイズの画像を url で指定して scaledSize に半分のサイズを指定すればOK

function initMap() {
  const map = google.maps.Map(document.getElementById(MAP_DIV_ID), {
    // map settings
  });

  const marker = new google.maps.Marker({
    position: MARKER_POSITION,
    title: 'MY MARKER TITLE',
    icon: {
      url: MARKER_IMAGE,
      scaledSize: new google.maps.Size(width, height),
    },
    map: map,
  });
}

これで map を表示させると Marker の imgタグに style 属性で scaledSize で指定した widthheight が設定されており、常にではありますが 2x な画像の Marker (ピン) を表示させることができました!SVG uploadして使わせてくれ…

また久しぶりに Google map のカスタマイズを行ったのですが、localjost でも API Key が必要になっていてデザインを始めるまでに少し戸惑ってしまいました。
なんとなく、AWS っぽい感じに集約されていってる感がありました。


[参考]

土曜日はアイカツ!をみて幸せになろう!!

世界平和のためにも外出せずに見放題になっているアイカツ!を見よう!!!!