@@ -21,6 +21,11 @@ listing:
21
21
overflow: hidden;
22
22
position: relative;
23
23
width: 100%;
24
+ cursor: grab;
25
+ }
26
+
27
+ #news-carousel-container.grabbing {
28
+ cursor: grabbing;
24
29
}
25
30
26
31
#news-carousel-container #news-carousel-track {
@@ -135,10 +140,16 @@ document.addEventListener('DOMContentLoaded', function () {
135
140
}
136
141
137
142
const slides = Array.from(carouselTrack.children);
138
- const displayDuration = 2500 ;
143
+ const displayDuration = 2000 ;
139
144
let currentTranslate = 0;
145
+ let prevTranslate = 0;
140
146
let currentIndex = 0;
141
147
let intervalId;
148
+
149
+ // Interaction state variables
150
+ let isDragging = false;
151
+ let startPos = 0;
152
+ let hasDragged = false;
142
153
let wheelTimeout;
143
154
let isWheeling = false;
144
155
@@ -148,6 +159,10 @@ document.addEventListener('DOMContentLoaded', function () {
148
159
if (width > 768 && width <= 1024) return 2;
149
160
return 3;
150
161
}
162
+
163
+ const getPositionX = (event) => {
164
+ return event.type.includes('mouse') ? event.pageX : event.touches[0].clientX;
165
+ }
151
166
152
167
const startAutoplay = () => {
153
168
stopAutoplay();
@@ -179,7 +194,7 @@ document.addEventListener('DOMContentLoaded', function () {
179
194
}
180
195
181
196
const autoplayNext = () => {
182
- if (document.hidden) return;
197
+ if (document.hidden || isDragging ) return;
183
198
const itemsPerView = getItemsPerView();
184
199
const maxIndex = slides.length > itemsPerView ? slides.length - itemsPerView : 0;
185
200
@@ -189,13 +204,52 @@ document.addEventListener('DOMContentLoaded', function () {
189
204
}
190
205
setPositionByIndex();
191
206
}
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
+ }
192
248
193
- const handleWheel = (event) => {
249
+ function handleWheel(event) {
194
250
event.preventDefault();
195
-
196
251
if (isWheeling) return;
197
252
isWheeling = true;
198
-
199
253
stopAutoplay();
200
254
201
255
const itemsPerView = getItemsPerView();
@@ -210,15 +264,30 @@ document.addEventListener('DOMContentLoaded', function () {
210
264
setPositionByIndex();
211
265
212
266
clearTimeout(wheelTimeout);
213
- wheelTimeout = setTimeout(startAutoplay, 300);
214
-
267
+ wheelTimeout = setTimeout(startAutoplay, 500);
215
268
setTimeout(() => { isWheeling = false; }, 100);
216
269
}
270
+
271
+ carouselContainer.addEventListener('mousedown', handleDragStart);
272
+ window.addEventListener('mouseup', handleDragEnd);
273
+ window.addEventListener('mousemove', handleDragMove);
217
274
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
+
218
285
carouselContainer.addEventListener('wheel', handleWheel, { passive: false });
286
+
219
287
carouselContainer.addEventListener('mouseenter', stopAutoplay);
220
288
carouselContainer.addEventListener('mouseleave', startAutoplay);
221
289
document.addEventListener('visibilitychange', () => document.hidden ? stopAutoplay() : startAutoplay());
290
+
222
291
window.addEventListener('resize', setPositionByIndex);
223
292
224
293
setPositionByIndex();
0 commit comments