2017-06-01 28 views
12

W Androidzie wspólny element przejściowy umożliwia dokładne 2 takie same elementy występujące w obu stron, aby połączyć ze sobą podczas przechodzenia stron, podobnie jak okładką w gif przedstawiono poniżej:Shared element przejściowy za pomocą ReactJS

Android shared element transition

Zastanawiam się, czy możliwe jest osiągnięcie tego samego rodzaju przejścia z ReactJS między klasami. Jeśli tak, to jakieś przykłady? Jeśli nie, to co z jQuery?

+3

Transakcja, którą pokazałeś, powinna być możliwa do osiągnięcia za pomocą przejścia jednego elementu (obraz + odtwarzacz muzyki) w html5/css3, podczas gdy reaktywowani mogą zarządzać zmianą treści podelementu odtwarzacza muzycznego. Aby nie trzeba było znaleźć alternatywy przekształcania elementu akcji w reakcję –

+1

Aby bezpośrednio odpowiedzieć na swoje pytanie, czy sprawdziłeś https://facebook.github.io/react/docs/animation.html#high-level-api- reactcsstransitiongroup? –

+1

@ChrisChen Już sprawdziłem, myślę, że zamierzam stworzyć własny system przejściowy Shared Elements. W międzyczasie, jeśli ktoś znajdzie bibliotekę, która już to robi, połącz ją tutaj. – Lucio

Odpowiedz

4

Możesz dokonać tego przejścia prawie w całości za pomocą właściwości CSS transform. React JS polega na manipulowaniu DOM, ale nie musisz tego robić zbyt wiele.

Animacja:

  1. Ukrywa zawartość tekstową małego panelu.
  2. Skaluje obraz i tło tekstowe, aby wypełnić cały ekran.
  3. Umieszcza w nowej treści tekstowej.

Spośród tych 1 i 3 są łatwe z React, więc naprawdę potrzebujesz tylko animacji przejścia.

Oto bardzo prosty przykład przy użyciu żadnych JS w ogóle:

body { 
 
    background-color: #ccc; 
 
} 
 

 
.card { 
 
    width: 150px; 
 
    padding: 0; 
 
    margin: 0; 
 
    background-color: #fff; 
 
    position: absolute; 
 
    top: 0: left: 0; 
 
    z-index: 1; 
 
    
 
    /* Transition properties mean changes to them are animated */ 
 
    transition-property: transform; 
 
    transition-timing-function: ease-in-out; 
 
    transition-duration: 500ms; 
 
    transform-origin: top left; 
 
} 
 

 
.card>img { 
 
    width: 150px; 
 
    height: 150px; 
 
    margin: 0; 
 
    padding: 0; 
 
} 
 

 
.card>.content { 
 
    width: 150px; 
 
    height: 50px; 
 
    background-color: #fff; 
 
    margin: 0; 
 
} 
 

 

 
/* This is only for the purposes of this demo. 
 
* In production you'd have an underlying grid layout and JS to figure out the position */ 
 
.card:nth-of-type(2) { 
 
    left: 175px; 
 
} 
 

 
.card:nth-of-type(3) { 
 
    top: 230px; 
 
} 
 

 
.card:nth-of-type(4) { 
 
    top: 230px; 
 
    left: 175px; 
 
} 
 

 

 
/* On hover transform the card to full size and translate it to the top left 
 
* Note that translate comes before scale. */ 
 
.card:nth-of-type(1):hover { 
 
    transform: scale(2.1667); 
 
    z-index: 2; 
 
} 
 

 
.card:nth-of-type(2):hover { 
 
    transform: translate(-175px, 0) scale(2.1667); 
 
    z-index: 2; 
 
} 
 

 
.card:nth-of-type(3):hover { 
 
    transform: translate(0, -230px) scale(2.1667); 
 
    z-index: 2; 
 
} 
 

 
.card:nth-of-type(4):hover { 
 
    transform: translate(-175px, -230px) scale(2.1667); 
 
    z-index: 2; 
 
}
<div class="card"> 
 
    <img src="http://via.placeholder.com/325/F50057/ffffff"> 
 
    <div class="content"></div> 
 
</div> 
 

 
<div class="card"> 
 
    <img src="http://via.placeholder.com/325/F44336/ffffff"> 
 
    <div class="content"></div> 
 
</div> 
 

 
<div class="card"> 
 
    <img src="http://via.placeholder.com/325/1DE9B6/000000"> 
 
    <div class="content"></div> 
 
</div> 
 

 
<div class="card"> 
 
    <img src="http://via.placeholder.com/325/FFEB3B/000000"> 
 
    <div class="content"></div> 
 
</div>

Podstawowym Sztuką jest, aby użyć CSS transform z translate i scale - te właściwości mogą być obsługiwane przez karta graficzna, dzięki czemu animacje są płynne nawet na urządzeniach mobilnych.

Należy zauważyć, że CSS jest raczej niezgrabny - zrobiłem to właśnie po to, aby pokazać, że można to zrobić za pomocą czystego CSS. W praktyce będziesz chciał, aby jakiś JS ustawił właściwości przesunięcia, kliknął zdarzenie, itp.

Inną sztuczką (czego tu nie zrobiłem) jest przeskalowanie animacji do tyłu - zacznij od pełnej rozmiar kontroli i translate/scale go w pozycji, w której wydaje się rozpocząć.Kiedy użytkownik kliknie, usuń transform - dzięki czemu przeglądarka nie musi ponownie obliczać DOM obiektu o pełnych wymiarach przed rozpoczęciem animacji.

+0

To jest całkiem fajne! Jednak nie pasuje do moich potrzeb. Reagując na listę z przedmiotami, a przedmiot skupia się na dwóch oddzielnych komponentach, nie mogę tego łatwo zrobić, jak pokazano w twoim przykładzie. – Lucio

+0

@ Luu Możesz po prostu wykonać dodatkowy krok po odtworzeniu animacji, aby zamienić element przedmiotu. Lub sprawisz, że komponent elementu zajmie się zarówno rozszerzonymi szczegółami, jak i widokiem listy, a następnie wykona przejścia. W obu przypadkach w ten sposób dokonuje się tego rodzaju przejścia w sieci. – Keith

3

Nie jestem pewien, czy poprawnie rozumiem pytanie, ponieważ nie znam struktury systemu Android. Oto moje rozwiązanie oparte na ReactJS wiedzy:

kroki:

  1. Utrzymanie zmienne 2 Stan: CurrentMode & NextMode. Możliwe wartości to: 1 & 2.
  2. Po kliknięciu albumu zmień NextMode na 2. I w kodzie porównać wartości CurrentMode & NextMode. Jeśli ustawisz odpowiednio większy rozmiar, niż .
  3. Podobnie, gdy CurrentMode>NextMode niż odpowiednio ustawić rozmiar.