Merge pull request #1184 from avandecreme/zoomtowithref

Fix zoomTo/zoomBy with ref point and immediately to true. Fix #800
This commit is contained in:
Ian Gilman 2017-05-11 10:16:02 -07:00 committed by GitHub
commit fc254c1c6f
2 changed files with 132 additions and 76 deletions

View File

@ -805,7 +805,7 @@ $.Viewport.prototype = {
* @return {OpenSeadragon.Viewport} Chainable. * @return {OpenSeadragon.Viewport} Chainable.
* @fires OpenSeadragon.Viewer.event:zoom * @fires OpenSeadragon.Viewer.event:zoom
*/ */
zoomTo: function( zoom, refPoint, immediately ) { zoomTo: function(zoom, refPoint, immediately) {
this.zoomPoint = refPoint instanceof $.Point && this.zoomPoint = refPoint instanceof $.Point &&
!isNaN(refPoint.x) && !isNaN(refPoint.x) &&
@ -813,13 +813,16 @@ $.Viewport.prototype = {
refPoint : refPoint :
null; null;
if ( immediately ) { if (immediately) {
this.zoomSpring.resetTo( zoom ); var _this = this;
this._adjustCenterSpringsForZoomPoint(function() {
_this.zoomSpring.resetTo(zoom);
});
} else { } else {
this.zoomSpring.springTo( zoom ); this.zoomSpring.springTo(zoom);
} }
if( this.viewer ){ if (this.viewer) {
/** /**
* Raised when the viewport zoom level changes (see {@link OpenSeadragon.Viewport#zoomBy} and {@link OpenSeadragon.Viewport#zoomTo}). * Raised when the viewport zoom level changes (see {@link OpenSeadragon.Viewport#zoomBy} and {@link OpenSeadragon.Viewport#zoomTo}).
* *
@ -832,7 +835,7 @@ $.Viewport.prototype = {
* @property {Boolean} immediately * @property {Boolean} immediately
* @property {?Object} userData - Arbitrary subscriber-defined object. * @property {?Object} userData - Arbitrary subscriber-defined object.
*/ */
this.viewer.raiseEvent( 'zoom', { this.viewer.raiseEvent('zoom', {
zoom: zoom, zoom: zoom,
refPoint: refPoint, refPoint: refPoint,
immediately: immediately immediately: immediately
@ -938,25 +941,10 @@ $.Viewport.prototype = {
* @returns {Boolean} True if any change has been made, false otherwise. * @returns {Boolean} True if any change has been made, false otherwise.
*/ */
update: function() { update: function() {
var _this = this;
if (this.zoomPoint) { this._adjustCenterSpringsForZoomPoint(function() {
var oldZoomPixel = this.pixelFromPoint(this.zoomPoint, true); _this.zoomSpring.update();
this.zoomSpring.update(); });
var newZoomPixel = this.pixelFromPoint(this.zoomPoint, true);
var deltaZoomPixels = newZoomPixel.minus(oldZoomPixel);
var deltaZoomPoints = this.deltaPointsFromPixels(
deltaZoomPixels, true);
this.centerSpringX.shiftBy(deltaZoomPoints.x);
this.centerSpringY.shiftBy(deltaZoomPoints.y);
if (this.zoomSpring.isAtTargetValue()) {
this.zoomPoint = null;
}
} else {
this.zoomSpring.update();
}
this.centerSpringX.update(); this.centerSpringX.update();
this.centerSpringY.update(); this.centerSpringY.update();
@ -972,6 +960,27 @@ $.Viewport.prototype = {
return changed; return changed;
}, },
_adjustCenterSpringsForZoomPoint: function(zoomSpringHandler) {
if (this.zoomPoint) {
var oldZoomPixel = this.pixelFromPoint(this.zoomPoint, true);
zoomSpringHandler();
var newZoomPixel = this.pixelFromPoint(this.zoomPoint, true);
var deltaZoomPixels = newZoomPixel.minus(oldZoomPixel);
var deltaZoomPoints = this.deltaPointsFromPixels(
deltaZoomPixels, true);
this.centerSpringX.shiftBy(deltaZoomPoints.x);
this.centerSpringY.shiftBy(deltaZoomPoints.y);
if (this.zoomSpring.isAtTargetValue()) {
this.zoomPoint = null;
}
} else {
zoomSpringHandler();
}
},
/** /**
* Convert a delta (translation vector) from viewport coordinates to pixels * Convert a delta (translation vector) from viewport coordinates to pixels
* coordinates. This method does not take rotation into account. * coordinates. This method does not take rotation into account.

View File

@ -36,7 +36,7 @@
var TALL_PATH = '/test/data/tall.dzi'; var TALL_PATH = '/test/data/tall.dzi';
var WIDE_PATH = '/test/data/wide.dzi'; var WIDE_PATH = '/test/data/wide.dzi';
var testZoomLevels = [-1, 0, 0.1, 0.5, 4, 10]; var testZoomLevels = [0.1, 0.2, 0.5, 1, 4, 10];
var testPoints = [ var testPoints = [
new OpenSeadragon.Point(0, 0), new OpenSeadragon.Point(0, 0),
@ -59,7 +59,6 @@
var reopenViewerHelper = function(config) { var reopenViewerHelper = function(config) {
var expected, level, actual, i = 0; var expected, level, actual, i = 0;
var openHandler = function(event) { var openHandler = function(event) {
viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport; var viewport = viewer.viewport;
expected = config.processExpected(level, expected); expected = config.processExpected(level, expected);
actual = viewport[config.method](); actual = viewport[config.method]();
@ -70,7 +69,7 @@
"Test " + config.method + " with zoom level of " + level + ". Expected : " + expected + ", got " + actual "Test " + config.method + " with zoom level of " + level + ". Expected : " + expected + ", got " + actual
); );
i++; i++;
if(i < testZoomLevels.length){ if (i < testZoomLevels.length) {
level = expected = testZoomLevels[i]; level = expected = testZoomLevels[i];
var viewerConfig = { var viewerConfig = {
id: VIEWER_ID, id: VIEWER_ID,
@ -80,15 +79,22 @@
viewerConfig[config.property] = level; viewerConfig[config.property] = level;
viewer = OpenSeadragon(viewerConfig); viewer = OpenSeadragon(viewerConfig);
viewer.addHandler('open', openHandler); viewer.addOnceHandler('open', openHandler);
viewer.open(DZI_PATH); viewer.open(DZI_PATH);
} else { } else {
start(); start();
} }
}; };
viewer.addHandler('open', openHandler);
level = expected = testZoomLevels[i]; level = expected = testZoomLevels[i];
viewer[config.property] = level; var viewerConfig = {
id: VIEWER_ID,
prefixUrl: PREFIX_URL,
springStiffness: SPRING_STIFFNESS
};
viewerConfig[config.property] = level;
viewer = OpenSeadragon(viewerConfig);
viewer.addOnceHandler('open', openHandler);
viewer.open(DZI_PATH); viewer.open(DZI_PATH);
}; };
@ -211,15 +217,9 @@
property: 'defaultZoomLevel', property: 'defaultZoomLevel',
method: 'getHomeBounds', method: 'getHomeBounds',
processExpected: function(level, expected) { processExpected: function(level, expected) {
// Have to special case this to avoid dividing by 0
if(level === -1 || level === 0){
expected = new OpenSeadragon.Rect(0, 0, 1, 1);
} else {
var sideLength = 1.0 / viewer.defaultZoomLevel; // it's a square in this case var sideLength = 1.0 / viewer.defaultZoomLevel; // it's a square in this case
var position = 0.5 - (sideLength / 2.0); var position = 0.5 - (sideLength / 2.0);
expected = new OpenSeadragon.Rect(position, position, sideLength, sideLength); return new OpenSeadragon.Rect(position, position, sideLength, sideLength);
}
return expected;
} }
}); });
}); });
@ -333,44 +333,39 @@
// I don't use the helper for this one because it sets a couple more // I don't use the helper for this one because it sets a couple more
// properties that would need special casing. // properties that would need special casing.
asyncTest('getHomeZoomWithHomeFillsViewer', function() { asyncTest('getHomeZoomWithHomeFillsViewer', function() {
var expected, level, i = 0; var i = 0;
var openHandler = function(event) { var openHandler = function(event) {
viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport; var viewport = viewer.viewport;
viewport.zoomTo(ZOOM_FACTOR, null, true); viewport.zoomTo(ZOOM_FACTOR, null, true);
// Special cases for oddball levels
if (level === -1) {
expected = 0.25;
} else if(level === 0){
expected = 1;
}
equal( equal(
viewport.getHomeZoom(), viewport.getHomeZoom(),
expected, testZoomLevels[i],
"Test getHomeZoom with homeFillsViewer = true and default zoom level of " + expected "Test getHomeZoom with homeFillsViewer = true and default zoom level of " + testZoomLevels[i]
); );
i++; i++;
if(i < testZoomLevels.length){ if (i < testZoomLevels.length) {
level = expected = testZoomLevels[i];
viewer = OpenSeadragon({ viewer = OpenSeadragon({
id: VIEWER_ID, id: VIEWER_ID,
prefixUrl: PREFIX_URL, prefixUrl: PREFIX_URL,
springStiffness: SPRING_STIFFNESS, springStiffness: SPRING_STIFFNESS,
defaultZoomLevel: level, defaultZoomLevel: testZoomLevels[i],
homeFillsViewer: true homeFillsViewer: true
}); });
viewer.addHandler('open', openHandler); viewer.addOnceHandler('open', openHandler);
viewer.open(TALL_PATH); // use a different image for homeFillsViewer viewer.open(TALL_PATH); // use a different image for homeFillsViewer
} else { } else {
start(); start();
} }
}; };
viewer.addHandler('open', openHandler); viewer = OpenSeadragon({
level = expected = testZoomLevels[i]; id: VIEWER_ID,
viewer.homeFillsViewer = true; prefixUrl: PREFIX_URL,
viewer.defaultZoomLevel = expected; springStiffness: SPRING_STIFFNESS,
defaultZoomLevel: testZoomLevels[i],
homeFillsViewer: true
});
viewer.addOnceHandler('open', openHandler);
viewer.open(TALL_PATH); // use a different image for homeFillsViewer viewer.open(TALL_PATH); // use a different image for homeFillsViewer
}); });
@ -725,27 +720,18 @@
viewer.open(DZI_PATH); viewer.open(DZI_PATH);
}); });
asyncTest('zoomBy', function(){ asyncTest('zoomBy no ref point', function() {
var openHandler = function(event) { var openHandler = function(event) {
viewer.removeHandler('open', openHandler); viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport; var viewport = viewer.viewport;
for (var i = 0; i < testZoomLevels.length; i++){ for (var i = 0; i < testZoomLevels.length; i++) {
viewport.zoomBy(testZoomLevels[i], null, true); viewport.zoomBy(testZoomLevels[i], null, true);
propEqual( propEqual(
viewport.getZoom(), viewport.getZoom(),
testZoomLevels[i], testZoomLevels[i],
"Zoomed by the correct amount." "Zoomed by the correct amount."
); );
// now use a ref point
// TODO: check the ending position due to ref point
viewport.zoomBy(testZoomLevels[i], testPoints[i], true);
propEqual(
viewport.getZoom(),
testZoomLevels[i],
"Zoomed by the correct amount."
);
} }
start(); start();
@ -754,27 +740,88 @@
viewer.open(DZI_PATH); viewer.open(DZI_PATH);
}); });
asyncTest('zoomTo', function(){ asyncTest('zoomBy with ref point', function() {
var openHandler = function(event) { var openHandler = function(event) {
viewer.removeHandler('open', openHandler); viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport; var viewport = viewer.viewport;
for (var i = 0; i < testZoomLevels.length; i++){ var expectedCenters = [
new OpenSeadragon.Point(5, 5),
new OpenSeadragon.Point(6.996, 6.996),
new OpenSeadragon.Point(7.246, 6.996),
new OpenSeadragon.Point(7.246, 6.996),
new OpenSeadragon.Point(7.621, 7.371),
new OpenSeadragon.Point(7.621, 7.371),
];
for (var i = 0; i < testZoomLevels.length; i++) {
viewport.zoomBy(testZoomLevels[i], testPoints[i], true);
propEqual(
viewport.getZoom(),
testZoomLevels[i],
"Zoomed by the correct amount."
);
assertPointsEquals(
viewport.getCenter(),
expectedCenters[i],
1e-14,
"Panned to the correct location."
);
}
start();
};
viewer.addHandler('open', openHandler);
viewer.open(DZI_PATH);
});
asyncTest('zoomTo no ref point', function() {
var openHandler = function(event) {
viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport;
for (var i = 0; i < testZoomLevels.length; i++) {
viewport.zoomTo(testZoomLevels[i], null, true); viewport.zoomTo(testZoomLevels[i], null, true);
propEqual( propEqual(
viewport.getZoom(), viewport.getZoom(),
testZoomLevels[i], testZoomLevels[i],
"Zoomed to the correct level." "Zoomed to the correct level."
); );
}
// now use a ref point start();
// TODO: check the ending position due to ref point };
viewer.addHandler('open', openHandler);
viewer.open(DZI_PATH);
});
asyncTest('zoomTo with ref point', function() {
var openHandler = function(event) {
viewer.removeHandler('open', openHandler);
var viewport = viewer.viewport;
var expectedCenters = [
new OpenSeadragon.Point(5, 5),
new OpenSeadragon.Point(4.7505, 4.7505),
new OpenSeadragon.Point(4.6005, 4.7505),
new OpenSeadragon.Point(4.8455, 4.9955),
new OpenSeadragon.Point(5.2205, 5.3705),
new OpenSeadragon.Point(5.2205, 5.3705),
];
for (var i = 0; i < testZoomLevels.length; i++) {
viewport.zoomTo(testZoomLevels[i], testPoints[i], true); viewport.zoomTo(testZoomLevels[i], testPoints[i], true);
propEqual( propEqual(
viewport.getZoom(), viewport.getZoom(),
testZoomLevels[i], testZoomLevels[i],
"Zoomed to the correct level." "Zoomed to the correct level."
); );
assertPointsEquals(
viewport.getCenter(),
expectedCenters[i],
1e-14,
"Panned to the correct location."
);
} }
start(); start();