Orchestrazione delle animazioni con le promesse, miglioramenti delle prestazioni con animazioni sostituibili, animazioni più fluide con le modalità composite e altro ancora.
Pubblicata il 27 maggio 2020
Se utilizzate correttamente, le animazioni migliorano la percezione e la memoria degli utenti del tuo brand, guidano le loro azioni e li aiutano a navigare nella tua applicazione, fornendo contesto in uno spazio digitale.
L'API Web Animations è uno strumento che consente agli sviluppatori di scrivere animazioni imperative con JavaScript. È stato scritto per supportare le implementazioni di animazioni e transizioni CSS e consentire lo sviluppo di effetti futuri, nonché la composizione e la temporizzazione di quelli esistenti.
Sebbene Firefox e Safari abbiano già implementato l'intero insieme di funzionalità delle specifiche, Chromium 84 offre una serie di funzionalità non supportate in precedenza a Chrome ed Edge, consentendo l'interoperabilità tra browser.
Per iniziare
La creazione di un'animazione utilizzando l'API Web Animations dovrebbe risultare molto familiare se hai utilizzato le regole @keyframe
. Innanzitutto, devi creare un oggetto keyframe. In CSS potrebbe avere il seguente aspetto :
@keyframes openAnimation {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
avrà il seguente aspetto in JavaScript:
const openAnimation = [
{ transform: 'scale(0)' },
{ transform: 'scale(1)' },
];
Dove imposti i parametri per l'animazione in CSS:
.modal {
animation: openAnimation 1s 1 ease-in;
}
in JS:
document.querySelector('.modal').animate(
openAnimation, {
duration: 1000, // 1s
iterations: 1, // single iteration
easing: 'ease-in' // easing function
}
);
La quantità di codice è più o meno la stessa, ma con JavaScript hai a disposizione un paio di superpoteri che non hai con il solo CSS. Sono incluse la possibilità di mettere in sequenza gli effetti e un maggiore controllo sugli stati di riproduzione.
Oltre element.animate()
Tuttavia, con l'aggiornamento, l'API Web Animations non è più limitata alle animazioni create utilizzando element.animate()
. Possiamo anche manipolare le animazioni e le transizioni CSS.
getAnimations()
è un metodo che restituisce tutte le animazioni di un elemento, indipendentemente dal fatto che sia stato creato utilizzando element.animate()
o le regole CSS (animazione o transizione CSS). Ecco un esempio:
Per prima cosa, "get"
i fotogrammi chiave per la transizione per determinare da dove stiamo effettuando la transizione. Poi, crea due nuove animazioni di opacità, attivando l'effetto di transizione incrociata. Al termine della transizione, elimina la copia.
Come orchestrare le animazioni con le promesse
In Chromium 84, ora sono disponibili due metodi che possono essere utilizzati con le promesse: animation.ready
e animation.finished
.
animation.ready
ti consente di attendere l'applicazione delle modifiche in attesa (ovvero il passaggio da un metodo di controllo della riproduzione all'altro, ad esempio la riproduzione e la messa in pausa).animation.finished
fornisce un mezzo per eseguire codice JavaScript personalizzato al termine di un'animazione.
Continuando con il nostro esempio, crea una catena di animazioni orchestrate con animation.finished
. In questo caso, viene eseguita una trasformazione verticale (scaleY
), seguita da una trasformazione orizzontale (scaleX
), seguita da una modifica dell'opacità in un elemento secondario:
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});
Abbiamo collegato queste animazioni utilizzando animation.finished.then()
prima di eseguire l'animazione successiva nella catena. In questo modo, le animazioni vengono visualizzate in ordine e puoi anche applicare effetti a diversi elementi target con opzioni diverse impostate (ad esempio velocità ed easing).
In CSS, sarebbe complicato ricrearlo, soprattutto quando si applicano animazioni uniche, ma sequenziate, a più elementi. Dovresti utilizzare un @keyframe
, stabilire le percentuali di tempo corrette per posizionare le animazioni e utilizzare animation-delay
prima di attivare le animazioni nella sequenza.
Esempio: riprodurre, mettere in pausa e riavvolgere
Ciò che può essere aperto, deve essere chiuso. Fortunatamente, a partire da Chromium 39, l'API Web Animations ci ha permesso di riprodurre, mettere in pausa e invertire le animazioni.
Puoi prendere l'animazione mostrata in precedenza e applicarle un'animazione fluida e inversa facendo di nuovo clic sul pulsante utilizzando .reverse()
. In questo modo, puoi creare un'interazione più fluida e contestuale per la nostra finestra modale.
Puoi creare due animazioni in attesa di riproduzione (openModal
e una trasformazione di opacità in linea) e mettere in pausa una delle animazioni, ritardandola fino al termine dell'altra. Puoi quindi utilizzare le promesse per attendere il completamento di ciascuna prima di iniziare a giocare. Infine, puoi controllare se è impostato un flag e invertire ogni animazione.
Esempio: interazioni dinamiche con fotogrammi chiave parziali
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
{duration: 1000, fill: 'forwards'});
In questo esempio è presente un solo fotogramma chiave e nessuna posizione di inizio specificata. Questo è un esempio di utilizzo dei keyframe parziali. Il gestore del mouse esegue alcune operazioni: imposta una nuova posizione di fine e attiva una nuova animazione. La nuova posizione iniziale viene dedotta dalla posizione di base corrente.
Le nuove transizioni possono essere attivate mentre quelle esistenti sono ancora in esecuzione. Ciò significa che la transizione corrente viene interrotta e ne viene creata una nuova.
Miglioramenti del rendimento con le animazioni sostituibili
Quando crei animazioni basate su eventi, ad esempio su 'mousemove'
, ogni volta viene creata una nuova animazione, che può consumare rapidamente la memoria e peggiorare il rendimento. Per risolvere questo problema, in Chromium 83 sono state introdotte le animazioni sostituibili, che consentono la pulizia automatica, in cui le animazioni complete vengono contrassegnate come sostituibili e rimosse automaticamente se sostituite da un'altra animazione completa. Considera l'esempio seguente:
elem.addEventListener('mousemove', evt => {
rectangle.animate(
{ transform: translate(${evt.clientX}px, ${evt.clientY}px) },
{ duration: 500, fill: 'forwards' }
);
});
Ogni volta che il mouse si muove, il browser ricalcola la posizione di ogni pallina nella scia della cometa e crea un'animazione per questo nuovo punto. Ora il browser sa di rimuovere le vecchie animazioni (attivando la sostituzione) quando:
- L'animazione è terminata.
- Esistono una o più animazioni più in alto nell'ordine composito che sono state completate.
- Le nuove animazioni animano le stesse proprietà.
Puoi vedere esattamente quante animazioni vengono sostituite conteggiando un contatore per ogni animazione rimossa, utilizzando anim.onremove
per attivare il contatore.
Esistono alcune proprietà e metodi aggiuntivi per migliorare ulteriormente il controllo dell'animazione:
animation.replaceState
fornisce un mezzo per monitorare se un'animazione è attiva, persistente o rimossa.animation.commitStyles()
aggiorna lo stile di un elemento in base allo stile sottostante, nonché tutte le animazioni dell'elemento nell'ordine composito.animation.persist()
contrassegna un'animazione come non sostituibile.
Animazioni più fluide con le modalità composite
Con l'API Web Animations, ora puoi impostare la modalità composita delle animazioni, il che significa che possono essere additive o cumulative, oltre alla modalità predefinita "sostituzione". Le modalità composite consentono agli sviluppatori di scrivere animazioni distinte e di avere il controllo sulla combinazione degli effetti. Ora sono supportate tre modalità composite: 'replace'
(la modalità predefinita), 'add'
e 'accumulate'
.
Quando componi animazioni, uno sviluppatore può scrivere effetti brevi e distinti e visualizzarli combinati. Nell'esempio seguente, a ogni riquadro viene applicata una keyframe di rotazione e scala, con l'unico aggiustamento della modalità composita, aggiunta come opzione:
Nella modalità composita 'replace'
predefinita, l'animazione finale sostituisce la proprietà transform e termina a rotate(360deg) scale(1.4)
. Per 'add'
, la composizione aggiunge la rotazione e moltiplica la scala, ottenendo uno stato finale di rotate(720deg) scale(1.96)
. 'accumulate'
combina le trasformazioni, ottenendo rotate(720deg) scale(1.8)
. Per saperne di più sulle complessità di queste modalità composite, consulta le enumerazioni CompositeOperation e CompositeOperationOrAuto delle specifiche delle animazioni web.
Dai un'occhiata al seguente esempio di elemento dell'interfaccia utente:
Qui vengono composte due animazioni top
. La prima è una macro-animazione, che sposta il menu a discesa per l'intera altezza del menu stesso come effetto di scorrimento dall'alto della pagina, mentre la seconda, una micro-animazione, applica un piccolo rimbalzo quando raggiunge il fondo. L'utilizzo della modalità composita 'add'
consente una transizione più fluida.
const dropDown = menu.animate(
[
{ top: `${-menuHeight}px`, easing: 'ease-in' },
{ top: 0 }
], { duration: 300, fill: 'forwards' });
dropDown.finished.then(() => {
const bounce = menu.animate(
[
{ top: '0px', easing: 'ease-in' },
{ top: '10px', easing: 'ease-out' },
{ ... }
], { duration: 300, composite: 'add' });
});
Novità per l'API Web Animations
Si tratta di interessanti aggiunte alle funzionalità di animazione dei browser attuali e sono previste altre aggiunte in futuro. Consulta queste specifiche future per saperne di più sulle prossime novità: