// JavaScript Document // ========================================================= // トップページ専用 JavaScript (top.js) // ========================================================= window.addEventListener('load', () => { /* ------------------------------------------------------- 1. メインビジュアル スライダー (#mainVisual) ------------------------------------------------------- */ const mainVisualEl = document.querySelector('#mainVisual'); if (mainVisualEl) { const mainSplide = new Splide(mainVisualEl, { type: 'fade', rewind: true, autoplay: true, interval: 6000, speed: 1200, arrows: false, pagination: false, drag: false, pauseOnHover: false, pauseOnFocus: false, updateOnMove: true, }); // アクティブ時にズーム開始 mainSplide.on('active', slide => { const img = slide.slide.querySelector('img'); if (img) img.classList.add('zoom'); }); // 非アクティブ(切り替わり後)の処理 mainSplide.on('inactive', slide => { const img = slide.slide.querySelector('img'); if (img) { // フェード時間(1200ms)より少し長く待ってからクラスを外す setTimeout(() => { img.classList.remove('zoom'); }, mainSplide.options.speed + 500); // 1200 + 500 = 1700ms に修正 } }); mainSplide.on('mounted', () => { mainSplide.Components.Autoplay.play(); }); mainSplide.mount(); // スクロールして見えたら再生(IntersectionObserver) const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.isIntersecting) { mainSplide.Components.Autoplay.play(); } }); }); observer.observe(mainVisualEl); } /* ------------------------------------------------------- 2. センタースライダー (#center-slider) ------------------------------------------------------- */ const centerSliderEl = document.querySelector('#center-slider'); if (centerSliderEl) { const centerSplide = new Splide(centerSliderEl, { type: 'loop', perPage: 3.5, focus: 'center', gap: '1rem', autoplay: true, interval: 5000, speed: 1500, pauseOnHover: false, pauseOnFocus: false, arrows: false, pagination: false, trimSpace: false, dragAngleThreshold: 30, flickMaxPages: 1, flickPower: 50, dragMinThreshold: { mouse: 10, touch: 20, }, breakpoints: { 768: { perPage: 1, padding: '10%', gap: '10px', } } }); centerSplide.on('mounted', () => { const autoplay = centerSplide.Components.Autoplay; if (autoplay) { autoplay.play(); } }); centerSplide.mount(); // スマホでのリサイズイベントの負荷軽減 let resizeTimer; window.addEventListener('resize', () => { clearTimeout(resizeTimer); resizeTimer = setTimeout(() => { centerSplide.refresh(); }, 200); }); } }); /* ------------------------------------------------------- 3. パララックス効果 (.mid-kv .image) ------------------------------------------------------- */ (() => { let scrollTick = false; let vh = document.documentElement.clientHeight; // リサイズ時に画面の高さを再取得 window.addEventListener("resize", () => { vh = document.documentElement.clientHeight; updateParallax(); }, { passive: true }); // パララックスの計算ロジック const updateParallax = () => { const midKvs = document.querySelectorAll(".mid-kv .image"); midKvs.forEach(kv => { const img = kv.querySelector("img"); if (!img) return; const rect = kv.getBoundingClientRect(); const speed = 0.1; if (rect.top < vh && rect.bottom > 0) { const centerShift = (vh / 2 - (rect.top + rect.height / 2)) * speed; img.style.transform = `translateY(calc(-50% + ${centerShift}px))`; } }); }; // スクロールイベント window.addEventListener("scroll", () => { if (!scrollTick) { window.requestAnimationFrame(() => { updateParallax(); scrollTick = false; }); scrollTick = true; } }, { passive: true }); // 初期読み込み時にも一度実行 window.addEventListener("DOMContentLoaded", updateParallax); })();