// scroll.js document.addEventListener('DOMContentLoaded', () => { // ───────────────────────────────────────────────────────────────────────────── // 1) Vertical “zoom‑in/out” on .scroll‑section using IntersectionObserver // ───────────────────────────────────────────────────────────────────────────── const sections = document.querySelectorAll('.scroll-section'); const io = new IntersectionObserver((entries) => { entries.forEach(entry => { entry.target.classList.toggle('in-view', entry.isIntersecting); }); }, { threshold: 0.15 }); sections.forEach(sec => io.observe(sec)); // ───────────────────────────────────────────────────────────────────────────── // 2) Horizontal‑scroll “pin & pan” for the Hobbies section // ───────────────────────────────────────────────────────────────────────────── const wrapper = document.getElementById('hobbies'); if (!wrapper) return; // no Hobbies section → exit // The element that will stay stuck in the viewport: const stickySection = wrapper.querySelector('.horizontal-section'); // The inner flex row we translate left/right: const inner = stickySection.querySelector('.horizontal-section__inner'); // A) Make the section itself “sticky” at the top of the viewport stickySection.style.position = 'sticky'; stickySection.style.top = '3rem'; stickySection.style.height = '100vh'; stickySection.style.overflow = 'hidden'; // B) Compute how far we need to scroll to reveal all cards let containerW = wrapper.clientWidth; // e.g. 70vw in px let scrollableDist = inner.scrollWidth - containerW; // total horizontal span minus one screen // C) Stretch the wrapper’s vertical height so that // scrolling wrapperHeight(px) → moving inner by scrollableDist(px) wrapper.style.height = `${window.innerHeight + scrollableDist}px`; // D) On scroll, when within the wrapper’s “pin zone,” // translate the inner row instead of moving vertically window.addEventListener('scroll', () => { const y = window.scrollY; const top = wrapper.offsetTop; const end = top + scrollableDist; if (y >= top && y <= end) { // map vertical scroll → horizontal translate inner.style.transform = `translateX(-${y - top}px)`; } }); // E) Recompute on resize window.addEventListener('resize', () => { containerW = wrapper.clientWidth; scrollableDist = inner.scrollWidth - containerW; wrapper.style.height = `${window.innerHeight + scrollableDist}px`; }); });