Initial commit with all files
This commit is contained in:
153
js/flipbook.js
Normal file
153
js/flipbook.js
Normal file
@@ -0,0 +1,153 @@
|
||||
// Навигация флипбука
|
||||
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();
|
||||
Reference in New Issue
Block a user