5 formas de personalizar a InfoWindow Google Maps A InfoWindow padrão do Google Maps pode ser personalizada com estes 5 passos de fácil implementação. Por um lado, uma infowindow personalizada oferece um aspecto diferenciado aos nossos mapas. Por outro lado, pode e deve ser adequada ao aspecto geral do web site.

5 formas de personalizar a InfoWindow Google Maps

por sexta-feira, 19 de setembro de 2014
infowindow

A InfoWindow padrão do Google Maps pode ser personalizada com estes 5 passos de fácil implementação.
Por um lado, uma infowindow personalizada oferece um aspecto diferenciado aos nossos mapas. Por outro lado, pode e deve ser adequada ao aspecto geral do web site.

Neste artigo não entrarei em detalhes quanto à criação de mapas, marcadores e Info Windows. Essa informação está disponível nos seguintes artigos:

Antes de iniciar o tutorial vê uma demonstração do mapa ou faz o download do código necessário para seguir este exemplo.

DEMO DOWNLOAD

Recursos necessários

Para ser mais fácil de personalizar/alterar os estilos existentes na API do Google Maps utilizamos a biblioteca jQuery.
O download do jQuery pode ser feito aqui ou utilizar o CDN do Google. Neste caso estou a utilizar o jQuery v1.11.1.
Para fazer uso do jQuery é necessário incluir o ficheiro jquery.js na nossa pasta js. De seguida introduzir a chamada para o ficheiro jquery.js no ficheiro mapa.html da seguinte forma.

HTML /index.htmlmarnoto.com
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">

    <link rel="stylesheet" type="text/css" href="css/style.css">
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.20&sensor=false"></script>
    
    <!-- utilização do ficheiro existente na pasta js -->
    <script type="text/javascript" src="js/jquery.js"></script></script>

    <!-- em alternativa podes recorrer ao CDN da Google -->
    <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script></script>
    <script type="text/javascript" src="js/map.js"></script>
  </head>
  ...
  ...

As alterações à InfoWindow apresentadas neste exemplo são válidas para as versões 3.18, 3.19 e 3.20 do Google Maps JavaScript API V3.
Para que futuramente não haja surpresas desagradáveis é aconselhável forçar a utilização desta versão. Para isso utiliza-se a opção v=3.20 no URL da chamada da API.
A versão 3.20 é a actual versão experimental (desde 17 de Fevereiro de 2015). Quer isto dizer que esta versão estará disponível até Novembro de 2015.

Assim, é necessário estar atento às alterações introduzidas pela equipa que desenvolve o Google Maps na estrutura da InfoWindow em próximas versões.

1. Criar um cabeçalho na InfoWindow

Para destacar o título do conteúdo da infowindow podemos criar um cabeçalho com uma cor de fundo diferente do restante conteúdo.
Isto é facilmente conseguido com algumas regras de CSS.
Admitindo que temos um div com id="iw-container", que agrupa todo o nosso conteúdo, e o nosso cabeçalho é um div com class="iw-title", atribuímos uma cor azul para o fundo do título e uma cor branca para o texto.

CSS /style.cssmarnoto.com
#iw-container  .iw-title {
   font-family: 'Open Sans Condensed', sans-serif;
   font-size: 22px;
   font-weight: 400;
   padding: 10px;
   background-color: #48b5e9;
   color: white;
   margin: 1px;
   border-radius: 2px 2px 0 0; /* De acordo com o arredondamento dos cantos da infowindow por padrão. */
}
Info window

Como é fácil de observar na imagem o fundo do título não fica bem com aquelas margens. Aqui começa a alteração à estrutura da infowindow.
Para conseguirmos remover as margens da infowindow é necessário encontrar o elemento HTML que controla a infowindow. Esse elemento é um div com a seguinte class ".gm-style-iw". Sabendo isto e utilizando algumas regras de CSS podemos alterar o estilo desse div para remover as margens

CSS /style.cssmarnoto.com
.gm-style-iw {
   width: 350px !important;
   top: 0 !important;
   left: 0 !important;
   border-radius: 2px 2px 0 0;
}

