Sterowanie odtwarzaniem animacji internetowych w Chrome 39

Jakiś czas temu w Chrome 36 wprowadziliśmy metodę Element.animate jako część szerszej specyfikacji Web Animation. Umożliwia to tworzenie wydajnych, natywnych animacji napisanych bez ograniczeń, dając deweloperom możliwość tworzenia animacji i przejść zgodnie z najbardziej odpowiednim dla nich podejściem.

Oto jak możesz animować chmurę na ekranie, a po zakończeniu wywoływać wywołanie zwrotne:

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

Już samo to jest niezwykle łatwe i warto uwzględnić je jako część zestawu narzędzi podczas tworzenia animacji lub przejść bez zbędnej zwłoki. Jednak w Chrome 39 do obiektu AnimationPlayer zwróconego przez element.animate zostały dodane funkcje sterowania odtwarzaniem. Wcześniej po utworzeniu animacji można było wywołać tylko funkcję cancel() lub nasłuchiwać zakończenia.

Te dodatki do odtwarzania otwierają możliwości, jakie dają animacje internetowe – zmieniają animacje w narzędzie ogólnego przeznaczenia, a nie wymagają ustanowienia przejść, np. „Naprawiono” lub wstępnie zdefiniowane animacje.

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

Zacznijmy od aktualizacji tego przykładu, aby wstrzymywać 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). Jest jednak kilka szczególnych przypadków:

  • Jeśli zmiana spowodowana przez metodę reverse() spowodowałaby efektywne zakończenie trwającej animacji, element currentTime również zostaje odwrócony – np.jeśli zupełnie nowa animacja zostanie odwrócona, cała animacja będzie odtwarzana wstecz.

  • Jeśli odtwarzacz zostanie wstrzymany, rozpocznie się odtwarzanie animacji.

Przewijanie odtwarzacza

Element AnimationPlayer umożliwia teraz modyfikowanie elementu currentTime podczas odtwarzania animacji. Normalnie ta wartość wzrasta z czasem (lub się zmniejsza, jeśli playbackRate jest ujemny). Może to umożliwić kontrolowanie pozycji animacji z zewnątrz, na przykład w wyniku interakcji użytkownika. Jest to tzw. szorowanie.

Jeśli na przykład na Twojej stronie HTML jest przedstawione niebo i chcesz zmienić położenie aktualnie odtwarzanej chmury za pomocą gestu przeciągania, możesz dodać do dokumentu kilka modułów obsługi:

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

Problem ten można nawet połączyć z odwracaniem działań, w zależności od miejsca, w którym użytkownik podniósł kursor na stronie (połączone demo).

Zamiast przeglądać pole AnimationPlayer w odpowiedzi na interakcję użytkownika, jego element currentTime może też służyć do pokazywania postępu lub stanu, np. do pokazywania stanu pobierania.

Zaletą tego rozwiązania jest to, że AnimationPlayer umożliwia ustawienie wartości, dzięki czemu wizualizacja postępu jest kontynuowana przez podstawowa implementacja natywna. W przypadku pobierania czas trwania animacji można ustawić na łączny rozmiar pobieranych danych, a w polu currentTime ustawiony jest rozmiar aktualnie pobieranego pliku (wersja demonstracyjna).

przejścia i gesty interfejsu,

Platformy mobilne od dawna są powszechnie używanymi gestami: przeciąganiem, przesuwaniem, przesuwaniem itp. Gesty te mają zwykle wspólny motyw: elementy interfejsu, które można przeciągać, np. funkcja „pociągnij, aby odświeżyć” w widoku listy lub pasek boczny utworzony od lewej strony ekranu.

W internecie animacje internetowe pozwalają bardzo łatwo odtworzyć podobny efekt w internecie – na komputerze lub na 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”. Działa od momentu wykonania gestu do znanego celu.

To działa, ponieważ animacje mają priorytet określony na podstawie kolejności ich utworzenia: w tym przypadku właściwość driftPlayer ma pierwszeństwo przed odtwarzaczem. Po zakończeniu driftPlayer jego działanie i efekty znikną. Ostateczny czas będzie jednak taki sam jak czas bieżący odtwarzacza, dlatego interfejs użytkownika pozostanie taki sam.

Jeżeli lubisz koty, możesz też skorzystać z demonstracyjnej aplikacji internetowej, która pokazuje te gesty. Jest przyjazny dla urządzeń mobilnych i korzysta z kodu polyfill na potrzeby zgodności wstecznej, więc spróbuj wczytać go na urządzeniu mobilnym.

Naprzód i element.animate

Metoda element.animate sprawdza się obecnie – niezależnie od tego, czy używasz jej do prostych animacji czy wykorzystujesz zwrócone dane AnimationPlayer w inny sposób.

Te 2 funkcje są w pełni obsługiwane również w innych nowoczesnych przeglądarkach dzięki uproszczonej wersji kodu polyfill. Ten kod polyfill wykrywa też funkcje, więc po wdrożeniu przez dostawców przeglądarek ta funkcja będzie działać coraz szybciej i lepiej.

Specyfikacja Web Animation również będzie się zmieniać. Jeśli chcesz przetestować nadchodzące funkcje, możesz je również znaleźć w bardziej szczegółowej postaci polyfill: web-animations-next.