full
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
.gallery-block .thumbnail {
|
||||
opacity: 0.5;
|
||||
transition: 180ms ease-in-out;
|
||||
|
||||
}
|
||||
|
||||
.gallery-block .thumbnail.active {
|
||||
opacity: 1;
|
||||
transition: 180ms ease-in-out;
|
||||
}
|
||||
|
||||
.gallery-block .tab-button {
|
||||
box-shadow: 0 2px 32px 0 rgba(16, 15, 15, 0.03);
|
||||
background: #fff;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
line-height: 195%;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.gallery-block .tab-button.active {
|
||||
font-size: 18px;
|
||||
line-height: 195%;
|
||||
color: #f8f8f8;
|
||||
box-shadow: none;
|
||||
background: linear-gradient(90deg, #9d9994 39.42%, #ccc9c4 92.9%);
|
||||
}
|
||||
.dark .gallery-block .tab-button.active {
|
||||
background: linear-gradient(90deg, #2b2c35 39.42%, #6e7996 92.9%);
|
||||
color: #f8f8f8;
|
||||
}
|
||||
|
||||
|
||||
.gallery-block .swiper-slide img {
|
||||
transition: opacity 180ms ease-in-out;
|
||||
}
|
||||
|
||||
.gallery-block .swiper-slide img[loading="lazy"] {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.gallery-block .swiper-slide img[loading="lazy"].loaded,
|
||||
.gallery-block .swiper-slide img:not([loading="lazy"]) {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.gallery-block .thumbnail:not(.active) {
|
||||
opacity: 0.6;
|
||||
transition: opacity 180ms ease-in-out;
|
||||
}
|
||||
|
||||
.gallery-block .thumbnail.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
document.querySelectorAll('.gallery-block').forEach(function(block) {
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
document.querySelectorAll('.gallery-block').forEach(function (block) {
|
||||
const blockId = block.getAttribute('data-gallery-id');
|
||||
initGalleryBlock(blockId);
|
||||
});
|
||||
@@ -10,99 +10,126 @@ function initGalleryBlock(blockId) {
|
||||
if (!container) return;
|
||||
|
||||
const swipers = {};
|
||||
const thumbnailSwipers = {};
|
||||
const initializedTabs = new Set();
|
||||
let lightbox;
|
||||
|
||||
function initAllSwipers() {
|
||||
const tabs = container.querySelectorAll('.tab-button');
|
||||
function initTabSwiper(tabId) {
|
||||
if (initializedTabs.has(tabId)) return;
|
||||
|
||||
tabs.forEach(button => {
|
||||
const tabId = button.getAttribute('data-tab');
|
||||
const tabContent = container.querySelector(`#tab-${tabId}`);
|
||||
const tabContent = container.querySelector(`#tab-${tabId}`);
|
||||
if (!tabContent?.querySelector('.gallery-swiper')) return;
|
||||
|
||||
if (tabContent && tabContent.querySelector('.swiper')) {
|
||||
const wasHidden = tabContent.classList.contains('hidden');
|
||||
if (wasHidden) {
|
||||
tabContent.style.visibility = 'hidden';
|
||||
tabContent.style.position = 'absolute';
|
||||
tabContent.classList.remove('hidden');
|
||||
tabContent.classList.add('block');
|
||||
}
|
||||
thumbnailSwipers[tabId] = new Swiper(`#${blockId} #thumbnail-swiper-${tabId}`, {
|
||||
slidesPerView: 'auto',
|
||||
spaceBetween: 24,
|
||||
freeMode: true,
|
||||
grabCursor: true,
|
||||
watchSlidesProgress: true,
|
||||
});
|
||||
|
||||
if (swipers[tabId]) {
|
||||
swipers[tabId].destroy(true, true);
|
||||
}
|
||||
|
||||
swipers[tabId] = new Swiper(`#${blockId} #swiper-${tabId}`, {
|
||||
slidesPerView: 1.5,
|
||||
spaceBetween: 20,
|
||||
loop: true,
|
||||
centeredSlides: true,
|
||||
grabCursor: true,
|
||||
observer: true,
|
||||
observeParents: true,
|
||||
watchSlidesProgress: true,
|
||||
navigation: {
|
||||
nextEl: `#${blockId} #swiper-${tabId} .swiper-button-next`,
|
||||
prevEl: `#${blockId} #swiper-${tabId} .swiper-button-prev`,
|
||||
},
|
||||
on: {
|
||||
slideChange: function() {
|
||||
updateThumbnails(tabId, this.realIndex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (wasHidden) {
|
||||
tabContent.style.visibility = '';
|
||||
tabContent.style.position = '';
|
||||
tabContent.classList.add('hidden');
|
||||
tabContent.classList.remove('block');
|
||||
swipers[tabId] = new Swiper(`#${blockId} #swiper-${tabId}`, {
|
||||
slidesPerView: 'auto',
|
||||
spaceBetween: 24,
|
||||
centeredSlides: true,
|
||||
initialSlide: 1,
|
||||
scrollbar: {
|
||||
el: `#swiper-scrollbar-${tabId}`,
|
||||
draggable: true,
|
||||
},
|
||||
grabCursor: true,
|
||||
watchSlidesProgress: true,
|
||||
lazy: {
|
||||
loadPrevNext: true,
|
||||
loadOnTransitionStart: true,
|
||||
},
|
||||
on: {
|
||||
slideChange: function () {
|
||||
updateThumbnails(tabId, this.realIndex);
|
||||
centerThumbnail(tabId, this.realIndex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
initializedTabs.add(tabId);
|
||||
}
|
||||
|
||||
function initLightbox(tabId) {
|
||||
if (lightbox) {
|
||||
lightbox.destroy();
|
||||
}
|
||||
const currentSelector = `#${blockId} #tab-${tabId} .glightbox`;
|
||||
|
||||
lightbox = GLightbox({
|
||||
selector: `#${blockId} #tab-${tabId} .glightbox`
|
||||
});
|
||||
if (lightbox?.settings?.selector !== currentSelector) {
|
||||
if (lightbox) {
|
||||
lightbox.destroy();
|
||||
}
|
||||
|
||||
lightbox = GLightbox({
|
||||
selector: currentSelector,
|
||||
preload: false,
|
||||
touchNavigation: true,
|
||||
loop: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateThumbnails(tabId, activeIndex) {
|
||||
const thumbnails = container.querySelectorAll(`#tab-${tabId} .thumbnail`);
|
||||
thumbnails.forEach((thumb, index) => {
|
||||
if (index === activeIndex) {
|
||||
thumb.classList.add('active', '!border-blue-500');
|
||||
thumb.classList.remove('border-transparent');
|
||||
thumb.classList.remove('opacity-50', 'hover:opacity-80');
|
||||
thumb.classList.add('opacity-100', 'active');
|
||||
} else {
|
||||
thumb.classList.remove('active', '!border-blue-500');
|
||||
thumb.classList.add('border-transparent');
|
||||
thumb.classList.remove('opacity-100', 'active');
|
||||
thumb.classList.add('opacity-50', 'hover:opacity-80');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initAllSwipers();
|
||||
function centerThumbnail(tabId, activeIndex) {
|
||||
if (thumbnailSwipers[tabId]) {
|
||||
thumbnailSwipers[tabId].slideTo(activeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
function preloadHeroImage() {
|
||||
const activeTab = container.querySelector('.tab-button.active');
|
||||
if (!activeTab) return;
|
||||
|
||||
const tabId = activeTab.getAttribute('data-tab');
|
||||
const firstImage = container.querySelector(`#tab-${tabId} .swiper-slide:first-child img`);
|
||||
|
||||
if (firstImage && firstImage.src) {
|
||||
const link = document.createElement('link');
|
||||
link.rel = 'preload';
|
||||
link.as = 'image';
|
||||
link.href = firstImage.src;
|
||||
document.head.appendChild(link);
|
||||
}
|
||||
}
|
||||
|
||||
function debounce(func, wait) {
|
||||
let timeout;
|
||||
return (...args) => {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => func.apply(this, args), wait);
|
||||
};
|
||||
}
|
||||
|
||||
preloadHeroImage();
|
||||
|
||||
const activeTab = container.querySelector('.tab-button.active');
|
||||
if (activeTab) {
|
||||
const tabId = activeTab.getAttribute('data-tab');
|
||||
initTabSwiper(tabId);
|
||||
initLightbox(tabId);
|
||||
}
|
||||
|
||||
container.querySelectorAll('.tab-button').forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
button.addEventListener('click', debounce(() => {
|
||||
const tabId = button.getAttribute('data-tab');
|
||||
|
||||
container.querySelectorAll('.tab-button').forEach(btn => {
|
||||
btn.classList.remove('active', 'underline');
|
||||
btn.classList.add('bg-gray-100');
|
||||
});
|
||||
button.classList.add('active', 'underline');
|
||||
button.classList.remove('bg-gray-100');
|
||||
container.querySelectorAll('.tab-button').forEach(btn =>
|
||||
btn.classList.remove('active'));
|
||||
button.classList.add('active');
|
||||
|
||||
container.querySelectorAll('.tab-content').forEach(content => {
|
||||
content.classList.remove('block');
|
||||
@@ -113,28 +140,41 @@ function initGalleryBlock(blockId) {
|
||||
targetTab.classList.remove('hidden');
|
||||
targetTab.classList.add('block');
|
||||
|
||||
if (swipers[tabId]) {
|
||||
requestAnimationFrame(() => {
|
||||
initTabSwiper(tabId);
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
if (swipers[tabId]) {
|
||||
swipers[tabId].update();
|
||||
});
|
||||
}
|
||||
}
|
||||
if (thumbnailSwipers[tabId]) {
|
||||
thumbnailSwipers[tabId].update();
|
||||
}
|
||||
});
|
||||
|
||||
initLightbox(tabId);
|
||||
});
|
||||
|
||||
}, 100));
|
||||
});
|
||||
|
||||
container.addEventListener('click', (e) => {
|
||||
if (e.target.closest('.thumbnail')) {
|
||||
const thumbnail = e.target.closest('.thumbnail');
|
||||
const index = parseInt(thumbnail.getAttribute('data-index'));
|
||||
const activeTab = container.querySelector('.tab-content.block');
|
||||
const tabId = activeTab.id.replace('tab-', '');
|
||||
const thumbnail = e.target.closest('.thumbnail');
|
||||
if (!thumbnail) return;
|
||||
|
||||
if (swipers[tabId]) {
|
||||
swipers[tabId].slideToLoop(index);
|
||||
}
|
||||
const index = parseInt(thumbnail.getAttribute('data-index'));
|
||||
const activeTabContent = container.querySelector('.tab-content.block');
|
||||
const tabId = activeTabContent.id.replace('tab-', '');
|
||||
|
||||
updateThumbnails(tabId, index);
|
||||
if (swipers[tabId]) {
|
||||
swipers[tabId].slideTo(index);
|
||||
}
|
||||
|
||||
updateThumbnails(tabId, index);
|
||||
centerThumbnail(tabId, index);
|
||||
});
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
Object.values(swipers).forEach(swiper => swiper?.destroy());
|
||||
Object.values(thumbnailSwipers).forEach(swiper => swiper?.destroy());
|
||||
if (lightbox) lightbox.destroy();
|
||||
});
|
||||
}
|
||||
@@ -1,85 +1,124 @@
|
||||
<?php
|
||||
|
||||
$id = 'gallery-tabs-' . $block['id'];
|
||||
if ( ! empty($block['anchor'] ) ) {
|
||||
if (!empty($block['anchor'])) {
|
||||
$id = $block['anchor'];
|
||||
}
|
||||
|
||||
$classes = 'block-gallery-tabs';
|
||||
if ( ! empty( $block['className'] ) ) {
|
||||
if (!empty($block['className'])) {
|
||||
$classes .= ' ' . $block['className'];
|
||||
}
|
||||
if ( ! empty( $block['align'] ) ) {
|
||||
if (!empty($block['align'])) {
|
||||
$classes .= ' align' . $block['align'];
|
||||
}
|
||||
|
||||
$use_homepage_content = get_field('use_homepage_content');
|
||||
|
||||
if ($use_homepage_content) {
|
||||
$homepage_id = get_option('page_on_front');
|
||||
|
||||
if ($homepage_id) {
|
||||
$page_content = get_post_field('post_content', $homepage_id);
|
||||
$blocks = parse_blocks($page_content);
|
||||
|
||||
foreach ($blocks as $homepage_block) {
|
||||
if ($homepage_block['blockName'] === 'acf/gallery-tabs') {
|
||||
echo render_block($homepage_block);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Если переключатель выключен или блок на главной не найден - рендерим локальные данные
|
||||
$heading = get_field('heading');
|
||||
$slider_tabs = get_field('slider_tabs');
|
||||
|
||||
?>
|
||||
|
||||
<div class="gallery-block mt-[24px]"
|
||||
id="<?php echo esc_attr( $id ); ?>"
|
||||
data-gallery-id="<?php echo esc_attr( $id ); ?>">
|
||||
<div class="gallery-block py-[45px] pb-[90px] <?php if (!is_front_page()): echo 'pb-0 py-[90px] mt-0'; endif ?>"
|
||||
id="<?php echo esc_attr($id); ?>"
|
||||
data-gallery-id="<?php echo esc_attr($id); ?>">
|
||||
|
||||
<div class="container mx-auto">
|
||||
<div class="flex justify-between flex-wrap">
|
||||
<?php if ($heading) : ?>
|
||||
<h2 class="text-[48px] font-[700] leading-[110%]"><?php echo esc_html($heading); ?></h2>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($heading) : ?>
|
||||
<h2 class="text-[32px] font-bold"><?php echo esc_html($heading); ?></h2>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($slider_tabs && !empty($slider_tabs['slider_tab'])) : ?>
|
||||
<div class="flex gap-[10px] mt-[24px]">
|
||||
<?php foreach ($slider_tabs['slider_tab'] as $tab_index => $tab) : ?>
|
||||
<?php if (!empty($tab['tab_name'])) : ?>
|
||||
<button class="tab-button px-[24px] py-[12px] border rounded-[25px] cursor-pointer transition-all <?php echo $tab_index === 0 ? 'active underline' : ''; ?>"
|
||||
data-tab="<?php echo $tab_index; ?>">
|
||||
<?php echo esc_html($tab['tab_name']); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if ($slider_tabs && !empty($slider_tabs['slider_tab'])) : ?>
|
||||
<div class="flex max-w-[872px] flex-wrap gap-[8px]">
|
||||
<?php foreach ($slider_tabs['slider_tab'] as $tab_index => $tab) : ?>
|
||||
<?php if (!empty($tab['tab_name'])) : ?>
|
||||
<button class="tab-button grey-gradient-button rounded-[90px] py-[8px] px-[28px] cursor-pointer transition-all <?php echo $tab_index === 0 ? 'active' : ''; ?>"
|
||||
data-tab="<?php echo $tab_index; ?>">
|
||||
<?php echo esc_html($tab['tab_name']); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if ($slider_tabs && !empty($slider_tabs['slider_tab'])) : ?>
|
||||
<?php foreach ($slider_tabs['slider_tab'] as $tab_index => $tab) : ?>
|
||||
<div class="tab-content <?php echo $tab_index === 0 ? 'block' : 'hidden'; ?>"
|
||||
<div class="tab-content relative <?php echo $tab_index === 0 ? 'block' : 'hidden'; ?>"
|
||||
id="tab-<?php echo $tab_index; ?>">
|
||||
|
||||
<?php if (!empty($tab['slider_images'])) : ?>
|
||||
<div class="swiper mt-[24px] gallery-swiper h-[440px]" id="swiper-<?php echo $tab_index; ?>">
|
||||
|
||||
<div class="swiper max-w-[2000px] mt-[45px] gallery-swiper h-[440px]"
|
||||
id="swiper-<?php echo $tab_index; ?>">
|
||||
<div class="swiper-wrapper">
|
||||
<?php foreach ($tab['slider_images'] as $image) : ?>
|
||||
<div class="swiper-slide cursor-pointer min-h-[440px]">
|
||||
<?php foreach ($tab['slider_images'] as $img_index => $image) : ?>
|
||||
<div class="swiper-slide max-w-[648px] cursor-pointer min-h-[440px]">
|
||||
<a href="<?php echo esc_url($image['url']); ?>"
|
||||
class="glightbox block w-full h-full"
|
||||
data-gallery="gallery-<?php echo $tab_index; ?>">
|
||||
<img src="<?php echo esc_url($image['url']); ?>"
|
||||
alt="<?php echo esc_attr($image['alt']); ?>"
|
||||
class="w-full h-full object-cover">
|
||||
<?php if ($img_index === 0) : ?>
|
||||
<img src="<?php echo esc_url($image['url']); ?>"
|
||||
alt="<?php echo esc_attr($image['alt']); ?>"
|
||||
class="w-full h-full object-cover rounded-[24px]"
|
||||
width="<?php echo esc_attr($image['width']); ?>"
|
||||
height="<?php echo esc_attr($image['height']); ?>"
|
||||
fetchpriority="high">
|
||||
<?php else : ?>
|
||||
<img data-src="<?php echo esc_url($image['url']); ?>"
|
||||
alt="<?php echo esc_attr($image['alt']); ?>"
|
||||
class="w-full h-full object-cover rounded-[24px] swiper-lazy"
|
||||
width="<?php echo esc_attr($image['width']); ?>"
|
||||
height="<?php echo esc_attr($image['height']); ?>">
|
||||
<div class="swiper-lazy-preloader"></div>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<div class="swiper-button-next"></div>
|
||||
<div class="swiper-button-prev"></div>
|
||||
</div>
|
||||
|
||||
<div class="flex mt-[24px] gap-[8px] overflow-x-auto">
|
||||
<?php foreach ($tab['slider_images'] as $thumb_index => $image) : ?>
|
||||
<div class="thumbnail flex-shrink-0 w-[80px] h-[60px] rounded-[5px] overflow-hidden cursor-pointer border-2 border-transparent <?php echo $thumb_index === 0 ? 'active !border-blue-500' : ''; ?>"
|
||||
data-index="<?php echo $thumb_index; ?>">
|
||||
<img src="<?php echo esc_url($image['sizes']['thumbnail']); ?>"
|
||||
alt="<?php echo esc_attr($image['alt']); ?>"
|
||||
class="w-full h-full object-cover">
|
||||
<div class="relative mt-[24px]">
|
||||
<div class="swiper thumbnail-swiper"
|
||||
id="thumbnail-swiper-<?php echo $tab_index; ?>">
|
||||
<div class="swiper-wrapper">
|
||||
<?php foreach ($tab['slider_images'] as $thumb_index => $image) : ?>
|
||||
<div class="swiper-slide max-w-[160px] !h-[100px]">
|
||||
<div class="thumbnail w-full h-full overflow-hidden cursor-pointer transition-opacity duration-[180ms] ease-in-out <?php echo $thumb_index === 0 ? 'active opacity-100' : 'opacity-50 hover:opacity-80'; ?>"
|
||||
data-index="<?php echo $thumb_index; ?>">
|
||||
<img src="<?php echo esc_url($image['sizes']['thumbnail']); ?>"
|
||||
alt="<?php echo esc_attr($image['alt']); ?>"
|
||||
class="w-full rounded-[12px] h-full object-cover"
|
||||
width="160"
|
||||
height="100">
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php if (!empty($image['caption'])) : ?>
|
||||
<p><?php echo esc_html($image['caption']); ?></p>
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
<div class="swiper-scrollbar !static !mx-auto !cursor-grab container mt-[44px] !w-full !p-0" id="swiper-scrollbar-<?php echo $tab_index; ?>"></div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
Reference in New Issue
Block a user