Sådan opbygges animerede mikrointeraktioner i React

Mikrointeraktioner guider en bruger gennem din applikation. De styrker din brugeroplevelse og giver glæde.

Du har muligvis set nogle af de smarte eksempler på mikrointeraktioner på Dribble eller CodePen. Men ved du hvordan man bygger dit eget bibliotek med lignende UI-widgets?

I denne artikel vil jeg fokusere på animerede mikrointeraktioner ved hjælp af React, Facebooks populære, komponentorienterede UI-ramme. Jeg bygger tre interaktioner til en søgefelt:

  • åbn og luk tekstfeltet
  • Gå til toppen af ​​skærmen
  • ryst (angiver en fejl)

Jeg bruger et par forskellige implementeringer:

  • CSS overgange
  • reagere-motion
  • reagere-animationer

Her er en live demo og den kode, der giver den mulighed.

Dette er et af flere indlæg om Højere orden (HOC) og statsløse funktionelle komponenter. Det første indlæg handler om genbrug af kode i React og React Native via disse teknikker.

Hvad er en mikrointeraktion?

Dan Saffer (som skrev bogen) giver os denne definition: "Mikrointeraktioner er indeholdt produktmomenter, der drejer sig om en enkeltbrugssag - de har en hovedopgave."

Eksempler kan være klarere. Nogle mikrointeraktioner er overalt, såsom en cursorændring, når du holder musepekeren over et link eller vibrationen af ​​din telefon, når du skifter til lydløs tilstand. Andre, såsom en vare, der føjes til en indkøbskurv, er ikke så almindelige (endnu).

Hvorfor skal jeg være interesseret i mikrointeraktioner?

Mikrointeraktioner kan give feedback og gøre din applikation mindeværdig. Når brugerne har så mange app-valg, kan bedre mikrointeraktioner muligvis være den klichéde bedre musefælde, du skal bygge.

Men jeg er ikke en UX-designer. Så jeg foreslår at du læser Nick Babichs indlæg om mikrointeraktioner.

Kom godt i gang

Jeg bruger create-react-app til at starte en reaktion-applikation, men enhver React-opsætningsmetode fungerer. Desuden kan jeg lide Material-UI, så det importerer jeg også. (Dette valg er vilkårligt - du kan bruge et andet widgetbibliotek eller manuelt style dine elementer.)

Opret-reager-app-søgefelt-animation
cd-søgefelt-animation
npm-installation - gem materiale-ui reager-tap-event-plugin

Komponenten: et simpelt søgefelt

Jeg opretter et simpelt søgefelt. Det vil bestå af to elementer: en søgeikoneknap og en tekstboks. Jeg opretter en statsløs funktionel komponent til søgefeltet. (Statsløse funktionelle komponenter er funktioner, der gengiver React-komponenter og ikke opretholder tilstand, dvs. brug setState. Du kan lære mere i denne tutorial eller mit tidligere indlæg.)

SearchBox.js

(Jeg bruger onClick-tilbagekald senere).

IsOpen-prop indstiller SearchBox til åben eller lukket gengivelse.

isOpen = true / isOpen = false

Brug af komponenter med højere orden til at adskille bekymringer

Jeg kunne ændre SearchBox til en almindelig komponent og tilføje kode, der f.eks. Ville åbne og lukke tekstfeltet, når der klikkes på det.

Men jeg foretrækker at adskille animationen fra det centrale formål med søgefeltet. Søgefeltet viser / optager en forespørgselsværdi og sender denne forespørgsel til en anden controller. Dette er en subjektiv designbeslutning, men det har praktiske fordele: Jeg kan genbruge mikrointeraktionslogikken med en anden brugerinputkomponent.

Komponenter med højere orden (HOC) er funktioner, der returnerer en ny komponent. Denne komponent indpakker en eller flere komponenter og tilføjer funktionalitet. Jeg opretter en HOC for at tilføje åben / tæt adfærd til SearchBox.

Opret expanding-animation.js

Opdater App.js som følger:

Hvis du kører npm start, har du et søgeikon, som du kan klikke på for at åbne og lukke tekstfeltet.

Det fungerer, men åbningen og lukningen skurrer. En animation kan glatte effekten.

Animationer

Der er tre generelle tilgange til animationer.

  1. CSS overgange
  2. CSS-animationer
  3. hurtig og gentagen gengivelse af et element til at simulere bevægelse (manuel nøglestramming)

CSS-overgange ændrer en egenskabsværdi (som bredde) over en vis tidsvarighed. Ændringen behøver ikke at være lineær; du kan specificere funktioner til ændring af værdier.

