Controles

Selecione a plataforma: Android iOS JavaScript

Visão geral dos controles

Os mapas apresentados pela API Maps JavaScript contêm elementos da interface que permitem a interação do usuário com o mapa. Esses elementos são conhecidos como controles, e é possível incluir variações dos controles no seu aplicativo. Outra opção é não fazer nada e deixar que a API Maps JavaScript processe o comportamento de todos os controles.

Confira no mapa a seguir o conjunto padrão de controles mostrado pela API Maps JavaScript:

No sentido horário, a partir do canto superior esquerdo: Tipo de mapa, Tela cheia, Câmera, Street View, Atalhos do teclado.

Estes são todos os controles que você pode usar nos mapas:

  • OControle de tipo de mapa Está disponível em formato de menu suspenso ou barra de botões horizontal, permitindo ao usuário escolher um tipo de mapa (ROADMAP, SATELLITE, HYBRID, ouTERRAIN Este controle aparece por padrão no canto superior esquerdo do mapa.
  • Tela Inteira: oferece a opção de abrir o mapa no modo de tela cheia. Esse controle é ativado por padrão em computadores e dispositivos móveis. Nota: O iOS não suporta o recurso de tela cheia. Portanto, o controle em tela cheia não fica visível em dispositivos iOS.
  • O Controle da câmera possui controles de zoom e panorâmica.
  • Street View: contém um ícone do Pegman, que ativa o Street View quando é arrastado para o mapa. Por padrão, esse controle fica à direita, próximo à parte de baixo do mapa.
  • O controle Rotacionar oferece uma combinação de opções de inclinação e rotação para mapas que contêm imagens 3D. Por padrão, fica à direita, próximo à parte de baixo do mapa. Consulte Visão geral 3D para obter mais informações.
  • Escala: mostra um elemento para alterar a escala do mapa. Esse controle fica desativado por padrão.
  • Atalhos do teclado: mostra uma lista de atalhos de teclado para interação com o mapa.

Não é possível acessar ou modificar diretamente esses controles do mapa. Você precisa modificar os campos MapOptions dele, que afetam a visibilidade e a apresentação dos controles. Ajuste a apresentação dos controles criando uma instância do mapa (com as MapOptions apropriadas) ou modifique o mapa de forma dinâmica chamando setOptions() para alterar as opções dele.

Nem todos esses controles são ativados por padrão. Para saber mais sobre o comportamento padrão da interface (e como fazer alterações), consulte a seção A interface padrão abaixo.

A interface padrão

Por padrão, todos os controles desaparecem quando o mapa é muito pequeno (200 x 200 px). Para substituir esse comportamento, defina explicitamente o controle como visível. Consulte Adicionar controles ao mapa.

O comportamento e o visual dos controles é o mesmo em dispositivos móveis e em computadores, exceto pelo controle de tela inteira (confira as descrições nesta lista).

Além disso, o processamento do teclado é ativado por padrão em todos os dispositivos.

Desativar a interface padrão

Se você quiser desativar completamente os botões de interface padrão da API, defina a propriedade disableDefaultUI do mapa (no objeto MapOptions) como true. Ela desativa os botões de controle de interface da API Maps JavaScript. No entanto, ela não afeta o mouse nem os atalhos de teclado no mapa base, que são controlados pelas propriedades gestureHandling e keyboardShortcuts, respectivamente.

O código a seguir desativa os botões da interface:

TypeScript

innerMap.setOptions({
    // Disable the default UI.
    disableDefaultUI: true,
});

JavaScript

innerMap.setOptions({
    // Disable the default UI.
    disableDefaultUI: true,
});
Exemplo

Testar amostra

Adicionar controles ao mapa

Personalize a interface removendo, adicionando ou modificando o comportamento ou os controles da interface e não permita que as atualizações futuras alterem esse comportamento. Para adicionar ou modificar um comportamento atual, verifique se o controle foi adicionado explicitamente ao seu aplicativo.

Alguns controles aparecem no mapa por padrão, outros, apenas quando especificamente solicitados. Os campos a seguir do objeto MapOptions definem a adição ou remoção de controles do mapa. Use true para tornar visíveis e false para ocultar os controles.

{
  cameraControl: boolean,
  mapTypeControl: boolean,
  scaleControl: boolean,
  streetViewControl: boolean,
  rotateControl: boolean,
  fullscreenControl: boolean
}

Por padrão, todos os controles desaparecem quando o mapa é menor que 200 x 200 px. Para substituir esse comportamento, defina explicitamente o controle como visível. Por exemplo, a tabela a seguir mostra se o controle de câmera fica visível ou não com base no tamanho do mapa e no campo cameraControl:

Tamanho do mapa cameraControl Visível?
Qualquer um false Não
Qualquer um true Sim
>= 200 x 200 px undefined Sim
< 200 x 200 px undefined Não

No exemplo a seguir, a configuração do mapa oculta o controle de câmera e mostra o de escala. Não desativamos a interface padrão de forma explícita, então essas modificações são adicionadas ao comportamento padrão da interface.

TypeScript

innerMap.setOptions({
    cameraControl: false,
    scaleControl: true,
});

JavaScript

innerMap.setOptions({
    cameraControl: false,
    scaleControl: true,
});
Exemplo

Testar amostra

Opções dos controles

É possível configurar vários controles, o que permite alterar o comportamento e a aparência deles. O Tipo de mapa, por exemplo, pode aparecer como uma barra horizontal ou um menu suspenso.

Para modificar esses controles, altere os campos apropriados das opções de controle no objeto MapOptions ao criar o mapa.

Por exemplo, o campo mapTypeControlOptions indica como alterar o "Tipo de mapa", que pode aparecer em uma das seguintes opções de style:

  • google.maps.MapTypeControlStyle.HORIZONTAL_BAR mostra a matriz de controles como botões em uma barra horizontal, igual à do Google Maps.
  • google.maps.MapTypeControlStyle.DROPDOWN_MENU mostra um controle de botão único para selecionar o tipo de mapa em um menu suspenso.
  • google.maps.MapTypeControlStyle.DEFAULT mostra o comportamento padrão, que depende do tamanho da tela e pode mudar em futuras versões da API.

Se você modificar alguma opção, ative também o controle de forma explícita, definindo o valor de MapOptions apropriado como true. Por exemplo, para que um controle "Tipo de mapa" tenha o estilo DROPDOWN_MENU, use o código a seguir no objeto MapOptions:

  ...
  mapTypeControl: true,
  mapTypeControlOptions: {
    style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
  }
  ...

Este exemplo demonstra como mudar a posição e o estilo padrão dos controles.

TypeScript

innerMap.setOptions({
    mapTypeControl: true,
    mapTypeControlOptions: {
        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
        mapTypeIds: [
            google.maps.MapTypeId.ROADMAP,
            google.maps.MapTypeId.TERRAIN,
        ],
        position: google.maps.ControlPosition.TOP_CENTER,
    },
});

JavaScript

innerMap.setOptions({
    mapTypeControl: true,
    mapTypeControlOptions: {
        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
        mapTypeIds: [
            google.maps.MapTypeId.ROADMAP,
            google.maps.MapTypeId.TERRAIN,
        ],
        position: google.maps.ControlPosition.TOP_CENTER,
    },
});
Exemplo

Testar amostra

Normalmente, os controles são configurados na criação do mapa, mas é possível alterar a apresentação deles de forma dinâmica chamando o método setOptions() do Map, transmitindo novas opções de controle.

Modificar controles

Você especifica uma apresentação do controle quando cria o mapa, usando os campos do objeto MapOptions, que são descritos abaixo:

  • cameraControl ativa/desativa o controle da câmera que permite ao usuário aplicar zoom e movimentar o mapa. Esse controle fica visível por padrão em todos os mapas. O campo cameraControlOptions também especifica o CameraControlOptions a ser usado nesse controle.
  • mapTypeControl ativa/desativa o controle "Tipo de mapa" usado para alternar entre tipos (como Mapa e Satélite). Por padrão, esse controle fica visível no canto superior esquerdo do mapa. O campo mapTypeControlOptions também especifica o MapTypeControlOptions a ser usado nele.
  • streetViewControl ativa/desativa o controle "Pegman", usado para ativar um panorama do Street View. Por padrão, esse controle fica visível à direita, próximo à parte de baixo do mapa. OstreetViewControlOptions O campo especifica adicionalmente oStreetViewControlOptions para usar neste controle.
  • rotateControl ativa/desativa a exibição de um controle de rotação para controlar a orientação de imagens 3D. Por padrão, a presença do controle é determinada pela presença ou ausência de imagens 3D para o tipo de mapa especificado, no nível de zoom e localização atuais. Você pode alterar o comportamento do controle definindo o mapa.rotateControlOptions para especificar oRotateControlOptions para usar. O controle só aparecerá em mapas base 3D.
  • scaleControl ativa/desativa o controle de escala que fornece uma escala para o mapa. Por padrão, esse controle não fica visível. Quando ativo, ele aparece no canto inferior direito do mapa. OscaleControlOptions especifica ainda oScaleControlOptions para usar neste controle.
  • fullscreenControl ativa/desativa o controle que abre o mapa no modo de tela inteira. Por padrão, esse controle é ativado em computadores e dispositivos Android. Quando ativo, ele fica à direita, perto da parte de cima do mapa. OfullscreenControlOptions especifica ainda oFullscreenControlOptions para usar neste controle.

É possível especificar opções para controles inicialmente desativados.

Posicionamento dos controles

A maioria das opções contém uma propriedade position (do tipo ControlPosition). Ela indica o posicionamento dos controles no mapa, que não é fixo. Na verdade, eles são posicionados pela API de forma inteligente, em torno de elementos ou outros controles, de acordo com as restrições informadas (como o tamanho do mapa).

Existem dois tipos de posições de controle: legadas e lógicas. Recomenda-se o uso de valores lógicos para poder suportar automaticamente contextos de layout da esquerda para a direita (LTR) e da direita para a esquerda (RTL). Consulte o guia de referência.

As tabelas a seguir mostram as posições de controle suportadas nos contextos LTR e RTL.

Posições LTR

Posição (contexto LTR) Constante lógica (recomendado) Constante legada
Canto superior esquerdo BLOCK_START_INLINE_START TOP_LEFT
Parte central superior BLOCK_START_INLINE_CENTER TOP_CENTER
Canto superior direito BLOCK_START_INLINE_END TOP_RIGHT
Canto superior esquerdo INLINE_START_BLOCK_START LEFT_TOP
Parte central esquerda INLINE_START_BLOCK_CENTER LEFT_CENTER
Canto inferior esquerdo INLINE_START_BLOCK_END LEFT_BOTTOM
Canto superior direito INLINE_END_BLOCK_START RIGHT_TOP
Central direita INLINE_END_BLOCK_CENTER RIGHT_CENTER
Canto inferior direito INLINE_END_BLOCK_END RIGHT_BOTTOM
Canto inferior esquerdo BLOCK_END_INLINE_START BOTTOM_LEFT
Parte central inferior BLOCK_END_INLINE_CENTER BOTTOM_CENTER
Canto inferior direito BLOCK_END_INLINE_END BOTTOM_RIGHT

Posições RTL

Posição (contexto RTL) Constante lógica (recomendado) Constante legada
Canto superior direito BLOCK_START_INLINE_START TOP_RIGHT
Parte central superior BLOCK_START_INLINE_CENTER TOP_CENTER
Canto superior esquerdo BLOCK_START_INLINE_END TOP_LEFT
Canto superior direito INLINE_START_BLOCK_START RIGHT_TOP
Central direita INLINE_START_BLOCK_CENTER RIGHT_CENTER
Canto inferior direito INLINE_START_BLOCK_END RIGHT_BOTTOM
Canto superior esquerdo INLINE_END_BLOCK_START LEFT_TOP
Parte central esquerda INLINE_END_BLOCK_CENTER LEFT_CENTER
Canto inferior esquerdo INLINE_END_BLOCK_END LEFT_BOTTOM
Canto inferior direito BLOCK_END_INLINE_START BOTTOM_RIGHT
Parte central inferior BLOCK_END_INLINE_CENTER BOTTOM_CENTER
Canto inferior esquerdo BLOCK_END_INLINE_END BOTTOM_LEFT

Clique nos rótulos para alternar o mapa entre os modos LTR e RTL.

É possível que essas posições coincidam com as de elementos da interface que não podem ser modificadas (como direitos autorais e o logotipo do Google). Nesses casos, os controles fluem de acordo com a lógica descrita para cada posição e são mostrados o mais próximo possível da posição indicada. Embora a API tente organizar os controles de modo inteligente, não é possível garantir que eles não se sobreponham em layouts complexos.

O exemplo a seguir mostra um mapa básico com todos os controles ativados em posições diferentes.

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 12,
      center: { lat: -28.643387, lng: 153.612224 },
      mapTypeControl: true,
      mapTypeControlOptions: {
        style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
        position: google.maps.ControlPosition.TOP_CENTER,
      },
      zoomControl: true,
      zoomControlOptions: {
        position: google.maps.ControlPosition.LEFT_CENTER,
      },
      scaleControl: true,
      streetViewControl: true,
      streetViewControlOptions: {
        position: google.maps.ControlPosition.LEFT_TOP,
      },
      fullscreenControl: true,
    }
  );
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 12,
    center: { lat: -28.643387, lng: 153.612224 },
    mapTypeControl: true,
    mapTypeControlOptions: {
      style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
      position: google.maps.ControlPosition.TOP_CENTER,
    },
    zoomControl: true,
    zoomControlOptions: {
      position: google.maps.ControlPosition.LEFT_CENTER,
    },
    scaleControl: true,
    streetViewControl: true,
    streetViewControlOptions: {
      position: google.maps.ControlPosition.LEFT_TOP,
    },
    fullscreenControl: true,
  });
}

