Files
landing/js/flipbook.js
2025-05-02 12:48:13 +00:00

153 lines
5.6 KiB
JavaScript

// Навигация флипбука
let currentPage = 3;
const totalPages = 6;
const flipbookContainer = document.querySelector('.flipbook-container');
const pages = document.querySelectorAll('.flipbook-page');
const indicator = document.querySelector('.flipbook-indicator');
let startTranslateX = 0; // Initial translateX of the active page
const pageSpacing = 16 * 1; // 1rem margin on each side of the page (0.5rem * 2)
function updatePages() {
pages.forEach(page => {
const pageNum = parseInt(page.dataset.page);
const diff = pageNum - currentPage;
// Apply original classes for animation on both mobile and desktop
page.classList.remove('active', 'left', 'right', 'far-left', 'far-right', 'far-far-right', 'far-far-left');
if (diff === 0) {
page.classList.add('active');
} else if (diff === -1) {
page.classList.add('left');
} else if (diff === -2) {
page.classList.add('far-left');
} else if (diff === -3) {
page.classList.add('far-far-left');
} else if (diff === 1) {
page.classList.add('right');
} else if (diff === 2) {
page.classList.add('far-right');
} else if (diff === 3) {
page.classList.add('far-far-right');
}
// Calculate and apply translateX for each page based on its position relative to the active page
// This is the core change for custom scrolling
let translateX;
// Calculate horizontal translation for each page
if (window.innerWidth <= 768) {
// Mobile: Adjusted translateX with tighter spacing
translateX = (pageNum - currentPage) * (page.offsetWidth * 0.6 + pageSpacing) - 15;
// Centering is handled by flexbox on the container
} else {
// Desktop: Adjusted translateX for spacing and to contribute to the curve effect
// Multiplier (0.9) controls horizontal spacing between pages
const desktopSpacing = page.offsetWidth * 0.9 + pageSpacing;
translateX = (pageNum - currentPage) * desktopSpacing;
// Centering is handled by flexbox on the container
}
// Apply combined transform: translateX, rotateY (for flip effect), and scale (for perspective)
// rotateY: Controls the rotation around the Y-axis (the "flip")
// Multipliers (12 for mobile, 20 for desktop) control the degree of rotation per page difference
// scale: Controls the size of the page, creating a perspective effect
// Multipliers (0.08 for mobile, 0.05 for desktop) control how much smaller pages get further away
page.style.transform = `translateX(${translateX}px) rotateY(${diff * (window.innerWidth <= 768 ? 12 : 20)}deg) scale(${1 - Math.abs(diff) * (window.innerWidth <= 768 ? 0.08 : 0.05)})`;
// Adjust z-index based on distance from active page to control stacking order
page.style.zIndex = totalPages - Math.abs(diff);
// Adjust opacity based on distance to create a fading effect for far pages
// Multipliers (0.15 for mobile, 0.1 for desktop) control how much pages fade
page.style.opacity = 1 - Math.abs(diff) * (window.innerWidth <= 768 ? 0.15 : 0.1);
});
// Update indicator position
let position;
if (window.innerWidth <= 768) {
// Indicator position for mobile (centered)
position = ((currentPage - 1) / (totalPages - 1)) * 100 - 50;
} else {
// Indicator position for desktop (adjusted for wider range)
position = ((currentPage - 1) / (totalPages - 1)) * 200 - 100;
}
indicator.style.transform = `translateX(${position}%)`;
}
// Click navigation (keep original logic)
pages.forEach(page => {
page.addEventListener('click', (e) => {
if (!page.classList.contains('active')) {
currentPage = parseInt(page.dataset.page);
updatePages();
}
});
});
// Mouse hover navigation (keep original logic)
let hoverTimer;
pages.forEach(page => {
page.addEventListener('mouseenter', () => {
if (!page.classList.contains('active')) {
clearTimeout(hoverTimer);
hoverTimer = setTimeout(() => {
currentPage = parseInt(page.dataset.page);
updatePages();
}, 300);
}
});
page.addEventListener('mouseleave', () => {
clearTimeout(hoverTimer);
});
});
// Touch swipe detection (removed for mobile as per user request)
// The following touch event listeners and related variables are removed.
// Navigation on mobile will now be handled by clicking on the cards.
// Handle window resize to switch between mobile/desktop layouts
window.addEventListener('resize', updatePages);
// Initialize
updatePages();
// Product details data - will be populated from HTML
const productDetails = {};
// Initialize product details from data attributes
function initProductDetails() {
const productElements = document.querySelectorAll('.flipbook-page');
productElements.forEach(page => {
const pageNum = parseInt(page.dataset.page);
const title = page.querySelector('.product-title').textContent;
const description = page.querySelector('.product-description').textContent;
productDetails[pageNum] = { title, description };
});
}
// Show product details modal
function showProductDetails(pageNum) {
const details = productDetails[pageNum];
if (details) {
document.getElementById('modalTitle').textContent = details.title;
document.getElementById('modalDescription').textContent = details.description;
document.getElementById('productModal').classList.add('show');
}
}
function hideProductDetails() {
document.getElementById('productModal').classList.remove('show');
}
// Close modal when clicking outside
document.getElementById('productModal').addEventListener('click', function(e) {
if (e.target === this) {
hideProductDetails();
}
});
// Initialize
initProductDetails();
updatePages();