Собственное информационное окно с анимацией на Google Maps, применяя API Google Maps v3, CCS3 и jQuery

В этой статье мы изучим с Вами технику размещения маркеров на карте, с использованием сочетания API Google Maps v3, анимации- jQuery и некоторых новых эффектов CSS.

Как работает пример.

Кликаем мышкой по одному из маркеров, в правом нижнем углу выезжает окно с информацией о метке. Значок метки изменяется. Кликаем еше раз, окно скрывается, метка становиться первоначального вида.

В начале мы создаем карту с центром в Нижнем Новгороде и с параметрами по умолчанию.

<!DOCTYPE html> 
<html> 
<head> 
<title>Собственное информационное окно с анимацией на Google Maps, применяя API Google Maps v3, CCS3 и jQuery</title> 
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script> 
  <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
<script type="text/javascript"> 
 
    $(function() { // onload handler
      var nnovgorod = new google.maps.LatLng(56.32,44.004);
      var mapOptions = {
        zoom:      15,
        center:    nnovgorod,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }
 
      var map = new google.maps.Map($("#map_canvas")[0], mapOptions);
 
});
 
</script> 
 
</head> 
<body> 
  <div class='map'> 
    <div id='map_canvas' style='height:600px; width: 800px'></div> 
    <div id='placeDetails'> 
      <h1></h1> 
      <p></p> 
    </div> 
  </div> 
</body> 
</html>

Здесь все понятно и не требует пояснений.

После этого мы можем на карту добавить метки.

Например так:

var marker = new google.maps.Marker({
  position: new google.maps.LatLng(56.324142,44.001486),
  map:      map,
  title:    'Московский вокзал',
  icon:     'http://google-maps-icons.googlecode.com/files/train.png'
});

При клике по маркеру метки происходить событие, которое мы будем использовать в своем примере.

К имеющемуся коду мы добавляем код CSS

<style type="text/css" media="screen"> 
 .map { 
      width: 800px;
 
      /* The following are required to allow absolute positioning of the
       * info window at the bottom right of the map, and for it to be hidden
       * when it is "off map" 
       */
      position: relative; 
      overflow: hidden;
    }
    #placeDetails { 
      position: absolute;
      width: 300px;
      bottom: 0;
      right: -320px;
      padding-left: 10px;
      padding-right: 10px;
 
      /* Semi-transparent background */
      background-color: rgba(0,0,0,0.8);
      color: white;
      font-size: 80%;
 
      /* Rounded top left corner */
      border-top-left-radius: 15px;
      -moz-border-radius-topleft: 15px;
      -webkit-border-top-left-radius: 15px;
    }
 
    /* Fit the text nicely inside the box */
    h1 {
      font-family: sans-serif;
      margin-bottom: 0;
    }
    #placeDetails p {
      margin-top: 0;
    }
  </style> 
  <!--[if IE]>
  <style>
    html #placeDetails {
      background-color: black;
    }
  </style>
  <![endif]-->

И код, отвечающий за анимацию

var currentPlace = null;
var info = $('#placeDetails');
google.maps.event.addListener(marker, 'click', function() {
  if (currentPlace) {
    info.animate({right: '-320px'});
    currentPlace = null;
  } else {
    info.animate({right: '0'});
    currentPlace = marker;
  }
});

Данные о метках на карте лучше всего записать в формате JSON, это будет наглядно и Вы сможете загружать данные о метках формируя файл данных в формате JSON с помощью кода

$.getJSON('places.json', function(places) {
  $(places).each(function() {
    // As above
  });
});

В файл ‘places.json добавляем код:

var places = [
  {
    "title": "Московский вокзал",
    "description": "Центральная железнодорожная станция Нижнего Новгорода.",
    "position": [56.324142,44.001486 ]
  },
  {
    "title": "Горький Сортировочный",
    "description": "Станция для сортировки поездов",
    "position": [ 56.324142,44.001486 ]
  }
]

В наш пример мы добавляем следующий код:

