Javascript:创建可拖动的元素,这些元素相互推开

Javascript:创建可拖动的元素,这些元素相互推开,javascript,jquery,jquery-ui,Javascript,Jquery,Jquery Ui,我想有一系列的盒子,可以拖在一个框架。当他们接触到另一个盒子时,它会被推开——如果你愿意,它会被排斥 我只是不知道从哪里开始,除了让他们拖拉 为了扩展我的评论并向您展示一个可能的概念证明,我创建了以下代码: HTML <div id="move-frame"> <div id="obj-1" class="drag"> <span class="top">T: 2</span> <span class="left">

我想有一系列的盒子,可以拖在一个框架。当他们接触到另一个盒子时,它会被推开——如果你愿意,它会被排斥


我只是不知道从哪里开始,除了让他们拖拉

为了扩展我的评论并向您展示一个可能的概念证明,我创建了以下代码:

HTML

<div id="move-frame">
  <div id="obj-1" class="drag">
    <span class="top">T: 2</span>
    <span class="left">L: 2</span>
    <span class="bottom">B:</span>
    <span class="right">R:</span>
  </div>
  <div id="obj-2" class="no-drag">
    <span class="top">T: 125</span>
    <span class="left">L: 175</span>
  </div>
</div>
jQuery用户界面

$(function() {
  var stuff = {};

  $(".no-drag").each(function(k, v) {
    var id = $(v).attr("id");
    var top = $(v).position().top;
    var left = $(v).position().left;
    var bottom = top + $(v).height();
    var right = left + $(v).width();
    stuff[k] = {
      id: id,
      top: top,
      left: left,
      bottom: bottom,
      right: right
    };
  });
  console.log(stuff);

  $("#obj-1").draggable({
    containment: '#move-frame',
    drag: function(e, ui) {
      var objW = ui.helper.width();
      var objH = ui.helper.height();
      var objP = ui.position;
      var buffer = 2;

      objP.right = objP.left + objW;
      objP.bottom = objP.top + objH;

      $(this).find(".top").html("T: " + objP.top);
      $(this).find(".left").html("L: " + objP.left);
      $(this).find(".bottom").html("B: " + objP.bottom);
      $(this).find(".right").html("R: " + objP.right);

      $.each(stuff, function(k, v) {
        if (objP.right == v.left - buffer) {
          var $el = $("#" + v.id);
          $el.css("left", v.left + buffer);
          v.left += buffer;
          $el.find(".top").html("T: " + $el.position().top);
          $el.find(".left").html("L: " + $el.position().left);
        }
        if (objP.bottom == v.top - buffer) {
          var $el = $("#" + v.id);
          $el.css("top", v.top + buffer);
          v.top += buffer;
          $el.find(".top").html("T: " + $el.position().top);
          $el.find(".left").html("L: " + $el.position().left);
        }
      });
    }
  });
});

有很多方法可以改进这一点。您可以看到,拖动缓冲区非常容易,但是如果移动缓慢,您会用绿色框轻推蓝色框。您还可以看到一些间隙问题,例如,如果您缓慢地将绿色框移过来,但不在同一Y平面上,蓝色框仍可以移动。

您可以从这里开始,谢谢,我已经解决了这一点——这让我头疼的是,让东西从拖拽的方式移开。你可以试着在snap示例中检查他们是如何进行坐标检测的,而不是snap——移开你的块哦,实际上这是snap参数,所以你需要编写自己的,我猜这最终将是一个相当复杂的答案。目前还没有一种方法可以做到这一点。让我们举一个用例,您在左侧有一个对象,然后将其沿X向右拖动。当对象的右边缘遇到另一个对象时,这两个对象应一起向右移动,但不能重叠。单独的边缘检测将是困难的。您需要1)知道对象的右边缘在哪里,2)其他对象的左边缘,3)鼠标和对象右边缘的偏移,4)边碰撞时。到目前为止你试过什么?
$(function() {
  var stuff = {};

  $(".no-drag").each(function(k, v) {
    var id = $(v).attr("id");
    var top = $(v).position().top;
    var left = $(v).position().left;
    var bottom = top + $(v).height();
    var right = left + $(v).width();
    stuff[k] = {
      id: id,
      top: top,
      left: left,
      bottom: bottom,
      right: right
    };
  });
  console.log(stuff);

  $("#obj-1").draggable({
    containment: '#move-frame',
    drag: function(e, ui) {
      var objW = ui.helper.width();
      var objH = ui.helper.height();
      var objP = ui.position;
      var buffer = 2;

      objP.right = objP.left + objW;
      objP.bottom = objP.top + objH;

      $(this).find(".top").html("T: " + objP.top);
      $(this).find(".left").html("L: " + objP.left);
      $(this).find(".bottom").html("B: " + objP.bottom);
      $(this).find(".right").html("R: " + objP.right);

      $.each(stuff, function(k, v) {
        if (objP.right == v.left - buffer) {
          var $el = $("#" + v.id);
          $el.css("left", v.left + buffer);
          v.left += buffer;
          $el.find(".top").html("T: " + $el.position().top);
          $el.find(".left").html("L: " + $el.position().left);
        }
        if (objP.bottom == v.top - buffer) {
          var $el = $("#" + v.id);
          $el.css("top", v.top + buffer);
          v.top += buffer;
          $el.find(".top").html("T: " + $el.position().top);
          $el.find(".left").html("L: " + $el.position().left);
        }
      });
    }
  });
});