Перейти к содержимому

Как сделать интерактивную карту в html

  • автор:

Как сделать интерактивную схему на SVG + jQuery

Как сделать интерактивную схему на SVG + jQuery

Задачу можно выполнить на основе векторной графики SVG, с помощью тегов и .

Итак, имеем картинку-подложку:

Над ней нужно абсолютно разместить холст и в нем разместить элементы , каждый магазин это отдельный элемент со своими координатами.

Координаты в теге задаются точками x,y разделенные пробелами.

Атрибут data-id=»1″ потребуется для связки полигона c названием магазина.

.scheme < height: 393px; width: 738px; margin: 0 auto; position: relative; >.scheme svg < position: absolute; top: 0px; left: 0px; height: 393px; width: 738px; >.scheme polygon

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

Как добавить интерактивную карту на сайт

�� Что делаем: добавляем интерактивную карту Яндекса на свой сайт, чтобы показать схему проезда или где находится офис или пункт выдачи. Для этого будем использовать возможности эмбеда.

�� Время: 3 минуты.

Понадобится: аккаунт в Яндексе.

�� Коротко суть: у карт Яндекса есть специальный сервис, который помогает сделать интерактивный фрагмент карты местности и добавить туда нужные обозначения — например, где находится офис или как до него добраться.

Собираем карту

Входим в свой аккаунт, переходим на страницу конструктора карт Яндекса и нажимаем «Создать карту»:

Как добавить интерактивную карту на сайт

Перед нами откроется панель конструктора, где мы можем подготовить карту — добавить на неё нужные объекты и области:

Как добавить интерактивную карту на сайт

Например, если нам нужно показать, где именно находится офис или точка выдачи заказов, используем кнопку «Метки» — она добавит метку на карту, а мы заполним её описание:

Как добавить интерактивную карту на сайт

Меток на карту можно добавлять сколько угодно, а ещё настраивать их цвет и внешний вид. Кроме метки на карту можно нанести линии — например схему проезда — и области. За области отвечают «Многоугольники»:

Как добавить интерактивную карту на сайт

Когда на карту добавлено всё, что нужно, нажимаем «Сохранить и продолжить».

Получаем код для вставки

Всё, что нужно от нас на этом этапе, — подобрать размеры и начальный масштаб карты. Так как нам нужна интерактивная версия карты, выбираем вариант «Вставить на сайт» и «Интерактивная карта»:

Как добавить интерактивную карту на сайт

Когда масштаб выбран — нажимаем «Получить код карты» и копируем себе код вставки:

Как добавить интерактивную карту на сайт

JavaScript или iframe?

Если у вас на сайте есть возможность вставить готовый код JavaScript, выбирайте его — это более современный и надёжный подход.

Иногда системы управления контентом «режут» такой код. Если у вас он не заработает, попробуйте iframe. Справедливости ради, если вам «зарезали» JS, то iframe, вероятнее всего, тоже зарежут.

Добавляем код на сайт

Последнее, что нам осталось сделать, — добавить код в нужное место на сайте. Например, чтобы добавить карту сразу после заголовка страницы, достаточно вставить код после тега :

    Карта  

Добавляем карту на страницу

Как добавить интерактивную карту на сайт

Ограничение

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

Правда, это довольно маловероятно, учитывая то, что Яндекс выдержал самую крупную в истории интернета DDoS-атаку. Кстати:

Веб-разработка — это новый чёрный

На базе веб-технологий делают всё — от сложного софта до высокобюджетных игр. Изучите технологии и начните карьеру в ИТ. Старт бесплатно. Попробуйте, вдруг вам понравится.

Создание интерактивной карты SVG Map

Интерактивная карта (SVG Map) так же, как и карта изображений (Image Map), позволяет привязывать ссылки и события к фрагментам изображения. Но, в отличие от Image Map, SVG карта не теряет четкости при изменении размера, а создание участка сложной формы в SVG не настолько трудоёмко.

Для построения SVG карты можно использовать любой векторный редактор. Например, Adobe Illustrator или CorelDRAW.

Применение SVG карт

SVG карты применяются для привязки событий или ссылок к различным произвольным участкам изображения. Это могут быть карты стран, регионов, городов, а также планы зданий.

В качестве примера приведена карта Краснодарского края с тремя выделенными районами, в которых расположены сахарные заводы концерна Покровский. При наведении указателя мышки на определенный район у его изображения меняется цвет заливки с помощью CSS и псевдокласса hover, а с помощью скрипта, срабатывающего по возникновению события onmouseover, появляется поясняющая надпись.

