@@ -49,6 +49,8 @@ import {
49
49
} from './Carousel.types'
50
50
import { carouselProps } from './carouselProps'
51
51
52
+ import { useDragging } from '@/composables'
53
+
52
54
export const Carousel = defineComponent ( {
53
55
name : 'VueCarousel' ,
54
56
props : carouselProps ,
@@ -331,11 +333,7 @@ export const Carousel = defineComponent({
331
333
/**
332
334
* Carousel Event listeners
333
335
*/
334
- let isTouch = false
335
- const startPosition = { x : 0 , y : 0 }
336
- const dragged = reactive ( { x : 0 , y : 0 } )
337
336
const isHover = ref ( false )
338
- const isDragging = ref ( false )
339
337
340
338
const handleMouseEnter = ( ) : void => {
341
339
isHover . value = true
@@ -376,93 +374,6 @@ export const Carousel = defineComponent({
376
374
document . removeEventListener ( 'keydown' , handleArrowKeys )
377
375
}
378
376
379
- function handleDragStart ( event : MouseEvent | TouchEvent ) : void {
380
- // Prevent drag initiation on input elements or if already sliding
381
- const targetTagName = ( event . target as HTMLElement ) . tagName
382
- if ( [ 'INPUT' , 'TEXTAREA' , 'SELECT' ] . includes ( targetTagName ) || isSliding . value ) {
383
- return
384
- }
385
-
386
- // Detect if the event is a touchstart or mousedown event
387
- isTouch = event . type === 'touchstart'
388
-
389
- // For mouse events, prevent default to avoid text selection
390
- if ( ! isTouch ) {
391
- event . preventDefault ( )
392
- if ( ( event as MouseEvent ) . button !== 0 ) {
393
- // Ignore non-left-click mouse events
394
- return
395
- }
396
- }
397
-
398
- // Initialize start positions for the drag
399
- startPosition . x = 'touches' in event ? event . touches [ 0 ] . clientX : event . clientX
400
- startPosition . y = 'touches' in event ? event . touches [ 0 ] . clientY : event . clientY
401
-
402
- // Attach event listeners for dragging and drag end
403
-
404
- const moveEvent = isTouch ? 'touchmove' : 'mousemove'
405
- const endEvent = isTouch ? 'touchend' : 'mouseup'
406
- document . addEventListener ( moveEvent , handleDragging , { passive : false } )
407
- document . addEventListener ( endEvent , handleDragEnd , { passive : true } )
408
- }
409
-
410
- const handleDragging = throttle ( ( event : TouchEvent | MouseEvent ) : void => {
411
- isDragging . value = true
412
-
413
- // Get the current position based on the interaction type (touch or mouse)
414
- const currentX = 'touches' in event ? event . touches [ 0 ] . clientX : event . clientX
415
- const currentY = 'touches' in event ? event . touches [ 0 ] . clientY : event . clientY
416
-
417
- // Calculate deltas for X and Y axes
418
- dragged . x = currentX - startPosition . x
419
- dragged . y = currentY - startPosition . y
420
-
421
- const draggedSlides = getDraggedSlidesCount ( {
422
- isVertical : isVertical . value ,
423
- isReversed : isReversed . value ,
424
- dragged,
425
- effectiveSlideSize : effectiveSlideSize . value ,
426
- threshold : config . dragThreshold ,
427
- } )
428
-
429
- activeSlideIndex . value = config . wrapAround
430
- ? currentSlideIndex . value + draggedSlides
431
- : getNumberInRange ( {
432
- val : currentSlideIndex . value + draggedSlides ,
433
- max : maxSlideIndex . value ,
434
- min : minSlideIndex . value ,
435
- } )
436
-
437
- // Emit a drag event for further customization if needed
438
- emit ( 'drag' , { deltaX : dragged . x , deltaY : dragged . y } )
439
- } )
440
-
441
- function handleDragEnd ( ) : void {
442
- handleDragging . cancel ( )
443
-
444
- // Prevent accidental clicks when there is a slide drag
445
- if ( activeSlideIndex . value !== currentSlideIndex . value && ! isTouch ) {
446
- const preventClick = ( e : MouseEvent ) => {
447
- e . preventDefault ( )
448
- window . removeEventListener ( 'click' , preventClick )
449
- }
450
- window . addEventListener ( 'click' , preventClick )
451
- }
452
-
453
- slideTo ( activeSlideIndex . value )
454
-
455
- // Reset drag state
456
- dragged . x = 0
457
- dragged . y = 0
458
- isDragging . value = false
459
-
460
- const moveEvent = isTouch ? 'touchmove' : 'mousemove'
461
- const endEvent = isTouch ? 'touchend' : 'mouseup'
462
- document . removeEventListener ( moveEvent , handleDragging )
463
- document . removeEventListener ( endEvent , handleDragEnd )
464
- }
465
-
466
377
/**
467
378
* Autoplay
468
379
*/
@@ -497,6 +408,33 @@ export const Carousel = defineComponent({
497
408
*/
498
409
const isSliding = ref ( false )
499
410
411
+ const onDrag = ( { deltaX, deltaY } : { deltaX : number ; deltaY : number } ) => {
412
+ const draggedSlides = getDraggedSlidesCount ( {
413
+ isVertical : isVertical . value ,
414
+ isReversed : isReversed . value ,
415
+ dragged : { x : deltaX , y : deltaY } ,
416
+ effectiveSlideSize : effectiveSlideSize . value ,
417
+ } )
418
+
419
+ activeSlideIndex . value = config . wrapAround
420
+ ? currentSlideIndex . value + draggedSlides
421
+ : getNumberInRange ( {
422
+ val : currentSlideIndex . value + draggedSlides ,
423
+ max : maxSlideIndex . value ,
424
+ min : minSlideIndex . value ,
425
+ } )
426
+
427
+ emit ( 'drag' , { deltaX, deltaY } )
428
+ }
429
+ const onDragEnd = ( ) => {
430
+ slideTo ( activeSlideIndex . value )
431
+ }
432
+ const { dragged, isDragging, handleDragStart } = useDragging ( {
433
+ isSliding : isSliding . value ,
434
+ onDrag,
435
+ onDragEnd,
436
+ } )
437
+
500
438
function slideTo ( slideIndex : number , skipTransition = false ) : void {
501
439
if ( ! skipTransition && isSliding . value ) {
502
440
return
0 commit comments