Kontrol pemutaran animasi web di Chrome 39

Awal tahun ini, Chrome 36 meluncurkan metode element.animate sebagai bagian dari spesifikasi Animasi Web yang lebih luas. Hal ini memungkinkan animasi native yang efisien ditulis secara imperatif, sehingga memberi developer pilihan untuk membuat animasi dan transisi dengan pendekatan yang paling sesuai bagi mereka.

Sebagai pengingat singkat, berikut cara menganimasikan awan di seluruh layar, dengan callback setelah selesai:

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

Hal ini sangat mudah dan sangat layak dipertimbangkan sebagai bagian dari toolbox Anda saat membuat animasi atau transisi secara imperatif. Namun, di Chrome 39, fitur kontrol pemutaran telah ditambahkan ke objek AnimationPlayer yang ditampilkan oleh element.animate. Sebelumnya, setelah animasi dibuat, Anda hanya dapat memanggil cancel() atau memproses peristiwa selesai.

Penambahan pemutaran ini membuka kemungkinan apa yang dapat dilakukan Animasi Web - mengubah animasi menjadi alat serbaguna, bukan bersifat preskriptif tentang transisi, yaitu, Animasi 'tetap' atau yang telah ditetapkan.

Menjeda, memundurkan, atau mengubah kecepatan pemutaran

Mari kita mulai dengan memperbarui contoh di atas untuk menjeda animasi jika awan diklik:

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

Anda juga dapat mengubah properti playbackRate:

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

Anda juga dapat memanggil metode reverse(), yang biasanya setara dengan membalik playbackRate saat ini (kalikan dengan -1). Namun, ada beberapa kasus khusus:

  • Jika perubahan yang disebabkan oleh metode reverse() akan menyebabkan animasi yang sedang berjalan berakhir secara efektif, currentTime juga akan terbalik - misalnya, jika animasi baru dibalik, seluruh animasi akan diputar mundur

  • Jika pemutar dijeda, animasi akan mulai diputar.

Menggeser pemutar

AnimationPlayer kini memungkinkan currentTime-nya diubah saat animasi berjalan. Biasanya, nilai ini akan meningkat seiring waktu (atau menurun, jika playbackRate negatif). Hal ini dapat memungkinkan posisi animasi dikontrol secara eksternal, mungkin melalui interaksi pengguna. Hal ini biasanya disebut sebagai scrubbing.

Misalnya, jika halaman HTML Anda merepresentasikan langit, dan Anda ingin gestur tarik untuk mengubah posisi cloud yang sedang diputar, Anda dapat menambahkan beberapa pengendali ke dokumen:

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

Saat Anda menarik dokumen, currentTime akan diubah untuk mencerminkan jarak dari peristiwa asli Anda. Anda juga dapat melanjutkan pemutaran animasi saat gestur berakhir:

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

Hal ini bahkan dapat digabungkan dengan perilaku pembalikan, bergantung pada tempat mouse diangkat dari halaman (demo gabungan).

Daripada menghapus AnimationPlayer sebagai respons terhadap interaksi pengguna, currentTime-nya juga dapat digunakan untuk menampilkan progres atau status: misalnya, untuk menampilkan status download.

Utilitas di sini adalah AnimationPlayer memungkinkan nilai ditetapkan dan memiliki implementasi native yang mendasarinya untuk menangani visualisasi progresnya. Dalam kasus download, durasi animasi dapat disetel ke total ukuran download, dan currentTime disetel ke ukuran yang saat ini didownload (demo).

Transisi dan gestur UI

Platform seluler telah lama menjadi tempat gestur umum: menarik, menggeser, melempar, dan sebagainya. Gestur ini cenderung memiliki tema umum: komponen UI yang dapat ditarik, seperti "tarik untuk memuat ulang" tampilan daftar atau sidebar yang dibuat dari sisi kiri layar.

Dengan Animasi Web, efek serupa sangat mudah direplikasi di sini di web - di desktop atau di perangkat seluler. Misalnya, saat gestur yang mengontrol currentTime selesai:

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

Tindakan ini akan membuat animasi tambahan yang melakukan 'drift'. Hal ini diputar antara tempat gestur diselesaikan, hingga target yang diketahui baik.

Hal ini berfungsi karena animasi memiliki prioritas berdasarkan urutan pembuatannya: dalam hal ini, driftPlayer akan lebih diprioritaskan daripada pemain. Saat selesai, driftPlayer dan efeknya akan hilang. Namun, waktu akhirnya akan cocok dengan currentTime pemutar yang mendasarinya, sehingga UI Anda akan tetap konsisten.

Terakhir, jika Anda menyukai anak kucing, ada aplikasi web demo yang menampilkan gestur ini. Aplikasi ini mobile-friendly dan menggunakan polyfill untuk kompatibilitas mundur, jadi coba muat di perangkat seluler Anda.

Go forth dan element.animate

Metode element.animate sangat keren saat ini - baik Anda menggunakannya untuk animasi sederhana, atau memanfaatkan AnimationPlayer yang ditampilkan dengan cara lain.

Kedua fitur ini juga didukung sepenuhnya di browser modern lainnya melalui polyfill ringan. Polyfill ini juga melakukan deteksi fitur, sehingga saat vendor browser menerapkan spesifikasi, fitur ini hanya akan menjadi lebih cepat dan lebih baik dari waktu ke waktu.

Spesifikasi Animasi Web juga akan terus berkembang. Jika Anda tertarik untuk mencoba fitur mendatang, fitur tersebut juga tersedia sekarang dalam polyfill yang lebih mendetail: web-animations-next.