(function () { function initVideoGallery() { var track = document.getElementById('vgTrack'); var outer = document.getElementById('vgOuter'); var btnNext = document.getElementById('vgNext'); var btnPrev = document.getElementById('vgPrev'); if (!track || !outer || !btnNext || !btnPrev) return; var cards = track.querySelectorAll('.vg-card'); var total = cards.length; var index = 0; // текущий сдвиг (в единицах карточек) var gap = 16; // должен совпадать с gap в CSS var visible = 5; // сколько карточек видно (меняется по ширине) /* ── Расчёт видимых карточек под ширину экрана ── */ function getVisible() { var w = outer.offsetWidth; if (w <= 600) return 2; if (w <= 900) return 3; return 5; } /* ── Ширина одной карточки ── */ function cardWidth() { var v = getVisible(); return (outer.offsetWidth - gap * (v - 1)) / v; } /* ── Максимальный индекс сдвига ── */ function maxIndex() { return Math.max(0, total - getVisible()); } /* ── Применить сдвиг ── */ function applyTranslate(animate) { var cw = cardWidth(); var tx = index * (cw + gap); if (!animate) track.style.transition = 'none'; track.style.transform = 'translateX(-' + tx + 'px)'; if (!animate) { // форсировать reflow и вернуть анимацию track.offsetHeight; // eslint-disable-line track.style.transition = ''; } updateButtons(); } /* ── Состояние кнопок ── */ function updateButtons() { btnPrev.style.opacity = index === 0 ? '0.35' : '1'; btnPrev.style.pointerEvents = index === 0 ? 'none' : ''; btnNext.style.opacity = index >= maxIndex() ? '0.35' : '1'; btnNext.style.pointerEvents = index >= maxIndex() ? 'none' : ''; } /* ── Навигация ── */ function goNext() { if (index < maxIndex()) { index++; applyTranslate(true); } } function goPrev() { if (index > 0) { index--; applyTranslate(true); } } btnNext.addEventListener('click', goNext); btnPrev.addEventListener('click', goPrev); /* ── Клавиатура ── */ document.addEventListener('keydown', function (e) { if (e.key === 'ArrowRight') goNext(); if (e.key === 'ArrowLeft') goPrev(); }); /* ── Свайп / перетаскивание мышью ── */ var dragStart = null; var dragDelta = 0; function onPointerDown(e) { dragStart = e.touches ? e.touches[0].clientX : e.clientX; dragDelta = 0; } function onPointerMove(e) { if (dragStart === null) return; var x = e.touches ? e.touches[0].clientX : e.clientX; dragDelta = x - dragStart; var cw = cardWidth(); var base = index * (cw + gap); track.style.transition = 'none'; track.style.transform = 'translateX(-' + (base - dragDelta) + 'px)'; } function onPointerUp() { if (dragStart === null) return; var threshold = cardWidth() * 0.25; if (dragDelta < -threshold) goNext(); else if (dragDelta > threshold) goPrev(); else applyTranslate(true); dragStart = null; dragDelta = 0; track.style.transition = ''; } outer.addEventListener('mousedown', onPointerDown); outer.addEventListener('mousemove', onPointerMove); outer.addEventListener('mouseup', onPointerUp); outer.addEventListener('mouseleave', onPointerUp); outer.addEventListener('touchstart', onPointerDown, { passive: true }); outer.addEventListener('touchmove', onPointerMove, { passive: true }); outer.addEventListener('touchend', onPointerUp); /* ── Ресайз ── */ var resizeTimer; window.addEventListener('resize', function () { clearTimeout(resizeTimer); resizeTimer = setTimeout(function () { // Не выходить за максимум index = Math.min(index, maxIndex()); applyTranslate(false); }, 120); }); /* ── Инициализация ── */ applyTranslate(false); } /* Совместимость с Tilda: DOM может грузиться позже */ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initVideoGallery); } else { initVideoGallery(); } /* Дополнительно — если Tilda перерисовывает блоки динамически */ if (window.tns && window.tns.on) { window.tns.on('blockRendered', initVideoGallery); } })();