-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcarousel.js
More file actions
119 lines (105 loc) · 3.38 KB
/
carousel.js
File metadata and controls
119 lines (105 loc) · 3.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
const slides = document.querySelectorAll('.carousel-slide');
const nextBtn = document.querySelector('.carousel-btn.next');
const prevBtn = document.querySelector('.carousel-btn.prev');
const carouselDots = document.querySelector('.carousel-dots');
let currentIndex = 0;
let isTransitioning = false;
// Dynamically generate dots based on number of slides
function generateDots() {
carouselDots.innerHTML = '';
slides.forEach((_, i) => {
const dot = document.createElement('span');
dot.classList.add('dot');
dot.dataset.index = i;
if (i === currentIndex) {
dot.classList.add('active');
}
dot.addEventListener('click', () => {
if (!isTransitioning) {
currentIndex = i;
updateCarousel();
}
});
carouselDots.appendChild(dot);
});
}
function updateCarousel(instant = false) {
if (isTransitioning && !instant) return;
isTransitioning = true;
const totalSlides = slides.length;
slides.forEach((slide, i) => {
slide.classList.remove('active', 'left', 'right');
// Calculate relative position from current index
let relativePos = i - currentIndex;
// Normalize position for wrapping
while (relativePos < -Math.floor(totalSlides / 2)) relativePos += totalSlides;
while (relativePos > Math.floor(totalSlides / 2)) relativePos -= totalSlides;
// Apply classes and transforms based on position
if (relativePos === 0) {
// Center slide (active)
slide.classList.add('active');
slide.style.transform = 'translateX(0) scale(1)';
slide.style.filter = 'brightness(1)';
slide.style.zIndex = '3';
slide.style.opacity = '1';
} else if (relativePos === -1) {
// Left slide
slide.classList.add('left');
slide.style.transform = 'translateX(-120%)';
slide.style.filter = 'brightness(0.4)';
slide.style.zIndex = '1';
slide.style.opacity = '1';
} else if (relativePos === 1) {
// Right slide
slide.classList.add('right');
slide.style.transform = 'translateX(120%)';
slide.style.filter = 'brightness(0.4)';
slide.style.zIndex = '1';
slide.style.opacity = '1';
} else {
// Hidden slides - position them far away
const direction = relativePos < 0 ? -1 : 1;
slide.style.transform = `translateX(${direction * 300}%)`;
slide.style.filter = 'brightness(0.4)';
slide.style.zIndex = '0';
slide.style.opacity = '0';
}
});
// Update dots
const dots = document.querySelectorAll('.dot');
dots.forEach((dot, i) => {
dot.classList.toggle('active', i === currentIndex);
});
// Allow next transition after animation completes
setTimeout(() => {
isTransitioning = false;
}, 800);
}
// Initialize carousel
generateDots();
updateCarousel(true);
// Next button - move to next project
if (nextBtn) {
nextBtn.addEventListener('click', () => {
if (!isTransitioning) {
currentIndex = (currentIndex + 1) % slides.length;
updateCarousel();
}
});
}
// Previous button - move to previous project
if (prevBtn) {
prevBtn.addEventListener('click', () => {
if (!isTransitioning) {
currentIndex = (currentIndex - 1 + slides.length) % slides.length;
updateCarousel();
}
});
}
// Auto-advance every 5 seconds
setInterval(() => {
if (!isTransitioning) {
currentIndex = (currentIndex + 1) % slides.length;
updateCarousel();
}
}, 5000);