Kontrol pemutaran animasi web di Chrome 39

Awal tahun ini, Chrome 36 menghadirkan metode element.animate sebagai bagian dari spesifikasi Web Animations yang lebih luas. Hal ini memungkinkan animasi native yang efisien ditulis secara imperatif - memberikan pilihan kepada developer untuk membuat animasi dan transisinya dengan pendekatan yang paling sesuai untuk mereka.

Untuk penyegaran singkat, berikut ini cara Anda menganimasikan awan di 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);
};

Ini sangat mudah dan layak dipertimbangkan sebagai bagian dari toolbox ketika Anda harus membuat animasi atau transisi. 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 terkait kemampuan Animasi Web - mengubah animasi menjadi alat serbaguna, bukan bersifat preskriptif tentang transisi, yaitu animasi 'tetap' atau yang telah ditentukan sebelumnya.

Menjeda, memundurkan, atau mengubah laju pemutaran

Mari kita mulai dengan memperbarui contoh di atas untuk menjeda animasi jika cloud 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 berjalan berakhir secara efektif, currentTime juga akan dibalik - misalnya, jika animasi baru dibalik, seluruh animasi akan diputar mundur

  • Jika pemutar dijeda, animasi akan mulai diputar.

Menggeser pemutar

AnimationPlayer kini memungkinkan currentTime untuk diubah saat animasi sedang berjalan. Biasanya, nilai ini akan meningkat seiring waktu (atau menurun, jika playbackRate negatif). Hal ini memungkinkan posisi animasi untuk dikontrol secara eksternal, mungkin melalui interaksi pengguna. Tindakan ini biasa disebut sebagai scrubs.

Misalnya, jika halaman HTML mewakili 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 berubah untuk mencerminkan jarak dari acara asli Anda. Anda mungkin juga ingin melanjutkan pemutaran animasi saat gestur berakhir:

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

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

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

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

Transisi dan gestur UI

Platform seluler telah lama menjadi ranah {i>gesture <i}umum: menyeret, menggeser, melempar, dan sejenisnya. Gestur ini cenderung memiliki tema umum: komponen UI yang dapat ditarik, seperti "tarik untuk memuat ulang" tampilan daftar atau sidebar yang ditampilkan dari sisi kiri layar.

Dengan Animasi Web, efek serupa sangat mudah direplikasi di web - di desktop atau di 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 menghasilkan animasi tambahan yang melakukan 'drift'. Ini diputar di antara tempat {i>gesture <i}diselesaikan, hingga ke target kita yang baik yang telah diketahui.

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

Terakhir, jika Anda suka anak kucing, ada aplikasi web demo yang menampilkan gestur ini. Class ini mobile-friendly dan menggunakan polyfill untuk kompatibilitas mundur, jadi cobalah memuatnya di perangkat seluler Anda!

Teruskan dan element.animate

Metode element.animate benar-benar menarik saat ini - baik Anda menggunakannya untuk animasi sederhana, maupun 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 vendor browser menerapkan spesifikasi ini, fitur ini akan menjadi lebih cepat dan lebih baik dari waktu ke waktu.

Spesifikasi Animasi Web juga akan terus berkembang. Jika Anda tertarik untuk mencoba fitur yang akan datang, fitur tersebut juga sudah tersedia di polyfill yang lebih detail: web-animations-next.