Peningkatan Web Animations API di Chromium 84

Mengorkestrasi animasi dengan promise, peningkatan performa dengan animasi yang dapat diganti, animasi yang lebih halus dengan mode komposit, dan banyak lagi.

Kevin Ellis
Kevin Ellis

Jika digunakan dengan benar, animasi akan meningkatkan persepsi pengguna dan memori terhadap brand Anda, memandu tindakan pengguna, dan membantu pengguna menjelajahi aplikasi—memberikan konteks dalam ruang digital.

Web Animations API adalah alat yang memungkinkan developer menulis animasi imperatif dengan JavaScript. Buku ini ditulis untuk mendasari implementasi animasi dan transisi CSS, dan memungkinkan pengembangan efek di masa mendatang, serta efek yang sudah ada untuk disusun dan diatur waktunya.

Meskipun Firefox dan Safari telah menerapkan rangkaian fitur spesifikasi lengkap, Chromium 84 menghadirkan sejumlah fitur yang sebelumnya tidak didukung ke Chrome dan Edge yang memungkinkan interoperabilitas lintas browser.

Web Animations API pertama kali membuka Chromium pada versi 36 pada Juli 2014. Sekarang spesifikasinya akan selesai, dalam versi 84, yang diluncurkan pada Juli 2020.
Histori panjang Web Animations API di Chromium.

Memulai

Membuat animasi melalui Web Animations API seharusnya sudah tidak asing lagi jika Anda telah menggunakan aturan @keyframe. Pertama, Anda harus membuat Objek Keyframe. Yang mungkin terlihat seperti ini di CSS:

@keyframes openAnimation {
  0% {
    transform: scale(0);
  }
  100% {
    transform: scale(1);
  }
}

akan terlihat seperti ini di JavaScript:

const openAnimation = [
  { transform: 'scale(0)' },
  { transform: 'scale(1)' },
];

Tempat Anda menetapkan parameter untuk animasi di CSS:

.modal {
  animation: openAnimation 1s 1 ease-in;
}

yang akan Anda tetapkan di JS:

document.querySelector('.modal').animate(
    openAnimation, {
      duration: 1000, // 1s
      iterations: 1, // single iteration
      easing: 'ease-in' // easing function
    }
);

Jumlah kodenya hampir sama, tetapi dengan JavaScript, Anda mendapatkan beberapa kemampuan super yang tidak Anda miliki dengan CSS saja. Hal ini mencakup kemampuan untuk mengurutkan efek, dan peningkatan kontrol atas status permainan.

Di atas element.animate()

Namun, dengan pembaruan ini, Web Animations API tidak lagi dibatasi untuk animasi yang dibuat melalui element.animate(). Kita juga bisa memanipulasi animasi dan transisi CSS.

getAnimations() adalah metode yang menampilkan semua animasi pada elemen, terlepas dari apakah dibuat melalui element.animate() atau melalui aturan CSS (animasi atau transisi CSS). Berikut adalah contoh tampilannya:

Pertama-tama, "get" keyframe untuk transisi guna menentukan titik transisi. Kemudian, Anda membuat dua animasi opasitas baru, yang memungkinkan efek memudar silang. Setelah cross-fade selesai, Anda akan menghapus salinan tersebut.

Mengorkestrasi animasi dengan promise

Di Chromium 84, kini Anda memiliki dua metode yang dapat digunakan dengan promise: animation.ready dan animation.finished.

  • animation.ready memungkinkan Anda menunggu perubahan yang tertunda diterapkan (yaitu, beralih antara metode kontrol pemutaran seperti putar dan jeda).
  • animation.finished menyediakan cara untuk mengeksekusi kode JavaScript kustom saat animasi selesai.

Mari kita lanjutkan dengan contoh kita, dan buat rantai animasi terorkestrasi dengan animation.finished. Di sini, Anda memiliki transformasi vertikal (scaleY), diikuti dengan transformasi horizontal (scaleX), diikuti dengan perubahan opasitas pada elemen turunan:

Menerapkan transformasi dan opasitas ke elemen modal pembuka. Lihat Demo di Codepen
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});

Kami telah merangkai animasi ini menggunakan animation.finished.then() sebelum mengeksekusi animasi berikutnya yang ditetapkan dalam rantai. Dengan cara ini, animasi muncul secara berurutan, dan Anda bahkan menerapkan efek ke elemen target yang berbeda dengan set opsi yang berbeda (seperti kecepatan dan kemudahan).

Dalam CSS, ini akan rumit untuk dibuat ulang, terutama saat menerapkan animasi yang unik namun berurutan ke beberapa elemen. Anda harus menggunakan @keyframe, memilah persentase waktu yang tepat untuk menempatkan animasi, dan menggunakan animation-delay sebelum memicu animasi secara berurutan.

Contoh: Memutar, menjeda, dan membalikkan

Apa yang bisa terbuka, harus tertutup! Untungnya, sejak Chromium 39, Web Animations API telah memberi kita kemampuan untuk memutar, menjeda, dan membalikkan animasi.

Anda dapat mengambil animasi di atas, lalu memberikan animasi yang halus dan terbalik saat mengklik tombol lagi menggunakan .reverse(). Dengan cara ini, Anda dapat membuat interaksi yang lebih lancar dan lebih kontekstual untuk modal kita.

Contoh membuka dan menutup modal saat tombol diklik. Lihat Demo tentang Glitch

Yang dapat Anda lakukan adalah membuat dua animasi tertunda (openModal, dan transformasi opasitas inline), lalu menjeda salah satu animasi, menundanya hingga animasi lainnya selesai. Lalu, Anda dapat menggunakan promise untuk menunggu hingga setiap promise selesai sebelum memutarnya. Terakhir, Anda dapat memeriksa untuk melihat apakah flag telah diatur, dan kemudian membalikkan setiap animasi.