CSS-animationer ændrer stil for et element (som størrelse, farve og placering). Hver trinvise stil er en keyframe. Du opretter en keyframe-serie for at opnå en ønsket effekt.

Begge CSS-taktik gengiver gentagne gange elementer for at simulere bevægelse. Du kan selv foretage beregningerne, dvs. mulighed (3). Flere Javascript-animationsrammer bruger denne tilgang til at styre beregningerne. (Jeg bruger reaktionsbevægelse i et senere eksempel.)

Jeg vil bruge alle disse teknikker i eksemplerne herunder, men jeg starter med CSS-overgange.

Udvidelse af søgefeltet

Den ekspanderende tekstboksanimation har brug for en CSS-egenskab: overgang

Skift expanding-animation.js som følger,

Ser man på ændringen i linje 21, additionalStyles, vil SearchBox flette denne stil med dets eksisterende stilarter i linje 29 og 31 nedenfor. (Jeg vender tilbage til overgangen CSS-egenskab på linje 2 om et øjeblik.)

Opdater SearchBox.js

Når de stilarter er fusioneret, træder animationen i kraft.

CSS-overgang: bredde

Resultatet er en jævn udvidelse af tekstfeltbredden, hvilket giver det udseende, det åbnes. CSS-overgangsejendommen kontrollerer dette (fra linje 2 i expanding-animation.js).

overgang: 'bredde 0,75s kubik-bezier (0,000, 0,795, 0,000, 1.000)'

Jeg opfordrer dig til at læse dokumentationen til CSS-overgangsejendommen, da der er en række forskellige muligheder. I eksemplet er der tre parametre:

  1. egenskab at ændre: bredde
  2. overgangsvarighed: 0,75s
  3. funktion til at styre timing: cubic-bezier (0,000, 0,795, 0,000, 1.000) '

Mens jeg valgte cubic-bezier som funktion, er lineær eller lethed blandt andre muligheder. Der er interaktive værktøjer, der hjælper dig med at vælge disse værdier, såsom denne cubic-bezier-builder.

Flytning af søgefeltet

Tjek følgende konceptanimation, som jeg fandt på Dribble:

https://dribbble.com/shots/2751256-Google-Search

Der er flere elementer i interaktionen; men jeg vil gerne fokusere på bevægelsen af ​​søgefeltet øverst på skærmen.

Jeg kan flytte min ydmyge søgefelt med en CSS-overgang. Opret en ny HOC, move-up-animation.js

Dette er som makeExpanding HOC-funktionen, bortset fra en oversættelse (flytte op). Animationstilen gælder også kun den ydre ramme (div).

Opdater App.js,

og du skulle se

CSS-overgang. transform: translateY

Måske vil du have en hoppeffekt. Du kan bruge reaktionsbevægelse. Det er et populært React-bibliotek, der bruger forårsdynamik til at kontrollere animationer. (En god introduktion af Nash Vail er her.)

npm installation - gem reaktionsbevægelse

Opret spring-up-animation.js

Da dette ikke er en reaktion-bevægelsesvejledning, vil jeg kort sammenfatte, hvordan dette fungerer. React-motion omslutter den animerede komponent, Target, med sin egen komponent, Motion. (Der er andre reaktionsbevægelseskomponenter, såsom TransitionMotion og Staggered Motion.)

React-motion interpolerer ved hjælp af fjederdynamik en række mellemliggende værdier. Det giver værdierne til den animerede komponent som en stil. Denne stil bestemmer den visuelle overgang i animationen.

Billedet herunder viser resultatet (med en vaggende fjeder for at fremhæve effekten).

reaktions-bevægelsesdynamik

Du kan bruge reaktionsbevægelse til en række effekter. For eksempel kan du ændre tekstfeltet til at udvide som en fjeder.

(spring-up-animation.js og move-up-animation.js har den samme onClick-tilstandslogik, så jeg refakturerede de fælles dele. Detaljerne er her.)

Rystning af søgefeltet

Jeg vil give feedback til brugeren om forkerte forespørgsler. Du kan bruge fejlmeddelelser, men jeg vil gerne gøre noget mere finurligt: ​​ryste søgefeltet.

Jeg kunne bruge reaktionsbevægelse, men jeg vil gerne se på en anden teknik: keyframe-animation.

React-animations er et React-bibliotek til keyframe-animationer. Den indsprøjter CSS-nøglerammer i et DOM-stilark. (De andre eksempler har kun brugt inline-stilarter.)