window.initMap = initMap;
Exemplo

Testar amostra

Controles personalizados

Além de modificar o estilo e a posição dos controles de API, você pode criar os seus para processar a interação com o usuário. Controles são widgets estáticos que flutuam sobre um mapa em posições fixas, diferente das sobreposições, que se movem com o mapa. Basicamente, um controle é um elemento <div> que tem uma posição fixa no mapa, mostra IUs e processa interações com o usuário ou o mapa, em geral, usando um manipulador de eventos.

É necessário seguir algumas regras para criar seu próprio controle personalizado. No entanto, as diretrizes abaixo podem servir como práticas recomendadas:

  • Defina um CSS adequado para os elementos de controle mostrarem.
  • Use manipuladores de eventos para processar a interação com o usuário ou o mapa em mudanças de propriedade ou eventos do usuário, por exemplo, 'click'.
  • Crie um elemento <div> para o controle e adicione à propriedade controls do Map.

Todas essas questões são discutidas abaixo.

Desenhar controles personalizados

Você decide como desenhar seu controle. Recomendamos que coloque toda a apresentação do controle em um só elemento <div> para que ele possa ser manipulado como uma única unidade. Nos exemplos mostrados a seguir, usamos esse padrão.

Criar controles atraentes exige algum conhecimento da estrutura de CSS e DOM. Os exemplos de código a seguir mostram como adicionar um controle personalizado usando HTML declarativo e métodos programáticos.

