Animeret graf i reageret indfødt

For nylig ledte jeg efter et React Native grafbibliotek til min Savee.io-app. Under forskningen indså jeg, at det ikke er let at behandle grafer i React Native. Og hvis du vil animere dem? Det ser næsten umuligt ud. Følgende gif er det, jeg har gjort og vil tale om i denne "tutorial"!

Målet med denne artikel

Uden ART-bibliotek

Da jeg lavede min research om diagrammer i React Native, fandt jeg ud af, at næsten alle bruger ART-biblioteket. Hvilket er virkelig cool og kraftfuldt tegne bibliotek. Se på dette cirkeldiagram, der er udført af ART-biblioteket til appen Savee.io.

ART-bibliotek Cirkeldiagram i savee.io

Men når du vil animere det? Det kan du godt. Det er muligt. Men animationen udføres af JS-tråden. Jeg prøver altid at finde en måde, hvordan man flytter alt til en indfødt del, så vores JS-tråd ikke er blokeret af animation og kan arbejde på noget andet.

Kolonnediagrammet, jeg skal tale om (og du kan se i gif'en nedenfor), er blevet udført af pure React Native. Intet ART-bibliotek!

Lad os gøre det lidt kompliceret

Jeg indså, at jeg også har brug for en negativ værdi i grafen. Brugere af Savee.io opretter normalt en gruppe til en tur og sporer deres udgifter. Der er selvfølgelig kun negative værdier - kun udgifter. Følgende gif viser, hvordan animationen ser ud for både negative og positive værdier.

Layout

Jeg besluttede at fremstille hver eneste søjle separat som en komponent. Så jeg kunne tilføje en “forsinkelse” -effekt. Du kan se, at animationen starter tilfældigt for hver enkelt kolonne, når grafen ændrer en placering af baseline. Lad os arbejde med 200 højden. Værdiens højde kan også være 25 og labelens højde 25 også. Det gør 150 til kolonne.

Layout for en enkelt kolonne

Hvis grafens højde er 150, er kolonnens højde 300. Hver søjle har en positiv del (A) og en negativ del (B). Modsat side af disse dele er altid skjult. A er skjult for den negative del, og B er skjult for den positive del. Det betyder, at hvis vi flytter den positive del (A) under basislinjen til B-rummet, vil den positive kolonne være helt skjult. Det er hvad vi ønsker, når værdien er negativ.

Positive dele af kolonner (venstre side) og negative dele af de samme kolonner (højre dele)

Du kan se den negative værdi for den sidste kolonne på billedet. Værdien er -5. Positiv kolonne flyttes fuldstændigt under baseline (den er skjult), og negativ kolonne flyttes til korrekt Y-position for at repræsentere -5 værdi. En maksimal værdi for denne graf er 10 (første kolonne). Det betyder, at -5 vil være i midten af ​​en negativ del (75/2).

Vi er nødt til at gøre lidt matematik her, fordi vi er nødt til at interpolere den faktiske værdi til Y-position. Men jeg vil ikke tale om dette her. Jeg tror, ​​at du kan finde ud af alt temmelig let.

Animeret kolonne

Jeg brugte mit open source bibliotek kaldet react-native-motion og komponent TranslateY. Hvilket gør animationer virkelig nemme at implementere. Se på koden. Let at forstå. Vi bruger TranslateY-komponenten på samme måde, som vi ville bruge View-komponenten. Det eneste, vi skal gøre, er at beregne Y-positioner til positiv kolonne, negativ kolonne, basislinje og en værdimærke.

Kontroller resultatet i en reel applikation. Savee.io implementerede allerede kolonnediagrammet. Som jeg sagde før, gøres alt ved hjælp af UI-tråd (det er ret hurtigt). Der er en onPress-begivenhed, så du kan ændre månederne. Når du vælger kategorien, ændrer den værdierne for en graf og beregner Y-positioner igen. Derefter tager reaktionen-native-motion sig af animation.

Animeret nummer

Antallet animation er et lidt problem. Fordi vi ikke kan flytte det til UI-tråd. Det skal udføres med JS-tråd. Jeg har set, at udviklere normalt har effekten udført af setInterval. Selvfølgelig kan du bruge det, men jeg ville gøre det mere sikkert.

Så jeg bruger React Native's Animated API selv til nummeranimationen. Vi kan tilføje en lytter til den animerede værdi, og når værdien ændres, gengiver vi bare nummeret igen. Det er let, og du kan drage fordel af det animerede API. Ved at bruge en Easing for eksempel. Og hvad er bedst? Jeg satte komponenten til biblioteket med reaktionskritisk bevægelse, der er åbent for jer

Du skal bare skrive et par linjer som denne. Når værdien er ændret i din kode, vil den passe resten.

Fås i reaktionskritisk bevægelse

Kunne du lide det? Klap, følg og animer det!

Faktisk behøver du ikke gøre noget af det. Men det vil hjælpe mig meget. Det er en stor motivation for næste artikler som denne.

Om mig

Jeg er forfatter af Savee.io (som jeg også bruger som legeplads til mine animationer ‍). Og forfatter af biblioteker med reaktivt native-materiale-ui og reaktivt native-bevægelse. At skrive om dem i denne blog.

Hvis du har brug for hjælp med din React Native-app (animationer, performance osv.), Så lad mig det vide, tak;) Jeg vil med glæde diskutere det.
LinkedIn || Github || Twitter