var currentPlace = null;
var info = $('#placeDetails');
$(places).each(function() {
  var place = this;
  var marker = new google.maps.Marker({
    position: new google.maps.LatLng(place.position[0], place.position[1]),
    map:      map,
    title:    place.title,
    icon:     'http://webmap-blog.ru/files/gmap3-jquery-css/ris/train.png'
  });
  google.maps.event.addListener(marker, 'click', function() {
    $('h1', info).text(place.title);
    $('p',  info).text(place.description);
    if (currentPlace == marker) {
      info.animate({right: '-320px'});
      currentPlace = null;
    } else {
      info.animate({right: '0'});
      currentPlace = marker;
    }
  });
});

В конечном итоге у нас получается следующее:

<!DOCTYPE html> 
<html> 
<head> 
<title>Собственное информационное окно с анимацией на Google Maps, применяя API Google Maps v3, CCS3 и jQuery</title> 
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/> 
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script> 
  <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> 
  <script> 
    $(function() { // onload handler
      var melbourne = new google.maps.LatLng(56.301721,43.920462);
      var mapOptions = {
        zoom:      12,
        center:    melbourne,
        mapTypeId: google.maps.MapTypeId.ROADMAP
      }
 
      var map = new google.maps.Map($("#map_canvas")[0], mapOptions);
 
      var currentPlace = null;
      var info = $('#placeDetails');
      var icons = {
        'train': 'http://webmap-blog.ru/files/gmap3-jquery-css/ris/train.png',
        'train-selected': 'http://webmap-blog.ru/files/gmap3-jquery-css/ris/train-selected.png'
      }
 
 
      $.getJSON('places.json', function(places) {
        $(places).each(function() {
          var place = this;
          var marker = new google.maps.Marker({
            position: new google.maps.LatLng(place.position[0], place.position[1]),
            map:      map,
            title:    place.title,
            icon:     icons['train']
          });
 
          google.maps.event.addListener(marker, 'click', function() {
            var hidingMarker = currentPlace;
            var slideIn = function(marker) {
              $('h1', info).text(place.title);
              $('p',  info).text(place.description);
 
              info.animate({right: '0'});
            }
 
            marker.setIcon(icons['train-selected']);
 
            if (currentPlace) {
              currentPlace.setIcon(icons['train']);
 
              info.animate(
                { right: '-320px' },
                { complete: function() {
                  if (hidingMarker != marker) {
                    slideIn(marker);
                  } else {
                    currentPlace = null;
                  }
                }}
              );
            } else {
              slideIn(marker);
            }
            currentPlace = marker;
          });
        });
      });
    });
  </script> 
  <style> 
    .map { 
      width: 800px;
 
      /* The following are required to allow absolute positioning of the
       * info window at the bottom right of the map, and for it to be hidden
       * when it is "off map" 
       */
      position: relative; 
      overflow: hidden;
    }
    #placeDetails { 
      position: absolute;
      width: 300px;
      bottom: 0;
      right: -320px;
      padding-left: 10px;
      padding-right: 10px;
 
      /* Semi-transparent background */
      background-color: rgba(0,0,0,0.7);
      color: white;
      font-size: 80%;
 
      /* Rounded top left corner */
      border-top-left-radius: 15px;
      -moz-border-radius-topleft: 15px;
      -webkit-border-top-left-radius: 15px;
    }
 
    /* Fit the text nicely inside the box */
    h1 {
      font-family: sans-serif;
      margin-bottom: 0;
    }
    #placeDetails p {
      margin-top: 0;
    }
  </style> 
  <!--[if IE]>
  <style>
    html #placeDetails {
      background-color: black;
    }
  </style>
  <![endif]--> 
</head> 
<body> 
  <div class='map'> 
    <div id='map_canvas' style='height:600px; width: 800px'></div> 
    <div id='placeDetails'> 
      <h1></h1> 
      <p></p> 
    </div> 
  </div> 
</body> 
</html>

Посмотреть пример в действии

