8

Jeśli ktoś mógłby mi pomóc wymyślić, jak utworzyć elementy przeciągalne zawarte w elemencie div, który zmienia skalę na podstawie rozmiaru okna, byłbym wdzięczny za wszelkie wskazówki.Przenoszone przez jquery wartości tablicy przechowawczej dla skalowanego kontenera

Jeśli zrobić:

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

Co się stanie, to daje mi pojemników do regularnej wielkości pojemnika. Więc jeśli mam transform: scale(1.5), w pojemniku będzie miejsce, do którego nie można przejść przez element przeciągalny.

Próbowałem również containment: 'parent', ale to jest bardzo glitchy.

EDIT

Znalazłem się jak dostać górny i lewy pojemników, ale nie mogę dowiedzieć się, jak uzyskać prawo i na dole.

var containmentArea = $("#container"); 

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

Próbowałem szerokość i wysokość z containmentArea[0].getBoundingClientRect() ale które nie wydają się być ruch w prawo albo.


Here is a jsfiddle of some example code.

+0

nie obejrzawszy szczegółowo w funkcji dragFix (ewentualnie można powstrzymać wartości tam, zamiast korzystania z pojemników), granice sami zdają się działa po przetestowaniu, ale wymaga odjętego wymiaru przeciągniętego elementu: 'var bounds = container.getBoundingClientRect(); var dragrect = $ ('. Przeciągalny') [0] .getBoundingClientRect() .... izolacja: [bounds.x, bounds.y, bounds.right - dragrect.width, bounds.bottom - dragrect.height] ' (skrzypce: http://jsfiddle.net/z0gqy9w2/4/) –

+0

@ Me.Name Hmm, prawy i dolny wydają się działać, ale teraz górny i lewy nie. Edytowanie dragfixa może być możliwym rozwiązaniem. Dobre myślenie. – bryan

+0

Ups, użyto x i y zamiast lewego i prawego, x i y pracują w firefoxie, więc nie miałem żadnych problemów. Działa to również w Chrome (nie testowano np.): 'Containment: [bounds.left, bounds.top, bounds.right - dragrect.width, bounds.bottom - dragrect.height]' (http: // jsfiddle. net/z0gqy9w2/5 /) (Wciąż jednak praca w dragfix jest bardziej ogólna, może później przyjrzeć się temu) –

Odpowiedz

3

Wersja z resetowania współrzędne w przypadku przeciągania (ponieważ były one przeliczane są już na przemian skalę), bez korzystania z pojemników:

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

W przykładzie szerokość i wysokość pojemnika są uzyskiwane wewnątrz dreageventu, można je również przechowywać podczas skalowania w celu uzyskania lepszej wydajności. Po obliczeniu ich w trakcie zdarzenia nadal działają po przeskalowaniu, chociaż zmienna procentowa musi jeszcze zostać ustawiona. Aby być prawdziwie ogólnym, można go również uzyskać wewnątrz zdarzenia (i zamiast stałego kontenera, ui.helper.może być użyty parent() Ponieważ przesunięcie wewnątrz dreageventu jest (0,0) powiązane z kontenerem (przynajmniej dla bieżącej konfiguracji), można było uprościć originalleft + (position - originalposition)/percent do position/percent Przesunięcie początkowe nie wydawało się być koniecznym, więc zostawić go w skrzypcach, ale w razie potrzeby można go ponownie dodać.

+0

To jest granica idealna! Dziękuję bardzo!! Nagrodzę nagrodę tak szybko, jak mi pozwoli – bryan

0

Spójrz do tego:

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

Edytowany kod jest następujący:

// 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)) ] 

    }); 

Jak widać, tutaj jest trick :

((containmentArea.offset().left + (containmentArea.width() * scaleValue)) - ($(".draggable").width() * scaleValue)) 

Twoja prawa pozycja maksymalna to: Przesunięcie lewego głównego kontenera + prawdziwa szerokość kontenera (ze skalą) - pozycja prawdziwa szerokość (aby umożliwić umieszczenie go wewnątrz kontenera).

(Wskazówka: Bądź wolny, aby zmienić „procent” wartość var ​​jak chcesz zbyt zobaczyć wyniki)

regex ref

+0

Wow @SerCrAsH dzięki za to! Wydajesz się zmierzać we właściwym kierunku. Z jakiegoś powodu, jeśli kontener znajduje się w przewijanym div, górna i dolna granica przechowawcza wydają się być zgniecione. – bryan

+0

napisz 'console.log (mecze)' i powiedz mi, czy 'dopasowuje [1] == [2]' – SerCrAsH

+0

Zamiast dopasowań właśnie zrobiłem 'scaleValue = percent'. Czy to zły pomysł? – bryan

0

Oto moje rozwiązanie:

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