Aggiornamento dell'animazione CSS con le curve di movimento

Pubblicato: 2022-03-10
Riepilogo rapido ↬ C'è l'animazione dell'interfaccia utente e poi c'è una buona animazione dell'interfaccia utente. Una buona animazione ti fa dire "Wow!" — è liscia, bella e, soprattutto, naturale, non a blocchi, rigida o robotica. Se frequenti Dribbble o UpLabs, saprai di cosa parlo. Con così tanti fantastici designer che creano animazioni così belle, qualsiasi sviluppatore vorrebbe naturalmente ricrearle nei propri progetti. Ora, CSS fornisce alcune preimpostazioni per transition-timing-function , come ease-in , ease-out e ease-in-out , che aggiungono un certo livello di fluidità e realismo, ma sono molto generiche, non è vero? Quanto sarebbe noioso se ogni animazione sul web seguisse le stesse tre funzioni di temporizzazione?

C'è l'animazione dell'interfaccia utente e poi c'è una buona animazione dell'interfaccia utente. Una buona animazione ti fa dire "Wow!" — è liscia, bella e, soprattutto, naturale, non a blocchi, rigida o robotica. Se frequenti Dribbble o UpLabs, saprai di cosa parlo.

Ulteriori letture su Smashing:

  • Animazioni SVG e CSS con percorso di clip
  • Tecniche pratiche di animazione
  • Creazione di animazioni "disegnate a mano" con SVG
  • La nuova API di animazione Web

Con così tanti fantastici designer che creano animazioni così belle, qualsiasi sviluppatore vorrebbe naturalmente ricrearle nei propri progetti. Ora, CSS fornisce alcune preimpostazioni per transition-timing-function , come ease-in , ease-out e ease-in-out , che aggiungono un certo livello di fluidità e realismo, ma sono molto generiche, non è vero? Quanto sarebbe noioso se ogni animazione sul web seguisse le stesse tre funzioni di temporizzazione?

(Credito: Lukaš Stranak)
Altro dopo il salto! Continua a leggere sotto ↓

Una delle proprietà della transition-timing-function è cubic-bezier(n1, n2, n3, n4) , in cui puoi passare quattro numeri per creare la tua funzione di temporizzazione. Verso la fine di questo articolo, saprai esattamente cosa rappresentano questi quattro numeri, tuttavia, credimi, trovare quattro numeri per catturare la transizione che stai immaginando nella tua testa non è affatto facile. Ma grazie a cubic-bezier ea Ceasar, non è necessario. Questi strumenti portano le curve di movimento sul web.

Le curve di movimento vengono utilizzate principalmente dagli animatori (ad esempio, in Adobe After Effects) per creare animazioni avanzate e realistiche. Con cubic-bezier e Ceasar, puoi semplicemente manipolare la forma di una curva e quei quattro numeri ( n1, n2, n3, n4 ) verranno compilati per te, il che è assolutamente fantastico! Tuttavia, per utilizzare e ottenere il massimo dalle curve di movimento, è necessario capire come funzionano, ed è quello che faremo in questo articolo. Cominciamo.

Comprendere le curve di movimento

Una curva di movimento non è altro che una trama tra qualsiasi proprietà animabile e il tempo. Una curva di movimento definisce come la velocità di un'animazione in esecuzione sotto la sua influenza varia nel tempo.

La curva di movimento è un grafico tra la proprietà animabile e il tempo.
Una curva di movimento è una trama tra una proprietà animabile e il tempo. (Visualizza versione grande)

Prendiamo distanza ( translateX ) come esempio di una proprietà animabile. (La spiegazione vale per qualsiasi altra proprietà animabile.)

Calcolo della velocità al tempo t1 su un diagramma distanza-tempo.
Calcolo della velocità al tempo t1 sul grafico distanza-tempo. (Visualizza versione grande)

Se hai avuto esperienza con la fisica e il calcolo di base, saprai che decifrare la velocità da un grafico distanza-tempo è molto semplice. La derivata prima della distanza in funzione del tempo , rispetto al tempo , è la velocità, il che significa che un oggetto che segue una curva distanza-tempo avrebbe una velocità maggiore nei punti in cui la curva è ripida e più bassa nei punti in cui la curva è più piatta . Se sai come funziona, fantastico! Sei pronto e puoi passare alla sezione successiva.

Ora, sono consapevole che il design e lo sviluppo sono un campo diversificato e non tutti hanno lo stesso background. Forse i due paragrafi precedenti erano tutti in gergo per te. Non preoccuparti. Andremo avanti e daremo un senso al gergo.

