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

Автор: | 06.05.2011

В этой статье мы изучим с Вами технику размещения маркеров на карте, с использованием сочетания 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

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

  1. Agent_008

    Поддерживаю предыдущий комментарий. Yandex — карты в нашей стране куда более актуальны

  2. Дмитрий

    Не отображаются метки…Что делать?
    Сделал как написано, получил 2 файла index.html и places.json,но картинок на карте нет.
    Спасибо.

  3. Michael

    Что от не могу понять, что за руки у меня кривые или что, но не могу высоту у карты задать в процентах 100% или другие только жестко в px иначе карту не показывает где копать?
    Уже упарился map_canvas мучить, чтоб он сволоч понимал 100% высоту.
    напишите кто нить как решить.

    1. admin Автор записи

      Нужно прописать в стилях для страницы с картой
      html, body{
      margin: 0;
      padding: 0;
      height: 100%;
      }

  4. Алекс

    Все сделал как написано, но метки не отображаются. Подскажите что может быть не так.

    1. admin Автор записи

      Может быть ошибка в файле с данными меток places.json, проверьте его. А также проверьте путь к самому файлу places.json

  5. Юрий

    Добрый день!
    Я не силен в программировании, поэтому возник вопрос:
    Как реализовать, чтобы на карте показывать маркеры 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]
    },

    Никак не получается реализовать, может сама идея неправильна?…. Помогите пожалуйста!

  6. Val

    Классная статья! Подскажите а как получить данные из двух и более источников, что бы у каждого была своя иконка?

  7. Val

    Здрасте! Не могу понять как вставлять html код в описание?

    Вставил в json файл
    { «title»: «Заголовок»,
    «description»: «HTML код ссылка»,
    «position»: [ 52.134362,92.929831] },

    Он просто выводит код как текст. Чё делать?

  8. Maxim

    Копирую полностью пример, не показывает объекты ((( В чем может быть проблема ?

    подключаю как написано $.getJSON(‘places.json’, function(places)

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

    1. admin Автор записи

      У меня в файле places.json содержится следующий код:

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

      никакого присвоения нет.

  9. Maxim

    Очень странно (
    Скопировал точно такой же places.json как указал ‘admin’
    В корне лежит два файла wqeq.html и places.json
    Вроде бы все должно работать, код одинаковый, копировал от сюда…
    Пример тут работает, а локально нет (выводит карту, но метки не показывает) я смотрю проблема не только у меня, в комментариях еще у пары человек не отображаются метки
    Не могу разобраться почему, помогите пожалуйста!
    Спасибо большое!

    1. admin Автор записи

      Может быть проблема с кодировкой файлов, должна быть UTF-8. Предлагаю проверить на простом (для одной метки) примере передаются данные из файла places.json в файл карты.

  10. Maxim

    Хотел залить на сервер и выложить пример, т.к. не работает локально!
    Выложил, проверил и о чудо, оно заработало на сервере…
    В чем причина так и не понял, но просто без сервера не работает пример

  11. St.

    Как и у многих тут локально метки не видны, на сервере еще не пробовал.
    Кто с локальным разобрался, помогите пожалуйста

  12. Иван

    Уважаемый 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/

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *