Попытка использовать Image-Map с Droppable не будет веселой и не получится так, как вы хотите.
Тег <area>
определяет область внутри карты изображений(изображение-карта - это изображение с интерактивными областями).
Элемент <area>
всегда вложен в тег.
Примечание: Атрибут usemap вТег <img>
связан с атрибутом имени элемента <map>
и создает связь между изображением и картой.
Что это означает, когда речь заходит о нашем пользовательском интерфейсе?Ну, это как бы предполагает, что элемент <area>
не квалифицируется как элемент в том же смысле, что и <img>
или <div>
.Это скорее ссылка на координаты, которые будут использоваться для проверки, была ли нажата область или нет.Он находится в DOM, но его блочная модель совпадает с изображением, с которым он связан.Таким образом, $("map .china")
будет иметь такую же ширину и положение, что и изображение.
Это не значит, что оно не может быть полезным.Каждый элемент <area>
все еще имеет атрибуты, которые определяют координаты.Таким образом, $("map .china").attr("coords")
приведет к "346,118,397,153"
, и мы можем что-то сделать с этой строкой!
Голы
- Разрешить пользователю перетаскивать флаг вкарта
- После сброса определить, находится ли флаг в пределах координат
- Укажите пользователю, попал ли он в цель или не попал в нее
- (Вернуть флаг в исходное положение?)
Пример
https://jsfiddle.net/Twisty/saufz8tg/
HTML
<div class="drag-area">
<div id="flags">
<div id="china" class="flag" title="China">Ch</div>
<div id="australia" class="flag" title="Autstralia">Au</div>
</div>
<img class="map-image" src="https://www.wpclipart.com/dl.php?img=/geography/world_maps/world_map_basic_color.png" alt="" width="520" height="289" usemap="#Map" />
<map name="Map">
<area class="china" shape="rect" coords="346,118,397,153" href="#" target="_self">
<area shape="rect" coords="409,209,461,240" class="australia" target="_self">
</map>
</div>
Не многоизменений здесь.A <div>
, чтобы помочь обернуть и содержать вещи.Еще несколько классов, которые помогут организовать и назначить стили.
CSS
#flags {
float: left;
height: 100px;
width: 35px;
padding: 2px;
margin-right: 10px;
}
.flag {
height: 20px;
width: 25px;
margin-bottom: 1px;
border: 1px solid #B7191C;
border-radius: 3px;
padding: 3px;
}
#china {
background-color: red;
}
#australia {
background-color: blue;
}
Опять же, никаких существенных изменений.Просто очистить и упростить организацию, меньше повторять код.
JavaScript
$(function() {
function getObjCoords(o) {
var p = o.position();
var d = {
width: o.width(),
height: o.height()
};
var coords = [
p.left, // X1
p.top, // Y1
p.left + d.width, // X2
p.top + d.height // Y2
];
return coords;
}
function getObjCenter(o) {
var p = o.position();
var d = {
width: o.width(),
height: o.height()
}
var c = [
parseInt(p.left + (d.width / 2)),
parseInt(p.top + (d.height / 2))
];
return c;
}
function hit(o, t, off) {
var x, y;
var center = getObjCenter(o);
var hit = false;
if (center[0] > (t[0] + off.left) && center[0] < (t[2] + off.left)) {
x = true
} else {
x = false;
}
if (center[1] > (t[1] + off.top) && center[1] < (t[3] + off.top)) {
y = true;
} else {
y = false;
}
if (x && y) {
hit = true;
}
return hit;
}
var $mapArea = $("map[name='Map']");
var imgOff = $(".map-image").position();
console.log("Image Position:", imgOff);
$(".flag").draggable({
containment: ".drag-area"
});
$(".flag").disableSelection();
$(".map-image").droppable({
drop: function(e, ui) {
var itemCenter = getObjCenter(ui.draggable);
console.log("Drop Center:", itemCenter);
var t = ui.draggable.attr("id");
var tPos = $mapArea.find("." + t).attr("coords").split(",");
$.each(tPos, function(k, v) {
tPos[k] = parseInt(v);
});
console.log("Target Coords:", tPos);
console.log("Target Offset: [ " + (tPos[0] + imgOff.left) + ", " + (tPos[1] + imgOff.top) + ", " + (tPos[2] + imgOff.left) + ", " + (tPos[3] + imgOff.top) + " ]");
if (hit(ui.draggable, tPos, imgOff)) {
console.log("Hit!");
return true;
} else {
console.log("Miss.");
return false;
}
}
});
});
Я выкладываю свой JavaScript / jQuery так: функции, константы и определение пользовательского интерфейса /Настроить.У нас есть три вспомогательные функции: getObjCoords()
, getObjCenter()
и hit()
.Я сравнил этот сценарий с игрой «Морской бой», поэтому использовал множество одинаковых терминов.
Я подозреваю, что у вас будет гораздо больше флагов и областей для их отбрасывания.Вот где эти вспомогательные функции вступают в игру.Мы оставим более тяжелый подъем для них и просто поработаем с нашими более простыми объектами в областях перетаскивания.
getObjCoords (jQuery Object)
Принимает jQueryObject и возвращает массив [x1, y1, x2, y2]
на основе положения и размеров объектов.
getObjCenter (jQuery Object)
Принимает объект jQuery и возвращает массив [x, y]
определение центра поля объекта.
hit (jQuery Object, Array Coords, Array Offset)
Определяет, находится ли Objects Center в пределах 4-х координат области.
Примечания
- Поскольку вы не определили, что делать с Hit или Miss, я просто отправляю это на консоль, когда флаг сбрасывается.Прямо сейчас флаг может быть сброшен, а затем снова перемещен.
.split()
используется для преобразования строки в массив, но это будет массив строк.JavaScript обычно принимает это, но для правильного сравнения я преобразовал их в целые числа. getObjCenter()
может использовать Math для округления значений.Помните, что деление нечетного целого числа приведет к длинному (3/2 = 1,5), а HTML не нравится половина пикселя.Вы можете использовать Math.round()
или Math.floor()
, но parseInt()
тоже выполняет свою работу.Выбери свой яд.
Надеюсь, это поможет.Кроме того, это не единственный способ сделать это, и вам придется решить, будет ли это полезно для вашего сценария.