Создаем интерактивную карту

Raphael - мощная библиотека для работы с векторной графикой в веб проектах. В данном уроке мы разберемся, как создать интерактивную карту её помощью.

demosourse

Сначала создаем структуру каталогов и файлов как на рисунке ниже:

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

 

Raphael (raphael.js)

Raphael  - маленькая библиотека JavaScript, которая упрощает работу с векторной графикой в веб проектах.

Raphael использует SVG W3C и VML как основу для создания графики. Каждый графический объект создается как объект DOM и, таким образом, к нему можно присоединить обработчик события или модифицировать в процессе обработки страницы.

 

paths.js

В данном файле хранятся траектории SVG paths и названия каждой страны.

 

index.html

Сделаем разметку HTML.

<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Строим интерактивную карту с помощью Raphael | Демонстрация для сайта RUSELLER.COM</title>
<link href="css/default.css" rel="stylesheet" type="text/css" />
<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/raphael.js" type="text/javascript"></script>
<script src="js/paths.js" type="text/javascript"></script>
<script src="js/init.js" type="text/javascript"></script>
</head>

<body>
	
	<div class="wrapper">
		<div id="map"></div>
	</div>

</body>
</html>

Мы подключаем таблицу стилей (default.css) , библиотеки jQuery, Raphael, и файлы paths.js и init.js.

 

Создаем траекторию из SVG файла (paths.js)

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

Таким образом, SVG является XML файлом, а, следовательно, мы можем редактировать его в текстовом редакторе.

Для карты используется SVG файл с изображением Европы. Вы может использовать свое векторное изображение (если взять что-то другое, кроме карты, то может получиться очень интересная интерактивная графика). Конвертировать векторное изображение в формат SVG можно с помощью Adobe Illustrator или Inkspace.

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

var paths = {}

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

Формат SVG

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

var paths = {
    iceland: {
        name: 'Исландия',
        path: // значение 'd'
    }
}

И далее действуем аналогичным образом для создания контуров других стран.

var paths = {
    iceland: {
        name: 'Исландия',
        path: // Значение 'd'
    },
    spain: {
        name: 'Испания',
        path: // Значение 'd'
    },
    portugal: {
        name: 'Португалия',
        path: // Значение 'd'
    }
    // и так далее
}

 

Создаем карту (init.js)

Теперь напишем скрипт, который будет выводить карту на экран.

$(function(){
     
    var r = Raphael('map', 1200, 820),
    // Cоздаем новый объект canvas, в котором будет происходить рисование контуров 
    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 />').addClass('point'));
    // Удаляем существующий div 'point' и создаем другой 
    $('.point')
    .html(paths[arr[this.id]].name)
    .prepend($('<a />').attr('href', '#').addClass('close').text('Закрыть'))
    .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();
    // Добавим контент html(название страны, изображение флага и кнопку закрытия), устанавливаем положение и выводим элемент
});

..и обработку события click для кнопки закрытия:

