перетаскивая элемент DROPABLE в определенную точку на фоновом изображении - PullRequest
0 голосов
/ 25 сентября 2018

Я пытаюсь создать простую обучающую игру, где флаг перетаскивается в правильное место на фоновом изображении карты.Так что я знаю, как сделать флаг (ы) перетаскиваемым и сбрасываемым, но не знаю, как сделать область сбрасывания этой конкретной точкой на карте.

Вот что у меня есть:

    <!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>temperate journeys</title>

<style>
    #flags{float:left; height:100px;width:35px; padding:2px;margin-right: 10px;}
    #china{height:20px; width:25px; background-color:red; border: 1px solid #B7191C;padding:3px;}
    .china{height:22px; width:27px; background-color:green; border: 1px solid green;}
    #australia {height:20px; width:25px; background-color:blue; border: 1px solid #3324AF;padding:3px;}
    </style>
 <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
  <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  <script>
  $( function() {
    $( "#china" ).draggable();
     $( "#australia" ).draggable(); 
     $( ".china" ).droppable({accept:"#china"});  
  } );
  </script>
</head>

<body>

    <div id="flags">
    <div id="china"> Ch </div>
    <div id="australia">Au</div>    


    </div>
<img src="map.gif" 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>
</body>

1 Ответ

0 голосов
/ 26 сентября 2018

Попытка использовать 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() тоже выполняет свою работу.Выбери свой яд.

Надеюсь, это поможет.Кроме того, это не единственный способ сделать это, и вам придется решить, будет ли это полезно для вашего сценария.

...