Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Zooming and Panning in Lightbox #387

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 86 additions & 31 deletions src/jquery.nanogallery2.core.js
Original file line number Diff line number Diff line change
Expand Up @@ -1466,6 +1466,10 @@
imageTransition : 'swipe2',
viewerTransitionMediaKind : 'img',
viewerZoom : true,
viewerRelativePinchZoom : false, // If false, pinch to zoom will always start at 1. True makes it work like expected.
viewerMinZoom : 0.2, // The minimum zoom scale allowed
viewerResetZoomAtMin : false, // When mim zoom is reached reset the view to non-zoomed mode?
viewerZoomOutScale : 3.0, // Zoom out scale when using relative zooming, smaller numbers make zooming out slower
viewerImageDisplay : '',
openOnStart : '',
viewerHideToolsDelay : 4000,
Expand Down Expand Up @@ -2612,7 +2616,8 @@
posX: 0, // position to center zoom in/out
posY: 0,
userFactor: 1, // user zoom factor (applied to the baseZoom factor)
isZooming: false
isZooming: false,
lastScale: 1, // The last scale factor requested by pinch to zoom, used for relative zoom
},
padding: { H: 0, V: 0 }, // padding for the image
window: { lastWidth: 0, lastHeight: 0 },
Expand Down Expand Up @@ -8480,22 +8485,31 @@
}
else {
// zoom out
G.VOM.zoom.userFactor -= 0.1;
ViewerZoomMin();
G.VOM.zoom.userFactor-=0.1;
if(ViewerZoomMin() && G.O.viewerResetZoomAtMin){
// Reset view
G.VOM.zoom.isZooming = false;
ResizeLightbox(true);
};
}
ViewerMediaSetPosAndZoom();
}

function ViewerZoomMax() {
if( G.VOM.zoom.userFactor > 3 ) {
G.VOM.zoom.userFactor = 3;
var item = G.VOM.content.current.NGY2Item();
var zoomBaseFactor = ViewerZoomBaseFactor(item);

if( G.VOM.zoom.userFactor > (1 / zoomBaseFactor) ) {
G.VOM.zoom.userFactor = (1 / zoomBaseFactor);
}
}
function ViewerZoomMin() {

if( G.VOM.zoom.userFactor < 0.2 ) {
G.VOM.zoom.userFactor = 0.2;
if( G.VOM.zoom.userFactor < G.O.viewerMinZoom ) {
G.VOM.zoom.userFactor = G.O.viewerMinZoom;
return true;
}
return false;
}


Expand Down Expand Up @@ -8526,6 +8540,40 @@
$media[0].style[G.CSStransformName] = 'translate(0px, "50%") ';
}

// Get Zoom Base Factor (image fill viewer)
function ViewerZoomBaseFactor(item){
var dpr = 1;
if( G.O.viewerImageDisplay == 'bestImageQuality' ) {
dpr = window.devicePixelRatio;
}

// retrieve the base zoom factor (image fill screen)
var zoomBaseFactorW = (G.VOM.window.lastWidth - G.VOM.padding.V) / (item.imageWidth / dpr);
var zoomBaseFactorH = (G.VOM.window.lastHeight - G.VOM.padding.H) / (item.imageHeight / dpr);
var zoomBaseFactor = Math.min(zoomBaseFactorW, zoomBaseFactorH);
if( zoomBaseFactor > 1 && G.O.viewerImageDisplay != 'upscale' ) {
// no upscale
zoomBaseFactor = 1;
}
return zoomBaseFactor;
}

// Get Media Dimensions
function ViewerMediaDimensions(item, isCurrent){
var zoomUserFactor = isCurrent == true ? G.VOM.zoom.userFactor : 1;

var dpr = 1;
if( G.O.viewerImageDisplay == 'bestImageQuality' ) {
dpr = window.devicePixelRatio;
}

var zoomBaseFactor = ViewerZoomBaseFactor(item);

var imageCurrentHeight = (item.imageHeight / dpr) * zoomUserFactor * zoomBaseFactor;
var imageCurrentWidth = (item.imageWidth / dpr) * zoomUserFactor * zoomBaseFactor;
return [imageCurrentHeight, imageCurrentWidth];
}

// Set position and size of ONE media container
function ViewerMediaSetPosAndZoomOne(content_item, isCurrent ) {

Expand All @@ -8544,25 +8592,12 @@
return;
}

// part 1: set the image size
var zoomUserFactor = isCurrent == true ? G.VOM.zoom.userFactor : 1;

var dpr = 1;
if( G.O.viewerImageDisplay == 'bestImageQuality' ) {
dpr = window.devicePixelRatio;
}

// retrieve the base zoom factor (image fill screen)
var zoomBaseFactorW = (G.VOM.window.lastWidth - G.VOM.padding.V) / (item.imageWidth / dpr);
var zoomBaseFactorH = (G.VOM.window.lastHeight - G.VOM.padding.H) / (item.imageHeight / dpr);
var zoomBaseFactor = Math.min(zoomBaseFactorW, zoomBaseFactorH);
if( zoomBaseFactor > 1 && G.O.viewerImageDisplay != 'upscale' ) {
// no upscale
zoomBaseFactor = 1;
}
// part 0: enforce zoom limits
ViewerZoomMin();
ViewerZoomMax();

var imageCurrentHeight = (item.imageHeight / dpr) * zoomUserFactor * zoomBaseFactor;
var imageCurrentWidth = (item.imageWidth / dpr) * zoomUserFactor * zoomBaseFactor;
// part 1: set the image size
var [imageCurrentHeight, imageCurrentWidth] = ViewerMediaDimensions(item, isCurrent);
$img.children().eq(1).css( {'height': imageCurrentHeight });
$img.children().eq(1).css( {'width': imageCurrentWidth });

Expand All @@ -8585,7 +8620,7 @@
}
G.VOM.zoom.posX = posX;
G.VOM.zoom.posY = posY;
ViewerImagePanSetPosition(G.VOM.panPosX, G.VOM.panPosY, $img, false);
ViewerImagePanSetPosition(item, G.VOM.panPosX, G.VOM.panPosY, $img, false);
}
// else {
//$img[0].style[G.CSStransformName]= 'translate3D('+ posX+'px, '+ posY+'px, 0) ';
Expand All @@ -8600,7 +8635,12 @@

