Web Animations API (WAAPI)
Web Animations API adalah animasi native JavaScript yang berjalan di compositor thread (sama seperti CSS animation), tapi kamu kontrol penuh via JS — play, pause, reverse, seek, change speed, dan bahkan gabungkan dengan event apapun. Tidak perlu library eksternal untuk kebutuhan menengah.
Kenapa WAAPI, bukan requestAnimationFrame?
requestAnimationFrame |
WAAPI (.animate()) |
|
|---|---|---|
| Thread | Main thread | Compositor thread (off-main) |
| Performa | Bagus, tapi bisa di-block rendering | Sangat bagus, tidak di-block |
| Kontrol | Penuh (hitung manual) | Penuh via timeline object |
| Use case | Custom physics, game loop | UI animation (slide, fade, morph) |
| Reverse/seek | Harus bikin sendiri | Built-in (.reverse(), .currentTime) |
WAAPI bukan pengganti rAF — rAF tetap juara untuk game loop & physics. Tapi untuk animasi UI (transition, slide panel, bounce notification), WAAPI lebih simple & cepat.
Sintaks Dasar: element.animate()
const box = document.querySelector('.box');
box.animate(
// Keyframes (array of objects)
[
{ transform: 'translateY(0)', opacity: 0 },
{ transform: 'translateY(-20px)', opacity: 1 },
],
// Timing options
{
duration: 500, // ms
easing: 'ease-out',
fill: 'forwards', // tetap di posisi akhir
}
);
Satu function call, animasi langsung jalan. Equivalent CSS @keyframes + animation: ... tapi 100% JavaScript.
Timing Options Lengkap
const animation = box.animate([...], {
duration: 800,
delay: 100, // tunggu sebelum mulai
endDelay: 50, // tunggu setelah selesai
iterations: 3, // jumlah loop (Infinity untuk tak terbatas)
direction: 'alternate', // normal, reverse, alternate, alternate-reverse
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
fill: 'both', // none, forwards, backwards, both
});
Kontrol Playback (keunggulan besar)
animation.pause(); // jeda
animation.play(); // lanjut
animation.reverse(); // balik arah
animation.cancel(); // stop & kembali ke state awal
animation.finish(); // lompat ke akhir
animation.playbackRate = 2; // 2x lebih cepat
animation.playbackRate = -1; // mundur dengan kecepatan normal
animation.currentTime = 400; // seek ke milidetik tertentu
// Event
animation.onfinish = () => console.log('Selesai!');
animation.finished.then(() => {
// Promise-based — bisa pakai await
});
Contoh Praktis: Notification Toast
function showToast(message) {
const toast = document.createElement('div');
toast.className = 'toast';
toast.textContent = message;
document.body.appendChild(toast);
// Masuk: slide dari atas + fade in
toast.animate(
[
{ transform: 'translateY(-100%)', opacity: 0 },
{ transform: 'translateY(0)', opacity: 1 },
],
{ duration: 300, easing: 'ease-out', fill: 'forwards' }
);
// Keluar setelah 3 detik
setTimeout(async () => {
const exitAnim = toast.animate(
[
{ transform: 'translateY(0)', opacity: 1 },
{ transform: 'translateY(-100%)', opacity: 0 },
],
{ duration: 300, easing: 'ease-in', fill: 'forwards' }
);
await exitAnim.finished; // tunggu animasi selesai
toast.remove(); // baru hapus dari DOM
}, 3000);
}
Perhatikan await exitAnim.finished — ini pola yang sulit dilakukan dengan rAF atau CSS saja, tapi trivial di WAAPI.
Kapan Pakai WAAPI vs CSS Animation vs Library?
- CSS animation — state statis, tidak butuh kontrol JS (hover, loop tak terbatas)
- WAAPI — butuh kontrol playback, trigger dari JS event, sync dengan async code
- Framer Motion / GSAP — animasi kompleks dengan orchestration, spring physics, atau gesture
Dukungan browser: WAAPI didukung semua browser modern sejak 2019. Tanpa perlu polyfill untuk kebutuhan umum.