Improved zoom and pan constraints

This commit is contained in:
Ian Gilman 2015-03-11 15:41:36 -07:00
parent 815cbd6019
commit 19ade7d76d
3 changed files with 89 additions and 24 deletions

View File

@ -596,8 +596,8 @@ $.Viewport.prototype = /** @lends OpenSeadragon.Viewport.prototype */{
return this.zoomTo(newZoom, null, true); return this.zoomTo(newZoom, null, true);
} }
if (Math.abs(newZoom - oldZoom) < 0.00000000001 || if (Math.abs(newZoom - oldZoom) < 0.00000001 ||
Math.abs(newBounds.width - oldBounds.width) < 0.00000000001) { Math.abs(newBounds.width - oldBounds.width) < 0.00000001) {
return this.panTo( center, immediately ); return this.panTo( center, immediately );
} }

View File

@ -57,7 +57,11 @@
} }
}); });
this.viewer.addHandler('viewport-change', function(event) { this.viewer.addHandler('zoom', function(event) {
self.applyConstraints();
});
this.viewer.addHandler('pan', function(event) {
self.applyConstraints(); self.applyConstraints();
}); });
@ -291,33 +295,69 @@
return; return;
} }
if (this.panBounds) { if (this.panBounds && !this.inZoomConstraints) {
var center = this.viewer.viewport.getCenter(true); var changed = false;
var viewBounds = this.viewer.viewport.getBounds(true); var viewBounds = this.viewer.viewport.getBounds();
var bounds = this.panBounds.clone(); var panBounds = this.panBounds.clone();
var left = bounds.x + (viewBounds.width / 2);
var top = bounds.y + (viewBounds.height / 2);
var right = (bounds.x + bounds.width) - (viewBounds.width / 2);
var bottom = (bounds.y + bounds.height) - (viewBounds.height / 2);
var x; if (viewBounds.x < panBounds.x - 0.00001) {
if (left <= right) { viewBounds.x = panBounds.x;
x = Math.max(left, Math.min(right, center.x)); changed = true;
} else {
x = bounds.x + (bounds.width / 2);
} }
var y; if (viewBounds.y < panBounds.y - 0.00001) {
if (top <= bottom) { viewBounds.y = panBounds.y;
y = Math.max(top, Math.min(bottom, center.y)); changed = true;
} else {
y = bounds.y + (bounds.height / 2);
} }
if (x !== center.x || y !== center.y) { if (viewBounds.width > panBounds.width + 0.00001) {
this.viewer.viewport.centerSpringX.current.value = x; viewBounds.width = panBounds.width;
this.viewer.viewport.centerSpringY.current.value = y; changed = true;
} }
if (viewBounds.height > panBounds.height + 0.00001) {
viewBounds.height = panBounds.height;
changed = true;
}
if (viewBounds.x + viewBounds.width > panBounds.x + panBounds.width + 0.00001) {
viewBounds.x = (panBounds.x + panBounds.width) - viewBounds.width;
changed = true;
}
if (viewBounds.y + viewBounds.height > panBounds.y + panBounds.height + 0.00001) {
viewBounds.y = (panBounds.y + panBounds.height) - viewBounds.height;
changed = true;
}
if (changed) {
this.inZoomConstraints = true;
this.viewer.viewport.fitBounds(viewBounds);
this.inZoomConstraints = false;
}
}
var zoom = this.viewer.viewport.getZoom();
var maxZoom = 2;
var zoomPoint = this.viewer.viewport.zoomPoint || this.viewer.viewport.getCenter();
var info = this.hitTest(zoomPoint);
if (info) {
var page = this.pages[info.index];
var tiledImage = page.hitTest(zoomPoint);
if (tiledImage) {
maxZoom = this.viewer.maxZoomLevel;
if (!maxZoom) {
var imageWidth = tiledImage.getContentSize().x;
var viewerWidth = this.$el.width();
maxZoom = imageWidth * this.viewer.maxZoomPixelRatio / viewerWidth;
maxZoom /= tiledImage.getBounds().width;
}
}
}
if (zoom > maxZoom) {
this.viewer.viewport.zoomSpring.target.value = maxZoom;
} }
}, },

View File

@ -105,6 +105,31 @@
}); });
}, },
// ----------
hitTest: function(pos) {
if (!this.details) {
return this.main.tiledImage;
}
var count = this.details.length;
var detail, box;
for (var i = 0; i < count; i++) {
detail = this.details[i];
if (!detail.tiledImage) {
continue;
}
box = detail.tiledImage.getBounds();
if (pos.x > box.x && pos.y > box.y && pos.x < box.x + box.width &&
pos.y < box.y + box.height) {
return detail.tiledImage;
}
}
return this.main.tiledImage;
},
// ---------- // ----------
getBounds: function() { getBounds: function() {
return this.bounds.clone(); return this.bounds.clone();