diff --git a/src/ViewerCore.tsx b/src/ViewerCore.tsx index 642aae5b..c055ec5d 100644 --- a/src/ViewerCore.tsx +++ b/src/ViewerCore.tsx @@ -614,8 +614,10 @@ export default (props: ViewerProps) => { if (Math.abs(scaleY) < minScale) { scaleY = minScale * directY; } - top = state.top + -direct * diffY / state.scaleX * scale * directX; - left = state.left + -direct * diffX / state.scaleY * scale * directY; + const scaleXDelta = Math.abs(scaleX) - Math.abs(state.scaleX); + const scaleYDelta = Math.abs(scaleY) - Math.abs(state.scaleY); + top = state.top - diffY / Math.abs(state.scaleY) * scaleYDelta; + left = state.left - diffX / Math.abs(state.scaleX) * scaleXDelta; width = state.width; height = state.height; } diff --git a/src/__tests__/viewer.test.tsx b/src/__tests__/viewer.test.tsx index 9c7a3ae4..cfbb76f6 100644 --- a/src/__tests__/viewer.test.tsx +++ b/src/__tests__/viewer.test.tsx @@ -156,8 +156,10 @@ function triggerMouseEvent(node, eventType, x = 0, y = 0) { node.dispatchEvent(clickEvent); } -function triggerWheel(node, eventType, deltaY) { +function triggerWheel(node, eventType, deltaY, x = 0, y = 0) { const wheelEvent = new WheelEvent(eventType, { + clientX: x, + clientY: y, view: window, bubbles: true, cancelable: true, @@ -986,6 +988,28 @@ describe('Viewer', () => { expect(getTransformValue(imgNode.style.transform).scaleX).toBe('0.88'); }); + it('keeps image position when zooming out at min scale', () => { + viewerHelper.new({ + minScale: 0.95, + }); + viewerHelper.open(); + + const imgNode = $$('img.react-viewer-image')[0]; + const viewer = $$('.react-viewer')[0]; + + triggerWheel(viewer, 'wheel', 1, 10, 20); + viewerHelper.skipAnimation(); + const transformAtMinScale = getTransformValue(imgNode.style.transform); + + triggerWheel(viewer, 'wheel', 1, 10, 20); + viewerHelper.skipAnimation(); + const transformAfterExtraZoomOut = getTransformValue(imgNode.style.transform); + + expect(transformAtMinScale.scaleX).toBe('0.95'); + expect(transformAfterExtraZoomOut.translateX).toBe(transformAtMinScale.translateX); + expect(transformAfterExtraZoomOut.translateY).toBe(transformAtMinScale.translateY); + }); + it('reset img when change images', () => { viewerHelper.new({ images: [{