2009-10-08 5 views
4

J'ai une page avec des éléments draggable/droppable qui, une fois abandonnés, doivent calculer leur position et largeur gauche par rapport aux autres objets dragables qu'ils peuvent toucher.Superposition d'éléments entrecroisés avec jQuery

Ce n'est pas trop difficile en soi, mais là où j'ai vraiment des problèmes c'est de les remplir pour remplir l'espace vide. Comment puis-je obtenir les draggables pour remplir l'espace vide sans doubler les uns sur les autres?

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

Une suggestion/aide serait très appréciée. Merci.

+1

Vous ne semblez pas avoir posé de question. De quoi avez-vous vraiment besoin d'aide? Quelle partie de votre script ne fonctionne pas? – James

+1

Vous faites ressembler JS à Perl. – slikts

+2

Votre code est un peu dense, peut-être si vous avez donné une phrase ou deux décrivant comment il fonctionne, et quelles parties sont problématiques? Il n'est pas immédiatement clair comment votre code fonctionne à partir de votre récit, et vous pourriez obtenir plus d'aide si vous avez expliqué plutôt que de nous demander d'analyser mentalement ce wall-o-code. :) –

Répondre

3

est ici l'algorithme de ce que vous devez faire:

  1. Bien qu'il y ait des formes touchant, figure la forme droite (celle avec les plus grands coordonnée x droite) qui touche une autre forme. Déplacez-le afin que son bord gauche soit juste à la droite de la forme qu'il touchait juste.
  2. Bien qu'il n'y ait pas de formes à côté de quelque chose à leur gauche, déterminez la forme avec la plus petite coordonnée x gauche qui n'est pas à côté de quelque chose à sa gauche. Déplacez-le afin que son bord gauche soit juste à droite de la forme avec la plus grande coordonnée x droite qui se trouve dans la plage y de l'objet.

Assez simple? Eh bien, voici la version simplifiée:

  1. Lorsque des formes se touchent, déplacez-les vers la droite pour qu'elles ne touchent aucune autre forme.
  2. Bien qu'il y ait des formes qui ne se blottissent pas l'une dans l'autre, déplacez-la vers la gauche pour qu'elle soit blottie jusqu'à la forme la plus proche.

Edit: Par exemple ...

Supposons que je pris place 3 et flac sur le dessus de la case 1 et 2 carrés:

 
1111 44 
1111 44 
1133333 
1133333 
    33333 
    3333322 
    3333322 
    2222 
    2222 

Étape 1. Trouver la forme droite C'est en train de croiser quelque chose. Dans ce cas, c'est la forme 2. Déplacez-le à droite de ce qu'il croise.

 
1111 44 
1111 44 
1133333 
1133333 
    33333 
    333332222 
    333332222 
     2222 
     2222 

Y a-t-il des formes qui se touchent maintenant? Oui, et le plus à droite est la forme 3. déplacer vers la droite de la forme qu'il touche, la forme 1:

 
1111 44 
1111 44 
111133333 
111133333 
    33333 
    3333322 
    3333322 
     2222 
     2222 

Y at-il façonne toucher maintenant? Oui, et le plus à droite est la forme 2. déplacer vers la droite de la forme qu'il touche, de la forme 3:

 
1111 44 
1111 44 
111133333 
111133333 
    33333 
    333332222 
    333332222 
     2222 
     2222 

Y at-il façonne toucher maintenant? Donc nous avons terminé l'étape 1.

Étape 2: Trouvez la forme la plus à gauche qui ne soit pas blottie à quoi que ce soit. Dans ce cas, le plus à gauche, on ne blotti rien est la forme 4. déplacer vers la gauche il est juste de la forme de droite à gauche de ce qui existe dans les mêmes coordonnées y comme il:

 
111144 
111144 
111133333 
111133333 
    33333 
    333332222 
    333332222 
     2222 
     2222 

Tout ce qui ne blotti contre quoi que ce soit? Nan! Donc vous avez terminé!Comme vous pouvez le voir, il y a essentiellement une phase d'expansion et une phase de contraction. Vous faites la phase d'expansion de droite à gauche, de sorte que rien ne se développe à travers quelque chose d'autre. Vous faites la phase de contraction de gauche à droite afin que rien ne se contracte à travers quelque chose d'autre.

+0

Pouvez-vous donner un exemple? – Jojo

+1

Un exemple a été donné! –

+0

Autre chose dont vous avez besoin pour accepter cette réponse? –

Questions connexes