かもメモ

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

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 っぽい感じに集約されていってる感がありました。


[参考]

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

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

Webpack .env から変数を取り込んで HTML に渡して使いたい。

API KEY が必要な script タグを HTML に書く必要があって API KEY を直接書いたファイルを git にコミットしたくないので、gitignore した .env に変数として持たせて HTML に渡す方法のメモ

JavaScript.env を使う

loadenv を使うと .env ファイルをオブジェクトとして読み込めるようです

.env ファイルを作成して使いたい変数を作る

$ touch .env

.env

API_KEY="API KEY"

.env ファイルをコミットしないように .gitignore に追加

.DS_Store
/node_modules
.env
!.gitkeep

loadenv のインストール

$ yarn add -D loadenv

webpack での config 内で .env を使う

// webpack.config.js
const loadenv = require('node-env-file');

function getENV() {
  const { API_KEY } = loadenv('./.env');
  return {
    API_KEY,
  };
}

HTML に変数を渡すために pug を使う

webpack で HTML に変数を埋め込む方法が分からなかったので、JavaScript が使える pug を噛ませて HTML を出力することにしました。

pug で HTML を出力する

必要なパッケージのインストール

$ yarn add -D pug pug-loader html-webpack-plugin

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// 中略

module.exports = (env, argv) => {
  const htmlTemplate = path.join('./src/index.pug');
  return {
    // 略
    module: {
      rules: [
        {
          test: /\.pug$/,
          use: {
            loader: 'pug-loader',
          },
        }
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: htmlTemplate,
      })
    ],
  };
}

pug に変数を渡す

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const loadenv = require('node-env-file');


function getENV() {
  const { API_KEY } = loadenv('./.env');
  return {
    API_KEY,
  };
}

module.exports = (env, argv) => {
  const htmlTemplate = path.join('./src/index.pug');
  const ENV = getENV();

  return {
    // 略
    module: {
      rules: [
        {
          test: /\.pug$/,
          use: {
            loader: 'pug-loader',
+           options: {
+             self: true,
+           }
          },
        }
      ],
    },
    plugins: [
      new HtmlWebpackPlugin({
        template: htmlTemplate,
+       data: ENV,
      })
    ],
  };
}

pug で 渡された変数を使う

HtmlWebpackPlugin の data で渡される値は pug 内で self.htmlWebpackPlugin.options.data という形で取得できる。
.env ファイルにある API_KEY="API KEY" は次のような形で取得することができる。

- const API_KEY = self.htmlWebpackPlugin.options.data.API_KEY
html
  body
    script(src=`example.com/api?key=${API_KEY}`)
所感

pug 使わなくても webpack の output.publicPath みたいなオプションで .env から取った変数で変換できそうな気がする。できないものだろうか?


[参考]

森永製菓 inタブレット塩分プラス 80g×6袋

森永製菓 inタブレット塩分プラス 80g×6袋

  • 発売日: 2018/03/20
  • メディア: 食品&飲料
塩分…

ディレクトリ削除する npm script のメモ

build したディレクトリを削除したいとか

rm -rf コマンドを npm script で呼ぶ

# package.json
"scripts": {
  "cleanup": "rm -rf build"
}

rimraf を使う

rm コマンドがない環境だと上記は使えないので

$ npm install --save-dev rimraf
# package.json
"scripts": {
  "cleanup": "rimraf build"
}

おしまい


[参考]

推し武道よい