4

ドラッグ可能/ドロップ可能な要素を含むページがあり、一度ドロップすると、触れている可能性のある他のドラッグ可能要素に関して、左の位置と幅を計算する必要があります。

これ自体はそれほど難しいことではありませんが、私が本当に苦労しているのは、空のスペースを埋めることです. ドラッグ可能オブジェクトを互いに重ならないように空のスペースを埋めるにはどうすればよいですか?

// $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>');

任意の提案/ヘルプをいただければ幸いです。ありがとう。

4

1 に答える 1

3

これがあなたがする必要があることのためのアルゴリズムです:

  1. 接触している形状がありますが、別の形状に接触している右端の形状(右のx座標が最大の形状)を見つけます。左端がちょうど触れていた右端の形状のすぐ右になるように移動します。
  2. それらの左側にあるものの隣にない形状がありますが、その左側にあるものの隣にない最小の左x座標を持つ形状を見つけてください。オブジェクトのy範囲にある最大の右x座標を使用して、左端が形状のすぐ右側になるように移動します。

簡単ですか?さて、これが簡略化されたバージョンです:

  1. 互いに接触している形状がありますが、他の形状に接触しないように右端の形状を移動します。
  2. 寄り添っていない形もありますが、一番左の形を動かして、一番近い形に寄り添います。

編集:例えば...

正方形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:何にも寄り添っていない左端の形を見つけます。この場合、何にも寄り添っていない左端の形状は形状4です。左に移動して、同じy座標に存在する左端の形状のすぐ右に配置します。

111144
111144
111133333
111133333
    33333
    333332222
    333332222
         2222
         2222

何かに寄り添っていないものはありますか?いいえ!これで完了です。

ご覧のとおり、基本的には拡張フェーズと縮小フェーズがあります。右から左に拡張フェーズを実行して、他の何かを介して右に拡張されるものがないようにします。収縮フェーズを左から右に実行するので、他の何かによって収縮することはありません。

于 2009-10-08T19:37:11.717 に答える