Kontrol pemutaran animasi web di Chrome 39

Pada 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 yang ditulis secara imperatif - memberikan pilihan kepada developer untuk membangun animasi dan transisi mereka 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);
};

Ini saja sangat mudah dan layak dipertimbangkan sebagai bagian dari {i>toolbox<i} Anda ketika membangun 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 mendengarkan peristiwa selesai.

Penambahan pemutaran ini membuka kemungkinan apa yang dapat dilakukan Animasi Web - mengubah animasi menjadi alat serba guna, alih-alih menjadi preskriptif tentang transisi, yaitu 'diperbaiki' atau animasi yang telah ditentukan sebelumnya.

Menjeda, memundurkan, atau mengubah kecepatan 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 membalikkan 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 pemain

AnimationPlayer kini memungkinkan currentTime-nya diubah saat animasi 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. Gerakan 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 acara asli Anda. Anda juga dapat melanjutkan pemutaran animasi saat gestur berakhir:

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

Tindakan ini bahkan dapat digabungkan dengan perilaku membalikkan, bergantung pada tempat 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.

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 ranah gerakan yang umum: menyeret, menggeser, mengayunkan jari, dan sejenisnya. Gestur ini cenderung memiliki tema yang sama: komponen UI yang dapat ditarik, seperti "tarik untuk memuat ulang" pada tampilan daftar atau {i>sidebar<i} 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 'penyimpangan'. Ini akan diputar di antara tempat gestur diselesaikan, hingga ke target bagus yang diketahui.

Ini berfungsi karena animasi memiliki prioritas berdasarkan urutan pembuatannya: dalam hal ini, driftPlayer akan lebih diutamakan daripada pemutar. Setelah driftPlayer selesai, aktivitas tersebut dan efeknya akan hilang. Namun, waktu terakhirnya akan sesuai 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. Library ini ramah seluler dan menggunakan polyfill untuk kompatibilitas mundur, jadi coba muat di perangkat seluler Anda.

Maju dan element.animate

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

Kedua fitur ini juga didukung penuh di browser modern lainnya melalui polyfill ringan. Polyfill ini juga melakukan deteksi fitur, jadi karena vendor browser menerapkan spesifikasi tersebut, 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-coba fitur mendatang, sekarang fitur tersebut juga tersedia dalam polyfill yang lebih mendetail: web-animasis-next.