我有一个包含可拖动/可拖放元素的页面,该元素一旦被拖放,就需要计算它们可能接触的其他可拖动元素的左侧位置和宽度。

它本身并不太难,但是我真正遇到麻烦的地方是让他们填补空白。如何使可拖动对象填充空白区域而又不加倍叠加?

// $t is the element being added/dropped.
// nd refers to New Dimensions, IE, the new dimensions for $t
// existingDivs gets any DIV's that have already been added to the dom
var $t = $(this), nd = {t:$t.position().top, h:$t.height(), l: 0, w: 95},
  existingDivs = $('#container .subContainer .draggable'), intersectArr = [],
  nonIntersectArr = [], finalArr = [];

// If there are no DIV's in the DOM you dont need to check if they intersect.
if (existingDivs.length > 0) {
// Find the DIV's that Intersect with the one being added
  intersectArr = $.grep(existingDivs, function(val,num){
    // xd is Existing Dimensions, for the current item being checked
    // verse the one being added.
    var $t2 = $(val), xd = {h:$t2.height(), w:parseFloat($t2.css('width')),
    l:parseFloat($t2.css('left')), t:$t2.position().top};
    // If they intersect add it to this array
    return ((xd.t <= nd.t && xd.t+xd.h > nd.t) ||
    (nd.t <= xd.t && nd.t+nd.h > xd.t));
  });
// Find the DIV's that DO NOT Intersect with the one being added
  nonIntersectArr = $.grep(existingDivs, function(val,num){
    // xd is Existing Dimensions, for the current item being checked
    // verse the one being added.
    var $t2 = $(val), xd = {h:$t2.height(), w:parseFloat($t2.css('width')),
    l:parseFloat($t2.css('left')), t:$t2.position().top};
    // If they DO NOT intersect add it to this array
    return ((xd.t > nd.t && xd.t > nd.t+nd.h) ||
    (nd.t > xd.t && nd.t > xd.t+xd.h));
  });
// For every element that does not intersect, check it verse the ones that do
  $(nonIntersectArr).each(function(){
    // nid is Non Intersecting Dimensions
    var $t2 = $(this), c = 0, nid = {h:$t2.height(),
    w:parseFloat($t2.css('width')),
    l:parseFloat($t2.css('left')), t:$t2.position().top};
    $(intersectArr).each(function(){
    // id is Intersecting Dimensions
      var $t3 = $(this), id = {h:$t3.height(), w:parseFloat($t3.css('width')),
      l:parseFloat($t3.css('left')), t:$t3.position().top};
    // if the non intersecting hits one that is intersecting, then there is no space
    // beneath/near it, so we add it to the final intersecting array then increment c
      if((id.t <= nid.t && id.t+id.h > nid.t) ||
      (nid.t <= id.t && nid.t+nid.h > id.t)){ finalArr.push(this); c++; }
      else { finalArr.push(this); }
    });
    // if c has been incremented, we cant use this nonIntersect, so add it to the final
    if(c > 0) { finalArr.push(this); }
  });
  // make sure all items in the final Array are unique
  finalArr = $.unique(finalArr);
  // iterate over the final array, processing the dimensions of each element in the
  // array layering them so you can see each one
  $(finalArr).each(function(num){
    // xd is Existing Dimensions, for the current item being checked
    // verse the one being added.
    var $t2 = $(this), xd = {h:$t2.height(), w:parseFloat($t2.css('width')),
    l:parseFloat($t2.css('left')), t:$t2.position().top};
    if(((xd.t <= nd.t && xd.t+xd.h > nd.t) ||
    (nd.t <= xd.t && nd.t+nd.h > xd.t))) {
      if(nd.l == xd.l){
        nd.w = ((95/(finalArr.length+1))*1.5);
        xd.l = ((nd.w)*(num));
        $(finalArr).each(function(ci){
          $(this).css({left:((nd.w*ci)*0.58)+'%',
          width:((95/(finalArr.length+1))*1.5)+'%'});
          nd.l = ((nd.w*ci)*0.58);
        });
      }
    }
  });
}
// Add the New Element to the container and position accordingly.
nd.l = ((nd.l/finalArr.length)*(finalArr.length+1))+'%';
nd.w = nd.w+'%';
$('#container .subContainer').append('<div style="top:'+nd.t+'px;left:'+nd.l+
';width:'+nd.w+';height:'+nd.h+'px;" class="dragId_'+$t.attr('id')+
' draggable"><div class="title">'+$t.attr('title')+'</div></div>');


任何建议/帮助将不胜感激。谢谢。

最佳答案

这是您需要执行的算法:


当有形状触摸时,找出最右边的形状(具有最大右x坐标的形状)正在触摸另一个形状。移动它,使其左边缘位于刚接触的最右边的形状的右边。
尽管有些形状不位于其左侧的某物旁边,但应找出其最小x坐标位于其左侧某物旁边的形状。移动它,使其左边缘恰好位于形状的右边,最大x坐标位于对象的y范围内。


很简单?好吧,这是简化版:


当形状彼此接触时,请移动最右边的形状,以使它不接触其他任何形状。
当某些形状彼此不依up在一起时,请移动最左边的形状,使其依ugg到最接近的形状。


编辑:例如...

假设我取了第3平方,并将其放在第1平方和第2平方的顶部:

1111 44
1111 44
1133333
1133333
  33333
  3333322
  3333322
     2222
     2222


步骤1.找到最相交的形状。在这种情况下,形状为2。将其移到相交的位置右边。

1111 44
1111 44
1133333
1133333
  33333
  333332222
  333332222
       2222
       2222


现在有形状在碰吗?是的,最右边的是形状3。将它移到要触摸的形状的右边,形状1:

1111 44
1111 44
111133333
111133333
    33333
    3333322
    3333322
       2222
       2222


现在有形状在碰吗?是的,最右边的是形状2。将它移到要触摸的形状的右边,形状3:

1111 44
1111 44
111133333
111133333
    33333
    333332222
    333332222
         2222
         2222


现在有形状在碰吗?否。所以我们完成了步骤1。

第2步:找到最左边的形状,该形状不会紧贴任何东西。在这种情况下,没有依not在任何东西上的最左边的一个是形状4。将它向左移动,使其恰好位于它最左边的形状的右边,该形状与它的y坐标相同:

111144
111144
111133333
111133333
    33333
    333332222
    333332222
         2222
         2222


有什么不依依不舍的吗?不!这样就完成了!

如您所见,基本上有一个扩展阶段和一个收缩阶段。您从右到左执行扩展阶段,因此没有任何东西可以通过其他方式进行扩展。您从左到右执行收缩阶段,因此没有其他事物收缩。

09-18 03:58