Tiga Babak Pengalaman Undangan Interaktif
Menyajikan alur cerita yang teratur: dimulai dari persiapan layar pembuka, sambutan nama tamu terhormat, hingga penjelajahan isi undangan secara utuh.
Menyajikan alur cerita yang teratur: dimulai dari persiapan layar pembuka, sambutan nama tamu terhormat, hingga penjelajahan isi undangan secara utuh.
Tantangan & Kebutuhan Pengguna
Memuat langsung kanvas undangan tanpa pengantar membuat pengalaman terasa mendadak dan kehilangan kesan eksklusif. Selain itu, browser modern memblokir pemutaran audio latar secara otomatis jika belum ada interaksi eksplisit (klik/ketukan) dari pengguna pada dokumen. Oleh karena itu, aplikasi memerlukan alur pembukaan terstruktur yang membangun ekspektasi visual sekaligus menjadi pemicu sah untuk menyalakan audio dan kanvas utama.
Layar pemuatan dan sampul pembuka bukan sekadar penghalang waktu, melainkan panggung pertama yang menentukan atmosfer keseluruhan aplikasi.
Solusi & Cara Kerja
Komponen akar Home dikendalikan oleh state bertipe Phase = 'loading' | 'opening' | 'experience'. Pada tahap 'loading', komponen Loading menjalankan progres inkremental hingga 94%, lalu mengunci interval menggunakan doneRef dan beralih ke sub-fase 'reveal' (300ms) yang merenggangkan letter-spacing judul dari 0.04em ke 0.18em disertai efek kilau garis emas, diikuti sub-fase 'out' (1400ms) sebelum memanggil callback onDone(2200ms). Selanjutnya pada tahap 'opening', komponen Opening menampilkan cincin konsentris dan menganimasikan kata ['Ais', '&', 'Tangkas'] secara berurutan (staggered). Ketika tombol 'Buka Undangan' diklik, event audio ditembakkan dan state berpindah ke 'experience'.
Detail & Hal yang Diperhatikan
- Pencegahan Eksekusi Ganda (Idempotency Lock): Penggunaan doneRef.current memastikan rangkaian timer transisi ('reveal' -> 'out' -> onDone) hanya dieksekusi tepat satu kali meskipun state pct memicu efek berulang pada nilai >= 94.
- Pembersihan DOM Bersih (Clean Unmounting): Karena perenderan dikondisikan dengan {phase === 'loading'} dan {phase === 'opening'}, seluruh elemen layar pembuka benar-benar dilepas dari memori DOM begitu pengguna masuk ke tahap 'experience'.
- Jembatan Kebijakan Autoplay: Fungsi handleOpen pada tahap 'opening' mengeksekusi window.dispatchEvent(new Event('wedding:play')) tepat di dalam call stack event onClick pengguna.
Transisi CSS menggunakan kurva cubic-bezier(0.4, 0, 0.2, 1) yang memberikan akselerasi awal cepat dan pendaratan akhir yang sangat halus.