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 e scritte in modo imperativo, dando agli sviluppatori la possibilità di creare animazioni e transizioni con l'approccio più adatto a loro.
Per un rapido ripasso, ecco come potresti animare una nuvola sullo schermo, con un callback al termine dell'operazione:
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 soluzione è incredibilmente facile e vale la pena prenderla in considerazione come parte del tuo strumento 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 cancel()
o ascoltare l'evento finale.
Queste aggiunte alla riproduzione aprono le possibilità delle animazioni web: trasformare le animazioni in uno strumento generico, invece di essere prescrittive per le transizioni, ovvero "fisso" o animazioni predefinite.
Mettere in pausa, riavvolgere o modificare la velocità di riproduzione
Inizia aggiornando l'esempio riportato sopra per mettere in pausa l'animazione quando l'utente 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 normalmente equivale all'inversione del valore playbackRate
corrente (moltiplica per -1). Tuttavia, esistono un paio di casi speciali:
Se la modifica causata dal metodo
reverse()
comporta la fine effettiva dell'animazione in esecuzione, anche ilcurrentTime
viene invertito.Ad esempio, se una nuova animazione viene invertita, l'intera animazione verrà riprodotta a ritroso.Se il player è in pausa, verrà avviata la riproduzione dell'animazione.
Eseguire lo scrubbing del player
Un AnimationPlayer
ora consente la modifica del relativo currentTime
mentre è in esecuzione un'animazione. Solitamente, questo valore aumenterà nel tempo (o diminuirà, se il valore playbackRate
è negativo). Ciò potrebbe consentire di controllare esternamente la posizione di un'animazione, magari attraverso l'interazione dell'utente. Questa operazione è comunemente nota come scrubbing.
Ad esempio, se la tua pagina HTML rappresentava il cielo e vuoi usare un gesto di trascinamento per cambiare la posizione della nuvola in riproduzione, puoi aggiungere al documento alcuni gestori:
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 sul documento, l'elemento currentTime
si modifica per riflettere la 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 potrebbe anche essere combinato con l'inversione del comportamento, a seconda di dove il mouse è stato spostato dalla pagina (demo combinata).
Anziché eseguire lo scrubbing di un AnimationPlayer
in risposta a un'interazione dell'utente, l'elemento currentTime
potrebbe essere utilizzato anche per mostrare l'avanzamento o lo stato, ad esempio per mostrare lo stato di un download.
In questo caso, l'utilità è che un AnimationPlayer
consente di impostare un valore e che l'implementazione nativa sottostante si occupi della sua visualizzazione dell'avanzamento. Nel caso del download, la durata di un'animazione potrebbe essere impostata sulla dimensione totale di download e currentTime
sulla dimensione attualmente scaricata (demo).
Transizioni e gesti della UI
Le piattaforme per dispositivi mobili sono da tempo il regno dei gesti comuni: trascinare, far scorrere, scorrazzare e così via. Questi gesti tendono ad avere un tema comune: un componente dell'interfaccia utente trascinabile, come il pulsante "Esegui il pull per aggiornare" di una visualizzazione elenco. o una barra laterale che viene creata sul lato sinistro dello schermo.
Con le animazioni web, un effetto simile è molto facile da replicare qui sul web: su desktop o su dispositivo mobile. Ad esempio, quando viene completato un gesto che controlla 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;
});
Verrà creata un'animazione aggiuntiva che esegue una "deviazione". Questo viene riprodotto dal punto in cui è stato completato il gesto fino al bersaglio noto.
Funziona perché le animazioni hanno una priorità basata sull'ordine di creazione: in questo caso, driftPlayer
ha la precedenza sul player. Al termine di driftPlayer
, i suoi effetti scompaiono. Tuttavia, il tempo finale corrisponderà all'ora corrente 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 e element.animate
Il metodo element.animate
è davvero ottimo al momento, sia che lo utilizzi per animazioni semplici o che utilizzi 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 le specifiche, questa funzionalità diventerà sempre più veloce e migliore con il passare del tempo.
Anche la specifica delle animazioni web continuerà a evolversi. Se ti interessa sperimentare le funzionalità in arrivo, sono disponibili anche in un polyfill più dettagliato: web-animations-next.