Considera la casella rossa qui sotto. Prendiamo un po' di indolenza qui e chiamiamo la scatola rossa “Boxy”; sarà più facile riferirsi ad esso in questo modo. Va bene, quindi Boxy si sposterà da un bordo all'altro dello schermo in modo lineare e analizzeremo il suo movimento.

Uno dei preset della transition-timing-function è linear . Per far muovere Boxy, tutto ciò che facciamo è aggiungere la seguente classe.

 .moveForward { transform: translateX(1000px); }

Per controllare l'animazione, impostiamo la proprietà di transition per Boxy come segue:

 #boxy { width: 200px; height: 200px; background: red; transition-property: transform; transition-duration: 1s; transition-timing-function: linear; }

Questo è un modo molto dettagliato per specificare la transition . In realtà, troverai quasi sempre la transition scritta nella sua forma abbreviata:

 #boxy { width: 200px; height: 200px; background: red; transition: transform 1s linear; }

Vediamolo andare.

Boxy in movimento lineare
Scatola in movimento lineare.

Robotica, vero? Si potrebbe dire che questo movimento sembra robotico perché è lineare, il che è una risposta perfettamente plausibile. Ma potresti spiegare perché? Possiamo vedere che l'impostazione linear si traduce in un movimento robotico, ma cosa sta succedendo esattamente dietro le quinte? Questo è ciò che scopriremo prima; andremo alle viscere e capiremo perché questo movimento sembra robotico, a blocchi e non naturale.

Iniziamo rappresentando graficamente il movimento di Boxy per vedere se possiamo ottenere qualche intuizione. Il nostro grafico avrà due assi, il primo è la distanza e il secondo tempo. Boxy copre una distanza totale di 1000 pixel (distanza) in 1 secondo (tempo). Ora, non farti spaventare da tutta la matematica qui sotto: è molto semplice.

Ecco il nostro semplicissimo grafico, con gli assi come detto.

Grafico vuoto con assi
Grafico vuoto con assi (Visualizza versione grande)

In questo momento, è vuoto. Riempiamolo con alcuni dati.

Per cominciare, sappiamo che a 0 secondi, quando l'animazione non è ancora iniziata, Boxy è nella sua posizione iniziale (0 pixel). E dopo 1 secondo, Boxy ha percorso un totale di 1000 pixel, atterrando sul bordo opposto del display.

Le posizioni iniziali e finali di Boxy
Posizioni iniziali e finali di Boxy (Visualizza versione grande)

Tracciamo questi dati sul grafico.

Grafico con le posizioni iniziali e finali di Boxy tracciate
Grafico con le posizioni iniziali e finali di Boxy tracciate (Visualizza versione grande)

Fin qui tutto bene. Ma due punti dati non sono sufficienti: ne abbiamo bisogno di più. La figura seguente mostra le posizioni di Boxy in diversi momenti (tutto grazie alla mia fotocamera ad alta velocità).

Le posizioni di Boxy in diversi momenti
Le posizioni di Boxy in diversi momenti (Visualizza versione grande)

Aggiungiamo questi dati al nostro grafico.

Grafico con diverse posizioni tracciate
Grafico con diverse posizioni tracciate (Visualizza versione grande)

Ovviamente potresti avere molti più punti dati per tempi diversi (ad esempio, 0,375 secondi, 0,6 secondi, ecc.) ma quello che abbiamo è sufficiente per completare il nostro grafico. Unendo tutti i punti, abbiamo completato il grafico. Batti il ​​cinque!

Grafico finale
Grafico finale (Visualizza versione grande)

Fantastico, ma cosa ci dice questo? Ricordi che abbiamo iniziato la nostra indagine con l'obiettivo di capire perché il movimento lineare di Boxy sembra innaturale e robotico? A prima vista, questo grafico che abbiamo appena costruito non ci dice nulla al riguardo. Dobbiamo andare più a fondo.

Tieni a mente il grafico e parliamo per un minuto di velocità. So che sai cos'è la velocità, vorrei solo dirla in termini matematici. Come va, la formula per la velocità è questa:

Formula matematica per la velocità
Formula matematica per la velocità (Visualizza versione grande)

Pertanto, se un'auto copre una distanza di 100 chilometri in 1 ora, diciamo che la sua velocità è di 100 chilometri all'ora.

Rappresentare la velocità
Rappresentazione della velocità (Visualizza versione grande)

Se l'auto raddoppia la sua velocità, comincerà a percorrere il doppio della distanza (200 chilometri) nello stesso intervallo (1 ora), o, in altre parole, percorrerà la distanza originaria di 100 chilometri in metà tempo (0,5 ore). . Ha senso?

Allo stesso modo, se l'auto dimezzasse la sua velocità (cioè rallentasse della metà), comincerebbe a percorrere una distanza di 50 chilometri nello stesso intervallo (1 ora), o, in altre parole, percorrerebbe la distanza originaria di 100 chilometri nel doppio del tempo (2 ore).

Grande! Detto questo, riprendiamo da dove eravamo rimasti. Stavamo cercando di capire come il grafico tra la distanza e il tempo possa aiutarci a capire perché il movimento lineare di Boxy sembra robotico.

Ehi, aspetta un secondo! Abbiamo un grafico tra la distanza e il tempo, e la velocità può essere calcolata dalla distanza e dal tempo, no? Proviamo a calcolare la velocità di Boxy a diversi intervalli di tempo.

Calcolo della velocità a diversi intervalli
Calcolo della velocità a intervalli diversi (Visualizza versione grande)

Qui ho scelto tre diversi intervalli di tempo: uno vicino alla partenza, uno a metà e uno alla fine vicino alla posizione finale. Come è evidente, a tutti e tre gli intervalli, Boxy ha esattamente la stessa velocità (s1 = s2 = s3) di 1000 pixel al secondo; cioè, indipendentemente dall'intervallo che scegli nel grafico sopra, troverai Boxy che si muove a 1000 pixel al secondo. Non è strano? Le cose nella vita reale non si muovono a una velocità costante; iniziano lentamente, aumentano gradualmente la loro velocità, si muovono per un po', quindi rallentano di nuovo prima di fermarsi, ma Boxy inizia bruscamente con una velocità di 1000 pixel al secondo, muovendosi con la stessa velocità e fermandosi bruscamente esattamente alla stessa velocità. Questo è il motivo per cui il movimento di Boxy sembra robotico e innaturale. Dovremo cambiare il nostro grafico per risolvere questo problema. Ma prima di immergerci, dovremo sapere in che modo le modifiche alla velocità influenzeranno il grafico tracciato tra distanza e tempo. Pronto? Sarà divertente.

Raddoppiamo la velocità di Boxy e vediamo come cambia l'aspetto del grafico in risposta. La velocità originale di Boxy, come abbiamo calcolato sopra, è di 1000 pixel al secondo. Poiché abbiamo raddoppiato la velocità, Boxy sarà ora in grado di coprire la distanza di 1000 pixel in metà tempo, ovvero in 0,5 secondi. Mettiamolo su un grafico.

Grafico che mostra la doppia velocità
Grafico che mostra la doppia velocità (Vedi versione grande)

E se triplicassimo la velocità? Boxy ora copre 1000 pixel in un terzo del tempo (un terzo di secondo).

Grafico che mostra la tripla velocità
Grafico che mostra la tripla velocità (Visualizza versione grande)

Hmm, hai notato qualcosa? Nota come, quando il grafico cambia, l'angolo che la linea forma con l'asse del tempo aumenta all'aumentare della velocità.

Va bene, andiamo avanti e dimezziamo la velocità di Boxy. Dimezzare la sua velocità significa che Boxy sarà in grado di coprire solo 500 pixel (metà della distanza originale) in 1 secondo. Mettiamo questo su un grafico.

Grafico che mostra la metà della velocità
Grafico che mostra la velocità dimezzata (Visualizza versione grande)

Rallentiamo ancora un po' Boxy, rendendo la velocità un terzo dell'originale. Boxy sarà in grado di coprire un terzo della distanza originale in 1 secondo.

Grafico che mostra un terzo della velocità
Grafico che mostra un terzo della velocità (Visualizza versione grande)

Vedi uno schema? La linea diventa sempre più ripida man mano che aumentiamo la velocità di Boxy e inizia ad appiattirsi mentre rallentiamo Boxy.

La linea diventa più ripida all'aumentare della velocità e si appiattisce al diminuire della velocità
La linea diventa più ripida all'aumentare della velocità e si appiattisce al diminuire della velocità. (Visualizza versione grande)

Questo ha senso perché, per una linea più ripida, un piccolo progresso nel tempo produce una variazione di distanza molto maggiore, implicando una maggiore velocità.

