Привет. Давеча мне довелось иметь дело с такой специфической фичей html как карта изображения. Скажу честно, что мне не часто доводилось использовать её, и то, обычно, всё обходилось зонами в форме прямоугольника. Но это был не тот самый случай. Задачей было повесить ссылки на отдельные регионы изображения, которым выступала карта страны, и, к сожалению, ни о каких канвасах или svg не могло быть и речи. Только html только хардкор! Итак, задача поставлена, гугл активизирован, можно и начинать.
Теория
Начнём пожалуй с теории, куда ж без неё. Карта изображения содержит в себе два тега: 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>'));
};
Обрамим всё в класс, немного вспомогательных функций, вот и всё. Надеюсь кому-то будет полезна сея тулза.
Ссылки
Автор: SerDIDG