Contoh: Interaksi dinamis dengan keyframe parsial

Contoh penargetan ulang, dengan klik mouse menyesuaikan animasi ke lokasi baru. Lihat Demo tentang Glitch
selector.animate([{transform: `translate(${x}px, ${y}px)`}],
    {duration: 1000, fill: 'forwards'});

Dalam contoh ini, hanya ada satu keyframe, dan tidak ada posisi awal yang ditentukan. Ini adalah contoh penggunaan frame utama parsial. Pengendali mouse melakukan beberapa hal di sini: menetapkan lokasi akhir baru dan memicu animasi baru. Posisi awal baru disimpulkan dari posisi dasar saat ini.

Transisi baru dapat dipicu saat transisi yang ada masih berjalan. Artinya, transisi saat ini terganggu, dan transisi baru dibuat.

Peningkatan performa dengan animasi yang dapat diganti

Saat membuat animasi berdasarkan peristiwa, seperti di 'mousemove', animasi baru akan dibuat setiap waktu, yang dapat dengan cepat menghabiskan memori dan menurunkan performa. Untuk mengatasi masalah ini, animasi yang dapat diganti diperkenalkan di Chromium 83, yang memungkinkan pembersihan otomatis, dengan animasi yang sudah selesai ditandai sebagai dapat diganti dan otomatis dihapus jika diganti dengan animasi lain yang telah selesai. Perhatikan contoh berikut:

Jejak komet bergerak saat mouse bergerak. Lihat Demo di Glitch
elem.addEventListener('mousemove', evt => {
  rectangle.animate(
    { transform: translate(${evt.clientX}px, ${evt.clientY}px) },
    { duration: 500, fill: 'forwards' }
  );
});

Setiap kali mouse bergerak, browser menghitung ulang posisi setiap bola dalam jejak komet dan membuat animasi ke titik baru ini. Browser kini mengetahui cara menghapus animasi lama (mengaktifkan penggantian) saat:

  1. Animasi selesai.
  2. Ada satu atau beberapa animasi yang lebih tinggi dalam pengurutan gabungan yang juga selesai.
  3. Animasi baru menganimasikan properti yang sama.

Anda dapat melihat dengan tepat berapa banyak animasi yang diganti dengan menghitung penghitung untuk setiap animasi yang dihapus, menggunakan anim.onremove untuk memicu penghitung.

Ada beberapa metode tambahan untuk meningkatkan kontrol animasi Anda:

  • animation.replaceState() menyediakan cara untuk melacak apakah animasi aktif, dipertahankan, atau dihapus.
  • animation.commitStyles() memperbarui gaya elemen berdasarkan gaya yang mendasarinya beserta semua animasi pada elemen dalam urutan komposit.
  • animation.persist() menandai animasi sebagai tidak dapat diganti.

Animasi yang lebih halus dengan mode gabungan

Dengan Web Animations API, Anda kini dapat menetapkan mode komposit animasi, yang berarti animasi tersebut dapat bersifat aditif atau akumulatif, selain mode default "replace". Mode gabungan memungkinkan developer menulis animasi yang berbeda dan memiliki kontrol atas cara efek digabungkan. Tiga mode gabungan kini didukung: 'replace' (mode default), 'add', dan 'accumulate'.

Saat Anda menggabungkan animasi, developer dapat menulis efek pendek yang berbeda lalu melihatnya digabungkan. Pada contoh di bawah, kita menerapkan rotasi dan penskalaan keyframe ke setiap kotak, dengan satu-satunya penyesuaian adalah mode gabungan, yang ditambahkan sebagai opsi:

Demo yang menunjukkan mode default, penambahan, dan akumulasi gabungan. Lihat Demo di Glitch

Dalam mode komposit 'replace' default, animasi akhir menggantikan properti transformasi dan berakhir di rotate(360deg) scale(1.4). Untuk 'add', gabungan menambahkan rotasi dan mengalikan skala, sehingga menghasilkan status akhir rotate(720deg) scale(1.96). 'accumulate' menggabungkan transformasi, sehingga menghasilkan rotate(720deg) scale(1.8). Untuk mengetahui seluk-beluk mode gabungan ini lebih lanjut, lihat Enumerasi CompositeOperation dan CompositeOperationOrAuto dari spesifikasi Web Animations.

Mari kita lihat contoh elemen UI:

Menu dropdown memantul yang memiliki dua animasi gabungan yang diterapkan padanya. Lihat Demo di Glitch

Di sini, dua animasi top digabungkan. Yang pertama adalah animasi makro, yang memindahkan dropdown sesuai tinggi penuh menu itu sendiri sebagai efek {i>slide-in <i}dari bagian atas halaman, dan yang kedua, animasi mikro, menerapkan sedikit pantulan saat menyentuh bagian bawah. Penggunaan mode gabungan 'add' memungkinkan transisi yang lebih lancar.

const dropDown = menu.animate(
    [
      { top: `${-menuHeight}px`, easing: 'ease-in' },
      { top: 0 }
    ], { duration: 300, fill: 'forwards' });

  dropDown.finished.then(() => {
    const bounce = menu.animate(
      [
        { top: '0px', easing: 'ease-in' },
        { top: '10px', easing: 'ease-out' },
        { ... }
      ], { duration: 300, composite: 'add' });
  });

Apa selanjutnya untuk Web Animations API

Semua itu adalah tambahan yang menarik pada kemampuan animasi di {i>browser<i} masa kini, dan ada lebih banyak lagi penambahan yang akan dilakukan. Lihat spesifikasi mendatang ini untuk bacaan lebih lanjut tentang apa yang akan datang: