Верх страницы
Обложка к записи Построение интерактивной карты с Raphaël
Время для прочтения: 0 мин. 24 сек.

Построение интерактивной карты с Raphaël

Raphaël — это мощная библиотека, которая должна упростить работу с векторной графикой в Интернете. Сегодня я научу вас, как создать интерактивную карту с нуля.

Для начала, пожалуйста, создайте следующую структуру папок и файлов:

Структура папок и файлов

Raphaël (raphael.js)

Raphaël — небольшая библиотека на JavaScript, которая должна упростить вашу работу с векторной графикой. Raphaël использует SVG и VML в качестве основы для создания графики. Это означает, что каждый графический объект который вы создаёте, также является объектом DOM, так что к нему можно добавить обработчик событий JavaScript или модифицировать его позднее.

paths.js

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

index.html

Как обычно, первым шагом будет создание разметки HTML.


<!DOCTYPE html>   
<html>   
 <head>   
 <meta charset="utf-8">   
 <title>Построение интерактивной карты с Raphaël</title>   
 <link href="css/default.css" rel="stylesheet">   
 <script src="js/jquery.js"></script>   
 <script src="js/raphael.js"></script>   
 <script src="js/paths.js"></script>   
 <script src="js/init.js"></script>   
 </head>     
 <body>   
 <div id="map"></div>   
 </body>   
</html>

Мы также вставляем стили (default.css) и перед закрытием тега включаем библиотеку jQuery, библиотеку Raphaël, paths.js и init.js.

Создание контуров из файла SVG

SVG (Scalable Vector Graphics, масштабируемая векторная графика) это семейство спецификаций основанной на формате XML для описания двумерной векторной графики.

Это определение сообщает, что SVG является файлом XML, так что вы сможете открыть его в текстовом редакторе. Я нашел в Интернете свободный SVG-файл с картой Европы, который и собираюсь использовать в этом уроке. Очевидно, что вы можете использовать собственную векторную карту и экспортировать её в SVG-файл с помощью программы Adobe Illustrator или Inkspace.

Открываем paths.js и создаём новый объект с именем paths.


var paths = {}

Затем откройте SVG-файл с картой и вы увидите много кода XML. К счастью, вам нужно только одно значение d. Посмотрите на изображение ниже.

Значение d

Давайте создадим первый контур страны. В SVG-файле, использованном в этом уроке, первой идёт Исландия, поэтому скопируйте значение d и создайте новый параметр iceland в объекте paths.


var paths = {
 iceland: {
  name: 'Iceland',
  path: // Значение d
 }
}

Таким же образом добавляются и другие контуры.


var paths = {
 iceland: {
  name: 'Iceland',
  path: // Значение d
 },
 spain: {
  name: 'Spain',
  path: // Значение d
 },
 portugal: {
  name: 'Portugal',
  path: // Значение d
 }
 // и т.д.
}

Создание карты (init.js)

В этой части урока я собираюсь написать скрипт, который будет показывать карту на экране.


$(function(){
 var r = Raphael('map', 1200, 820),
  // создаём холст, на котором рисуются наши контуры
  attributes = {
   fill: '#fff',
   stroke: '#3899E6',
   'stroke-width': 1,
   'stroke-linejoin': 'round'
  },
  // создаём объект attributes с параметрами
  arr = new Array();
   for (var country in paths) {
    var obj = r.path(paths[country].path);
    obj.attr(attributes);
   }
  // в цикле обходим все контуры (контуры, которые включены в объект paths),
  // показываем их и устанавливаем для них параметры
});

В первую очередь создадим событие hover.


obj.hover(function(){
 this.animate({
  fill: '#1669AD'
 }, 300);
}, function(){
 this.animate({
  fill: attributes.fill
 }, 300);
});

Далее добавим событие click.


obj.click(function(){
 document.location.hash = arr[this.id];
 // меняем адрес документа (после #)
 var point = this.getBBox(0);
 // возвращает размер элемента
 $('#map').next('.point').remove();
 $('#map').after($('<div></div>').addClass('point'));
 // удаляем существующий div с классом point и создаём ещё один
 $('.point')
 .html(paths[arr[this.id]].name)
 .prepend($('<a></a>').attr('href', '#').addClass('close').text('Close'))
 .prepend($('<img />').attr('src', 'flags/'+arr[this.id]+'.png'))
 .css({
 left: point.x+(point.width/2)-80,
 top: point.y+(point.height/2)-20
 })
 .fadeIn();
 // добавляем контент (название страны, рисунок и кнопку закрытия),
 // задаём позицию и показваем элемент
});

