// Фотогалерея Coverflow на странице подкатегории (tpl/blocks/category_gallery.tpl, styles/gallery.css). // Карусель — Swiper, увеличенный просмотр — fancyBox; обе библиотеки приходят в бандле jsf (конец страницы), // поэтому ждём их появления, а не DOMContentLoaded (его задерживают внешние виджеты). (function () { 'use strict'; // соседние фото — 85% от центрального (центральное крупнее на ~18%), крайние — 70% var SIDE_SCALE = 0.85; // Swiper считает смещение соседа с учётом промежутка между слайдами — без поправки соседние фото // уменьшаются сильнее заданного (центральное выходило крупнее на ~22% вместо ~18%) function normalizeScale(s) { var size = s.slidesSizesGrid && s.slidesSizesGrid[0]; if (!size) return; s.params.coverflowEffect.modifier = size / (size + s.params.spaceBetween); s.setTranslate(s.translate); } function init(root) { var el = root.querySelector('[data-cg-swiper]'); var slides = el.querySelectorAll('.swiper-slide'); var total = slides.length; if (!total) { root.style.display = 'none'; return; } var current = root.querySelector('[data-cg-current]'); root.querySelector('[data-cg-total]').textContent = total; var items = Array.prototype.map.call(slides, function (slide) { var link = slide.querySelector('[data-cg-full]'); return { src: link.getAttribute('data-cg-full'), opts: { caption: link.getAttribute('data-caption') || '' } }; }); var swiper = new Swiper(el, { effect: 'coverflow', centeredSlides: true, loop: total > 5, rewind: total <= 5, speed: 400, grabCursor: true, slideToClickedSlide: true, slidesPerView: 1.6, spaceBetween: 10, coverflowEffect: { rotate: 0, stretch: 0, depth: 0, modifier: 1, scale: SIDE_SCALE, slideShadows: false }, breakpoints: { 768: { slidesPerView: 3, spaceBetween: 14 }, 1024: { slidesPerView: 5, spaceBetween: 14 } }, keyboard: { enabled: true, onlyInViewport: true }, // только горизонтальная прокрутка (тачпад, Shift+колесо): обычное колесо по-прежнему листает страницу mousewheel: { forceToAxis: true, thresholdDelta: 10 }, navigation: { prevEl: root.querySelector('[data-cg-prev]'), nextEl: root.querySelector('[data-cg-next]') }, on: { init: normalizeScale, resize: function (s) { setTimeout(function () { normalizeScale(s); }, 0); }, breakpoint: function (s) { setTimeout(function () { normalizeScale(s); }, 0); }, slideChange: function () { current.textContent = this.realIndex + 1; } } }); // клик по центральному фото — увеличенный просмотр; по боковому — Swiper сам переводит его в центр. // Было ли фото центральным, запоминаем при нажатии: к событию click Swiper уже делает его активным. var pressedOnActive = false; el.addEventListener('pointerdown', function (event) { var slide = event.target.closest('.swiper-slide'); pressedOnActive = !!slide && slide.classList.contains('swiper-slide-active'); }, true); el.addEventListener('click', function (event) { var link = event.target.closest('.cg__link'); if (!link) return; event.preventDefault(); var slide = link.closest('.swiper-slide'); if (!pressedOnActive) return; pressedOnActive = false; var index = parseInt(slide.getAttribute('data-swiper-slide-index'), 10); openLightbox(isNaN(index) ? swiper.realIndex : index); }); function openLightbox(index) { if (!window.jQuery || !jQuery.fancybox) { window.open(items[index].src, '_blank'); return; } swiper.keyboard.disable(); jQuery.fancybox.open(items, { loop: true, beforeClose: function (instance) { // карусель встаёт на фото, которое смотрели последним var viewed = instance && typeof instance.currIndex === 'number' ? instance.currIndex : index; if (swiper.params.loop) { swiper.slideToLoop(viewed, 0); } else { swiper.slideTo(viewed, 0); } }, afterClose: function () { swiper.keyboard.enable(); } }, index); } } var attempts = 0; (function waitForLibraries() { if (window.Swiper) { Array.prototype.forEach.call(document.querySelectorAll('[data-cg]'), init); } else if (++attempts < 400) { setTimeout(waitForLibraries, 50); } })(); })();