CSS declarativo

Os estilos CSS a seguir fornecem uma aparência consistente com os controles padrão. Use esses estilos com os dois exemplos abaixo:

.streetview-toggle-button {
  align-items: center;
  background: white;
  border: none;
  border-radius: 2px;
  box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3);
  color: rgb(86, 86, 86);
  cursor: pointer;
  display: flex;
  font-family: Roboto, Arial, sans-serif;
  font-size: 18px;
  font-weight: 400;
  height: 40px;
  justify-content: center;
  margin: 10px 0;
  padding: 0 17px;
}

.streetview-toggle-button:hover {
  background: #f4f4f4;
  color: #000;
}

HTML declarativo

Estes snippets de código mostram como criar um controle personalizado de forma declarativa. No HTML, uma DIV com o ID container é usada para posicionar o controle. Ela está aninhada no elemento gmp-map, e o botão é adicionado à DIV. O atributo slot é definido como control-inline-start-block-start para posicionar o controle no canto superior esquerdo do mapa.

<gmp-map
  center="41.027748173921374, -92.41852445367961"
  zoom="13"
  map-id="DEMO_MAP_ID">
  <div id="container" slot="control-inline-start-block-start">
    <input type="button"
    id="streetview-toggle-button"
    class="button"
    value="Click this button" />
  </div>