npm installation - gem reaktionsanimationer

Jeg har også brug for et bibliotek, som Radium eller Aphrodite, til at håndtere CSS-stilarkinjektionen. Jeg har valgt Aphrodite, som jeg har brugt det før.

npm installation - gem afrodit

Opret en anden HOC, shake-animation.js

Der er et par nøglesektioner. Linie 4 bruger Afrodite til at oprette typografien til reaktions-animationseffekten, head-shake. Linie 29 sætter CSS-klassen til animationen på Target. (Dette kræver en justering til SearchBox for at bruge CSS-klassen. Se på brugen af ​​frameClass i kilden til SearchBox.js.) OnClick-behandleren på linje 17 er mere kompliceret.

Genstart af en animation

Jeg vil gerne gøre 'head shake' på hver valideringsfejl (eller hvilken som helst trigger der bruges). Men da animationen er en CSS-klasse, kan jeg ikke blot indstille den samme klasse igen; det ville ikke have nogen virkning. Dette CSS Tricks-indlæg beskriver et par muligheder. Den enkleste er en timeout, der fjerner CSS-animationsklassen. Når du tilføjer det igen (til en ny begivenhed), kan du se 'hoved ryste'.

react-animationer (bruger keyframes, CSS-animation)

At sætte det sammen: Komponering af en kompleks komponent

Jeg har oprettet flere HOC'er til forskellige animationer. Men du kan også kæde HOC'erne for at oprette en sammensat komponent. Det åbner tekstfeltet, når det klikkes og ryste på fejlagtigt input.

Først skal du foretage et par ændringer tilSearchBox

SearchBox er nu en kontrolleret komponent (dekorativ betegnelse for at bruge React til at administrere tekstfeltets inputværdi). Det giver også et tilbagekald, onSubmit, til indsendelse af søgeforespørgslen (når en bruger trykker på Enter-tasten).

Du skal også ændre shake-animation.js. Hvis du klikker på søgeikonet, skal det ikke forårsage rysten. I stedet vil jeg have en anden komponent til at bestemme, hvornår man skal 'ryste'. Dette adskiller valideringslogikken fra kode, der styrer animationen.

startShake er et flag for at nulstille animationen. Men dette er en implementeringsdetalje. Det skal være indkapslet som intern tilstand i makeShakeAnimation HOC.

startShake er afhængig af shouldShake. Jeg kan bruge componentWillReceiveProps til at svare på ændringsforslag. (Det er overordnet, valideringskomponenten, indeholder disse rekvisitter.) Så jeg flyttede den forrige onClick-logik til componentWillReceiveProps.

Ændringen i linje 27, {... this.props}, overfører alle rekvisitter til den indpakkede komponent, Target. (Jeg skal på lignende måde ændre render-metoden i expanding-animation.js. Detaljerne er her.)

Jeg kan nu tilføje en komponent, der kontrollerer, hvornår jeg skal ryste.

Opret search-box-controller.js

Dette er en anden HOC. Det har ikke visuelle elementer, men det kontrollerer den logiske opførsel af den indpakket komponent. (Dan Abramov har et godt indlæg, der forklarer en sådan adskillelse.) I dette tilfælde er alle forespørgsler fejlagtige, men i en reel applikation ville jeg validere forespørgsler og oprette forbindelse til API'er.

Til sidst vil jeg fremhæve, at makeAnimatedValidationSearchBox er en HOC, der kæder to andre HOC'er.

const WrappedComponent = makeShakingAnimation (makeExpanding (Target));

En anden lille opdatering tilApp.js

(Linie 12 bruger den nye HOC)

og udfør kørsel npm start

en sammensat komponent, fremstillet af kæde af tre HOC'er

Jeg har oprettet en sammensat komponent, der bruger flere mikrointeraktioner. De er genanvendelige og diskrete.

Afslutter

Jeg har taget stikprøven på hver af fremgangsmåderne: CSS-overgange, react-motion og react-animationer. Jeg ville ønske, at du kunne vælge en fremgangsmåde, men det er svært at fordreje en enkelt tilgang til alle brugssager. Heldigvis kan du blande-og-matche biblioteker og teknikker. Og du kan kapsle detaljerne i genanvendelige HOC'er.

Det kan være en god ide at tjekke biblioteker som sådan omkomponere, der gør HOC-oprettelsen lettere.

GitHub-repoen til dette projekt er her.

Venligst ♡ dette indlæg og følg mig for fremtidige historier. Tak for at have læst.