Peningkatan Web Animations API di Chromium 84

Mengatur animasi dengan promise, peningkatan performa dengan animasi yang dapat diganti, animasi yang lebih lancar dengan mode gabungan, dan lainnya.

Dipublikasikan: 27 Mei 2020

Jika digunakan dengan benar, animasi akan meningkatkan persepsi dan ingatan pengguna tentang merek Anda, memandu tindakan pengguna, dan membantu pengguna menavigasi aplikasi Anda—memberikan konteks di ruang digital.

Web Animations API adalah alat yang memungkinkan developer menulis animasi imperatif dengan JavaScript. API ini ditulis untuk mendukung implementasi animasi dan transisi CSS serta memungkinkan pengembangan efek di masa mendatang, serta efek yang ada untuk disusun dan diberi waktu.

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

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

Memulai

Membuat animasi menggunakan Web Animations API akan terasa sangat familiar jika Anda telah menggunakan aturan @keyframe. Pertama, Anda harus membuat Objek Frame Kunci. Tampilannya mungkin 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;
}

Anda akan menetapkannya 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 menyusun urutan efek, dan peningkatan kontrol atas status pemutarannya.

Di luar element.animate()

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

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

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

Cara mengatur animasi dengan promise

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

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

Melanjutkan contoh kita, dan membuat rantai animasi yang diatur 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 yang terbuka. Lihat Demo di Codepen
const transformAnimation = modal.animate(openModal, openModalSettings);
transformAnimation.finished.then(() => { text.animate(fadeIn, fadeInSettings)});

Kita telah merantai animasi ini menggunakan animation.finished.then() sebelum menjalankan kumpulan animasi berikutnya dalam rantai. Dengan cara ini, animasi akan muncul secara berurutan, dan Anda bahkan menerapkan efek ke berbagai elemen target dengan opsi yang berbeda (seperti kecepatan dan kemudahan).

Dalam CSS, hal ini akan merepotkan untuk dibuat ulang, terutama saat menerapkan animasi yang unik, tetapi berurutan ke beberapa elemen. Anda harus menggunakan @keyframe, mengurutkan persentase pengaturan waktu yang benar untuk menempatkan animasi, dan menggunakan animation-delay sebelum memicu animasi dalam urutan.

Contoh: Memutar, menjeda, dan memutar balik

Yang dapat dibuka, harus ditutup. Untungnya, sejak Chromium 39, Web Animations API telah memberi kita kemampuan untuk memutar, menjeda, dan membalikkan animasi.

Anda dapat mengambil animasi yang ditampilkan sebelumnya, dan 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 kami.

Contoh modal yang terbuka dan tertutup saat tombol diklik. Lihat Demo di Glitch

Yang dapat Anda lakukan adalah membuat dua animasi yang menunggu pemutaran (openModal, dan transformasi opasitas inline), lalu menjeda salah satu animasi, menundanya hingga animasi lainnya selesai. Kemudian, Anda dapat menggunakan promise untuk menunggu setiap promise selesai sebelum diputar. Terakhir, Anda dapat memeriksa apakah tanda telah ditetapkan, lalu membalikkan setiap animasi.

Contoh: Interaksi dinamis dengan keyframe sebagian

Contoh penargetan ulang, saat klik mouse menyesuaikan animasi ke lokasi baru. Lihat Demo di 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 keyframe parsial. Pengendali mouse melakukan beberapa hal di sini: menetapkan lokasi akhir baru dan memicu animasi baru. Posisi awal baru disimpulkan dari posisi pokok 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 kali, 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 sudah selesai. Perhatikan contoh berikut:

Jejak komet akan dianimasikan 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 akan menghitung ulang posisi untuk setiap bola di 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 komposit yang juga selesai.
  3. Animasi baru menganimasikan properti yang sama.

Anda dapat melihat jumlah animasi yang diganti secara tepat dengan menjumlahkan penghitung dengan setiap animasi yang dihapus, menggunakan anim.onremove untuk memicu penghitung.

Ada beberapa properti dan metode tambahan untuk mengontrol animasi Anda lebih jauh:

  • 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 gabungan animasi, yang berarti animasi dapat bersifat tambahan atau kumulatif, selain mode default "ganti". Mode gabungan memungkinkan developer menulis animasi yang berbeda dan memiliki kontrol atas cara penggabungan efek. Tiga mode komposit kini didukung: 'replace' (mode default), 'add', dan 'accumulate'.

Saat Anda mengomposisi animasi, developer dapat menulis efek singkat dan berbeda serta melihatnya digabungkan. Pada contoh berikut, kita menerapkan keyframe rotasi dan skala ke setiap kotak, dengan satu-satunya penyesuaian adalah mode komposit, yang ditambahkan sebagai opsi:

Demo yang menampilkan mode komposit default, tambahkan, dan akumulasi. Lihat Demo di Glitch

Dalam mode gabungan 'replace' default, animasi akhir akan 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 Animasi Web.

Lihat contoh elemen UI berikut:

Menu drop-down yang memantul dan memiliki dua animasi gabungan yang diterapkan padanya. Lihat Demo di Glitch

Di sini, dua animasi top digabungkan. Yang pertama adalah animasi makro, yang memindahkan drop-down dengan tinggi penuh menu itu sendiri sebagai efek geser masuk dari bagian atas halaman, dan yang kedua, animasi mikro, menerapkan sedikit pantulan saat mencapai bagian bawah. Menggunakan 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' });
  });

Langkah selanjutnya untuk Web Animations API

Semua ini adalah tambahan yang menarik untuk kemampuan animasi di browser saat ini, dan masih banyak lagi tambahan yang akan hadir. Lihat spesifikasi mendatang ini untuk membaca lebih lanjut tentang hal yang akan datang: