2017-04-08 4 views
0

Ich habe vor kurzem versucht, an einem jQuery-Plugin zu arbeiten, mit dem eine beliebige Anzahl von Containern zufällig in einem Container verteilt werden kann, um sie anschließend auf eine spezielle Art zu animieren. Sie können meine Versuche hier sehen: http://www.manuelmaurer.at/randposplugin.phpjQuery Overlapping Containers vermeiden

Das Problem ist, dass einige von ihnen sich überschneiden und ich kann nicht herausfinden, warum. Zuerst dachte ich, dass der Grund dafür sein könnte, dass $ .each() nicht darauf wartet, dass eine Schleife beendet wird, bevor die nächste gestartet wird, aber ich habe auch versucht, das mit rekursiven Funktionen zu lösen - das hat nicht geholfen. Ich hoffe, jemand könnte mir einen kleinen Schub geben, um herauszufinden, wo das Problem tatsächlich ist, danke im Voraus! Sie können den Code entweder auf der Seite selbst sehen oder sich einfach die folgenden wichtigen Teile ansehen.


Dieser Code wird verwendet, um alle Elemente zu durchlaufen. Dies ist nicht weiter wichtig, aber die Funktion "NoCollision" versucht herauszufinden, ob ein Element in diesem Bereich existiert. Wenn ja, wird false zurückgegeben, wenn das Leerzeichen verwendet werden kann, wird true zurückgegeben. Wenn der Speicherplatz nicht verwendet werden kann, werden einige zufällige andere Koordinaten ausgewählt und es wird erneut versucht.

var Counter2 = 0; 
    $(FlowContainer).children(':not(:last)').each(function(elem) { 
     Counter2++; 
     ElemNow = $(FlowContainer).children().eq(Counter2); 
     ElemWidth = $(ElemNow).data("animwidth") 
     ElemHeight = $(ElemNow).data("animheight") 
     var Tries = 0; 
     var TryNowX = ElemPrevLeft; 
     var TryNowY = ElemPrevTop; 
     while (!NoCollision(TryNowX, TryNowY, ElemWidth, ElemHeight, PositionsArray, Settings.MinSpreadX, Settings.MinSpreadY) && Tries <= Settings.MaxTries) { 
      if (TryNowY < 15) { 
       TryNowY += randomIntFromInterval(0, 10); 
      } else if (TryNowY > (FlowContainer.height() - ElemHeight - 15)) { 
       TryNowY += randomIntFromInterval(-10, 0); 
      } else { 
       TryNowY += randomIntFromInterval(-10, 10); 
      } 
      if (TryNowX < 15) { 
       TryNowX += randomIntFromInterval(0, 10); 
      } else if (TryNowX > (FlowContainer.width() - ElemWidth - 15)) { 
       TryNowX += randomIntFromInterval(-10, 0); 
      } else { 
       TryNowX += randomIntFromInterval(-10, 10); 
      } 
      Tries++; 
     } 
     if (Tries == Settings.MaxTries) { 
      console.log("Warning: Couldn't fit all elements - hiding some.") 
      $(ElemNow).remove(); 
     } else { 
      $(ElemNow).css({ top: TryNowY, left: TryNowX }); 
      ElemPrevLeft = TryNowX; 
      ElemPrevTop = TryNowY; 
      PositionArray = [TryNowY, TryNowX, ElemHeight, ElemWidth]; 
      PositionsArray[Counter2] = PositionArray; 
     } 
    }) 

Die eigentliche Prüfung, wenn der Raum genutzt werden kann, nimmt im NoCollision-Funktionsteil, das Sie in dem folgenden Code sehen können.

function NoCollision(X, Y, W, H, PositionsArray, SpreadX, SpreadY) { 
    var NoErrors = true; 
    //Jedes Element im PositionsArray durchgehen und Prüfen 
    $.each(PositionsArray, function(PositionArray) { 
     var ArrY = PositionsArray[PositionArray][0]; 
     var ArrX = PositionsArray[PositionArray][1]; 
     var ArrW = PositionsArray[PositionArray][3]; 
     var ArrH = PositionsArray[PositionArray][2]; 
     if ((X < (ArrX - W - SpreadX) || X > (ArrX + ArrW + SpreadX)) && (Y < (ArrY - H - SpreadY) || Y > (ArrY + ArrH + SpreadY))) { 
      //SHOULD BE OKAY HERE 
     } else { 
      NoErrors = false; 
     } 
    }) 
    return NoErrors; 
} 

Das Array, das ich die Koordinaten aller bereits positioniert divs zu speichern verwende sieht wie folgt aus.

PositionsArray[ 
    [Elem1PositionY, Elem1PositionX, Elem1Height, Elem1Width] 
    [Elem2PositionY, Elem2PositionX, Elem2Height, Elem2Width] 
] 

war mein Gedanke, es so zu tun. Ist etwas falsch mit der Art und Weise, wie ich es machen würde oder gibt es einen Fehler bei meiner Implementierung?

Image

Ich bin absolut für jeden etwas Hilfe dankbar! Danke im Voraus!

+1

Ich schlage vor, dass Sie aus der Angewohnheit der Verwendung globaler Variablen für alles, was Sie in Javascript tun, und die Angewohnheit der lokalen setzen mit 'var',' let', 'const' usw. wird unvorhersehbar und schwer zu treffen Probleme mit dieser schlechten Praxis zu debuggen – charlietfl

+0

@charlietfl Hallo, vielen Dank für Ihr Feedback! Ich bin ziemlich neu und versuche mein Bestes, um es zu lernen. Würdest du mir gerne sagen, über welche Variablen du genau sprichst? -> Es gibt kein einziges globales, außer der "FlowContainer" -Variable, die unbedingt global sein muss. Oder muss ich "var ..." vor jeder einzelnen Variablen-Deklaration setzen? Danke für Ihre Hilfe! – Blackbird

+1

Jede Variablendeklaration im obigen Code ist global, weil Sie 'var' oder' let' nicht verwenden. – charlietfl

Antwort

0

Ich löste schließlich das Problem - meine Berechnung der Überlappung war ein bisschen falsch, musste nur die & & (und) ändern, um || (oder) - funktioniert jetzt wie Charme.

Gefunden eine bessere Lösung mit einem Plugin, das auf einem anderen stackoverflow-thread verwiesen wurde - funktioniert jetzt besser.