【Google Maps API】マーカーのドラッグ移動範囲を制限する裏技(透明マーカーの活用)

投稿者: | 2026-04-19

先日、Googleマップ上でPowerPointのように図形を変形・回転できるエリアエディタを公開しました。
実はこのコンポーネントを実装する中で、地味に苦労した(そして工夫した)のが、「マーカーのドラッグ移動範囲の制限」です。

Google Maps JavaScript APIでカスタムUIを作ろうとしたことがある方なら直面する問題かと思いますが、備忘録も兼ねてその解決手法(ハック)を紹介します。

標準APIの「ドラッグ機能」が抱える課題

図形をリサイズするためのアンカー(四隅の丸印)や、回転させるためのハンドルを実装する際、当然ユーザーにはそれらをマウスでドラッグして操作してもらいます。

最新の AdvancedMarkerElement では gmpDraggable: true を設定するだけで簡単にマーカーをドラッグ可能にできます。しかし、ここに大きな問題があります。標準機能では、マーカーが地図上のどこへでも自由に移動できてしまうのです。

図形の辺を伸縮させるアンカーは「特定の直線上」だけを動いてほしいですし、回転ハンドルは「特定の円周上」を動くように制限されなければ、画面上のUIとして破綻してしまいます。

解決策:見た目のマーカーと、操作用の透明マーカーを分離する

「ドラッグ中の座標を強制的に上書きして固定する」といった処理を単一のマーカーで行おうとすると、マウスカーソルの位置とマーカーの実際の描画位置がズレてしまい、イベントの挙動が非常に不安定になります。

そこで辿り着いたのが、「実際の見た目を担当するマーカー」の上に、「ドラッグイベントを受け取るための透明なマーカー」を重ねて配置するという手法です。

実装のイメージ

役割を完全に分離することで、複雑な拘束条件付きのドラッグを滑らかに実現します。

  • 描画用マーカー: ドラッグ不可(gmpDraggable: false)。常に「計算上の正しい位置」にプログラムから配置される。
  • 操作用(透明)マーカー: ドラッグ可能。CSSで opacity: 0 にして隠しておく。ユーザーはこれを自由にドラッグする。

実際のコード例

Vanilla JSで実装した場合のコアとなるロジックの抜粋(イメージ)です。
(実際はもう少し色々と小細工しています。)

// 1. 実際の見た目を担当するマーカー(ドラッグ不可)
const visibleMarker = new google.maps.marker.AdvancedMarkerElement({
    map: map,
    content: createMarkerSvg(), // 表示したいSVG等の要素
    gmpClickable: false,        // クリックイベントも不要
    zIndex: 200,
});

// 2. ドラッグ操作を受け付ける透明なマーカー(ドラッグ可能)
const draggableMarker = new google.maps.marker.AdvancedMarkerElement({
    map: map,
    content: createDraggableContent(12), // 当たり判定用のdiv要素など
    gmpDraggable: true,
    zIndex: 201, // 描画マーカーより上に配置
});
// 透明にして画面から隠す
draggableMarker.style.opacity = "0";

// 3. ドラッグイベントの監視と座標補正
draggableMarker.addListener("drag", (event) => {
    // ユーザーがドラッグしている生の座標を取得
    const rawLatLng = event.latLng;

    // 独自のベクトル計算などで、移動可能な直線・円周上の座標に補正する
    const correctedLatLng = calculateRestrictedPosition(rawLatLng);

    // 描画用のマーカーを、補正された「正しい位置」に移動させる
    visibleMarker.position = correctedLatLng;

    // ※必要に応じて、図形(Polygon)自体の再描画もここで行う
});

まとめ

この「透明マーカーによるハック」を使うことで、Google Maps APIの標準機能では難しい「自由度を制限したリッチなUI操作」が可能になります。

最近はReactなどのフレームワークで状態管理を隠蔽してしまうことが多いですが、こういったVanilla JSでの泥臭いDOM / APIハックは、応用が効くので知っておくと非常に便利です。

このロジックを組み込んだ実際のエリアエディタの全ソースコードは、GitHub (google-maps-area-editor) で公開していますので、数学的なベクトル計算(math.js)等と合わせて興味がある方は覗いてみてください。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。