$('.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 />').addClass('point'));
             
            $('.point')
            .html(paths[arr[this.id]].name)
            .prepend($('<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;
     
    /* Скругленные углы CSS3 */
    -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;
}

 

Готово!

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: playground.mobily.pl/tutorials/building-an-interactive-map-with-raphael.html
Перевел: Сергей Фастунов
Урок создан: 28 Февраля 2011
Просмотров: 146165
Правила перепечатки


5 последних уроков рубрики "jQuery"

или авторизуйтесь, чтобы добавлять комментарии, оценивать уроки и сохранять их в личном кабинете
  • 28 Февраля 2011 20:37
    Zedamin
    Круто, и это не flash!)) Только карту бы по больше, и там перепутали Швецию со Швейцарией. Где можно полную карту скачать?
    • 4 Марта 2011 18:32
      serg_panasyuk
      Я качал c Википедии
      • 4 Марта 2011 22:02
        Revy
        поделись ссылочкой)
        • 7 Марта 2011 18:42
          serg_panasyuk
          http://commons.wikimedia.org/wiki/Category:SVG_maps_of_the_world
          • 7 Марта 2011 21:04
            Revy
            спасибо
      • 28 Февраля 2012 19:04
        temirlan
        не подскажете как сделать такое же только из своей карты? не могли бы вы дать подробный мастер-класс =))))
    • 24 Марта 2011 16:36
      vborblik
      если вы гдето нашли полную карту пожалуйста киньте ссылку мне очень надо vborblik@ukr.net
  • 28 Февраля 2011 22:01
    david92
    Да в общем не плохо
    • 4 Марта 2011 11:27
      Александр Борисов
      +1 согласен )
  • 28 Февраля 2011 23:54
    denx_b
    что делается та)
  • 1 Марта 2011 08:09
    Let4ik_Russia
    Как раз вовремя, обязательно использую в своем проекте, правда я уже сделал карту, но использовал DIV, а теперь все будет куда красивее))) Спасибо!!!
  • 1 Марта 2011 10:25
    Let4ik_Russia
    При реализации столкнулся вот с чем: в Вашем изображении используется везде тег "path" в котором присутствует значение "d", я же рисовал карту сам в illustrator после сохранения в svg у меня в основном используется тег "polygon", в котором отсутствует значение "d", но присутствует значение "points", как быть с этим?
  • 1 Марта 2011 13:42
    ppaull
    Впечатляет. Я для таких целей использовал набор дивов с абсолютным позиционированием.
  • 1 Марта 2011 14:40
    art_reklama_com
    Отличный и полезный урок! Спасибо!
  • 1 Марта 2011 16:20
    Overlord888
    Класс! А я думал, как же это реализовать в быстрые сроки....
  • 3 Марта 2011 00:50
    HexEditor
    Чтобы атрибут "d" появился, нужно рисовать свободной формой. В кореле инструмент вызывается кнопкой F5.
    • 12 Марта 2011 12:52
      Роман Старинский
      еп
  • 3 Марта 2011 21:47
    Metis
    Отличный урок. Обязательно воспользуюсь им!
  • 10 Марта 2011 20:07
    gibigate
    Подскажите пожалуйста, например я сделал див на 500х500 пикселей, но карта в 2 раза больше, как добавить кнопки навигаций?
  • 24 Марта 2011 16:34
    vborblik
    Подскажите пожалуйста а где взять такую же карту только для всего мира, искал нигде не могу найти пожалуйста напишите мне на email vborblik@ukr.net очень очень надо!
  • 25 Марта 2011 13:11
    Alex96
    Отличный урок. Только как бы победить проблему с некорректным отображением названий стран в IE.(У меня сайт в Win1251) Может кто-нибудь может помочь?!
  • 13 Апреля 2011 17:33
    Turkmen
    Ребят, вобщем нарисовал карту своего региона и столкнулся с такой стукой. В регионе присутвует речка и её хочется выделить также как и другие участки, только другим цветом. У кого нить есть решение этой задачи?
  • 18 Апреля 2011 18:45
    GrAnd1S
    Подскажите ,а можно ли как то сделать ссылкой страну?
    • 27 Февраля 2012 12:09
      zerov
      присоединяюсь к вопросу! подскажите пожалуйста!
  • 19 Апреля 2011 16:24
    yuran2010
    Скажите кто нибудь а как сделать карту России как на olx.ru
  • 19 Апреля 2011 16:40
    yuran2010
    а точнеее вот сдесь http://www.olx.ru/map_selector.php
    • 25 Мая 2011 22:23
      zhenya1243
      там использовали обычную карту изображений. там все вручную печатали, каждую область <map name="m_rusia" id="m_rusia"> <area href="http://moscow. итд..
  • 7 Мая 2011 15:21
    sevada
    Круто!)
  • 31 Мая 2011 18:32
    mr_ko
    Подскажите как можно реализировать чтобы при наведении на название страны в отдельном списке подсвечивалась соответсвующая область на карте. Буду благодарен за любую подсказку :)
    • 23 Сентября 2011 10:00
      andreysolo
      Реализовал быдлоспособом) Каждому пункту списка присвоил id такое же как его элемент имеет место в DOM. При наведении меняется прозрачность у элемента .eq(id) http://scriptology.ru/map/
      • 22 Февраля 2012 12:14
        NikSTamb
        Спасибо! Классно. Только вот не могу понять почему-то Москва, Адыгея и Чечня не меняют цвет при наведении? Кто может подскажет в чем дело? http://ifolder.ru/28867472 И как можно добавить Калининградскую обл. и Сахалин?
  • 9 Августа 2011 09:34
    yuran2010
    Ура получилась карта как на http://www.olx.ru/map_selector.php просто скопировал код и скрипты со стилями и всееееееееееее
    • 3 Марта 2016 13:50
      Pet_ko
      А исходником поделишся? Очень нужно.
  • 12 Августа 2011 16:43
    andreysolo
    Все получается если рисую простые фигуры. Если вставляю длинный path сложной фигуры то она сильно деформируется. Кто знает в чем может быть причина? Пользуюсь Inkscape
  • 15 Августа 2011 23:01
    dimo12
    Подскажите, как реализовать такое: при наведении курсора на страну, появлялась бы подсказка с ее названием,а при клике, браузер переходил бы на другую страницу. Заранее спасибо!
    • 27 Февраля 2012 12:10
      zerov
      присоединяюсь к вопросу! подскажите пожалуйста, очень срочно нужно, спасите!!!
      • 9 Июля 2012 10:49
        makaaymv
        также интересует способ реализации простой подсказки javascript но не для обычной ссылки а для конкретной области которая описана в файле paths.js. для того чтобы область стала ссылкой нужно каждому объекту дописать параметр url: 'http://ruseller.com', а в файле init.js после функции .hover все убрать и добавить функцию .click(function(){ document.location = paths[arr[this.id]].url; });
  • 16 Августа 2011 13:02
    kot1987
    кто рисует в corel-е или illustrator-е и сохраняет в svg могут подставить вместо d соответственно points только в начале нужно дописать 'M ' а в конце ' z ' и всё заработает
  • 31 Августа 2011 07:55
    levanoff
    Отличная статья, спасибо огромное! Теперь подскажите, реально ли область на карте связать с пунктом меню, например, чтобы при наведении курсора на пункт меню, область на карте также подсвечивалась, как будто курсор навели непосредственно на неё?
  • 6 Октября 2011 16:58
    Chif
    Спасибо, все понятно, доступно! Ответьте пожалуйста на вопрос, можно ли при нажатии выводить не только флаг, кнопку и текст а еще и содержимое какого либо html документа??? Если можно с примером кода. Как я понял картинка выводится так: ".prepend($('<img />').attr('src', 'flags/'+arr[this.id]+'.png'))"... мне бы так же выводить содержимое html странички... Заранее спасибо!
    • 21 Декабря 2011 02:45
      stis
      в файле paths.js в атрибут name: вставить свой html код. прим. name: '<h3>Company LTD<h3><p>Tel.: +3712322232</p><p>mail@mail.com</p>', Ну и дальше все это дело поправить в css
  • 9 Декабря 2011 09:33
    tree_d
    Подскажите пожалуйста. Мне очень срочно надо. Срок горит просто. Сделал всё по уроку, но в IE 8 не работает. Хотя демо из урока в нём же работает. Что не так? Пожалуйста ответьте. Мне уже сайт сдавать. Только это осталось. А заказчик хочет именно так, как здесь. Спасибо!
  • 9 Декабря 2011 10:03
    tree_d
    Разобрался. Цвет если менять на black, orange и т.п. (то что словами написано), то в IE8 не отображает. Писать кодом #39613e и т.п.
  • 20 Февраля 2012 22:40
    zerov
    Помогите чайнику! Скачал исходники, в paths.js заменил параметры d на параметры своей карты. Карты больше не отображаются (ни моя, ни Ваша)! Подскажите какие ещё параметры необходимо заменить. Буду премного благодарен!
    • 28 Февраля 2012 19:05
      temirlan
      Салам! =) не поможешь разобраться с картой)) не могу свою карту вставить сюда...
  • 21 Февраля 2012 00:06
    zerov
    Разобрался, спасибо.
  • 23 Марта 2012 13:56
    deus34
    Сделал карту, но встала задача добавить города. Как это сделать?
  • 5 Апреля 2012 23:43
    Ablyakimov
    подскажите, как сделать ссылку на самой карте((
  • 3 Мая 2012 09:23
    dvigok
    Спасибо отличная карта, подскажите а как сделать, что бы вместо всплывающего окна человек мог переходить по ссылке на сайт в той стране какую выделил и кликнул??...очень нужно такое реализовать...Заранее спасибо.
  • 11 Мая 2012 10:05
    dvigok
    А как например использовать свою карту - то есть другую от карты-примера, например есть карта: http://upload.wikimedia.org/wikipedia/commons/6/65/Euro_Plus_Pact_map.svg Как мне ее добавить по поводу добавления новых d в объекте paths понятно, но как вообще сделать что бы появилась новая карта??
  • 25 Июня 2012 07:42
    Klano
    здравствуйте, урок просто класс! Скажите а как зумирование (маштобирование карты (+ / - )) на карте организовать?
  • 13 Августа 2012 22:25
    casador
    Здравствуйте. Скажите пожалуйста, кто знает как встроить эту карту в модуль joomla.
  • 6 Марта 2013 17:12
    radjab
    а как города добавить в эту карту подскажите пожалуйста ?
  • 10 Марта 2013 01:42
    silver_9998
    День добрый! как можно добавить на карту ссылку (например: при выводе названия страны с флагом, можно было кликать на название страны и переходить на другую страницу)
  • 14 Мая 2013 08:34
    stas46
    Добрый день! Ссылка исходников нерабочая, и изображения "структура каталогов и файлов как на рисунке ниже", и "открываем карту SVG и видим XML код" тоже... Не могли бы перезалить, очень уж надо))) Заранее благодарен!
  • 31 Июля 2013 20:03
    Rolik
    не подскажите как можно показывать при клике на страну различную информацию из БД???
  • 20 Октября 2013 19:49
    aleksandr_n
    Всем большой привет, пытаюсь решить задачу как можно сделать чтоб при наведении на один объектов подсвечивался и второй объект, то есть по сути надо сделать в xml файле значения двух объектов пробовал сделать вручную но координаты начинают ломаться пробовал сгруппировать эти два объекта но не помогло если кто знает решение задачи помогите пожалуйста особенно если может помочь администрация сайта буду благодарен, для обработки svg и xml файла использовал программу Inkscape. Заранее все спасибо.
  • 9 Ноября 2013 23:09
    borockov
    Здравствуйте! Помогите пожалуйста реализовать такое: при наведении курсора на регион, появлялась бы подсказка с ее названием,а при клике, браузер переходил бы на другую страницу. Заранее спасибо! p.s автор поста, отпишись пожалуйста, данный вопрос уже несколько раз поднимался в комментариях.
  • 3 Декабря 2013 07:47
    maxmostovoy
    Поддерживаю предыдущий вопрос!!!
  • 31 Января 2014 12:50
    radjab
    Добрый день помогите пожалуйста я сделал свою карту и к этому добавил круги это у меня города как изменить цвет этих кругом ну эта как области на карте и дать им название чтоб было видно ???
  • 6 Октября 2014 12:06
    Evgen Efh
    Здравствуйте. Такое дело. Нужно сделать карту. Есть файлик .ai, перегоняю его через тот же AdobeIllustrator в svg, на выходе выдает файлик svg, но другой структуры. Отличной от той что тут. Как быть. Мб как-нибудь специально надо перегонять в svg?
  • 9 Ноября 2014 12:59
    rushone
    Подскажите как отобразить название стран на карте и как задать id определённой стране?
    • 15 Апреля 2015 18:03
      bee4
      на Хабре статейка есть об этом
  • 12 Января 2015 00:50
    igor.peschak
    Подскажите, как сделать то-же cамое, только на java?
  • 18 Февраля 2015 17:07
    AlinaBeawer
    Добрый день! Спасибо за урок, все получилось) Я совсем не разбираюсь в JS, подскажите, плиз: как сделать позиционирование всплывающего окна относительно области выделения (области на карте), а не относительно экрана? На моей схеме, во всплывающем окне не один флаг и название, а около 11 фирм сразу (Правый нижний край карты здание 1.) Пробовала средствами css- ничего не получилось(( Окно или сжимается или уходит за границу экрана. Видимо надо писать какое то условие в коде для размера окна в зависимости от количества текста и размещения справа или слева? Вот ссылка на песочницу http://jsbin.com/mimowi/2/watch?css,js,output
  • 27 Марта 2015 23:24
    allawitte
    Замечательный урок! Но у меня проблема. Здесь js ожидает, что координаты пути будут задаваться парами значений через запятую, типа "...342.88405,757.48513 C 343.14819,751.93816 341.82748,751.01365 ...", а я делаю определенную карту, и Иллюстратор сохраняет это как "M-495.3 211.6c-3.9-3.7-11.5-7.3-16.9-8l-12.2-1.5 ...." Как мне так это сохранить в Иллюстаторе, чтобы js читал координаты и не выдавал постоянно ошибку?
  • 14 Апреля 2015 11:28
    bee4
    Реализовали ли кто-нибудь это в Joomla?
  • 16 Апреля 2015 12:21
    Gruffi
    Что касается joomla - можно создать модуль html и туда запихнуть. По поводу перехода на новую страничку при клике: в init.js делаем так:
    .click(function(){ window.open(paths[arr[this.id]].url, 'NewWindow' + this.id);
    })
    
  • 14 Мая 2015 16:24
    gore88
    Всем привет! Подскажите, как сделать на карте, чтобы один из регионов по умолчанию был подсвечен?
  • 26 Мая 2015 20:37
    Марина Шутова
    Спасибо огромное за урок! подскажите, пожалуйста, как добавить надписи к странам на карту?
  • 2 Июня 2015 16:00
    mozhby
    "Затем открываем карту SVG и видим XML код. К счастью, нам нужно только одно значение, которое называется d." скачал я карту http://commons.wikimedia.org/wiki/File:BlankMap-World6-Equirectangular.svg , открыл через нотпад++. Копирую любой D меняю на текущем примере, и не видно изменений. Может точки SVG нужно преобразовывать как-то? Не могу получить всю карту мира
  • 4 Августа 2015 21:51
    Serge89
    Как можно добавить id к path? в идеале, что бы id присваивался из name каждого path.
    • 9 Октября 2015 23:51
      ivaspbru
      у меня не получаеться добавлять в patchs второй 'd' показывает только первую и все. Начинаешь прописывать вторую карту, он ее не видет и хоть убейся об каленку, ковырком через плече. перепробовал все что можно. помогите...пжл
  • 12 Октября 2015 15:36
    Vdeo3
    Подскажите. Как выводить разный текст при нажатии на страны. Чтоб выводилось например несколько картинок и 1000 символов текста. Какой будет код? И куда добавлять? Подскажите пожалуйста
  • 17 Марта 2016 14:02
    Яна Новосёлова
    Добрый день, ребята! Может кто подскажет!На карту я должна попадать с другой страницы, где из таблички выбираю регион и перехожу на карту. Как сделать чтобы этот регион подсвечивался и сразу было активно окошко с инфой. Пожалуйста, кто чем может, помогите!
^ Наверх ^