scroll stepbystep showcase section
This commit is contained in:
@@ -643,7 +643,7 @@ section[class*='-section'] {
|
|||||||
}
|
}
|
||||||
.scroll-track {
|
.scroll-track {
|
||||||
width: 5px;
|
width: 5px;
|
||||||
height: 93px;
|
height: 86px;
|
||||||
background: #dfdfdf;
|
background: #dfdfdf;
|
||||||
border-radius: 26.6px;
|
border-radius: 26.6px;
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -672,7 +672,7 @@ body.dragging-scroll {
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: 48px;
|
gap: 48px;
|
||||||
position: relative;
|
position: relative;
|
||||||
/* top: 69px; */
|
top: 69px;
|
||||||
transition: transform 0.3s ease;
|
transition: transform 0.3s ease;
|
||||||
}
|
}
|
||||||
.side-buttons {
|
.side-buttons {
|
||||||
@@ -1504,7 +1504,7 @@ textarea {
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(280px, 389px));
|
grid-template-columns: repeat(auto-fit, minmax(280px, 389px));
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
margin-top: 24px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.related-card {
|
.related-card {
|
||||||
@@ -1733,6 +1733,7 @@ textarea {
|
|||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
transition: transform 0.6s cubic-bezier(0.25, 1, 0.5, 1);
|
||||||
}
|
}
|
||||||
.text-item {
|
.text-item {
|
||||||
height: 60dvh;
|
height: 60dvh;
|
||||||
|
|||||||
@@ -611,11 +611,126 @@ function updateScrollScene() {
|
|||||||
setActiveSlide(current);
|
setActiveSlide(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.addEventListener('scroll', updateScrollScene);
|
let currentSlideIndex = 0;
|
||||||
|
let isAnimating = false;
|
||||||
|
|
||||||
window.addEventListener('resize', updateScrollScene);
|
function goToSlide(index) {
|
||||||
|
if (index < 0 || index >= totalSlides) return;
|
||||||
|
|
||||||
|
currentSlideIndex = index;
|
||||||
|
isAnimating = true;
|
||||||
|
|
||||||
|
const progress = index / (totalSlides - 1);
|
||||||
|
const exactIndex = index;
|
||||||
|
|
||||||
|
const isMobile = window.innerWidth <= 768;
|
||||||
|
|
||||||
|
if (isMobile) {
|
||||||
|
textTrack.style.transform = 'translateY(0)';
|
||||||
|
resetTextItemInlineStyles();
|
||||||
|
setActiveSlide(currentSlideIndex);
|
||||||
|
setTimeout(() => {
|
||||||
|
isAnimating = false;
|
||||||
|
}, 500);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
textTrack.style.transform = `translateY(-${exactIndex * 60}vh)`;
|
||||||
|
|
||||||
|
textItems.forEach((item) => {
|
||||||
|
item.classList.remove('active');
|
||||||
|
});
|
||||||
|
|
||||||
|
textItems.forEach((item, idx) => {
|
||||||
|
const offset = idx - exactIndex;
|
||||||
|
const absOffset = Math.abs(offset);
|
||||||
|
|
||||||
|
let blur = 0;
|
||||||
|
let opacity = 1;
|
||||||
|
|
||||||
|
if (offset > 0) {
|
||||||
|
blur = absOffset > 0.1 ? Math.min((absOffset - 0.1) * 25, 20) : 0;
|
||||||
|
opacity = Math.max(1 - absOffset * 2.5, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
item.style.filter = `blur(${blur}px)`;
|
||||||
|
item.style.opacity = opacity;
|
||||||
|
});
|
||||||
|
|
||||||
|
setActiveSlide(currentSlideIndex);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
isAnimating = false;
|
||||||
|
}, 600);
|
||||||
|
}
|
||||||
|
|
||||||
|
let lastScrollTime = 0;
|
||||||
|
const scrollCooldown = 800;
|
||||||
|
|
||||||
|
showcase.addEventListener('wheel', function(e) {
|
||||||
|
const currentTime = new Date().getTime();
|
||||||
|
const isAtEnd = currentSlideIndex === totalSlides - 1;
|
||||||
|
const isAtStart = currentSlideIndex === 0;
|
||||||
|
|
||||||
|
|
||||||
|
if ((e.deltaY > 0 && !isAtEnd) || (e.deltaY < 0 && !isAtStart)) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (isAnimating || (currentTime - lastScrollTime < scrollCooldown)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Math.abs(e.deltaY) < 10) return;
|
||||||
|
|
||||||
|
if (e.deltaY > 0) {
|
||||||
|
if (!isAtEnd) {
|
||||||
|
lastScrollTime = currentTime;
|
||||||
|
goToSlide(currentSlideIndex + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isAtStart) {
|
||||||
|
lastScrollTime = currentTime;
|
||||||
|
goToSlide(currentSlideIndex - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, { passive: false });
|
||||||
|
|
||||||
|
showcase.addEventListener('touchmove', function(e) {
|
||||||
|
const currentTime = new Date().getTime();
|
||||||
|
const isAtEnd = currentSlideIndex === totalSlides - 1;
|
||||||
|
const isAtStart = currentSlideIndex === 0;
|
||||||
|
|
||||||
|
const currentTouchY = e.touches[0].clientY;
|
||||||
|
const diffY = touchStartY - currentTouchY;
|
||||||
|
|
||||||
|
|
||||||
|
if ((diffY > 0 && !isAtEnd) || (diffY < 0 && !isAtStart)) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAnimating || (currentTime - lastScrollTime < scrollCooldown)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Math.abs(diffY) > 50) {
|
||||||
|
if (diffY > 0) {
|
||||||
|
if (!isAtEnd) {
|
||||||
|
lastScrollTime = currentTime;
|
||||||
|
goToSlide(currentSlideIndex + 1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!isAtStart) {
|
||||||
|
lastScrollTime = currentTime;
|
||||||
|
goToSlide(currentSlideIndex - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, { passive: false });
|
||||||
|
|
||||||
|
goToSlide(0);
|
||||||
|
|
||||||
updateScrollScene();
|
|
||||||
|
|
||||||
const portfolioNavConfig = {
|
const portfolioNavConfig = {
|
||||||
actionType: 'project',
|
actionType: 'project',
|
||||||
@@ -971,25 +1086,27 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
updateUI();
|
updateUI();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const relatedCards = [
|
const relatedCards = [
|
||||||
...document.querySelectorAll('[data-related-section="gallery"] .related-card'),
|
...document.querySelectorAll('[data-related-section="gallery"] .related-card'),
|
||||||
];
|
];
|
||||||
|
|
||||||
let currentPopupIndex = 0;
|
const hasGalleryThumbnail = document.querySelector('.gallery-thumbnail') !== null;
|
||||||
const galleryItems = [
|
|
||||||
{
|
|
||||||
type: 'project',
|
|
||||||
},
|
|
||||||
|
|
||||||
...[...document.querySelectorAll('[data-related-section="gallery"] .related-card')].map(
|
let currentPopupIndex = 0;
|
||||||
(card) => ({
|
const galleryItems = [];
|
||||||
|
|
||||||
|
if (hasGalleryThumbnail) {
|
||||||
|
galleryItems.push({
|
||||||
|
type: 'project',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
relatedCards.forEach((card) => {
|
||||||
|
galleryItems.push({
|
||||||
type: 'card',
|
type: 'card',
|
||||||
element: card,
|
element: card,
|
||||||
})
|
});
|
||||||
),
|
});
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
function openPopupByIndex(index) {
|
function openPopupByIndex(index) {
|
||||||
const item = galleryItems[index];
|
const item = galleryItems[index];
|
||||||
@@ -998,7 +1115,6 @@ function openPopupByIndex(index) {
|
|||||||
|
|
||||||
currentPopupIndex = index;
|
currentPopupIndex = index;
|
||||||
|
|
||||||
// اول هر دو پاپآپ بسته شوند
|
|
||||||
overlay.classList.remove('active');
|
overlay.classList.remove('active');
|
||||||
imagePopup.classList.remove('active');
|
imagePopup.classList.remove('active');
|
||||||
|
|
||||||
@@ -1024,13 +1140,11 @@ function openPopupByIndex(index) {
|
|||||||
function updatePopupButtons() {
|
function updatePopupButtons() {
|
||||||
document.querySelectorAll('.next-popup').forEach((btn) => {
|
document.querySelectorAll('.next-popup').forEach((btn) => {
|
||||||
btn.disabled = currentPopupIndex === galleryItems.length - 1;
|
btn.disabled = currentPopupIndex === galleryItems.length - 1;
|
||||||
|
|
||||||
btn.classList.toggle('disabled', currentPopupIndex === galleryItems.length - 1);
|
btn.classList.toggle('disabled', currentPopupIndex === galleryItems.length - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelectorAll('.prev-popup').forEach((btn) => {
|
document.querySelectorAll('.prev-popup').forEach((btn) => {
|
||||||
btn.disabled = currentPopupIndex === 0;
|
btn.disabled = currentPopupIndex === 0;
|
||||||
|
|
||||||
btn.classList.toggle('disabled', currentPopupIndex === 0);
|
btn.classList.toggle('disabled', currentPopupIndex === 0);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1040,15 +1154,18 @@ document.querySelector('.gallery-thumbnail .wrapper')?.addEventListener('click',
|
|||||||
openPopupByIndex(0);
|
openPopupByIndex(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
relatedCards.forEach((card, index) => {
|
relatedCards.forEach((card) => {
|
||||||
card.addEventListener('click', (e) => {
|
card.addEventListener('click', (e) => {
|
||||||
if (e.target.closest('.play-btn')) return;
|
if (e.target.closest('.play-btn')) return;
|
||||||
|
|
||||||
openPopupByIndex(index + 1);
|
const targetIndex = galleryItems.findIndex(item => item.element === card);
|
||||||
|
|
||||||
|
if (targetIndex !== -1) {
|
||||||
|
openPopupByIndex(targetIndex);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
document.querySelectorAll('.next-popup').forEach((btn) => {
|
document.querySelectorAll('.next-popup').forEach((btn) => {
|
||||||
btn.addEventListener('click', () => {
|
btn.addEventListener('click', () => {
|
||||||
if (currentPopupIndex < galleryItems.length - 1) {
|
if (currentPopupIndex < galleryItems.length - 1) {
|
||||||
@@ -1064,6 +1181,8 @@ document.querySelectorAll('.prev-popup').forEach((btn) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
window.addEventListener('keydown', (e) => {
|
window.addEventListener('keydown', (e) => {
|
||||||
if (!imagePopup.classList.contains('active')) return;
|
if (!imagePopup.classList.contains('active')) return;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user