И обработчик для кнопки «закрыть».


$('.point').find('.close').live('click', function(){
 var t = $(this),
  parent = t.parent('.point');
 parent.fadeOut(function(){
  parent.remove();
 });
 return false;
});

Окончательно init.js выглядит так:


$(function(){
 var r = Raphael('map', 1200, 820),
 attributes = {
  fill: '#fff',
  stroke: '#3899E6',
  'stroke-width': 1,
  'stroke-linejoin': 'round'
 },
 arr = new Array();
 for (var country in paths) {
  var obj = r.path(paths[country].path);
  obj.attr(attributes);
  arr[obj.id] = country;
  obj
  .hover(function(){
   this.animate({
    fill: '#1669AD'
   }, 300);
  }, function(){
   this.animate({
    fill: attributes.fill
   }, 300);
  })
  .click(function(){
   document.location.hash = arr[this.id];
   var point = this.getBBox(0);
   $('#map').next('.point').remove();
   $('#map').after($('<div></div>').addClass('point'));
   $('.point')
   .html(paths[arr[this.id]].name)
   .prepend($('<a></a>').attr('href', '#').addClass('close').text('Close'))
   .prepend($('<img />').attr('src', 'flags/'+arr[this.id]+'.png'))
   .css({
    left: point.x+(point.width/2)-80,
    top: point.y+(point.height/2)-20
   })
   .fadeIn();
  });
  $('.point').find('.close').live('click', function(){
   var t = $(this),
   parent = t.parent('.point');
   parent.fadeOut(function(){
    parent.remove();
   });
   return false;
  });
 }
});

default.css

Последний шаг состоит в добавлении некоторого стиля с помощью CSS.


#map {
 float:left;
 clear:both;
 width:1200px;
 height:820px;
}
   
.point {
 position:absolute;
 display:none;
 padding:10px 15px;
 background:#7BB9F0;
 font-size:14px;
 font-weight:bold;
 /* скруглённые уголки */
 -moz-border-radius:8px;
 -webkit-border-radius:8px;
 border-radius:8px;
}
   
.point .close {
 display:block;
 position:absolute;
 top:-10px;
 right:-10px;
 width:24px;
 height:24px;
 text-indent:-9999px;
 outline:none;
 background:url(../img/close.png) no-repeat;
}
   
.point img {
 vertical-align:middle;
 margin-right:10px;
}

Данная публикация является переводом статьи Marcin Dziewulski «Building an interactive map with Raphael«. Автор перевода Влад Мержевич.

Ссылки

Автор: Кобзарёв Михаил

Русский разработчик с 20-ти летним стажем. Работаю с PHP, ООП, JavaScript, Git, WordPress, Битрикс, Joomla, Drupal, Opencart, DLE, Laravel, Moonshine, SuiteCRM.

Оптимизирую сайты под Google Page Speed, настраиваю импорты для больших магазинов на WooCommerce + WP All Import. Пишу плагины на заказ. Все мои услуги.

Веду блог о разработке, дайджест в телеграмме и в ВК.

Вы всегда можете нанять меня.

Комментарии
Подписаться
Уведомить о
guest

6 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии
Роман
Роман
11 лет назад

Я поражаюсь сколько учителей развелос, на копировали один и тот же урок и радуются, сами то побывали создать карту, а то везде одна и та же фраза «Я нашел в Интернете бесплатный файл SVG с картой Европы» хотя бы один свой фал предложил и технологию по его созданию.

Даниил
Даниил
5 лет назад
Ответить на  Кобзарёв Михаил

Здравствуйте! а можно ли попросить у вас какие-нибудь исходники с интерактивной картой человека? либо, хотя бы, статьи на нечто подобное.. сам, к сожалению, отыскать не сумел

Алиса Стронхольд
6 лет назад

Скажите пожалуйста как можно уменьшить размер каждой страны на карте?

Предыдущая запись
Следующая запись

Давайте дружить
в Телеграме

Авторский блог вашего покорного слуги в Telegram про web, программирование, алгоритмы, инструменты разработчика, WordPress, Joomla, Opencart, Laravel, Moonshine, фильмы и сериалы