8

Wenn mir jemand helfen könnte herauszufinden, wie man die ziehbaren Elemente in einem div, das die Skalierung basierend auf der Fenstergröße ändert, erstellt, würde ich jede Anleitung sehr schätzen.jquery ziehbare containment array-Werte für skalierten Container

Wenn ich tun:

element.draggable({ 
    cursor: "move", 
    containment: '#container' 
}); 

Was passiert, ist es mir die Eindämmung für die regelmäßige Größe des Behälters gibt. Also, wenn ich eine transform: scale(1.5) habe, wird Platz im Container sein, den das ziehbare Element nicht gehen kann.

Ich habe auch versucht containment: 'parent', aber das ist sehr glitchy.

EDIT

Ich habe, wie herausgefunden, die obere und linke Eindämmung zu bekommen, aber ich kann nicht herausfinden, wie die rechts und unten zu bekommen.

var containmentArea = $("#container"); 

containment: [containmentArea.offset().left, containmentArea.offset().top, ???, ???] 

Ich habe versucht, Breite und Höhe von containmentArea[0].getBoundingClientRect() aber das scheint nicht die richtige Bewegung zu sein.


Here is a jsfiddle of some example code.

+0

Nicht an der dragFix Funktion im Detail betrachtet hat (möglicherweise die Werte dort anstelle der Verwendung von Rückhaltezurückhalten können), die Grenzen selbst scheinen zu funktionieren, wenn ich es getestet habe, aber die gezogenen Elementdimensionen müssen subtrahiert werden: 'var bounds = container.getBoundingClientRect(); var dragrect = $ ('. Draggable') [0] .getBoundingClientRect() .... containment: [bounds.x, bounds.y, bounds.right - dragrect.width, bounds.bottom - dragrect.height] ' (fiddle: http://jsfiddle.net/z0gqy9w2/4/) –

+0

@ Me.Name Hmm, die rechte und untere scheinen zu funktionieren, aber jetzt oben und links nicht. Das Bearbeiten des Dragfix könnte eine mögliche Lösung sein. Guter Gedanke. – bryan

+0

Hoppla, benutze x und y statt links und rechts, x und y arbeiten im firefox, also hatten dort keine Probleme. Das funktioniert auch in Chrome (habe ich nicht getestet): containment: [bounds.left, bounds.top, bounds.right - dragrect.width, bounds.bottom - dragrect.height] '(http: // jsfiddle. net/z0gqy9w2/5 /) (Immer noch, die Arbeit in dragfix fühlt sich generischer an, könnte später einen Blick darauf werfen) –

Antwort

3

Eine Version mit Rücksetzen der Koordinaten im Drag-Ereignis (da sie waren wobei bereits für die Skalentransformationen neu berechnet), ohne dass die Eindämmung mit:

var percent = 1, containmentArea = $("#container"); 

function dragFix(event, ui) { 
    var contWidth = containmentArea.width(), contHeight = containmentArea.height(); 
    ui.position.left = Math.max(0, Math.min(ui.position.left/percent , contWidth - ui.helper.width())); 
    ui.position.top = Math.max(0, Math.min(ui.position.top/percent, contHeight- ui.helper.height())); 
} 

$(".draggable").draggable({ 
    cursor: "move", 
    drag: dragFix, 
}); 

//scaling here (where the percent variable is set too) 

Fiddle

Im Beispiel werden Breite und Höhe des Containers innerhalb des Dragagevent erhalten, Sie können diese aber auch beim Skalieren für bessere Performance speichern. Wenn sie innerhalb des Ereignisses berechnet werden, funktionieren sie immer noch nach der Neuskalierung, obwohl die prozentuale Variable noch festgelegt werden muss. Um wirklich generisch zu sein, könnte es auch innerhalb der Veranstaltung erhalten werden (und statt eines festen Containers, ui.helper.parent() könnte verwendet werden) Da der Offset innerhalb des dragevent ist (0,0) bezogen auf den Container (zumindest ist es für die aktuelle Einrichtung), nahm die Freiheit der Vereinfachung zu position/percent Start Offset schien nicht notwendig sein, mehr, so dass es in der Geige, aber kann bei Bedarf wieder hinzugefügt werden.

+0

Das ist Borderline perfekt! Ich danke dir sehr!! Wird das Kopfgeld belohnen, sobald es mich lässt – bryan

0

einen Blick auf diese nehmen:

http://jsfiddle.net/z0gqy9w2/3/

Der bearbeitete Code ist die folgende:

// Matrix regex to take the scale value property of $('#container') element  
    var matrixRegex = /matrix\((-?\d*\.?\d+),\s*0,\s*0,\s*(-?\d*\.?\d+),\s*0,\s*0\)/, 
    matches = $('#container').css('transform').match(matrixRegex); 
    // Matches have this value : ["matrix(1.5, 0, 0, 1.5, 0, 0)", "1.5", "1.5"] , so we need matches[1] value : 
    var scaleValue = matches[1]; 
    $(".draggable").draggable({ 
     cursor: "move", 
     start: startFix, 
     drag: dragFix, 
     containment: [containmentArea.offset().left, containmentArea.offset().top, 
         ((containmentArea.offset().left + (containmentArea.width() * scaleValue)) - ($(".draggable").width() * scaleValue)) , 
         ((containmentArea.offset().top + (containmentArea.height() * scaleValue)) - ($(".draggable").height() * scaleValue)) ] 

    }); 

Wie Sie sehen, hier ist der Trick :

Ihre rechte maximale Position wird sein: Der Hauptbehälter links versetzt + die wahre Breite des Behälters (mit Skala) - der Artikel wahre Breite (um es in den Behälter zu lassen).

(Tipp: Schreiben Sie den „Prozent“ var Wert frei zu ändern, wie Sie die Ergebnisse sehen möchten)

regex ref

+0

Wow @SerCrAsH danke dafür! Du scheinst in die richtige Richtung zu gehen. Wenn sich der Container in einem scrollbaren div befindet, scheinen die oberen und unteren Containment-Grenzen aus irgendeinem Grund zu glänzen. – bryan

+0

schreibe ein 'console.log (Übereinstimmungen)' und sag mir, ob 'stimmt überein [1] == [2]' – SerCrAsH

+0

Anstelle von Übereinstimmungen habe ich gerade 'scaleValue = percent'. Ist das eine schlechte Idee? – bryan

0

Hier ist meine Lösung:

var _zoom = 1.2, 
    $element = $('.draggable-element'), 
    $container = $('#container'); 

var containmentW, 
    containmentH, 
    objW, 
    objH; 

$element.draggable({ 

    start: function(evt, ui) { 
     ui.position.left = 0; 
     ui.position.top = 0; 

     containmentW = $container.width() * _zoom; 
     containmentH = $container.height() * _zoom; 
     objW = $(this).outerWidth() * _zoom; 
     objH = $(this).outerHeight() * _zoom; 

    }, 

    drag: function(evt, ui) { 

     var boundReached = false, 

      changeLeft = ui.position.left - ui.originalPosition.left, 
      newLeft = ui.originalPosition.left + changeLeft/_zoom, 

      changeTop = ui.position.top - ui.originalPosition.top, 
      newTop = ui.originalPosition.top + changeTop/_zoom; 


     // right bound check 
     if(ui.position.left > containmentW - objW) { 
      newLeft = (containmentW - objW)/_zoom; 
      boundReached = true; 
     } 

     // left bound check 
     if(newLeft < 0) { 
      newLeft = 0; 
      boundReached = true; 
     } 

     // bottom bound check 
     if(ui.position.top > containmentH - objH) { 
      newTop = (containmentH - objH)/_zoom; 
      boundReached = true; 
     } 

     // top bound check 
     if(newTop < 0) { 
      newTop = 0; 
      boundReached = true; 
     } 

     // fix position 
     ui.position.left = newLeft; 
     ui.position.top = newTop; 

     // inside bounds 
     if(!boundReached) { 

      // do stuff when element is dragged inside bounds 

     } 

    } 
}); 

Link to fiddle