Commande de lecture des animations Web dans Chrome 39

Plus tôt cette année, Chrome 36 a ajouté la méthode item.animate dans le cadre de la spécification Web Animations plus large, ce qui permet de créer des animations natives efficaces, écrites de façon impérative. Les développeurs ont ainsi la possibilité de créer leurs animations et transitions selon l'approche qui leur convient le mieux.

Voici comment animer un nuage sur l'écran, avec un rappel une fois l'opération terminée:

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);
};

C'est un outil incroyablement simple qui mérite d'être intégré à votre boîte à outils lorsque vous créez des animations ou des transitions de façon impérative. Toutefois, dans Chrome 39, des fonctionnalités de commande de lecture ont été ajoutées à l'objet AnimationPlayer renvoyé par element.animate. Auparavant, une fois qu'une animation était créée, vous ne pouviez appeler que cancel() ou écouter l'événement de fin.

Ces ajouts de lecture ouvrent le champ des possibilités offertes par les animations Web : transformer les animations en un outil à usage général, plutôt que d'être normatif sur les transitions, c'est-à-dire Animations fixes ou prédéfinies

Mettre en pause, revenir en arrière ou modifier la vitesse de lecture

Commençons par mettre à jour l'exemple ci-dessus pour mettre en pause l'animation lorsque l'utilisateur clique sur le nuage:

cloud.addEventListener('mousedown', function() {
    player.pause();
});

Vous pouvez également modifier la propriété playbackRate:

function changeWindSpeed() {
    player.playbackRate *= (Math.random() * 2.0);
}

Vous pouvez également appeler la méthode reverse(), ce qui équivaut normalement à inverser la valeur playbackRate actuelle (en la multipliant par -1). Il existe toutefois quelques cas particuliers:

  • Si la modification causée par la méthode reverse() entraîne la fin effective de l'animation en cours, currentTime est également inversé.Par exemple, si une toute nouvelle animation est inversée, toute l'animation sera lue en arrière.

  • Si le lecteur est mis en pause, la lecture de l'animation commence.

Utiliser la barre de lecture du lecteur

Un AnimationPlayer permet désormais de modifier son currentTime pendant l'exécution d'une animation. Normalement, cette valeur augmente au fil du temps (ou diminue, si playbackRate est négatif). La position d'une animation peut ainsi être contrôlée de manière externe, éventuellement par le biais d'une interaction de l'utilisateur. C'est ce que l'on appelle généralement le frottage.

Par exemple, si votre page HTML représentait le ciel et que vous souhaitez effectuer un geste de glissement pour modifier la position d'un nuage en cours de lecture, vous pouvez ajouter des gestionnaires au document:

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;
});

Lorsque vous faites glisser le document, la currentTime est modifiée pour refléter la distance par rapport à l'événement d'origine. Vous pouvez également reprendre la lecture de l'animation à la fin du geste:

document.addEventListener('touchend', function(event) {
    startEvent = null;
    player.play();
});

Cela peut même être associé à un comportement d'inversion, selon l'endroit où la souris a été retirée de la page (démonstration combinée).

Au lieu d'utiliser la barre de lecture d'une AnimationPlayer en réponse à une interaction de l'utilisateur, son currentTime peut également être utilisé pour afficher la progression ou l'état, par exemple pour indiquer l'état d'un téléchargement.

L'avantage ici est qu'un AnimationPlayer permet de définir une valeur et que l'implémentation native sous-jacente se charge de sa visualisation de la progression. Dans le cas d'un téléchargement, la durée d'une animation peut être définie sur la taille de téléchargement totale et la currentTime sur la taille actuellement téléchargée (démonstration).

Transitions et gestes dans l'interface utilisateur

Les plates-formes mobiles sont depuis longtemps le domaine des gestes courants: faire glisser, faire glisser, faire glisser d'un geste vif, etc. Ces gestes ont généralement un thème commun: un composant d'interface utilisateur déplaçable, tel qu'une fonction "Tirer pour actualiser" dans une vue sous forme de liste ou une barre latérale ouverte à partir du côté gauche de l'écran.

Avec les animations Web, un effet similaire est très facile à reproduire ici sur le Web, sur ordinateur ou sur mobile. Par exemple, lorsqu'un geste contrôlant currentTime se termine:

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;
});

Cela crée une animation supplémentaire qui effectue un "drift" (dérive). Elle s'effectue entre l'endroit où le geste a été effectué et jusqu'à notre bonne cible connue.

Cela fonctionne, car la priorité des animations dépend de leur ordre de création: dans ce cas, driftPlayer prévaut sur le lecteur. Lorsque driftPlayer sera terminé, il disparaîtra et ses effets. Cependant, son heure finale correspond à l'heure actuelle du joueur sous-jacent, de sorte que votre UI reste cohérente.

Enfin, si vous aimez les chatons, il existe une application Web de démonstration qui vous montre ces gestes. Il est adapté aux mobiles et utilise le polyfill pour assurer la rétrocompatibilité, alors essayez de le charger sur votre appareil mobile !

Aller à l'étape suivante et afficher "Element.animate"

La méthode element.animate fonctionne parfaitement actuellement, que vous l'utilisiez pour des animations simples ou que vous utilisiez le AnimationPlayer renvoyé d'autres manières.

Ces deux fonctionnalités sont également entièrement prises en charge dans les autres navigateurs récents grâce à un polyfill léger. Ce polyfill assure également la détection de caractéristiques. Ainsi, à mesure que les fournisseurs de navigateurs implémentent la spécification, cette fonctionnalité deviendra plus rapide et plus efficace au fil du temps.

La spécification Web Animations continuera également d'évoluer. Si vous souhaitez tester les fonctionnalités à venir, sachez qu'elles sont également disponibles dans un polyfill plus détaillé: web-animations-next.