// position the image depending on the zoom factor and the pan X/Y position
// IMG is the only media kind supporting zoom/pan
function ViewerImagePanSetPosition(posX, posY, imageContainer, savePosition ) {
function ViewerImagePanSetPosition(item, posX, posY, imageContainer, savePosition ) {
// limit panning so that edge of image cannot cross center line of viewer
var [imageCurrentHeight, imageCurrentWidth] = ViewerMediaDimensions(item, true);
posX = Math.max(-(imageCurrentWidth / 2), Math.min(posX, (imageCurrentWidth / 2)));
posY = Math.max(-(imageCurrentHeight / 2), Math.min(posY, (imageCurrentHeight / 2)));

if( savePosition ) {
G.VOM.panPosX = posX;
G.VOM.panPosY = posY;
Expand Down Expand Up @@ -8908,7 +8948,7 @@
switch( G.VOM.panMode ) {
case 'zoom':
// pan zoomed image
ViewerImagePanSetPosition(G.VOM.panPosX + ev.deltaX, G.VOM.panPosY + ev.deltaY, G.VOM.content.current.$media, false);
ViewerImagePanSetPosition(G.VOM.content.current.NGY2Item(), G.VOM.panPosX + ev.deltaX, G.VOM.panPosY + ev.deltaY, G.VOM.content.current.$media, false);
G.VOM.toolsHide();
break;

Expand Down Expand Up @@ -8954,7 +8994,7 @@
case 'zoom':
// PAN END in image zoom mode
G.VOM.timeImgChanged = new Date().getTime();
ViewerImagePanSetPosition( G.VOM.panPosX+ev.deltaX, G.VOM.panPosY+ev.deltaY, G.VOM.content.current.$media, true);
ViewerImagePanSetPosition( G.VOM.content.current.NGY2Item(), G.VOM.panPosX+ev.deltaX, G.VOM.panPosY+ev.deltaY, G.VOM.content.current.$media, true);
break;
case 'media':
var panY = false;
Expand Down Expand Up @@ -9107,15 +9147,30 @@
ev.srcEvent.stopPropagation();
ev.srcEvent.preventDefault(); // cancel mouseenter event
G.VOM.timeImgChanged = new Date().getTime();
G.VOM.zoom.lastScale = 1; // reset to 1
});
G.VOM.hammertime.on('pinch', function(ev) {
ev.srcEvent.stopPropagation();
ev.srcEvent.preventDefault(); // cancel mouseenter event

if( ViewerZoomStart() ) {
G.VOM.zoom.userFactor = ev.scale;
if(G.O.viewerRelativePinchZoom){
var scale = ev.scale;
if (scale < 1){
scale = 1 - ((1 - scale) * G.O.viewerZoomOutScale);
}
G.VOM.zoom.userFactor = G.VOM.zoom.userFactor + (scale - G.VOM.zoom.lastScale);
G.VOM.zoom.lastScale = scale;
}
else {
G.VOM.zoom.userFactor = ev.scale;
}
ViewerZoomMax();
ViewerZoomMin();
if (ViewerZoomMin() && G.O.viewerResetZoomAtMin){
// Reset view
G.VOM.zoom.isZooming = false;
ResizeLightbox(true);
}
ViewerMediaSetPosAndZoom(); // center media
}
});
Expand Down