All'inizio di quest'anno, Chrome 36 ha introdotto il metodo element.animate nell'ambito della più ampia specifica sulle animazioni web. Ciò consente di creare animazioni native efficienti scritte in modo imperativo, offrendo agli sviluppatori la possibilità di creare animazioni e transizioni con l'approccio più adatto a loro.
Per un breve ripasso, ecco come puoi animare una nuvola sullo schermo, con un callback al termine:
var player = cloud.animate([
{transform: 'translateX(' + start + 'px)'},
{transform: 'translateX(' + end + 'px)'}
], 5000);
player.onfinish = function() {
console.info('Cloud moved across the screen!');
startRaining(cloud);
};
Questa operazione è incredibilmente semplice e vale la pena di inserirla nel tuo kit di strumenti quando crei animazioni o transizioni in modo imperativo. Tuttavia, in Chrome 39, le funzionalità di controllo della riproduzione sono state aggiunte all'oggetto AnimationPlayer
restituito da element.animate
. In precedenza, una volta creata un'animazione, potevi chiamare solo cancel()
o ascoltare l'evento di completamento.
Queste aggiunte alla riproduzione ampliano le possibilità di ciò che le animazioni web possono fare: trasformano le animazioni in uno strumento per uso generale, anziché essere prescrittive per le transizioni, ad esempio Animazioni "fisse" o predefinite.
Mettere in pausa, riavvolgere o modificare la velocità di riproduzione
Iniziamo aggiornando l'esempio riportato sopra per mettere in pausa l'animazione quando si fa clic sul cloud:
cloud.addEventListener('mousedown', function() {
player.pause();
});
Puoi anche modificare la proprietà playbackRate
:
function changeWindSpeed() {
player.playbackRate *= (Math.random() * 2.0);
}
Puoi anche chiamare il metodo reverse()
, che di solito equivale all'inversione del valore playbackRate
corrente (moltiplica per -1). Esistono però un paio di casi speciali:
Se la modifica causata dal metodo
reverse()
determina la fine effettiva dell'animazione in esecuzione, anche il valorecurrentTime
viene invertito.Ad esempio, se una nuova animazione viene invertita, l'intera animazione verrà riprodotta a ritroso.Se il player è in pausa, l'animazione inizierà a essere riprodotta.
Scrub del player
Ora un AnimationPlayer
consente di modificare il relativo currentTime
durante l'esecuzione di un'animazione. In genere, questo valore aumenta nel tempo (o diminuisce se playbackRate
è negativo). Ciò potrebbe consentire di controllare esternamente la posizione di un'animazione, magari attraverso l'interazione dell'utente. Questo processo è comunemente noto come scrubbing.
Ad esempio, se la tua pagina HTML rappresenta il cielo e vuoi che un gesto di trascinamento modifichi la posizione di una nuvola attualmente in riproduzione, puoi aggiungere alcuni gestori al documento:
var startEvent, startEventTime;
document.addEventListener('touchstart', function(event) {
startEvent = event;
startEventTime = players.currentTime;
player.pause();
});
document.addEventListener('touchmove', function(event) {
if (!startEvent) return;
var delta = startEvent.touches[0].screenX -
event.changedTouches[0].screenX;
player.currentTime = startEventTime + delta;
});
Mentre trascini il documento, il simbolo currentTime
viene modificato in base alla distanza dall'evento originale. Puoi anche riprendere la riproduzione dell'animazione al termine del gesto:
document.addEventListener('touchend', function(event) {
startEvent = null;
player.play();
});
Questo può essere combinato anche con il comportamento di inversione, a seconda di dove il mouse è stato sollevato dalla pagina (demo combinata).
Anziché eseguire la scansione di un AnimationPlayer
in risposta a un'interazione dell'utente, il relativo currentTime
potrebbe essere utilizzato anche per mostrare l'avanzamento o lo stato: ad esempio, per mostrare lo stato di un download.
L'utilità di AnimationPlayer
è che consente di impostare un valore e di lasciare che l'implementazione nativa di base si occupi della visualizzazione dei progressi. Nel caso del download, la durata di un'animazione potrebbe essere impostata sulle dimensioni totali del download e currentTime
impostato sulle dimensioni attualmente scaricate (demo).
Transizioni e gesti dell'interfaccia utente
Le piattaforme mobile sono da tempo il regno dei gesti comuni: trascinamento, scorrimento, lancio e simili. Questi gesti tendono ad avere un tema comune: un componente dell'interfaccia utente trascinabile, ad esempio "Tira per aggiornare" di una visualizzazione elenco o una barra laterale che viene creata dal lato sinistro dello schermo.
Con le animazioni web, è molto facile replicare un effetto simile qui sul web, su computer o dispositivo mobile. Ad esempio, quando viene completato un gesto di controllo di currentTime
:
var steps = [ /* animation steps */ ];
var duration = 1000;
var player = target.animate(steps, duration);
player.pause();
configureStartMoveListeners(player);
var setpoints = [0, 500, 1000];
document.addEventListener('touchend', function(event) {
var srcTime = player.currentTime;
var dstTime = findNearest(setpoints, srcTime);
var driftDuration = dstTime - srcTime;
if (!driftDuration) {
runCallback(dstTime);
return;
}
var driftPlayer = target.animate(steps, {
duration: duration,
iterationStart: Math.min(srcTime, dstTime) / duration,
iterations: Math.abs(driftDuration) / duration,
playbackRate: Math.sign(driftDuration)
});
driftPlayer.onfinish = function() { runCallback(dstTime); };
player.currentTime = dstTime;
});
Viene creata un'animazione aggiuntiva che esegue una "deviazione". Il video viene riprodotto dal punto in cui è stato completato il gesto fino al nostro target noto buono.
Funzionano perché le animazioni hanno una priorità basata sul loro ordine di creazione: in questo caso, driftPlayer
ha la precedenza sul player. Al termine di driftPlayer
, l'effetto e l'effetto stesso scompaiono. Tuttavia, il tempo finale corrisponderà all'attuale ora del player sottostante, quindi la tua UI rimarrà coerente.
Infine, se vi piacciono i gattini, c'è un'applicazione web demo che mette in mostra questi gesti. È ottimizzato per il mobile e utilizza il polyfill per essere compatibile con le versioni precedenti, quindi prova a caricarlo sul tuo dispositivo mobile.
Vai avanti ed element.animate
Il metodo element.animate
è fantastico in questo momento, che tu lo utilizzi per animazioni semplici o per sfruttare il AnimationPlayer
restituito in altri modi.
Queste due funzionalità sono pienamente supportate anche in altri browser moderni tramite un polyfill leggero. Questo polyfill esegue anche il rilevamento delle funzionalità, quindi, man mano che i fornitori di browser implementano la specifica, questa funzionalità diventerà sempre più veloce e migliorerà nel tempo.
Anche le specifiche di Web Animations continueranno a evolversi. Se vuoi provare le funzionalità in arrivo, sono ora disponibili anche in un polyfill più dettagliato: web-animations-next.