Kontrol pemutaran animasi web di Chrome 39

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

Untuk penyegaran singkat, berikut adalah cara menganimasikan cloud di seluruh layar, dengan callback jika sudah 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 membalikkan 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 mewakili langit, dan Anda menginginkan 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 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 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.

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

Transisi dan gestur UI

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

Dengan Animasi Web, efek yang mirip sangat mudah direplikasi di sini di web - di desktop atau 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 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.