Agora o cabeçalho e o conteúdo ocupam a margem esquerda e o topo mas não ocupam a totalidade da infowindow. Isto acontece porque com a actualização da API para a versão 3.18 é aplicada uma margem direita na infowindow não permitindo que o respectivo conteúdo possa ocupar a sua largura na totalidade.

Info window

Para remover aquela margem direita é necessário remover os DIV que compõem o fundo branco e a sombra. O fundo branco da infowindow e a sua sombra são dois elementos distintos mas ambos fazem parte do div anterior ao div .gm-style-iw. Sabendo isto e utilizando o jQuery e o evento da API do google maps google.maps.event.addListener(infowindow, 'domready', function(), podemos alterar o estilo desse div para remover a margem direita.

JavaScript /map.jsmarnoto.com
/*
 * O evento google.maps.event.addListener() espera pela
 * criação da estrutura HTML da infowindow 'domready'
 * e antes da abertura da infowindow serão aplicados
 * os estilos definidos
 */
google.maps.event.addListener(infowindow, 'domready', function() {

   // Referência ao DIV que recebe o conteúdo da infowindow recorrendo ao jQuery
   var iwOuter = $('.gm-style-iw');

   /* Uma vez que o div pretendido está numa posição anterior ao div .gm-style-iw.
    * Recorremos ao jQuery e criamos uma variável iwBackground,
    * e aproveitamos a referência já existente do .gm-style-iw para obter o div anterior com .prev().
    */
   var iwBackground = iwOuter.prev();

   // Remover o div da sombra do fundo
   iwBackground.children(':nth-child(2)').css({'display' : 'none'});

   // Remover o div de fundo branco
   iwBackground.children(':nth-child(4)').css({'display' : 'none'});

});

Para completar a personalização da infowindow é necessário aplicar as seguinte regras CSS ao div com a class .gm-style-iw.

CSS /style.cssmarnoto.com
.gm-style-iw {
   width: 350px !important;
   top: 0 !important;
   left: 0 !important;
   background-color: #fff;
   box-shadow: 0 1px 6px rgba(178, 178, 178, 0.6);
   border: 1px solid rgba(72, 181, 233, 0.6);
   border-radius: 2px 2px 0 0;
}

Agora a nossa infowindow não apresenta a margem direita e o título e o conteúdo ocupam a totalidade da largura da infowindow.

Info window

Com esta alteração surgem dois problemas, o botão de fechar e a cauda da infowindow não estão na posição correcta. Isto leva-nos a aproveitar esta oportunidade para mais duas formas de personalizar a nossa infowindow.

2. Reposicionar a infowindow

A última grande alteração dada à infowindow, por parte dos programadores do Google Maps, foi o enquadramento desta com o respectivo marcador. Agora a infowindow surge centrada em relação ao marcador.
Mas as coisas não têm que ser assim tão lineares e podemos dar um ligeiro "chega pra lá" na infowindow.
Esta alteração requer duas acções. Reposicionar a indowindow em relação ao respectivo marcador e reposicionar a cauda(seta) da infowindow.
Para deslocar a infowindow criamos uma referência a um div que engloba todos os elementos que compõem a infowindow. Esse div encontra-se dois patamares acima do div .gm-style-iw.
Esse div é referenciado da seguinte forma.

JavaScript /map.jsmarnoto.com
// Desloca a infowindow 115px para a direita
iwOuter.parent().parent().css({left: '115px'});
Info window

Como é possível observar na imagem anterior a cauda da infowindow não aponta para o respectivo marcador. Torna-se necessário deslocar a cauda para apontar ao nosso marcador.
Os elementos que compõem a cauda e a sua sombra estão dentro do mesmo div que agrupa o fundo da infowindow.
Os elementos da sombra da cauda estão agrupados no primeiro descendente de iwBackground. Com o jQuery utilizamos iwBackground.children(':nth-child(1)'). Os elementos que compõem a cauda estão no terceiro descendente - iwBackground.children(':nth-child(3)').

JavaScript /map.jsmarnoto.com
// Desloca a sombra da seta a 76px da margem esquerda 
iwBackground.children(':nth-child(1)').attr('style', function(i,s){ return s + 'left: 76px !important;'});

// Desloca a seta a 76px da margem esquerda 
iwBackground.children(':nth-child(3)').attr('style', function(i,s){ return s + 'left: 76px !important;'});

Já que estamos a mexer na cauda podemos aproveitar e alterar a cor do contorno para se enquadrar com os contornos da infowindow e aplicar o valor 1 a z-index para sobrepor a cauda à infowindow.

JavaScript /map.jsmarnoto.com

// Altera a cor desejada para o contorno da cauda.
// O contorno da cauda é composto por dois descendentes do div que contem a cauda.
// O método .find('div').children() faz referência a todos os div que sejam os descendentes directos do div anterior. 
iwBackground.children(':nth-child(3)').find('div').children().css({'box-shadow': 'rgba(72, 181, 233, 0.6) 0px 1px 6px', 'z-index' : '1'});

Agora basta descer um pouco a infowindow para a deixar enquadrada com a cauda.

CSS /style.cssmarnoto.com
.gm-style-iw {
   width: 350px !important;
   top: 15px !important; // mover a infowindow 15px para baixo
   left: 0 !important;
   background-color: #fff;
   box-shadow: 0 1px 6px rgba(178, 178, 178, 0.6);
   border: 1px solid rgba(72, 181, 233, 0.6);
   border-radius: 2px 2px 0 0;
}
Info window

3. Botão fechar infowindow

O botão de fechar a infowindow necessita de ser reposicionado e pode receber um pouco mais de destaque.
O seguinte código reposiciona o botão no canto superior direito e cria um efeito à volta do botão.

JavaScript /map.jsmarnoto.com
// Aproveitando a referência já criada ao div .gm-style-iw com a variável iwOuter.
// Criamos uma nova variável iwCloseBtn.
// Utilizando o método .next() do JQuery referenciamos o div seguinte ao div .gm-style-iw.
// É este div que agrupa os elementos do botão fechar.
var iwCloseBtn = iwOuter.next();

// Aplica o efeito desejado ao botão fechar
iwCloseBtn.css({
  opacity: '1', // por padrão o botão fechar tem uma opacidade de 0.7
  right: '38px', top: '3px', // reposicionamento do botão
  border: '7px solid #48b5e9', // aumento da borda do botão e nova cor
  'border-radius': '13px', // efeito circular
  'box-shadow': '0 0 5px #3990B9' // efeito 3D para salientar o botão
  });

// A API aplica automaticamente 0.7 de opacidade ao botão após o evento mouseout.
// Esta função reverte esse evento para o valor desejado.
iwCloseBtn.mouseout(function(){
  $(this).css({opacity: '1'});
});
Info window

4. Cantos arredondados

Em versões anteriores do Google Maps a infowindow tinha os cantos muito mais arredondados. É uma questão de gosto e de tendências, por isso fica ao gosto de cada um atribuir ou não mais enfase ao contorno dos cantos.
Esta tarefa é muito simples, basta aplicar 10px à regra CSS border-radius da classe .gm-style-iw.

CSS /style.cssmarnoto.com
.gm-style-iw {
   width: 350px !important;
   top: 15px !important;
   left: 0 !important;
   background-color: #fff;
   box-shadow: 0 1px 6px rgba(178, 178, 178, 0.6);
   border: 1px solid rgba(72, 181, 233, 0.6);
   border-radius: 2px 2px 10px 10px; // aplicar 10px nos cantos inferiores da infowindow
}
Info window

5. Efeito "fade" na base da infowindow

Por último podemos aplicar um efeito "fade" na base do conteúdo da infowindow. Este efeito sugere que existe mais conteúdo escondido, sendo necessário fazer "scroll".
Este efeito é conseguido sobrepondo um div com efeito gradiente sobre a última linha do conteúdo.

Primeiro de tudo é necessário criar o DIV no final do conteúdo HTML da infowindow.

HTML /index.htmlmarnoto.com
   <div class="iw-bottom-gradient"></div>

Seguidamente aplicamos as regras CSS para a class iw-bottom-gradient.

CSS /style.cssmarnoto.com
   .iw-bottom-gradient {
      position: absolute;
      width: 326px;
      height: 25px;
      bottom: 10px;
      right: 18px;
      background: linear-gradient(to bottom, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%);
      background: -webkit-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
      background: -moz-linear-gradient(top, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
      background: -ms-linear-gradient(top, rgba(255,255,255,0) 0%,rgba(255,255,255,1) 100%);
   }
Info window

Assim concluímos as 5 formas de personalizar a InfoWindow do Google Maps. Cada personalização pode ser aplicada isoladamente ou na totalidade.
O resultado final não é o "estado da arte" mas antes uma exemplificação de um caminho possível para dar nova vida à InfoWindow.
Convido-te a deixar um link nos comentários e mostrar a tua criatividade com a personalização das infowindows.

Ver exemplo do mapa.

Todas as dúvidas ou comentários são bem-vindos. Por favor, utiliza a secção de comentários para que todos partilhem da informação.

Download dos ficheiros necessários para este exemplo

Miguel Marnoto

A minha especialização no Google Maps e na sua API JavaScript v3 é uma consequência do gosto pelos mapas e o reconhecimento da importância que o serviço Google Maps tem hoje no dia-a-dia das pessoas.

14 comentários para ''5 formas de personalizar a InfoWindow Google Maps"

COMENTAR
  1. Boas tardes Miguel, escriboche en galego, porque non sei portugues. Teño problemas para personalizar o infowindows tal como indicas, podes echarme unha mao. Obrigado

    ResponderEliminar
  2. Parabéns, Miguel. Poderia me direcionar em como proceder para listar vários marcadores? O caminho mais simples seria transformar as variáveis fabrica e conteúdo em Array?

    ResponderEliminar
    Respostas
    1. Olá Thiago, para listar vários marcadores podes consultar este artigo: http://www.marnoto.com/2013/12/mapa-com-varios-marcadores-google-maps.html.

      Eliminar
  3. Boas
    Muitos parabens, por partilhar toda esta informação, muito obrigado mesmo, tem sido de grande ajuda. Tenho estado a tentar fazer uma janela de informação como esta no teu site (googlemap).
    Mas aquilo é um pouco mais complexo de se fazer, ehehe existe algum tutorial, ou vai sair algum tutorial, para fazer algo do mesmo genero? Mas uma vez muito obrigado

    Abrços

    ResponderEliminar
  4. Estou tentando remover a piscada que a janela da, na posição original. Chegou a tentar algo? customizei seguindo seu tutorial pode no meu caso não tenho a ponta do balão então o removi, porem ela insiste em dar essa piscada, ja que o script acontece depois que o balão é carregado.

    ResponderEliminar
  5. excelente material esse que voce criou, vai me ajudar muito com meu tcc, muito obrigado por compartilhar seu conhecimento

    ResponderEliminar
  6. Obrigado Miguel! Me ajudo muito!

    Abraços

    ResponderEliminar
  7. Funciona bem se conteúdo for grande. Se tiver uma ou duas palavras acaba disposicionando. Puxando tudo pra esquerda, no limite de tamanho do texto do conteúdo.

    ResponderEliminar
  8. Excelente lembrando que se for usar isso com bootstrap tem que ajustar o box-sizing.

    ResponderEliminar
  9. Oi, muito bom o post, alguém pode me ajudar: como listar uma tabela de valores do mysql em um infoWindow, não achei nada parecido na internet, só consigo mostrar o último registro da tabela, sempre prevalece o último, agradeço, já estou a semanas procurando e nada

    ResponderEliminar
  10. Olá favor atualizar essa publicação. Estou precisando aumentar o tamanho da info box. Fica muito reduzido...

    ResponderEliminar