2014-07-26 17 views
11

Skalowuję element sortowalny JQuery z transformacją CSS. Oba sortowalne pozycje rozpoczynają pozycje i przesunięcia, podczas gdy przeciąganie jest nieprawidłowe. JQuery nie bierze pod uwagę skal CSS. Rozwiązałem go częściowo z kodem znaleźć tutaj:Sortable zachowuje się nieprawidłowo po zastosowaniu skali CSS

jQuery Drag/Resize with CSS Transform Scale

Ale rzecz nie mogę rozwiązać to sortable pozycja pozycja przy rozpoczęciu przeciągania. Podskakuje i trochę w prawo. Nie mogę dowiedzieć się, co włożyć do obsługi zdarzeń start:

 start: function(e, ui) 
     { 
      // something is needed here to fix the initial offset 
     } 

Fiddle to pokazuje problem: http://jsfiddle.net/adrianrosca/zbvLp/4/

+0

zacząłem bounty na to pytanie.Chociaż niekoniecznie myślę, że to pytanie jest szeroko stosowane w przypadku dużej grupy odbiorców, to lubię * zobaczyć kanoniczną odpowiedź, która dotyczy tego, co dokładnie musi zostać poprawione w sortowalnych procedurach obsługi zdarzeń i dlaczego zaproponowano rozwiązanie, które można przeciągnąć za pomocą jquery. w OP [odwołanie do pytania SO] (https://stackoverflow.com/q/10212683/165154), nie ma zastosowania do sortables jquery. –

Odpowiedz

8

Różnica z Draggable jest to, że przekształcić nie jest na same elementy, ale na rodzica. Więc zmienia nieco logikę.

Oto rozwiązanie dla tego konkretnego przypadku, ale zobaczysz, że w zależności od sytuacji może się zmienić. Na przykład, jeśli zmienisz przekształcenie-pochodzenie, lub jeśli masz poziomy do sortowania, będzie musiał zostać dostosowany. Ale logika pozostaje taka sama:

var zoomScale = 0.5; 

$(".container") 
    .sortable({ 

    sort: function(e, ui) { 
    console.log(ui.position.left) 
     var changeLeft = ui.position.left - ui.originalPosition.left; 
     // For left position, the problem here is not only the scaling, 
     // but the transform origin. Since the position is dynamic 
     // the left coordinate you get from ui.position is not the one 
     // used by transform origin. You need to adjust so that 
     // it stays "0", this way the transform will replace it properly 
     var newLeft = ui.originalPosition.left + changeLeft/zoomScale - ui.item.parent().offset().left; 

     // For top, it's simpler. Since origin is top, 
     // no need to adjust the offset. Simply undo the correction 
     // on the position that transform is doing so that 
     // it stays with the mouse position 
     var newTop = ui.position.top/zoomScale; 

     ui.helper.css({ 
     left: newLeft, 
     top: newTop 
     }); 
    } 
    }); 

http://jsfiddle.net/aL4ntzsh/5/

EDIT:

Poprzednia odpowiedź będzie działać do pozycjonowania, ale jak wskazano przez godnej dyletant, nie jest to wada z funkcją przecięcia, który sprawdza poprawność kiedy powinno nastąpić sortowanie. Zasadniczo pozycje są poprawnie obliczane, ale te wartości mają wartości width i , które nie są przekształcane, co jest przyczyną problemu. Można dostosować te wartości, modyfikując je w zdarzeniu początkowym, aby uwzględnić współczynnik skali. Jak to na przykład:

start: function(e, ui) { 
     var items = $(this).data()['ui-sortable'].items; 
     items.forEach(function(item) { 
     item.height *= zoomScale; 
     item.width *= zoomScale; 
     }); 
    } 

http://jsfiddle.net/rgxnup4v/2/

+0

Zarówno odpowiedź użytkownika, jak i [user3765122] (https://stackoverflow.com/a/36715198/165154) wydają się rozwiązywać problem OP w równie dużym stopniu. Jednak subtelny problem, który, podejrzewam, jest sprawcą mojego własnego problemu, wydaje się pozostawać w obu: wykrywanie sortowania jest przesunięte w prawo. Jeśli chwycisz element w centrum poziomym i przeciągniesz go na inne, ostrożnie przesuwając w lewo i prawo, zobaczysz to. Ponieważ używam połączonych sortowników, które są znacznie szersze * i * poziomych rodzeństwa, ten subtelny problem jest niezwykle powiększony. Czy wiesz, jak to zrekompensować? –

+0

Może będę musiał zacząć nowe pytanie w mojej konkretnej sprawie, ponieważ jest to dużo bardziej skomplikowane niż OP, ale mój problem może zniknąć, jeśli wiesz, jak rozwiązać ten subtelny problem. W każdym razie: skoro obie twoje odpowiedzi wydają się być jak dotąd równe, nie jestem do końca pewien, na jaką odpowiedź odpowiedzieć nagrodą. Mogę zdecydować o przyznaniu nagrody obu. Ale może mógłbyś wyjaśnić, dlaczego obie odpowiedzi wydają się mieć ten sam wynik? PS .: Bardzo dziękuję za dotychczasowe rozwiązania! –

+0

OK, dziękuję bardzo za dodanie! To * nie * rozwiązuje problem w przypadku OP. Niestety nie rozwiązuje to mojego przypadku z moimi połączonymi pakietami sortującymi (połączone elementy pokazują, że mają '{width: 0, height: 0, left: 0, top: 0}'), ale tak jak powiedziałem, mój przypadek jest bardzo bardziej złożony. Tak więc, albo zamierzam już trochę sobie z tym pogodzić, żeby naprawdę spróbować zrozumieć zawiłości/przesunięcia/itd., Albo zacznę nowe pytanie na ten temat, jeśli nie będę w stanie tego rozgryźć. Ale nagroda jest zasłużona i dałeś mi mnóstwo wskazówek, gdzie szukać. Dzięki jeszcze raz! –

1

Są dwie rzeczy w swoim problemie: nieruchomość

  1. Pozycja elementu jest obliczana na podstawie najbliższego rodzica, który ma pozycja jest absolutna lub względna. Macierzystym rodzicem w tej chwili jest ciało, które nie jest dobre, więc musisz dodać do kontenera position:relative;.
  2. Ponieważ, jak już zauważyłeś, JQuery nie bierze pod uwagę skal CSS, gdy oblicza zarówno ui.position, jak i ui.originalPosition, więc musisz "zastosować" do nich obu: zoomScale.

CSS

.container 
{ 
    position: relative; 
    transform: scale(0.5); 
    transform-origin: center top; 
} 

Script

var changeLeft = ui.position.left - ui.originalPosition.left; 
var newLeft = (ui.originalPosition.left + changeLeft)/zoomScale; 
var changeTop = ui.position.top - ui.originalPosition.top; 
var newTop = (ui.originalPosition.top + changeTop)/zoomScale; 

Jest to kod zmiana: http://jsfiddle.net/zbvLp/9/

+0

Zarówno twój, jak i [odpowiedź Juliena Grégoire'a] (https://stackoverflow.com/a/36684822/165154) wydają się rozwiązywać problem PO, w równie dużym stopniu. Jednak subtelny problem, który, podejrzewam, jest sprawcą mojego własnego problemu, wydaje się pozostawać w obu: wykrywanie sortowania jest przesunięte w prawo. Jeśli chwycisz element w centrum poziomym i przeciągniesz go na inne, ostrożnie przesuwając w lewo i prawo, zobaczysz to. Ponieważ używam połączonych sortowników, które są znacznie szersze * i * poziomych rodzeństwa, ten subtelny problem jest niezwykle powiększony. Czy wiesz, jak to zrekompensować? –

+0

Może będę musiał zacząć nowe pytanie w mojej konkretnej sprawie, ponieważ jest to dużo bardziej skomplikowane niż OP, ale mój problem może zniknąć, jeśli wiesz, jak rozwiązać ten subtelny problem. W każdym razie: skoro obie twoje odpowiedzi wydają się być jak dotąd równe, nie jestem do końca pewien, na jaką odpowiedź odpowiedzieć nagrodą. Mogę zdecydować o przyznaniu nagrody obu. Ale może mógłbyś wyjaśnić, dlaczego obie odpowiedzi wydają się mieć ten sam wynik? PS .: Bardzo dziękuję za dotychczasowe rozwiązania! –

Powiązane problemy