Un piccolo cambiamento nel tempo produce un cambiamento relativamente grande nella distanza, creando un grafico più ripido.
Un piccolo cambiamento nel tempo produce un cambiamento relativamente grande nella distanza, creando un grafico più ripido. (Visualizza versione grande)
Un piccolo cambiamento nel tempo produce un cambiamento relativamente grande nella distanza, creando un grafico più ripido.
Un piccolo cambiamento nel tempo produce un cambiamento relativamente grande nella distanza, creando un grafico più ripido. (Visualizza versione grande)

D'altra parte, per una linea meno ripida, una grande variazione di tempo produce solo una piccola variazione di distanza, ovvero una velocità inferiore.

Cambiamento nel tempo rispetto al cambiamento nella distanza in un grafico meno ripido
Variazione del tempo rispetto alla variazione della distanza in un grafico meno ripido (Visualizza versione grande)
Variazione del tempo rispetto alla variazione della distanza in un grafico meno ripido
Variazione del tempo rispetto alla variazione della distanza in un grafico meno ripido (Visualizza versione grande)

Con tutte le modifiche che abbiamo apportato, Boxy si sta ancora muovendo in modo lineare, solo a velocità diverse. Tuttavia, con la nostra nuova conoscenza di come le modifiche alla distanza rispetto al tempo possono influenzare la velocità, possiamo sperimentare e disegnare un grafico che fa muovere Boxy in un modo che sembra naturale e realistico.

Facciamolo passo dopo passo. Primo, le cose nella vita reale iniziano lentamente e lentamente aumentano di velocità. Quindi, facciamolo.

In tutte le iterazioni del grafico mostrato di seguito, noterai che i punti agli angoli opposti rimangono fissi. Questo perché non stiamo cambiando la durata di esecuzione dell'animazione, né stiamo cambiando la distanza percorsa da Boxy.

Costruire una curva di movimento personalizzata
Costruire una curva di movimento personalizzata (Visualizza versione grande)

Se Boxy deve seguire il grafico sopra, si sposterà a una velocità inferiore per 0,25 secondi, perché la linea è meno ripida a partire da 0 a 0,25 secondi, quindi passerà bruscamente a una velocità più alta dopo 0,25 secondi (il motivo è che che la linea nel grafico diventa più ripida dopo 0,25 secondi). Tuttavia, dovremo rendere più fluida questa transizione; non vogliamo angoli, dopotutto si chiama curva di movimento. Convertiamo quell'angolo in una curva.

Costruire una curva di movimento personalizzata
Costruire una curva di movimento personalizzata (Visualizza versione grande)

Notare la transizione graduale che Boxy subisce dall'essere a riposo all'aumento graduale della velocità.

Boxy seguendo la curva di movimento sopra
Riquadro che segue la curva di movimento sopra (Visualizza versione grande)

Bene! Successivamente, gli oggetti nella vita reale rallentano progressivamente prima di fermarsi. Cambiamo il grafico per farlo accadere. Ancora una volta, prenderemo un momento dopo il quale vorremmo che Boxy iniziasse a rallentare. Che ne dici di circa 0,6 secondi? Ho già smussato l'angolo della transizione in una curva qui.

Curva di movimento finale personalizzata
Curva di movimento personalizzata finale (Visualizza versione grande)

Guarda Boxy vai! Molto più naturale, vero?

Boxy seguendo la curva di movimento personalizzata
Boxy seguendo la curva di movimento personalizzata (Visualizza versione grande)

La curva che abbiamo disegnato al posto dell'angolo è in realtà una raccolta di molti piccoli segmenti di linea; e, come già sai, più la linea sul grafico è ripida, maggiore è la velocità e più piatta è la linea, più lenta è la velocità. Notare come nella parte sinistra dell'immagine, i segmenti di linea che compongono la curva diventano sempre più ripidi, determinando un graduale aumento della velocità, e progressivamente si appiattiscono sul lato destro, con conseguente diminuzione progressiva della velocità?

Una curva non è altro che un insieme di molti segmenti di linea.
Una curva non è altro che un insieme di molti segmenti di linea. (Visualizza versione grande)

Con tutta questa conoscenza, dare un senso alle curve di movimento diventa molto più facile. Diamo un'occhiata ad alcuni esempi.

(Visualizza versione grande)
Esempio 1
Esempio 1 (Visualizza versione grande)
(Visualizza versione grande)
Esempio 2
Esempio 2 (Visualizza versione grande)
(Visualizza versione grande)
Esempio 3
Esempio 3 (Visualizza versione grande)