</gmp-map>

No JavaScript, getElementById() é usado para encontrar a DIV e o botão. Um listener de eventos é adicionado ao botão, que é anexado à DIV.

// Create a DIV to attach the control UI to the Map.
const container = document.getElementById("container");

// Get the control button from the HTML page.
const controlButton = document.getElementById("streetview-toggle-button");

// Add a click event listener.
controlButton.addEventListener("click", () => {
  window.alert("You clicked the button!");
});

// Add the control to the DIV.
container.append(controlButton);

JavaScript programático

Este snippet de código demonstra como criar um controle de botão de maneira programática. Os estilos CSS são definidos acima.

// Create a DIV to attach the control UI to the Map.
const container = document.getElementById("container");

// Position the control in the top left corner of the map.
container.slot = "control-block-start-inline-start";

// Create the control.
const controlButton = document.createElement("button");
controlButton.classList.add("streetview-toggle-button");
controlButton.textContent = "Click this button";
controlButton.type = "button";

// Add a click event listener.
controlButton.addEventListener("click", () => {
  window.alert("You clicked the button!");
});

// Add the control to the DIV.
container.append(controlButton);

Processar eventos de controles personalizados

Para ser útil, o controle precisa fazer alguma coisa, e é você quem decide o quê. Ele pode responder a entradas do usuário ou a mudanças no estado do Map.

