Sub-Scroll pada Adegan Kisah Cinta
Pola pembajakan arah scroll sementara di dalam satu adegan untuk membalik halaman sub-bab sebelum mengizinkan kamera lanjut ke adegan berikutnya.
Membaca sekitar 2 menit
Pola pembajakan arah scroll sementara di dalam satu adegan untuk membalik halaman sub-bab sebelum mengizinkan kamera lanjut ke adegan berikutnya.
Saat pengguna berada di Scene 4 (Kisah Cinta), guliran ke bawah atau ke atas ditangkap untuk mengirim CustomEvent 'story:step' hingga seluruh bab selesai dibaca.
Komunikasi antar-komponen menggunakan referensi bersama (storyIdxRef) dan event jendela menjaga logika scroll tetap sinkron tanpa prop drilling.
Masalahnya dulu
Adegan ke-5 (Scene indeks 4: Kisah Cinta) memiliki tiga bab cerita perjalanan cinta ('Pertemuan Pertama', 'Bersama Melewati Segalanya', dan 'Babak Baru'). Jika kita menaruh tombol kecil 'Selanjutnya' di dalam kartu, banyak tamu yang tidak sadar dan langsung menggulir ke bawah, sehingga dua bab terakhir terlewat begitu saja.
Bagaimana pembajakan scroll (sub-scroll) bekerja
Solusinya adalah menyatukan pergantian bab cerita ke dalam gerakan scroll yang sama. Ketika pengguna tiba di Scene 4 dan menggulir ke bawah, SnapScroller menahan perpindahan ke Scene 5 dan mengalihkan aksi guliran tersebut untuk membuka bab cerita berikutnya. Baru setelah bab terakhir tercapai, guliran berikutnya akan melepaskan pengguna menuju adegan Info Resepsi.
Pengguna tidak perlu mengubah kebiasaan jarinya; biarkan gerakan scroll yang sama mengurus perpindahan sub-bab sekaligus perpindahan adegan utama.
Implementasi di ngodingan ini
Agar SnapScroller dan StoryOv bisa berkomunikasi secara instan tanpa membebani state di komponen induk Home, keduanya berbagi objek referensi ringan storyIdxRef dan bertukar pesan melalui CustomEvent pada window:
// Di dalam SnapScroller (handleScroll):
if (cur === STORY_SCENE && dir === 1) {
const chIdx = storyIdxRef.current;
if (chIdx < CHAPTERS.length - 1) {
coolRef.current = true;
setTimeout(() => { coolRef.current = false; }, 650);
window.dispatchEvent(new CustomEvent("story:step", { detail: 1 }));
return; // tahan perpindahan scene utama
}
}
// Di dalam StoryOv:
useEffect(() => {
const handler = (e: Event) => {
const dir = (e as CustomEvent<1 | -1>).detail;
setFade(false);
setTimeout(() => {
setIdx((p) => Math.max(0, Math.min(CHAPTERS.length - 1, p + dir)));
setFade(true);
}, 260);
};
window.addEventListener("story:step", handler);
return () => window.removeEventListener("story:step", handler);
}, []);Jebakan dan detail yang harus dijaga
- Mekanisme ini juga harus bekerja dua arah: saat pengguna menggulir mundur (dir === -1) di tengah bab ke-3, cerita harus mundur ke bab ke-2 dan ke-1 terlebih dahulu sebelum kembali ke adegan Kutipan Ar-Rum.
- Jika pengguna melompat langsung ke adegan Kisah Cinta melalui titik navigasi samping (DotNav), event 'story:reset' ditembakkan agar cerita selalu dimulai rapi dari bab pertama.
- Petunjuk teks di bawah kartu berubah secara dinamis dari 'Scroll untuk lanjut' menjadi 'Scroll untuk resepsi' pada bab terakhir sebagai umpan balik visual yang jelas bagi pembaca.