Utilizzo delle curve di movimento nell'animazione dell'interfaccia utente

La prossima volta che dovrai animare un elemento dell'interfaccia utente, avrai a disposizione il potere delle curve di movimento. Che si tratti di una barra a scorrimento, di una finestra modale o di un menu a discesa, aggiungere la giusta quantità di animazione e farla sembrare liscia e naturale aumenterà notevolmente la qualità della tua interfaccia utente. Farà sentire bene l'interfaccia utente. Prendi il menu a scorrimento qui sotto:

Guarda la Pen nJial di Nash Vail (@nashvail) su CodePen.

Guarda la Pen nJial di Nash Vail (@nashvail) su CodePen.

Facendo clic sul menu dell'hamburger si accede al menu da sinistra, ma l'animazione sembra a blocchi. La riga 51 del CSS mostra che l'animazione ha transition-timing-function impostata su linear . Possiamo migliorare questo. Andiamo su cubic-bezier e creiamo una funzione di temporizzazione personalizzata.

Se stai leggendo questo, è lecito ritenere che tu sia un designer o uno sviluppatore o entrambi e, quindi, non estraneo alle curve di Bezier cubiche; ci sono buone probabilità che li abbia incontrati almeno una volta. Le curve di Bezier sono una meraviglia. Sono utilizzati principalmente nella computer grafica per disegnare forme e sono utilizzati in strumenti come Sketch e Adobe Illustrator per disegnare grafica vettoriale. Il motivo per cui le curve di Bézier cubiche sono così popolari è che sono così facili da usare: basta modificare le posizioni dei quattro diversi punti e creare il tipo di curva di cui hai bisogno.

Poiché conosciamo sempre lo stato iniziale e finale dell'oggetto animato, possiamo correggere due dei punti. Rimangono solo due punti di cui dobbiamo modificare le posizioni. I due punti fissi sono chiamati punti di ancoraggio e i due rimanenti sono punti di controllo.

Parti di una curva di Bézier
Parti di una curva di Bézier (Visualizza versione grande)

Come ricorderai, cubic-bezier accetta quattro numeri ( n1, n2, n3, n4 ) quando crei una transition-timing-function personalizzata. Questi quattro numeri non rappresentano altro che le posizioni dei due punti di controllo: n1, n2 rappresenta le coordinate xey del primo punto di controllo e n3, n4 rappresenta le coordinate del secondo punto di controllo. Poiché la modifica della posizione dei punti di controllo cambierà la forma della curva e, quindi, la nostra animazione in generale, il risultato è lo stesso quando uno o tutti gli n1, n2, n3, n4 vengono modificati. Ad esempio, la figura seguente rappresenta cubic-bezier(.14, .78, .89, .35) :

Una curva di Bézier cubica che rappresenta (.14, .78, .89, .35).
Una curva di Bézier cubica che rappresenta (.14, .78, .89, .35) (Visualizza versione grande)

La matematica dietro queste curve apparentemente semplici è affascinante.

Va bene, va bene, torniamo al punto in cui stavamo andando con cubic-bezier: creare una transition-timing-function personalizzata. Voglio il tipo di animazione in cui il menu scorre molto rapidamente e poi rallenta con grazia e termina:

Regolazione della curva di Bézier cubica
Regolazione della curva di Bézier cubica (Visualizza versione grande)

Questo sembra buono. L'animazione inizierà velocemente e poi rallenterà, invece di muoversi a velocità costante per tutto il tempo. Copierò semplicemente cubic-bezier(.05, .69, .14, 1) dalla parte superiore della pagina e sostituirò linear con esso.

Guarda la Pen nJial di Nash Vail (@nashvail) su CodePen.

Guarda la Pen nJial di Nash Vail (@nashvail) su CodePen.

Vedi la differenza? La seconda iterazione sembra molto più naturale e accattivante. Immagina se ogni animazione nella tua interfaccia utente seguisse una funzione di temporizzazione naturale. Non sarebbe grandioso?

Come abbiamo visto, le curve di movimento non sono affatto complicate. Sono molto facili da capire e da usare. Con loro, puoi portare la tua interfaccia utente al livello successivo.

Spero che tu abbia imparato come funzionano le curve di movimento. Se stavi attraversando molti tentativi ed errori per far funzionare le curve di movimento nel modo desiderato, o se non le stavi utilizzando affatto, ora dovresti essere a tuo agio nel piegarle alla tua volontà e creare bellissime animazioni. Perché, dopotutto, l'animazione conta.