Para responder à entrada do usuário, use addEventListener(), que processa eventos DOM compatíveis. O snippet de código a seguir adiciona um listener ao evento 'click' do navegador. Esse evento é recebido do DOM e não do mapa.

// Setup the click event listener: set the map to center on Chicago
var chicago = {lat: 41.850, lng: -87.650};

controlButton.addEventListener('click', () => {
  map.setCenter(chicago);
});

Tornar controles personalizados acessíveis

Para garantir que os controles recebam eventos de teclado e apareçam corretamente nos leitores de tela:

  • Sempre use elementos HTML nativos para botões, itens de formulários e rótulos. Use elementos DIV apenas como contêiner para controles nativos. Nunca reutilize um DIV como um elemento interativo da interface.
  • Use o elemento label, o atributo title ou o atributo aria-label, quando apropriado, para disponibilizar informações sobre um elemento da interface.

Posicionar controles personalizados

Use o atributo slot para posicionar controles personalizados, especificando a posição necessária. Consulte mais informações sobre o assunto em Posicionamento dos controles.

Cada ControlPosition armazena um MVCArray dos controles mostrados na posição. Como resultado, a API atualiza os controles quando são adicionados ou removidos da posição.

O código a seguir cria um novo controle personalizado (o construtor não é mostrado) e o adiciona ao mapa na posição BLOCK_START_INLINE_END (canto superior direito no contexto LTR).

// Create a DIV to attach the control UI to the Map.
const centerControlDiv = document.createElement("div");

// Create the control. This code calls a function that
// creates a new instance of a button control.
const centerControl = createCenterControl(map);

// Append the control to the DIV.
centerControlDiv.appendChild(centerControl);

// Push the control to the BLOCK_START_INLINE_END position.
innerMap.controls[google.maps.ControlPosition.BLOCK_START_INLINE_END].push(centerControlDiv);

Para definir a posição de um controle personalizado de forma declarativa, defina o atributo slot no HTML:

<gmp-map center="30.72851568848909, -81.54675994068873" zoom="12">
  <div slot="control-block-start-inline-end">
    <!-- Control HTML -->
  </div>
</gmp-map>

Exemplo de controle personalizado

O controle a seguir é simples (embora não muito útil) e combina os padrões mostrados acima. Ele responde a eventos DOM 'click' centralizando o mapa em um determinado local padrão:

TypeScript

