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 krótkie przypomnienie, jak animować chmurę na ekranie z powrotem do niej po zakończeniu:

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. W Chrome 39 do obiektu AnimationPlayer zwracanego przez funkcję element.animate dodano funkcje sterowania odtwarzaniem. Wcześniej po utworzeniu animacji można było wywołać tylko 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 zatrzymać animację 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(), co zwykle odpowiada odwróceniu obecnej wartości playbackRate (pomnożenie jej przez -1). Istnieją jednak pewne przypadki szczególne:

  • Jeśli zmiana wywołana przez metodę reverse() spowoduje zakończenie bieżącej animacji, currentTime zostanie również odwrócona.Przykład: 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

Element AnimationPlayer umożliwia teraz modyfikowanie elementu 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ć palcem, aby zmienić pozycję aktualnie odtwarzanej chmury, możesz dodać 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 po dokumencie, pole currentTime zmieni się, aby odzwierciedlać odległość od pierwotnego wydarzenia. Możesz też wznowić odtwarzanie animacji 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 zajmie się 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 wyświetlany po lewej stronie ekranu.

Dzięki animacjom w sieci możesz łatwo odtworzyć podobny efekt w internecie – na komputerze lub urządzeniu mobilnym. Na przykład po zakończeniu gestu sterującego funkcją 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;
});

Spowoduje to utworzenie dodatkowej animacji wykonującej „dryf”. Odtwarza się od miejsca, w którym gest został wykonany, do celu, który został rozpoznany.

Dzieje się tak, ponieważ animacje mają priorytet na podstawie kolejności ich utworzenia: w tym przypadku driftPlayer ma wyższy priorytet niż player. Gdy driftPlayer zostanie ukończone, zniknie ono wraz ze swoimi efektami. Jednak jego ostateczny czas będzie zgodny z wartością currentTime podrzędnego odtwarzacza, dzięki czemu interfejs pozostanie 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 w celu zapewnienia zgodności wstecznej, więc spróbuj ją wczytać 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 się z czasem tylko szybciej i skuteczniej działać.

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