Remove code duplication in Viewport.applyConstraints.

This commit is contained in:
Antoine Vandecreme 2016-05-10 18:49:55 -04:00
parent 521e020b9a
commit e4c29d649b
3 changed files with 122 additions and 72 deletions

View File

@ -555,40 +555,27 @@ $.Viewport.prototype = {
},
/**
* Enforces the minZoom, maxZoom and visibilityRatio constraints by
* zooming and panning to the closest acceptable zoom and location.
* @function
* @param {Boolean} [immediately=false]
* @return {OpenSeadragon.Viewport} Chainable.
* @fires OpenSeadragon.Viewer.event:constrain
*/
applyConstraints: function( immediately ) {
var actualZoom = this.getZoom(),
constrainedZoom = Math.max(
Math.min( actualZoom, this.getMaxZoom() ),
this.getMinZoom()
),
bounds,
constrainedBounds;
if ( actualZoom != constrainedZoom ) {
this.zoomTo( constrainedZoom, this.zoomPoint, immediately );
}
bounds = this.getBoundsNoRotate();
constrainedBounds = this._applyBoundaryConstraints( bounds, immediately );
if ( bounds.x !== constrainedBounds.x || bounds.y !== constrainedBounds.y || immediately ){
this.fitBounds( constrainedBounds, immediately );
}
applyConstraints: function(immediately) {
this.fitBoundsWithConstraints(this.getBounds(), immediately);
return this;
},
/**
* Equivalent to {@link OpenSeadragon.Viewport#applyConstraints}
* @function
* @param {Boolean} immediately
* @param {Boolean} [immediately=false]
* @return {OpenSeadragon.Viewport} Chainable.
* @fires OpenSeadragon.Viewer.event:constrain
*/
ensureVisible: function( immediately ) {
return this.applyConstraints( immediately );
ensureVisible: function(immediately) {
return this.applyConstraints(immediately);
},
/**
@ -670,29 +657,41 @@ $.Viewport.prototype = {
},
/**
* Makes the viewport zoom and pan so that the specified bounds take
* as much space as possible in the viewport.
* Note: this method ignores the constraints (minZoom, maxZoom and
* visibilityRatio).
* Use {@link OpenSeadragon.Viewport#fitBoundsWithConstraints} to enforce
* them.
* @function
* @param {OpenSeadragon.Rect} bounds
* @param {Boolean} immediately
* @param {Boolean} [immediately=false]
* @return {OpenSeadragon.Viewport} Chainable.
*/
fitBounds: function( bounds, immediately ) {
return this._fitBounds( bounds, {
fitBounds: function(bounds, immediately) {
return this._fitBounds(bounds, {
immediately: immediately,
constraints: false
} );
});
},
/**
* Makes the viewport zoom and pan so that the specified bounds take
* as much space as possible in the viewport while enforcing the constraints
* (minZoom, maxZoom and visibilityRatio).
* Note: because this method enforces the constraints, part of the
* provided bounds may end up outside of the viewport.
* Use {@link OpenSeadragon.Viewport#fitBounds} to ignore them.
* @function
* @param {OpenSeadragon.Rect} bounds
* @param {Boolean} immediately
* @param {Boolean} [immediately=false]
* @return {OpenSeadragon.Viewport} Chainable.
*/
fitBoundsWithConstraints: function( bounds, immediately ) {
return this._fitBounds( bounds, {
fitBoundsWithConstraints: function(bounds, immediately) {
return this._fitBounds(bounds, {
immediately: immediately,
constraints: true
} );
});
},
/**

View File

@ -678,45 +678,20 @@
} );
// ----------
asyncTest( 'Viewer: preventDefaultAction', function () {
var $canvas = $( viewer.element ).find( '.openseadragon-canvas' ).not( '.navigator .openseadragon-canvas' ),
tracker = viewer.innerTracker,
origClickHandler,
origDragHandler,
dragCount = 10,
originalZoom = 0,
originalBounds = null;
var onOpen = function ( event ) {
viewer.removeHandler( 'open', onOpen );
// Hook viewer events to set preventDefaultAction
origClickHandler = tracker.clickHandler;
tracker.clickHandler = function ( event ) {
event.preventDefaultAction = true;
return origClickHandler( event );
};
origDragHandler = tracker.dragHandler;
tracker.dragHandler = function ( event ) {
event.preventDefaultAction = true;
return origDragHandler( event );
};
originalZoom = viewer.viewport.getZoom();
originalBounds = viewer.viewport.getBounds();
var event = {
clientX:1,
clientY:1
};
asyncTest('Viewer: preventDefaultAction', function() {
var $canvas = $(viewer.element).find('.openseadragon-canvas')
.not('.navigator .openseadragon-canvas');
var tracker = viewer.innerTracker;
var epsilon = 0.0000001;
function simulateClickAndDrag() {
$canvas.simulate( 'focus', event );
// Drag to pan
Util.simulateViewerClickWithDrag( {
viewer: viewer,
widthFactor: 0.25,
heightFactor: 0.25,
dragCount: dragCount,
dragCount: 10,
dragDx: 1,
dragDy: 1
} );
@ -730,20 +705,57 @@
dragDy: 0
} );
$canvas.simulate( 'blur', event );
}
var zoom = viewer.viewport.getZoom(),
bounds = viewer.viewport.getBounds();
var onOpen = function() {
viewer.removeHandler('open', onOpen);
equal( zoom, originalZoom, "Zoom prevented" );
ok( bounds.x == originalBounds.x && bounds.y == originalBounds.y, 'Pan prevented' );
// Hook viewer events to set preventDefaultAction
var origClickHandler = tracker.clickHandler;
tracker.clickHandler = function(event) {
event.preventDefaultAction = true;
return origClickHandler(event);
};
var origDragHandler = tracker.dragHandler;
tracker.dragHandler = function(event) {
event.preventDefaultAction = true;
return origDragHandler(event);
};
var originalZoom = viewer.viewport.getZoom();
var originalBounds = viewer.viewport.getBounds();
simulateClickAndDrag();
var zoom = viewer.viewport.getZoom();
var bounds = viewer.viewport.getBounds();
Util.assessNumericValue(zoom, originalZoom, epsilon,
"Zoom should be prevented");
Util.assertRectangleEquals(bounds, originalBounds, epsilon,
'Pan should be prevented');
tracker.clickHandler = origClickHandler;
tracker.dragHandler = origDragHandler;
simulateClickAndDrag();
var zoom = viewer.viewport.getZoom();
var bounds = viewer.viewport.getBounds();
Util.assessNumericValue(zoom, 0.002, epsilon,
"Zoom should not be prevented");
Util.assertRectangleEquals(
bounds,
new OpenSeadragon.Rect(-250, -0.25, 500, 0.5),
epsilon,
'Pan should not be prevented');
viewer.close();
start();
};
viewer.addHandler( 'open', onOpen );
viewer.open( '/test/data/testpattern.dzi' );
} );
viewer.addHandler('open', onOpen);
viewer.open('/test/data/testpattern.dzi');
});
// ----------
asyncTest( 'EventSource/MouseTracker/Viewer: event.originalEvent event.userData canvas-drag canvas-drag-end canvas-release canvas-click', function () {

View File

@ -409,7 +409,7 @@
viewer.open(DZI_PATH);
});
asyncTest('ensureVisible', function(){
asyncTest('ensureVisible', function() {
var openHandler = function(event) {
viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport;
@ -427,6 +427,45 @@
viewer.open(DZI_PATH);
});
asyncTest('applyConstraints', function() {
var openHandler = function() {
viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport;
viewport.fitBounds(new OpenSeadragon.Rect(1, 1, 1, 1), true);
viewport.visibilityRatio = 0.3;
viewport.applyConstraints(true);
var bounds = viewport.getBounds();
Util.assertRectangleEquals(
bounds,
new OpenSeadragon.Rect(0.7, 0.7, 1, 1),
EPSILON,
"Viewport.applyConstraints should move viewport.");
start();
};
viewer.addHandler('open', openHandler);
viewer.open(DZI_PATH);
});
asyncTest('applyConstraints with rotation', function() {
var openHandler = function() {
viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport;
viewport.setRotation(45);
viewport.fitBounds(new OpenSeadragon.Rect(1, 1, 1, 1), true);
viewport.applyConstraints(true);
var bounds = viewport.getBounds();
Util.assertRectangleEquals(
bounds,
new OpenSeadragon.Rect(1, 0, Math.sqrt(2), Math.sqrt(2), 45),
EPSILON,
"Viewport.applyConstraints with rotation should move viewport.");
start();
};
viewer.addHandler('open', openHandler);
viewer.open(DZI_PATH);
});
// Fit bounds tests
var testRectsFitBounds = [
new OpenSeadragon.Rect(0, -0.75, 0.5, 1),