Пример использования SVG карты
 .b-map-svg < position: relative; >#kanev, #kurgan, #timash 
g .fil2 g:hover .fil2 .fil3 g:hover .fil3 .fil0 .fil4 g:hover .fil4 .fil5 .fil1 .fil6
ПАО «КАНЕВСКСАХАР»
Каневской район
ООО «ТИМАШЕВСКИЙ САХАРНЫЙ ЗАВОД»
Тимашевский район
ЗАО «САХАРНЫЙ КОМБИНАТ «КУРГАНИНСКИЙ»
Курганинский район

HTML и SVG: создаём интерактивную карту

Давайте создадим интерактивную карту. Чего-нибудь. Что значит интерактивную? Ну, она должна взаимодействовать с пользователем и с данными на веб-странице, на которой она расположена. Думаю, этого достаточно, чтобы считать её интерактивной.

Что же, и возьмём мы SVG. Почему? Да потому что с ним легко работать человеку, знакомому с HTML. SVG — это векторный формат, основанный на XML. То есть у SVG-рисунка есть своя DOM, к различным элементам можно применять CSS-правила и управлять старым добрым JavaScript’ом.

Что же, начнём?

Самые нетерпеливые, могут сразу посмотреть демо, но я предлагаю читать обо всём по порядку.

Готовим карту

Для начала нам нужна суть. То бишь сама карта. В случае, если гугл не помогает, то её можно нарисовать и самому, даром что в Inkscape это сделать не трудно.

Я же, к примеру, возьму карту одной круглой страны (исходник на Wikimedia Commons)

Поскольку, по моему замыслу, у областей карты не должно быть различного окраса, то вначале я вырезаю из интересующих меня тегов стили fill и stroke, зато взамен даю этим элементам нужные мне class и id. Например, для регионов и для городов.

Далее, в секции изображения помещаем до боли знакомое:

 .area < stroke: black; stroke-width: 2px; fill: #E9FFE9; >.city 

Вот и обещанный мною CSS в действии. В принципе, этого уже достаточно. Diff.

Результат:

Вставляем SVG в HTML

Достаточно подробно этот процесс был освещён в хабратопике К вопросу о кроссбраузерном использовании SVG.

Мы же будем использовать HTML5 и воспользуемся самым простым, гуманным и стандартным способом:

Все браузеры, поддерживающие SVG, его корректно «скушают» и покажут. И даже дадут нам с ним поработать. При одном условии: если веб-сервер отдаст его с MIME-типом image/svg+xml. Другой MIME-тип может очень смутить Google Chrome (но не Оперу, которая из тега твёрдо знает, что идёт за SVG и на провокации не поддаётся).

Второй правильный метод — вставка SVG-кода прямо в HTML. Великолепно с точки зрения скриптинга, но поддержка браузерами пока похуже. Кстати, заметьте, что SVG, вставленный в «либеральный» HTML, всё-таки остаётся «суровым» XML’ем. Так что кавычки и закрывающие теги обязательны.

Подводные грабли

Но не всё так просто. Сразу можно заметить, что браузеры упорно не хотят масштабировать нашу карту, а если она не влезает, то показывают полосы прокрутки, вот так:

Чтобы заставить браузеры работать с SVG так, как мы ожидаем, следует убрать в SVG-файле из тега атрибуты width и height (или задать им значения в 100%), а вставить специально предназначенный для браузеров атрибут viewBox со значениями координат левого верхнего и правого нижнего углов изображения:

viewBox="0 0 493 416"

После этого ситуация значительно улучшается, но другую граблю нам подкладывает Google Chrome: он упорно стремится смасштабировать картинку по высоте до высоты элемента , а не увеличить высоту согласно ширине тега и пропорциям изображения, как ведут себя остальные браузеры.

Жаль. Придётся привлечь JavaScript и подогнать высоту элемента вручную.

var viewBox = svgdom.rootElement.getAttribute("viewBox").split(" "); var aspectRatio = viewBox[2] / viewBox[3]; svgobject.height = parseInt(svgobject.offsetWidth / aspectRatio);

Результат:

Взаимодействуем с SVG

Чтобы нам взаимодействовать с SVG, вписаннным прямо в HTML, ничего не нужно — он уже часть DOM веб-страницы.

