Привет. Давеча мне довелось иметь дело с такой специфической фичей html как карта изображения. Скажу честно, что мне не часто доводилось использовать её, и то, обычно, всё обходилось зонами в форме прямоугольника. Но это был не тот самый случай. Задачей было повесить ссылки на отдельные регионы изображения, которым выступала карта страны, и, к сожалению, ни о каких канвасах или svg не могло быть и речи. Только html только хардкор! Итак, задача поставлена, гугл активизирован, можно и начинать.
Начнём пожалуй с теории, куда ж без неё. Карта изображения содержит в себе два тега: map — контейнер карты и area — зона выделения. Карта не ограничена одной зоной и может содержать неограниченное их количество. Тег area кроме стандартных атрибутов имеет и свои собственные:
Чтобы подключить карту к изображению, указываем тегу map атрибут name с произвольным именем, а на изображения вешаем тег usemap, значение которому указываем в формате "#имя".
Так как зона выделения у меня должна была быть многоугольной, значение атрибута shape, тега area, мы указываем как poly — полигональная область. В таком режиме через запятую указываются координаты точки относительно левого верхнего угла — x,y. Точки также разделяются запятыми, что по началу при чтении такого кода вызывает недоумение.

Меня не тешила перспектива фотошопом находить координаты каждой точки, переписывать вручную цифры с окошка Info, а инструменты, которые попадались в гугле, были слишком монструозны. Было принято решения на коленке написать свой небольшой скрипт, который бы позволял расставлять точки просто кликая по нужной зоне на изображении, и выводил бы готовый код.
Для начала подготовим вёрстку:
В #bar будут вставляться кнопки для управления «пеинтом».
В #info будет выводится сгенерированный html код.
CSS:
В javascript'е всё достаточно просто. В процессе написания я использовал свою боевую библиотечку, так что не удивляйтесь нестандартным функциям. Для начала повесим событие mousedown на #canvas, в котором будет рендериться точка на изображении и записываться её координаты.
Затем напишем функцию, которая будет генерировать html код нашей карты.
Обрамим всё в класс, немного вспомогательных функций, вот и всё. Надеюсь кому-то будет полезна сея тулза.
Демо.
Сурсы (~60 KB).
GitHub
PS. Добавил ссылку на гитхаб.
PS2. Теперь «paint» работает на канвасе.
Теория
Начнём пожалуй с теории, куда ж без неё. Карта изображения содержит в себе два тега: map — контейнер карты и area — зона выделения. Карта не ограничена одной зоной и может содержать неограниченное их количество. Тег area кроме стандартных атрибутов имеет и свои собственные:
- coords — координаты зоны выделения
- href — ссылка, на которую будет произведён переход при клике на зону
- nohref — указывает на то, что зона не содержит ссылки
- shape — форма выделения
- circle — зона выделения в виде круга
- default — выделяет всю зону изображения
- poly — зона выделения в виде многоугольника
- rect — зона выделения в виде прямоугольника
- target — определяет где будет открываться ссылка
Чтобы подключить карту к изображению, указываем тегу map атрибут name с произвольным именем, а на изображения вешаем тег usemap, значение которому указываем в формате "#имя".
Так как зона выделения у меня должна была быть многоугольной, значение атрибута shape, тега area, мы указываем как poly — полигональная область. В таком режиме через запятую указываются координаты точки относительно левого верхнего угла — x,y. Точки также разделяются запятыми, что по началу при чтении такого кода вызывает недоумение.

<img src="sample.png" width="200" height="200" alt="Sample" usemap="#sample"> <map name="sample"> <area shape="poly" coords="30,100,100,30,100,170,170,100"> </map>
Пишем Paint
Меня не тешила перспектива фотошопом находить координаты каждой точки, переписывать вручную цифры с окошка Info, а инструменты, которые попадались в гугле, были слишком монструозны. Было принято решения на коленке написать свой небольшой скрипт, который бы позволял расставлять точки просто кликая по нужной зоне на изображении, и выводил бы готовый код.
Для начала подготовим вёрстку:
<div class="canvas" id="container"> <div class="inner" id="canvas"> <img src="img/sample.jpg" width="934" height="407" alt="Sample"> </div> </div> <div class="bar" id="bar"></div> <div class="info" id="info"></div>
В #bar будут вставляться кнопки для управления «пеинтом».
В #info будет выводится сгенерированный html код.
CSS:
body { margin: 0; padding: 20px; font-family: Arial, Helvetica, sans-serif; } img { border: none; outline: none; display: block; -moz-user-select: none; -webkit-user-select: none; user-select: none; } .canvas { border: 2px solid #333; padding: 2px; margin-bottom: 16px; display: inline-block; //display: inline; //zoom:1; } .canvas.draw { border-color: #3C0; } .canvas .inner { position: relative; } .canvas .point { width: 1px; height: 1px; background-color: #fff; border: 1px solid #000; overflow: hidden; position: absolute; } .bar { margin-bottom: 16px; } .info { background-color: #FCFCFC; border: 1px dotted #CCC; font-size: 12px; font-style: italic; padding: 8px; word-wrap: break-word; }
В javascript'е всё достаточно просто. В процессе написания я использовал свою боевую библиотечку, так что не удивляйтесь нестандартным функциям. Для начала повесим событие mousedown на #canvas, в котором будет рендериться точка на изображении и записываться её координаты.
var addPoint = function(e){ var e = _.getEvent(e), offset = _.getOffset(nodes['canvas']), x = e.clientX + _.getDocScrollLeft() - offset[0], y = e.clientY + _.getDocScrollTop() - offset[1], node = nodes['canvas'].appendChild(_.node('div', {'class':'point'})); node.style.top = y-1+'px'; node.style.left = x-1+'px'; points.push({'x' : x, 'y' : y, 'node' : node}); e.preventDefault && e.preventDefault(); return false; };
Затем напишем функцию, которая будет генерировать html код нашей карты.
var renderInfo = function(){ var text; _.clearNode(nodes['info']); nodes['info'].appendChild(_.node('span', '<map>')); nodes['info'].appendChild(_.node('br')); for(var i = 0, l = areas.length; i < l; i++){ if(areas[i].length > 0){ text = '<area shape="poly" coords="'; for(var i2 = 0, l2 = areas[i].length; i2 < l2; i2++){ if(i2 > 0){ text += ','; } text += areas[i][i2]['x'] + ',' + areas[i][i2]['y']; } text += '">'; nodes['info'].appendChild(_.node('span', text)); nodes['info'].appendChild(_.node('br')); } } nodes['info'].appendChild(_.node('span', '</map>')); };
Обрамим всё в класс, немного вспомогательных функций, вот и всё. Надеюсь кому-то будет полезна сея тулза.
Ссылки
Демо.
Сурсы (~60 KB).
GitHub
PS. Добавил ссылку на гитхаб.
PS2. Теперь «paint» работает на канвасе.
