Sterowanie odtwarzaniem animacji internetowych w Chrome 39

Wcześniej w tym roku w Chrome 36 pojawiła się metoda element.animate, która jest częścią szerszej specyfikacji animacji internetowych. Umożliwia ona tworzenie wydajnych, natywnych animacji w manierze imperatywnej, co daje deweloperom możliwość tworzenia animacji i przejść w najbardziej dogodny dla nich sposób.

Oto szybki przypomnienie, jak animować chmurę na ekranie z powrotnym wywołaniem:

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

To samo w sobie jest bardzo proste i warto wziąć to pod uwagę podczas tworzenia animacji lub przejść w sposób imperatywny. Jednak w Chrome 39 do obiektu AnimationPlayer zwracanego przez element.animate dodano funkcje sterowania odtwarzaniem. Wcześniej po utworzeniu animacji można było tylko wywołać funkcję cancel() lub odsłuchać zdarzenie zakończenia.

Te dodatki do odtwarzania zwiększają możliwości animacji internetowych, czyniąc je uniwersalnym narzędziem, a nie narzędziem do tworzenia przejść, np. „stałe” lub zdefiniowane wstępnie animacje.

Wstrzymywanie, przewijanie do tyłu i zmienianie szybkości odtwarzania

Zacznijmy od zaktualizowania powyższego przykładu, aby animacja była wstrzymywana po kliknięciu chmury:

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

Możesz też zmodyfikować właściwość playbackRate:

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

Możesz też wywołać metodę reverse(), która zwykle odpowiada odwróceniu bieżącej wartości playbackRate (pomnoż przez -1). Istnieją jednak pewne przypadki szczególne:

  • Jeśli zmiana wywołana przez metodę reverse() spowoduje, że bieżąca animacja zostanie zakończona, currentTime zostanie również odwrócona.Przykładowo, jeśli nowa animacja zostanie odwrócona, cała animacja będzie odtwarzana wstecz.

  • Jeśli odtwarzacz jest wstrzymany, animacja zacznie się odtwarzać.

Przewijanie odtwarzacza

AnimationPlayer umożliwia teraz modyfikowanie currentTime podczas odtwarzania animacji. Zwykle ta wartość zwiększa się z czasem (lub maleje, jeśli playbackRate jest ujemna). Pozwala to na kontrolowanie pozycji animacji z zewnątrz, np. przez interakcję użytkownika. Jest to tak zwane przewijanie.

Jeśli na przykład Twoja strona HTML przedstawia niebo i chcesz, aby można było przeciągać chmurę, która jest obecnie odtwarzana, dodaj do dokumentu odpowiednie elementy sterujące:

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

Gdy przeciągniesz kursor po dokumencie, wartość currentTime zmieni się, aby odzwierciedlić odległość od pierwotnego zdarzenia. Możesz też wznowić animację po zakończeniu gestu:

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

Można to połączyć z odwracaniem, w zależności od tego, gdzie mysz została odłączona od strony (demo łączone).

Zamiast przewijać AnimationPlayer w odpowiedzi na działanie użytkownika, możesz użyć currentTime, aby wyświetlić postęp lub stan, np. stan pobierania.

Zaletą jest to, że AnimationPlayer umożliwia ustawienie wartości, a podstawowa implementacja natywnych funkcji zadba o wizualizację postępów. W przypadku pobierania czas trwania animacji można ustawić na łączny rozmiar pobrania, a wartość currentTime na aktualnie pobierany rozmiar (demo).

Przejścia i gesty w interfejsie

Platformy mobilne od dawna są domeną zwykłych gestów: przeciągania, przesuwania, rzucania i podobnych. Te gesty mają zwykle wspólny motyw: przeciągany element interfejsu, np. „przeciągnij, aby odświeżyć” w widoku listy lub pasek boczny wysuwany z lewej strony ekranu.

Dzięki animacjom w sieci możesz łatwo odtworzyć podobny efekt w internecie – na komputerze lub urządzeniu mobilnym. Na przykład, gdy gest sterujący currentTime zostanie wykonany:

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

Spowoduje to utworzenie dodatkowej animacji, która wykonuje „drift”. Odtwarza się od miejsca, w którym gest został wykonany, do celu, który został rozpoznany.

Animacje mają priorytet na podstawie kolejności ich utworzenia: w tym przypadku driftPlayer ma wyższy priorytet niż player. Po zakończeniu driftPlayer zniknie ona wraz ze swoimi efektami. Jednak jego ostateczny czas będzie zgodny z wartością currentTime podrzędnego odtwarzacza, dzięki czemu interfejs będzie spójny.

Jeśli lubisz kotki, możesz skorzystać z aplikacji internetowej z demonstracją, która pokazuje te gesty. Jest ona zoptymalizowana pod kątem urządzeń mobilnych i korzysta z polyfilla do zapewnienia zgodności wstecznej, więc spróbuj ją załadować na urządzeniu mobilnym.

Idź i użyj element.animate

Metoda element.animate jest bardzo dobra – niezależnie od tego, czy używasz jej do tworzenia prostych animacji, czy też wykorzystujesz zwracane wartości AnimationPlayer w inny sposób.

Te dwie funkcje są też w pełni obsługiwane w innych nowoczesnych przeglądarkach za pomocą lekkiego rozwiązania polyfill. Ta polyfill wykonuje też wykrywanie funkcji, więc wraz z wdrażaniem specyfikacji przez dostawców przeglądarek ta funkcja będzie z czasem tylko szybsza i lepsza.

Specyfikacja animacji internetowych będzie się też rozwijać. Jeśli chcesz wypróbować nadchodzące funkcje, możesz to zrobić w ramach bardziej szczegółowego rozwiązania polyfill: web-animations-next.