let map: google.maps.Map;

const chicago = { lat: 41.85, lng: -87.65 };

/**
 * Creates a control that recenters the map on Chicago.
 */
 function createCenterControl(map) {
  const controlButton = document.createElement('button');

  // Set CSS for the control.
  controlButton.style.backgroundColor = '#fff';
  controlButton.style.border = '2px solid #fff';
  controlButton.style.borderRadius = '3px';
  controlButton.style.boxShadow = '0 2px 6px rgba(0,0,0,.3)';
  controlButton.style.color = 'rgb(25,25,25)';
  controlButton.style.cursor = 'pointer';
  controlButton.style.fontFamily = 'Roboto,Arial,sans-serif';
  controlButton.style.fontSize = '16px';
  controlButton.style.lineHeight = '38px';
  controlButton.style.margin = '8px 0 22px';
  controlButton.style.padding = '0 5px';
  controlButton.style.textAlign = 'center';

  controlButton.textContent = 'Center Map';
  controlButton.title = 'Click to recenter the map';
  controlButton.type = 'button';

  // Setup the click event listeners: simply set the map to Chicago.
  controlButton.addEventListener('click', () => {
    map.setCenter(chicago);
  });

  return controlButton;
}

function initMap() {
  map = new google.maps.Map(document.getElementById('map') as HTMLElement, {
    zoom: 12,
    center: chicago,
  });

  // Create the DIV to hold the control.
  const centerControlDiv = document.createElement('div');
  // Create the control.
  const centerControl = createCenterControl(map);
  // Append the control to the DIV.
  centerControlDiv.appendChild(centerControl);

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(centerControlDiv);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

let map;
const chicago = { lat: 41.85, lng: -87.65 };

/**
 * Creates a control that recenters the map on Chicago.
 */
function createCenterControl(map) {
  const controlButton = document.createElement("button");

  // Set CSS for the control.
  controlButton.style.backgroundColor = "#fff";
  controlButton.style.border = "2px solid #fff";
  controlButton.style.borderRadius = "3px";
  controlButton.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)";
  controlButton.style.color = "rgb(25,25,25)";
  controlButton.style.cursor = "pointer";
  controlButton.style.fontFamily = "Roboto,Arial,sans-serif";
  controlButton.style.fontSize = "16px";
  controlButton.style.lineHeight = "38px";
  controlButton.style.margin = "8px 0 22px";
  controlButton.style.padding = "0 5px";
  controlButton.style.textAlign = "center";
  controlButton.textContent = "Center Map";
  controlButton.title = "Click to recenter the map";
  controlButton.type = "button";
  // Setup the click event listeners: simply set the map to Chicago.
  controlButton.addEventListener("click", () => {
    map.setCenter(chicago);
  });
  return controlButton;
}

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 12,
    center: chicago,
  });

  // Create the DIV to hold the control.
  const centerControlDiv = document.createElement("div");
  // Create the control.
  const centerControl = createCenterControl(map);

  // Append the control to the DIV.
  centerControlDiv.appendChild(centerControl);
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(centerControlDiv);
}

window.initMap = initMap;
Exemplo

Testar amostra

Adicionar estado aos controles

Os controles também podem armazenar estado. O exemplo a seguir é semelhante ao mostrado anteriormente, mas o controle tem um outro botão "Definir casa" que configura uma nova localização de casa a ser exibida. Para isso, criamos uma propriedade home_ no controle para armazenar esse estado e fornecer getters e setters a ele.

TypeScript

let map: google.maps.Map;

const chicago: google.maps.LatLngLiteral = { lat: 41.85, lng: -87.65 };

/**
 * The CenterControl adds a control to the map that recenters the map on
 * Chicago.
 */
