-
Notifications
You must be signed in to change notification settings - Fork 0
/
customCarousel.js
133 lines (111 loc) · 3.77 KB
/
customCarousel.js
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
document.addEventListener('DOMContentLoaded', function () {
const testimonialWrapper = document.querySelector('.logo-testimonials_wrapper');
const testimonialList = document.querySelector('.logo-testimonials_list');
const testimonialLogosList = document.querySelector('.slider-logo_list-wrapper');
const testimonials = Array.from(testimonialWrapper.querySelectorAll('.logo-testimonials_item'));
const testimonialLogos = Array.from(testimonialWrapper.querySelectorAll('.slider-logo_item'));
let currentIndex = 0;
const setActiveItem = (index) => {
const currentTestimonial = testimonials[currentIndex];
const currentLogo = testimonialLogos[currentIndex];
// remove active class from current testimonial
currentTestimonial.classList.remove('active');
currentLogo.classList.remove('active');
currentLogo.classList.remove('clickedActive');
// add active class to new testimonial
testimonials[index].classList.add('active');
testimonialLogos[index].classList.add('active');
// translate testimonial list
testimonialList.style.transform = `translateX(-${index * 100}%)`;
// scroll testimonial logos list
const scrollWidth = testimonialLogos
.slice(0, index)
.reduce((acc, logo) => acc + logo.offsetWidth, 0);
testimonialLogosList.scroll({
left: scrollWidth,
behavior: 'smooth',
});
currentIndex = index;
};
const handleNextTestimonial = (callback = () => {}) => {
if (currentIndex === testimonials.length - 1) {
setActiveItem(0);
} else {
setActiveItem(currentIndex + 1);
}
callback();
};
const handlePreviousTestimonial = (callback = () => {}) => {
if (currentIndex === 0) {
setActiveItem(testimonials.length - 1);
} else {
setActiveItem(currentIndex - 1);
}
callback();
};
const handleTestimonialClick = (index, callback = () => {}) => {
setActiveItem(index);
callback();
};
let hasIntersected = false;
let carouselInterval = null;
// set initial active item and interval when wrapper is on the screen
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
setActiveItem(0);
carouselInterval = setInterval(handleNextTestimonial, 6000);
if (!hasIntersected) {
hasIntersected = true;
testimonialLogos.forEach((logo, index) => {
logo.addEventListener('click', () => {
handleTestimonialClick(index, () => {
clearInterval(carouselInterval);
carouselInterval = setInterval(handleNextTestimonial, 6000);
});
});
});
}
} else {
clearInterval(carouselInterval);
}
});
},
{ threshold: 0.5 }
);
observer.observe(testimonialWrapper);
let touchstartX = 0;
let touchendX = 0;
testimonialList.addEventListener(
'touchstart',
(event) => {
touchstartX = event.changedTouches[0].screenX;
},
false
);
testimonialList.addEventListener(
'touchend',
(event) => {
touchendX = event.changedTouches[0].screenX;
handleGesture();
},
false
);
function handleGesture() {
// add deadzone to touch so that when scrolling on mobile it doesn't trigger the carousel
if (Math.abs(touchendX - touchstartX) < 100) return;
if (touchendX <= touchstartX) {
handleNextTestimonial(() => {
clearInterval(carouselInterval);
carouselInterval = setInterval(handleNextTestimonial, 6000);
});
}
if (touchendX >= touchstartX) {
handlePreviousTestimonial(() => {
clearInterval(carouselInterval);
carouselInterval = setInterval(handleNextTestimonial, 6000);
});
}
}
});