@@ -14,6 +14,7 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
1414 limitToOriginalSize : false ,
1515 maxRatio : 3 ,
1616 minRatio : 1 ,
17+ panOnMouseMove : false ,
1718 toggle : true ,
1819 containerClass : 'swiper-zoom-container' ,
1920 zoomedSlideClass : 'swiper-slide-zoomed' ,
@@ -26,6 +27,9 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
2627
2728 let currentScale = 1 ;
2829 let isScaling = false ;
30+ let isPanningWithMouse = false ;
31+ let mousePanStart = { x : 0 , y : 0 } ;
32+ const mousePanSensitivity = - 3 ; // Negative to invert pan direction
2933 let fakeGestureTouched ;
3034 let fakeGestureMoved ;
3135 let preventZoomOut ;
@@ -262,6 +266,9 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
262266 image . touchesStart . y = event . pageY ;
263267 }
264268 function onTouchMove ( e ) {
269+ const isMouseEvent = e . pointerType === 'mouse' ;
270+ const isMousePan = isMouseEvent && swiper . params . zoom . panOnMouseMove ;
271+
265272 if ( ! eventWithinSlide ( e ) || ! eventWithinZoomContainer ( e ) ) {
266273 return ;
267274 }
@@ -270,8 +277,14 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
270277 return ;
271278 }
272279 if ( ! image . isTouched || ! gesture . slideEl ) {
280+ if ( isMousePan ) onMouseMove ( e ) ;
281+ return ;
282+ }
283+ if ( isMousePan ) {
284+ onMouseMove ( e ) ;
273285 return ;
274286 }
287+
275288 if ( ! image . isMoved ) {
276289 image . width = gesture . imageEl . offsetWidth || gesture . imageEl . clientWidth ;
277290 image . height = gesture . imageEl . offsetHeight || gesture . imageEl . clientHeight ;
@@ -435,6 +448,53 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
435448 gesture . originY = 0 ;
436449 }
437450 }
451+ function onMouseMove ( e ) {
452+ // Only pan if zoomed in and mouse panning is enabled
453+ if ( currentScale <= 1 || ! gesture . imageWrapEl ) return ;
454+ if ( ! eventWithinSlide ( e ) || ! eventWithinZoomContainer ( e ) ) return ;
455+
456+ const currentTransform = window . getComputedStyle ( gesture . imageWrapEl ) . transform ;
457+ const matrix = new window . DOMMatrix ( currentTransform ) ;
458+
459+ if ( ! isPanningWithMouse ) {
460+ isPanningWithMouse = true ;
461+ mousePanStart . x = e . clientX ;
462+ mousePanStart . y = e . clientY ;
463+
464+ image . startX = matrix . e ;
465+ image . startY = matrix . f ;
466+ image . width = gesture . imageEl . offsetWidth || gesture . imageEl . clientWidth ;
467+ image . height = gesture . imageEl . offsetHeight || gesture . imageEl . clientHeight ;
468+
469+ gesture . slideWidth = gesture . slideEl . offsetWidth ;
470+ gesture . slideHeight = gesture . slideEl . offsetHeight ;
471+ return ;
472+ }
473+
474+ const deltaX = ( e . clientX - mousePanStart . x ) * mousePanSensitivity ;
475+ const deltaY = ( e . clientY - mousePanStart . y ) * mousePanSensitivity ;
476+
477+ const scaledWidth = image . width * currentScale ;
478+ const scaledHeight = image . height * currentScale ;
479+ const slideWidth = gesture . slideWidth ;
480+ const slideHeight = gesture . slideHeight ;
481+
482+ const minX = Math . min ( slideWidth / 2 - scaledWidth / 2 , 0 ) ;
483+ const maxX = - minX ;
484+ const minY = Math . min ( slideHeight / 2 - scaledHeight / 2 , 0 ) ;
485+ const maxY = - minY ;
486+
487+ const newX = Math . max ( Math . min ( image . startX + deltaX , maxX ) , minX ) ;
488+ const newY = Math . max ( Math . min ( image . startY + deltaY , maxY ) , minY ) ;
489+
490+ gesture . imageWrapEl . style . transitionDuration = '0ms' ;
491+ gesture . imageWrapEl . style . transform = `translate3d(${ newX } px, ${ newY } px, 0)` ;
492+
493+ mousePanStart . x = e . clientX ;
494+ mousePanStart . y = e . clientY ;
495+ image . startX = newX ;
496+ image . startY = newY ;
497+ }
438498
439499 function zoomIn ( e ) {
440500 const zoom = swiper . zoom ;
@@ -598,6 +658,15 @@ export default function Zoom({ swiper, extendParams, on, emit }) {
598658 gesture . slideEl = undefined ;
599659 gesture . originX = 0 ;
600660 gesture . originY = 0 ;
661+
662+ if ( swiper . params . zoom . panOnMouseMove ) {
663+ mousePanStart = { x : 0 , y : 0 } ;
664+ if ( isPanningWithMouse ) {
665+ isPanningWithMouse = false ;
666+ image . startX = 0 ;
667+ image . startY = 0 ;
668+ }
669+ }
601670 }
602671
603672 // Toggle Zoom
0 commit comments