class CenterControl {
  private map_: google.maps.Map;
  private center_: google.maps.LatLng;
  constructor(
    controlDiv: HTMLElement,
    map: google.maps.Map,
    center: google.maps.LatLngLiteral
  ) {
    this.map_ = map;
    // Set the center property upon construction
    this.center_ = new google.maps.LatLng(center);
    controlDiv.style.clear = "both";

    // Set CSS for the control border
    const goCenterUI = document.createElement("button");

    goCenterUI.id = "goCenterUI";
    goCenterUI.title = "Click to recenter the map";
    controlDiv.appendChild(goCenterUI);

    // Set CSS for the control interior
    const goCenterText = document.createElement("div");

    goCenterText.id = "goCenterText";
    goCenterText.innerHTML = "Center Map";
    goCenterUI.appendChild(goCenterText);

    // Set CSS for the setCenter control border
    const setCenterUI = document.createElement("button");

    setCenterUI.id = "setCenterUI";
    setCenterUI.title = "Click to change the center of the map";
    controlDiv.appendChild(setCenterUI);

    // Set CSS for the control interior
    const setCenterText = document.createElement("div");

    setCenterText.id = "setCenterText";
    setCenterText.innerHTML = "Set Center";
    setCenterUI.appendChild(setCenterText);

    // Set up the click event listener for 'Center Map': Set the center of
    // the map
    // to the current center of the control.
    goCenterUI.addEventListener("click", () => {
      const currentCenter = this.center_;

      this.map_.setCenter(currentCenter);
    });

    // Set up the click event listener for 'Set Center': Set the center of
    // the control to the current center of the map.
    setCenterUI.addEventListener("click", () => {
      const newCenter = this.map_.getCenter()!;

      if (newCenter) {
        this.center_ = newCenter;
      }
    });
  }
}

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    zoom: 12,
    center: chicago,
  });

  // Create the DIV to hold the control and call the CenterControl()
  // constructor passing in this DIV.
  const centerControlDiv = document.createElement("div");
  const control = new CenterControl(centerControlDiv, map, chicago);

  // @ts-ignore
  centerControlDiv.index = 1;
  centerControlDiv.style.paddingTop = "10px";
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(centerControlDiv);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

let map;
const chicago = { lat: 41.85, lng: -87.65 };

/**
 * The CenterControl adds a control to the map that recenters the map on
 * Chicago.
 */
class CenterControl {
  map_;
  center_;
  constructor(controlDiv, map, center) {
    this.map_ = map;
    // Set the center property upon construction
    this.center_ = new google.maps.LatLng(center);
    controlDiv.style.clear = "both";

    // Set CSS for the control border
    const goCenterUI = document.createElement("button");

    goCenterUI.id = "goCenterUI";
    goCenterUI.title = "Click to recenter the map";
    controlDiv.appendChild(goCenterUI);

    // Set CSS for the control interior
    const goCenterText = document.createElement("div");

    goCenterText.id = "goCenterText";
    goCenterText.innerHTML = "Center Map";
    goCenterUI.appendChild(goCenterText);

    // Set CSS for the setCenter control border
    const setCenterUI = document.createElement("button");

    setCenterUI.id = "setCenterUI";
    setCenterUI.title = "Click to change the center of the map";
    controlDiv.appendChild(setCenterUI);

    // Set CSS for the control interior
    const setCenterText = document.createElement("div");

    setCenterText.id = "setCenterText";
    setCenterText.innerHTML = "Set Center";
    setCenterUI.appendChild(setCenterText);
    // Set up the click event listener for 'Center Map': Set the center of
    // the map
    // to the current center of the control.
    goCenterUI.addEventListener("click", () => {
      const currentCenter = this.center_;

      this.map_.setCenter(currentCenter);
    });
    // Set up the click event listener for 'Set Center': Set the center of
    // the control to the current center of the map.
    setCenterUI.addEventListener("click", () => {
      const newCenter = this.map_.getCenter();

      if (newCenter) {
        this.center_ = newCenter;
      }
    });
  }
}

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 12,
    center: chicago,
  });

  // Create the DIV to hold the control and call the CenterControl()
  // constructor passing in this DIV.
  const centerControlDiv = document.createElement("div");
  const control = new CenterControl(centerControlDiv, map, chicago);

  // @ts-ignore
  centerControlDiv.index = 1;
  centerControlDiv.style.paddingTop = "10px";
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(centerControlDiv);
}

window.initMap = initMap;
Exemplo

Testar amostra

JSFiddle.net (link em inglês) Google Cloud Shell