Kembali ke Blog

Animasi Background Halus Tanpa Library JavaScript

#css#animation#frontend
Animasi Background Halus Tanpa Library JavaScript

Commit terakhir yang saya push ke situs ini nambahin efek “signal field” di background — grid tipis yang drift pelan, partikel-partikel kecil yang mengambang, plus glow yang ngikutin posisi kursor. Nggak pakai canvas, nggak pakai library animasi apapun. Semuanya CSS, plus sedikit JavaScript yang dibatesin ketat.

Grid dan partikel murni CSS

Grid-nya dibuat dari dua linear-gradient — satu garis horizontal, satu vertikal — yang di-tile jadi pattern 64x64px, terus dianimasiin geser posisi lewat @keyframes gridDrift. Partikelnya cuma <span> kosong yang posisi, ukuran, durasi, dan delay animasinya di-random di frontmatter komponen Astro pakai Math.random(), baru dianimasiin naik-turun (floatY) dan berkedip opacity-nya (pulseGlow) — semuanya CSS juga, nggak ada satu baris JS buat gerakinnya.

Detail yang menurut saya menarik: random-nya jalan pas build, bukan pas runtime. Karena Math.random() itu dieksekusi di frontmatter Astro, dia cuma jalan sekali pas situsnya di-build jadi HTML statis. Efeknya agak nggak terduga — tiap halaman (home, tiap blog post, tiap portfolio entry) punya layout partikel yang beda satu sama lain, karena masing-masing di-render terpisah pas build. Tapi pengunjung yang sama, buka halaman yang sama berkali-kali, bakal liat pola partikel yang identik terus, karena posisinya udah “beku” di HTML yang di-generate. Trade-off yang saya terima demi nggak perlu JavaScript buat generate posisi di client tiap kali halaman dibuka.

Satu-satunya JavaScript yang jalan

Cuma buat glow yang ngikutin kursor. Itu pun dibatesin ketat — cuma aktif kalau device-nya punya hover dan pointer presisi (matchMedia('(hover: hover) and (pointer: fine)')), jadi nggak nyalain event listener yang nggak guna di HP atau tablet. Ada juga pengecekan prefers-reduced-motion sebelum listener-nya dipasang sama sekali — kalau user set itu, listener-nya nggak pernah di-attach.

Aksesibilitas yang nggak saya lewatin

Di prefers-reduced-motion: reduce, grid berhenti gerak, transisi glow dimatiin, partikel berhenti animasi dengan opacity statis — bukan cuma animasinya diperlambat, tapi beneran mati. Di prefers-reduced-transparency: reduce dan pas nge-print halaman, seluruh efeknya disembunyiin total. Nggak ada alasan buat maksain efek dekoratif di kondisi-kondisi itu, dan jujur bagian ini yang paling makan waktu saya dibanding animasinya sendiri — mikirin semua kombinasi preferensi yang mungkin, bukan cuma bikin satu path “default” yang keliatan bagus doang.

Pelajarannya: animasi dekoratif skala kecil kayak gini nggak butuh library seberat apapun. CSS @keyframes plus sedikit randomization pas build udah cukup buat efek yang kelihatan hidup. Yang justru butuh perhatian lebih itu bukan animasinya, tapi constraint aksesibilitas di sekitarnya.