Для примера использовалась статья Embellishing Your Google Map with CSS3 and jQuery

  • Гость: а реализовать то же самое с Яндекс возможно??
  • Гость: Поддерживаю предыдущий комментарий. Yandex - карты в нашей стране куда более актуальны
  • Гость: Не отображаются метки...Что делать? Сделал как написано, получил 2 файла index.html и places.json,но картинок на карте нет. Спасибо.
  • Гость: Что от не могу понять, что за руки у меня кривые или что, но не могу высоту у карты задать в процентах 100% или другие только жестко в px иначе карту не показывает где копать? Уже упарился map_canvas мучить, чтоб он сволоч понимал 100% высоту. напишите кто нить как решить.
  • Гость: Нужно прописать в стилях для страницы с картой html, body{ margin: 0; padding: 0; height: 100%; }
  • Гость: Все сделал как написано, но метки не отображаются. Подскажите что может быть не так.
  • Гость: Может быть ошибка в файле с данными меток places.json, проверьте его. А также проверьте путь к самому файлу places.json
  • Гость: Добрый день! Я не силен в программировании, поэтому возник вопрос: Как реализовать, чтобы на карте показывать маркеры c картинкой "train.png" а при нажатии маркера "вокзал" картинку moskva-vokzal.jpg, при нажатии маркера "Горький Сортировочный" картинку sortirovochniy.jpg. Все эти иконки я хочу прописать в var icons = { 'train': 'http://webmap-blog.ru/files/gmap3-jquery-css/ris/train.png', 'train-selected1': 'http://.../moskva-vokzal.jpg' 'train-selected2': 'http://.../sortirovochniy.jpg' .... } Предполагается около 20 таких маркеров, то есть я думаю правильно будет в .jason указывать { "title": "тратата", "description": "парапапа", "kartinka": "['train']", "position": [56.321424,43.945374] }, Никак не получается реализовать, может сама идея неправильна?.... Помогите пожалуйста!
  • Гость: Разобрался, все работает как часы.
  • Гость: Классная статья! Подскажите а как получить данные из двух и более источников, что бы у каждого была своя иконка?
  • Гость: всем спасибки разобрался
  • Гость: Здрасте! Не могу понять как вставлять html код в описание? Вставил в json файл { "title": "Заголовок", "description": "HTML код ссылка", "position": [ 52.134362,92.929831] }, Он просто выводит код как текст. Чё делать?
  • Гость: Копирую полностью пример, не показывает объекты ((( В чем может быть проблема ? подключаю как написано $.getJSON(‘places.json’, function(places) внутри var places = [ { "title": "Московский вокзал", "description": "Центральная железнодорожная станция Нижнего Новгорода.", "position": [56.324142,44.001486 ] }, { «title»: «Горький Сортировочный», «description»: «Станция для сортировки поездов», «position»: [ 56.324142,44.001486 ] } ] ничего не происходит ( Помогите пожалуйста… Спасибо
  • Гость: У меня в файле places.json содержится следующий код: <pre lang="html"> [{ "title": "Московский вокзал", "description": "Центральная железнодорожная станция Нижнего Новгорода.", "position": [56.321424, 43.945374] }, { "title": "Горький Сортировочный", "description": "Станция для сортировки поездов", "position": [56.285837, 43.852439] }] </pre> никакого присвоения нет.
  • Гость: Очень странно ( Скопировал точно такой же places.json как указал 'admin' В корне лежит два файла wqeq.html и places.json Вроде бы все должно работать, код одинаковый, копировал от сюда... Пример тут работает, а локально нет (выводит карту, но метки не показывает) я смотрю проблема не только у меня, в комментариях еще у пары человек не отображаются метки Не могу разобраться почему, помогите пожалуйста! Спасибо большое!
  • Гость: Может быть проблема с кодировкой файлов, должна быть UTF-8. Предлагаю проверить на простом (для одной метки) примере передаются данные из файла places.json в файл карты.
  • Гость: Хотел залить на сервер и выложить пример, т.к. не работает локально! Выложил, проверил и о чудо, оно заработало на сервере... В чем причина так и не понял, но просто без сервера не работает пример
  • Гость: Как и у многих тут локально метки не видны, на сервере еще не пробовал. Кто с локальным разобрался, помогите пожалуйста
  • Гость: Уважаемый admin, а есть ли способ применить "Собственное информационное окно с анимацией на Google Maps" к маркерам, которые создаются запросом из Fusion Tables? т.е. которые получаются вот так: FTlayer = new google.maps.FusionTablesLayer(table_id, { query: "SELECT lat, lng from table_id"} ); FTlayer.setMap(map); Я так понял что в Infowindow которое формируется при клике на FT, можно изменить только цвет и стиль текста внутри Infowindow, а хотелось бы создавать "Собственное инф.окно"... Сижу, ломаю голову - обработать "click" не получается. (перевод данных из FT в формат json нашел здесь: http://ft2json.appspot.com/