Получить доступ к SVG, вставленным через чуть сложнее:

jQuery(window).load(function () < // Нам нужно дождаться, пока вся графика (и наша карта тоже) загрузится, поэтому используем window.onload, var svgobject = document.getElementById('svgmap'); // Находим тег if ('contentDocument' in svgobject) < // У нас действительно там что-то есть? var svgdom = jQuery(svgobject.contentDocument); // Получаем доступ к объектной модели SVG-файла // Теперь делаем свою работу, например: jQuery("#figure1", svgdom).attr("fill", "red"); // Находим тег с в SVG DOM и заливаем его красным >>);

Да, jQuery работает с SVG, но только частично. Например, я заметил, что не работают функции addClass и removeClass, а так же поиск по классам ( jQuery(«.class») ). Приходится извращаться.

Заметьте, что я использую событие window.onload, так как нам необходимо дождаться полной загрузки страницы, вместе со всеми связанными элементами (в числе которых и наша карта). Однако и тут Google Chrome спешит подложить нам свинью: в том случае, если скрипт с window.onload находится в html-коде до тега , то код в обработчике выполняется ДО того, как карта на самом деле загрузится. Поэтому тег необходимо разместить после нашей карты. Sad but true.

Интерактивность первая: выделяем районы на карте щелчком по чекбоксу на странице.

Для этого взаимодействия нам понадобятся чекбоксы в каждой строке таблицы с районами, а так же совпадающие или схожие id у строк таблицы и районов на карте.

Здесь мы будем при щелчке по флажку ставить или убирать класс selected у соответствующей области на карте, а так уже у самой строки. Это несложно:

$("#areas input[type=checkbox]").change(function() < var row = $(this).parent().parent(); var if (this.checked) < row.addClass("selected"); $("#"+id, svgdom).myAddClass("selected"); >else < row.removeClass("selected"); $("#"+id, svgdom).myRemoveClass("selected"); >>);

Соответственно, нужно добавить и стилевые определения для данного класса. Предоставляю вам это сделать самостоятельно, согласно своих вкусов и предпочтений. Diff.

Интерактивность вторая: вскрываем/показываем названия на карте щелчком по чекбоксу на странице.

Это взаимодействие делается ещё проще. Вставляем на страницу и немножко яваскрипта, который добавляет/удаляет всем связанным с названиями элементам на карте класс hidden :

$("#titleswitch").change(function () < var elements = $(svgdom.getElementsByClassName("areatitle")) .add($(svgdom.getElementsByClassName("citytitle"))) .add($(svgdom.getElementsByClassName("titlebox"))) .add($(svgdom.getElementsByClassName("titleline"))); if (this.checked) < elements.myAddClass("hidden"); >else < elements.myRemoveClass("hidden"); >>);

Вот так.

Интерактивность третья: подсвечиваем районы на карте при наведении на строку таблицы (и наоборот)

Для этого необходимо повешать обработчики события onhover как на таблицу:

// Подсвечиваем регион на карте при наведении мыши на соотв. строку таблицы. $("#areas tr").hover( function () < var $("#"+id, svgdom).myAddClass("highlight"); >, function () < var $("#"+id, svgdom).myRemoveClass("highlight"); >); 

…так и на районы на карте:

// Подсвечиваем строку в таблице при наведении мыши на соотв. регион на карте $(svgdom.getElementsByClassName("area")).hover( function () < var $("#areas #"+id).addClass("highlight"); >, function () < var $("#areas #"+id).removeClass("highlight"); >);

Для того, чтобы мы это видели, добавим соответствующие CSS-правила в страницу:

tr.highlight, tr:hover, tr:nth-child(even):hover

…и в SVG-карту:

.highlight, .area:hover

При наведении мышкой на строку таблицы (или на район на карте) на соответствующий район на карте (на строку таблицы) вешается нужный для подсвечивания класс. Чтобы приведённый выше код работал, необходимо, чтобы у районов на карте и строк таблицы были совпадающие (или схожие) id. Diff.

Интерактивность четвёртая: Отображаем данные со страницы на карте

Ну что же, банальное присваивание классов, наверное, уже наскучило. Пускай карта нам показывает на себе какие-нибудь данные.

Перво-наперво: данные. Добавим к нашей табличке пару столбцов, например «Люди» и «Деньги». Внимание: Данные взяты от балды и никакого отношения к реальному Аместрису не имеют. А так же радиокнопки, по которым будем переключать, какие данные показывать.

Во-вторых, нам нужно место на карте, где будут отображаться данные. Добавим на карту пять блоков (по одному на каждый регион, соотнеся их id с регионами) и соответствующие стили в :

Ну и JavaScript-код, который будет брать данные из ячеек таблицы и помещать в блоки текста:

$("input[name=tabledata]").change(function () < var descnum = $(this).parent().prevAll().length+1; $("#areas tbody tr").each(function() < var var value = $(this).children(":nth-child("+descnum+")").text(); $("#text"+id, svgdom).text(value); >); >);

И по переключению радиокнопок карта будет показывать нужные цифры. Вуаля!

Интерактивность пятая: всплывающие подсказки

Возможно, это уже и лишнее, но пусть будет. Для ровного счёта.

Для данного взаимодействия возьмём плагин jQuery.tooltip и привяжем его к областям на карте. Текст для подсказок будем брать, конечно же, из таблицы:

$(svgdom.getElementsByClassName("area")).tooltip(< bodyHandler: function() < var var area = $("#areas #"+id+" td:nth-child(2)").text(); var result = $("

").append($("").text(area)); $("#areas #"+id+" td:nth-child(2)").nextAll().each(function()< var pos = $(this).prevAll().length+1; var title = $("#areas thead th:nth-child("+pos+")").text(); var value = $(this).text(); result.append($("

").text(title + ": " + value)); >); return result; > >);

Diff.

И так далее…

Разумеется, этим возможности взаимодействия с SVG не ограничиваются. Вы можете делать всё. Перетасовывать DOM, менять страницу и SVG по AJAX-запросам и многое, многое другое. Дерзайте.

Результат

Оставшиеся подводные камни

Из известных проблем пока что можно отметить, что Google Chrome не выводит на печать SVG-картинки. Это или его баг или баг WebKit в целом.

Обратная совместимость

Почти все современные браузеры поддерживают SVG: IE 9+, Opera 8+, Firefox 3+ (в Firefox 1.5+ частичная поддержка), Chrome всех версий, Safari 3.2+ (более полный список)

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

Стандартный и самый простой путь, если SVG — это просто картинка: вставляем замещающее содержимое (отрендеренную в PNG картинку и абзац текста) внутрь тега .

  Неинтерактивная карта

К сожалению, вы используете устаревшую версию браузера, который не поддерживает интерактивную карту.

Если в браузере поддержки SVG нет, будет показана PNG-картинка и текст, уведомляющий пользователей, что их браузер устарел. Никакого интерактива. Впрочем, он, может быть, не очень-то и нужен. Правда, есть один минус — как я заметил, современные браузеры упорно скачивают себе замещающую png-картинку, несмотря на то, что они её всё равно не отобразят.

Желающие могут воспользоваться детектированием поддержки SVG с помощью Modernizr и наворотить на яваскрипте что-нибудь посложнее.

В более сложных случаях вам могут помочь многочисленные решения на Flash, VML или Canvas (или на всех вместе). Список можно посмотреть здесь: HTML5 Crossbrowser Polyfills, но те решения, которые я опробовал, мне, к сожалению, не помогли. Возможно потому, что тот SVG c CSS’ом, что я набросал на коленке — оказался им не по зубам.

Конвертирование SVG в PNG

В сети есть много мест, где можно конвертнуть SVG-картинку во что-нибудь другое. Я же предложу воспользоваться командой rsvg-convert из пакета librsvg2-bin. Примерно вот так:

cat map.svg | rsvg-convert > map.png

Впрочем, она может преобразовывать и в другие форматы, а так же увеличивать/уменьшать картинку, смотрите —help.
Для массовых преобразований можно сочинить команду посложнее или посмотреть примеры в форумной ветке, где я эту команду и нашёл.

Вместо заключения

Ну вот и всё. При ближайшем рассмотрении это не так уж и сложно, а главное — всё близко и знакомо веб-разработчику. Смотрите, о чём я написал выше в виде демо-страницы, раздирайте исходный код из репозитория, если есть предложения и улучшения — высказывайте в комментариях или присылайте в репозиторий в виде пулл реквестов. Приятной вам работы с современными веб-технологиями!

  • Веб-разработка
  • JavaScript

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

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

https://kapelnicza.vyvod-iz-zapoya-v-stacionare-samara12.ru/