Animarea Gradienților în React Native

Lucrez la un proiect personal numit KaoCards, o aplicație flashcard pentru amintirea numelor și chipurilor oamenilor. Când am proiectat produsul, m-am gândit că ar fi interesant să am un gradient animat ca fundal, dar când am încercat să implementez, s-a dovedit a fi mai mult lucru decât credeam.

Iată povestea despre cum am reușit să o fac să funcționeze. Dacă doriți TL; DR, am făcut un depozit pe care îl puteți urmări.

O încercare naivă.

Dacă doriți să înțelegeți acest lucru, este important să știți de ce prima mea încercare nu a funcționat.

Pentru a afișa un gradient în React Native, oamenii folosesc un proiect numit react-native-linear-gradient. Am vrut să văd dacă cineva a încercat să anime culorile și am găsit exemplul Transition Gradient Transition în acea repo. Privind codul, am avut această reacție:

Nu am înțeles de ce este nevoie de două clase, de ce există atât de multe coduri. Nu credeam că ai nevoie de atât de mult. Am decis că nu voi deranja să înțeleg toate acestea. M-am gândit că modul de a face acest lucru ar trebui să fie destul de simplu:

  1. Creați o componentă AnimatedLinearGradient folosind Animate.createAnimatedComponent
  2. Interpolați unele culori și treceți-le pe AnimatedLinearGradient

Simplu, nu? Iată sursa (se va bloca). Am făcut o aplicație experimentală, am rulat-o și apoi, womp womp. Obținem eroarea:

Valoarea JSON `` de tip NSNull nu poate fi convertită într-un UIColor. Ați uitat să apelați processColor () pe partea JS?

Ceva undeva în linie nu a obținut valori de culori. Așa că am apelat la Twitter pentru ajutor:

Jason Brown a răspuns cu ideea cheie:

Aaahhh bine! Animația nu funcționează cu tablouri. Deși am crezut că fac totul corect, biblioteca animată nu prelucrează valorile de recuzită pentru tablă, astfel încât componenta autohtonă de bază este să obțină gunoi în loc să obțină culori animate.

A devenit clar de ce exemplul inițial era atât de mare.

Construirea corectă.

Bine, înțelegând această limitare cu privire la Animated, modificăm planul nostru de joc și o facem puțin mai robustă.

  1. Vrem ca componenta noastră principală, AnimatedGradient, să funcționeze la fel ca LinearGradient. Ar trebui să ia o serie de culori.
  2. Vrem să se producă o tranziție atunci când schimbăm suportul culorilor. Pentru a face acest lucru, AnimatedGradient trebuie să țină evidența culorilor anterioare.
  3. Deoarece nu putem anima valori în tablouri, putem construi o componentă GradientHelper care să ia culori în mod individual și să numim Animated.createAnimatedComponent în acest sens. GradientHelper va introduce valorile într-un tablou și le va transmite la componenta LinearGradient din pachetul de reacție nativ-liniar-liniar.

Pentru a păstra lucrurile simple pentru acest exemplu, vom presupune că tabloul de culori are doar 2 valori.

Componenta animatăGradient

Cod sursa

În primul rând, vom crea un AnimatedGradientHelper din GradientHelper, pe care îl vom crea un pic.

În constructorul AnimatedGradient, vom inițializa un câmp de stare prevColors pentru a urmări culorile anterioare. De asemenea, inițializăm un Valor animat numit Tweener.

În getDerivedStateFromProps, luăm valoarea state.colors și rămânem în state.prevColors. Am setat noul stat.color, și am resetat interacțiunea.

În componentWillUpdate (de asemenea, atunci când elementele de recenzie se schimbă), vom face ca tweenerul să se mute de la 0 la 1.

În metoda de redare, folosim tweener, prevColors și culori pentru a crea două interpolări de culori și le transmitem individual la AnimatedGradientHelper.

Ajutor gradient

Cod sursa

În GradientHelper, tot ce facem este să preluăm recuzitele color1 și color2, să le introducem într-un tablou și să le transmitem lui LinearGradient. Facem asta pentru că trebuie să ocolim limitările animate.

Și acesta este esențialul. Iată demo-ul:

Acum știm de ce exemplul inițial este atât de mare. Trebuia să facă toate aceste lucruri și să se ocupe de gradienți cu mai mult de 2 culori.

Dar stai, ce altceva putem anima?

Putem efectua pasul suplimentar și să animăm alte proprietăți. Componenta LinearGradient vă permite să specificați coordonatele pentru începutul și sfârșitul gradientului. De ce să nu le interpolăm și pe acestea? Iată o metodă de redare actualizată. Probabil puteți ghici ce s-a întâmplat în restul componentei. Sursă

Va trebui doar să ne modificăm un pic GradientHelper, făcând ceva cu recuzita. Sursă

Și acum avem o demonstrație mai cool.

Am putut combina acest gradient animat cu alte animații pentru a crea un efect de fundal interesant pentru proiectul meu KaoCards:

Deci, acum știți cum să animați gradienții în React Native și un pic mai multe despre cum funcționează Animated. Ce alte proprietăți credeți că puteți anima?

Mulțumesc lui Jason Brown pentru furnizarea informațiilor cheie. Tot ce am învățat despre lucruri animatoare din React Native am aflat de la el. Asigurați-vă că îl urmăriți pe Twitter și consultați cursul lui React Native Animations.