@@ -21,6 +21,11 @@ listing:
2121 overflow: hidden;
2222 position: relative;
2323 width: 100%;
24+ cursor: grab;
25+ }
26+
27+ #news-carousel-container.grabbing {
28+ cursor: grabbing;
2429}
2530
2631#news-carousel-container #news-carousel-track {
@@ -135,10 +140,16 @@ document.addEventListener('DOMContentLoaded', function () {
135140 }
136141
137142 const slides = Array.from(carouselTrack.children);
138- const displayDuration = 2500 ;
143+ const displayDuration = 2000 ;
139144 let currentTranslate = 0;
145+ let prevTranslate = 0;
140146 let currentIndex = 0;
141147 let intervalId;
148+
149+ // Interaction state variables
150+ let isDragging = false;
151+ let startPos = 0;
152+ let hasDragged = false;
142153 let wheelTimeout;
143154 let isWheeling = false;
144155
@@ -148,6 +159,10 @@ document.addEventListener('DOMContentLoaded', function () {
148159 if (width > 768 && width <= 1024) return 2;
149160 return 3;
150161 }
162+
163+ const getPositionX = (event) => {
164+ return event.type.includes('mouse') ? event.pageX : event.touches[0].clientX;
165+ }
151166
152167 const startAutoplay = () => {
153168 stopAutoplay();
@@ -179,7 +194,7 @@ document.addEventListener('DOMContentLoaded', function () {
179194 }
180195
181196 const autoplayNext = () => {
182- if (document.hidden) return;
197+ if (document.hidden || isDragging ) return;
183198 const itemsPerView = getItemsPerView();
184199 const maxIndex = slides.length > itemsPerView ? slides.length - itemsPerView : 0;
185200
@@ -189,13 +204,52 @@ document.addEventListener('DOMContentLoaded', function () {
189204 }
190205 setPositionByIndex();
191206 }
207+
208+ function handleDragStart(event) {
209+ isDragging = true;
210+ hasDragged = false;
211+ startPos = getPositionX(event);
212+ const style = window.getComputedStyle(carouselTrack);
213+ const matrix = new DOMMatrix(style.transform);
214+ prevTranslate = matrix.m41;
215+ carouselContainer.classList.add('grabbing');
216+ carouselTrack.style.transition = 'none';
217+ stopAutoplay();
218+ }
219+
220+ function handleDragMove(event) {
221+ if (!isDragging) return;
222+ const currentPosition = getPositionX(event);
223+ currentTranslate = prevTranslate + currentPosition - startPos;
224+ setSliderPosition();
225+ if (Math.abs(currentPosition - startPos) > 10) {
226+ hasDragged = true;
227+ }
228+ }
229+
230+ function handleDragEnd() {
231+ if (!isDragging) return;
232+ isDragging = false;
233+ carouselContainer.classList.remove('grabbing');
234+ const movedBy = currentTranslate - prevTranslate;
235+ const itemsPerView = getItemsPerView();
236+ const maxIndex = slides.length > itemsPerView ? slides.length - itemsPerView : 0;
237+
238+ if (movedBy < -50 && currentIndex < maxIndex) {
239+ currentIndex++;
240+ }
241+ if (movedBy > 50 && currentIndex > 0) {
242+ currentIndex--;
243+ }
244+
245+ setPositionByIndex();
246+ startAutoplay();
247+ }
192248
193- const handleWheel = (event) => {
249+ function handleWheel(event) {
194250 event.preventDefault();
195-
196251 if (isWheeling) return;
197252 isWheeling = true;
198-
199253 stopAutoplay();
200254
201255 const itemsPerView = getItemsPerView();
@@ -210,15 +264,30 @@ document.addEventListener('DOMContentLoaded', function () {
210264 setPositionByIndex();
211265
212266 clearTimeout(wheelTimeout);
213- wheelTimeout = setTimeout(startAutoplay, 300);
214-
267+ wheelTimeout = setTimeout(startAutoplay, 500);
215268 setTimeout(() => { isWheeling = false; }, 100);
216269 }
270+
271+ carouselContainer.addEventListener('mousedown', handleDragStart);
272+ window.addEventListener('mouseup', handleDragEnd);
273+ window.addEventListener('mousemove', handleDragMove);
217274
275+ carouselContainer.addEventListener('touchstart', handleDragStart, { passive: true });
276+ window.addEventListener('touchend', handleDragEnd);
277+ window.addEventListener('touchmove', handleDragMove, { passive: true });
278+
279+ carouselContainer.addEventListener('click', (e) => {
280+ if (hasDragged) {
281+ e.preventDefault();
282+ }
283+ }, true);
284+
218285 carouselContainer.addEventListener('wheel', handleWheel, { passive: false });
286+
219287 carouselContainer.addEventListener('mouseenter', stopAutoplay);
220288 carouselContainer.addEventListener('mouseleave', startAutoplay);
221289 document.addEventListener('visibilitychange', () => document.hidden ? stopAutoplay() : startAutoplay());
290+
222291 window.addEventListener('resize', setPositionByIndex);
223292
224293 setPositionByIndex();
0 commit comments