Merge branch 'openseadragon:master' into master

This commit is contained in:
Aiosa 2022-01-06 10:56:43 +01:00 committed by GitHub
commit 745a788d84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 1244 additions and 1398 deletions

View File

@ -197,7 +197,7 @@ module.exports = function(grunt) {
}, },
eslint: { eslint: {
options: { options: {
configFile: '.eslintrc.json' overrideConfigFile: '.eslintrc.json'
}, },
target: sources target: sources
}, },

View File

@ -1,7 +1,16 @@
OPENSEADRAGON CHANGELOG OPENSEADRAGON CHANGELOG
======================= =======================
3.0.0: (In progress) 3.0.1: (in progress)
* Added subPixelRoundingForTransparency Viewer option to address seams that can appear in semi-transparent images (#2075 @TanukiSharp)
* Added Viewer.isAnimating() (#2075 @TanukiSharp)
* Added isFullScreen method to Viewer (#2067 @JachiOnuoha)
* Fixed an issue where turning off panVertical or panHorizontal would not affect the panning keyboard combos (#2069 @JachiOnuoha)
* Cleaned up console.logs so that errors and warnings use console.error and console.warn as appropriate (#2073 @Abhishek-90)
* Improved documentation (#2067 @JachiOnuoha)
3.0.0:
* BREAKING CHANGE: Dropped support for older browsers (IE < 11) (#1872 #1949 #1951 @msalsbery, #1950 @rmontroy) * BREAKING CHANGE: Dropped support for older browsers (IE < 11) (#1872 #1949 #1951 @msalsbery, #1950 @rmontroy)
* BREAKING CHANGE: Removed deprecated OpenSeadragon.getEvent function (#1949 @msalsbery) * BREAKING CHANGE: Removed deprecated OpenSeadragon.getEvent function (#1949 @msalsbery)

2377
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "openseadragon", "name": "openseadragon",
"version": "2.4.2", "version": "3.0.0",
"description": "Provides a smooth, zoomable user interface for HTML/Javascript.", "description": "Provides a smooth, zoomable user interface for HTML/Javascript.",
"keywords": [ "keywords": [
"image", "image",
@ -29,15 +29,15 @@
"url": "https://github.com/openseadragon/openseadragon.git" "url": "https://github.com/openseadragon/openseadragon.git"
}, },
"devDependencies": { "devDependencies": {
"grunt": "^1.1.0", "grunt": "^1.4.1",
"grunt-contrib-clean": "^2.0.0", "grunt-contrib-clean": "^2.0.0",
"grunt-contrib-compress": "^1.6.0", "grunt-contrib-compress": "^2.0.0",
"grunt-contrib-concat": "^1.0.1", "grunt-contrib-concat": "^2.0.0",
"grunt-contrib-connect": "^2.1.0", "grunt-contrib-connect": "^3.0.0",
"grunt-contrib-qunit": "^3.1.0", "grunt-contrib-qunit": "^5.1.1",
"grunt-contrib-uglify": "^4.0.1", "grunt-contrib-uglify": "^5.0.1",
"grunt-contrib-watch": "^1.1.0", "grunt-contrib-watch": "^1.1.0",
"grunt-eslint": "^23.0.0", "grunt-eslint": "^24.0.0",
"grunt-git-describe": "^2.4.4", "grunt-git-describe": "^2.4.4",
"grunt-istanbul": "^0.8.0", "grunt-istanbul": "^0.8.0",
"grunt-text-replace": "^0.4.0", "grunt-text-replace": "^0.4.0",

View File

@ -344,15 +344,18 @@ $.Drawer.prototype = {
* where <code>rendered</code> is the context with the pre-drawn image. * where <code>rendered</code> is the context with the pre-drawn image.
* @param {Float} [scale=1] - Apply a scale to tile position and size. Defaults to 1. * @param {Float} [scale=1] - Apply a scale to tile position and size. Defaults to 1.
* @param {OpenSeadragon.Point} [translate] A translation vector to offset tile position * @param {OpenSeadragon.Point} [translate] A translation vector to offset tile position
* @param {Boolean} [shouldRoundPositionAndSize] - Tells whether to round
* position and size of tiles supporting alpha channel in non-transparency
* context.
*/ */
drawTile: function(tile, drawingHandler, useSketch, scale, translate) { drawTile: function(tile, drawingHandler, useSketch, scale, translate, shouldRoundPositionAndSize) {
$.console.assert(tile, '[Drawer.drawTile] tile is required'); $.console.assert(tile, '[Drawer.drawTile] tile is required');
$.console.assert(drawingHandler, '[Drawer.drawTile] drawingHandler is required'); $.console.assert(drawingHandler, '[Drawer.drawTile] drawingHandler is required');
if (this.useCanvas) { if (this.useCanvas) {
var context = this._getContext(useSketch); var context = this._getContext(useSketch);
scale = scale || 1; scale = scale || 1;
tile.drawCanvas(context, drawingHandler, scale, translate); tile.drawCanvas(context, drawingHandler, scale, translate, shouldRoundPositionAndSize);
} else { } else {
tile.drawHTML( this.canvas ); tile.drawHTML( this.canvas );
} }

View File

@ -446,8 +446,11 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
/** /**
* Determine whether arbitrary tile requests can be made against a service with the given profile * Determine whether arbitrary tile requests can be made against a service with the given profile
* @function * @function
* @param {array} profile - IIIF profile array * @param {Object} options
* @throws {Error} * @param {Array|String} options.profile
* @param {Number} options.version
* @param {String} options.extraFeatures
* @returns {Boolean}
*/ */
function canBeTiled ( options ) { function canBeTiled ( options ) {
var level0Profiles = [ var level0Profiles = [

View File

@ -209,6 +209,17 @@
* You can pass a CSS color value like "#FF8800". * You can pass a CSS color value like "#FF8800".
* When passing a function the tiledImage and canvas context are available as argument which is useful when you draw a gradient or pattern. * When passing a function the tiledImage and canvas context are available as argument which is useful when you draw a gradient or pattern.
* *
* @property {Object} [subPixelRoundingForTransparency=null]
* Determines when subpixel rounding should be applied for tiles when rendering images that support transparency.
* This property is a subpixel rounding enum values dictionary [{@link BROWSERS}] --> {@link SUBPIXEL_ROUNDING_OCCURRENCES}.
* The key is a {@link BROWSERS} value, and the value is one of {@link SUBPIXEL_ROUNDING_OCCURRENCES},
* indicating, for a given browser, when to apply subpixel rounding.
* Key '*' is the fallback value for any browser not specified in the dictionary.
* This property has a simple mode, and one can set it directly to
* {@link SUBPIXEL_ROUNDING_OCCURRENCES.NEVER}, {@link SUBPIXEL_ROUNDING_OCCURRENCES.ONLY_AT_REST} or {@link SUBPIXEL_ROUNDING_OCCURRENCES.ALWAYS}
* in order to apply this rule for all browser. The values {@link SUBPIXEL_ROUNDING_OCCURRENCES.ALWAYS} would be equivalent to { '*', SUBPIXEL_ROUNDING_OCCURRENCES.ALWAYS }.
* The default is {@link SUBPIXEL_ROUNDING_OCCURRENCES.NEVER} for all browsers, for backward compatibility reason.
*
* @property {Number} [degrees=0] * @property {Number} [degrees=0]
* Initial rotation. * Initial rotation.
* *
@ -1258,11 +1269,12 @@ function OpenSeadragon( options ){
flipped: false, flipped: false,
// APPEARANCE // APPEARANCE
opacity: 1, opacity: 1,
preload: false, preload: false,
compositeOperation: null, compositeOperation: null,
imageSmoothingEnabled: true, imageSmoothingEnabled: true,
placeholderFillStyle: null, placeholderFillStyle: null,
subPixelRoundingForTransparency: null,
//REFERENCE STRIP SETTINGS //REFERENCE STRIP SETTINGS
showReferenceStrip: false, showReferenceStrip: false,
@ -1403,6 +1415,20 @@ function OpenSeadragon( options ){
CHROMEEDGE: 7 CHROMEEDGE: 7
}, },
/**
* An enumeration of when subpixel rounding should occur.
* @static
* @type {Object}
* @property {Number} NEVER Never apply subpixel rounding for transparency.
* @property {Number} ONLY_AT_REST Do not apply subpixel rounding for transparency during animation (panning, zoom, rotation) and apply it once animation is over.
* @property {Number} ALWAYS Apply subpixel rounding for transparency during animation and when animation is over.
*/
SUBPIXEL_ROUNDING_OCCURRENCES: {
NEVER: 0,
ONLY_AT_REST: 1,
ALWAYS: 2
},
/** /**
* Keep track of which {@link Viewer}s have been created. * Keep track of which {@link Viewer}s have been created.
* - Key: {@link Element} to which a Viewer is attached. * - Key: {@link Element} to which a Viewer is attached.
@ -2316,7 +2342,7 @@ function OpenSeadragon( options ){
protocol !== "https:" )) { protocol !== "https:" )) {
onSuccess( request ); onSuccess( request );
} else { } else {
$.console.log( "AJAX request returned %d: %s", request.status, url ); $.console.error( "AJAX request returned %d: %s", request.status, url );
if ( $.isFunction( onError ) ) { if ( $.isFunction( onError ) ) {
onError( request ); onError( request );
@ -2347,7 +2373,7 @@ function OpenSeadragon( options ){
request.send(postData); request.send(postData);
} catch (e) { } catch (e) {
$.console.log( "%s while making AJAX request: %s", e.name, e.message ); $.console.error( "%s while making AJAX request: %s", e.name, e.message );
request.onreadystatechange = function(){}; request.onreadystatechange = function(){};

View File

@ -267,7 +267,7 @@ $.ReferenceStrip.prototype = {
*/ */
update: function () { update: function () {
if ( THIS[this.id].animating ) { if ( THIS[this.id].animating ) {
$.console.log( 'image reference strip update' ); // $.console.log( 'image reference strip update' );
return true; return true;
} }
return false; return false;

View File

@ -83,7 +83,7 @@ $.extend( $, /** @lends OpenSeadragon */{
string = container[ props[ i ] ]; string = container[ props[ i ] ];
if ( typeof ( string ) !== "string" ) { if ( typeof ( string ) !== "string" ) {
$.console.log( "Untranslated source string:", prop ); $.console.error( "Untranslated source string:", prop );
string = ""; // FIXME: this breaks gettext()-style convention, which would return source string = ""; // FIXME: this breaks gettext()-style convention, which would return source
} }

View File

@ -326,8 +326,11 @@ $.Tile.prototype = {
* where <code>rendered</code> is the context with the pre-drawn image. * where <code>rendered</code> is the context with the pre-drawn image.
* @param {Number} [scale=1] - Apply a scale to position and size * @param {Number} [scale=1] - Apply a scale to position and size
* @param {OpenSeadragon.Point} [translate] - A translation vector * @param {OpenSeadragon.Point} [translate] - A translation vector
* @param {Boolean} [shouldRoundPositionAndSize] - Tells whether to round
* position and size of tiles supporting alpha channel in non-transparency
* context.
*/ */
drawCanvas: function( context, drawingHandler, scale, translate ) { drawCanvas: function( context, drawingHandler, scale, translate, shouldRoundPositionAndSize ) {
var position = this.position.times($.pixelDensityRatio), var position = this.position.times($.pixelDensityRatio),
size = this.size.times($.pixelDensityRatio), size = this.size.times($.pixelDensityRatio),
@ -371,6 +374,14 @@ $.Tile.prototype = {
//an image with an alpha channel, then the only way //an image with an alpha channel, then the only way
//to avoid seeing the tile underneath is to clear the rectangle //to avoid seeing the tile underneath is to clear the rectangle
if (context.globalAlpha === 1 && this._hasTransparencyChannel()) { if (context.globalAlpha === 1 && this._hasTransparencyChannel()) {
if (shouldRoundPositionAndSize) {
// Round to the nearest whole pixel so we don't get seams from overlap.
position.x = Math.round(position.x);
position.y = Math.round(position.y);
size.x = Math.round(size.x);
size.y = Math.round(size.y);
}
//clearing only the inside of the rectangle occupied //clearing only the inside of the rectangle occupied
//by the png prevents edge flikering //by the png prevents edge flikering
context.clearRect( context.clearRect(

View File

@ -160,24 +160,25 @@ $.TiledImage = function( options ) {
_hasOpaqueTile: false, // Do we have even one fully opaque tile? _hasOpaqueTile: false, // Do we have even one fully opaque tile?
_tilesLoading: 0, // The number of pending tile requests. _tilesLoading: 0, // The number of pending tile requests.
//configurable settings //configurable settings
springStiffness: $.DEFAULT_SETTINGS.springStiffness, springStiffness: $.DEFAULT_SETTINGS.springStiffness,
animationTime: $.DEFAULT_SETTINGS.animationTime, animationTime: $.DEFAULT_SETTINGS.animationTime,
minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio, minZoomImageRatio: $.DEFAULT_SETTINGS.minZoomImageRatio,
wrapHorizontal: $.DEFAULT_SETTINGS.wrapHorizontal, wrapHorizontal: $.DEFAULT_SETTINGS.wrapHorizontal,
wrapVertical: $.DEFAULT_SETTINGS.wrapVertical, wrapVertical: $.DEFAULT_SETTINGS.wrapVertical,
immediateRender: $.DEFAULT_SETTINGS.immediateRender, immediateRender: $.DEFAULT_SETTINGS.immediateRender,
blendTime: $.DEFAULT_SETTINGS.blendTime, blendTime: $.DEFAULT_SETTINGS.blendTime,
alwaysBlend: $.DEFAULT_SETTINGS.alwaysBlend, alwaysBlend: $.DEFAULT_SETTINGS.alwaysBlend,
minPixelRatio: $.DEFAULT_SETTINGS.minPixelRatio, minPixelRatio: $.DEFAULT_SETTINGS.minPixelRatio,
smoothTileEdgesMinZoom: $.DEFAULT_SETTINGS.smoothTileEdgesMinZoom, smoothTileEdgesMinZoom: $.DEFAULT_SETTINGS.smoothTileEdgesMinZoom,
iOSDevice: $.DEFAULT_SETTINGS.iOSDevice, iOSDevice: $.DEFAULT_SETTINGS.iOSDevice,
debugMode: $.DEFAULT_SETTINGS.debugMode, debugMode: $.DEFAULT_SETTINGS.debugMode,
crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy, crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy,
ajaxWithCredentials: $.DEFAULT_SETTINGS.ajaxWithCredentials, ajaxWithCredentials: $.DEFAULT_SETTINGS.ajaxWithCredentials,
placeholderFillStyle: $.DEFAULT_SETTINGS.placeholderFillStyle, placeholderFillStyle: $.DEFAULT_SETTINGS.placeholderFillStyle,
opacity: $.DEFAULT_SETTINGS.opacity, opacity: $.DEFAULT_SETTINGS.opacity,
preload: $.DEFAULT_SETTINGS.preload, preload: $.DEFAULT_SETTINGS.preload,
compositeOperation: $.DEFAULT_SETTINGS.compositeOperation compositeOperation: $.DEFAULT_SETTINGS.compositeOperation,
subPixelRoundingForTransparency: $.DEFAULT_SETTINGS.subPixelRoundingForTransparency
}, options ); }, options );
this._preload = this.preload; this._preload = this.preload;
@ -1612,7 +1613,7 @@ function loadTile( tiledImage, tile, time ) {
*/ */
function onTileLoad( tiledImage, tile, time, image, errorMsg, tileRequest ) { function onTileLoad( tiledImage, tile, time, image, errorMsg, tileRequest ) {
if ( !image ) { if ( !image ) {
$.console.log( "Tile %s failed to load: %s - error: %s", tile, tile.url, errorMsg ); $.console.error( "Tile %s failed to load: %s - error: %s", tile, tile.url, errorMsg );
/** /**
* Triggered when a tile fails to load. * Triggered when a tile fails to load.
* *
@ -1638,7 +1639,7 @@ function onTileLoad( tiledImage, tile, time, image, errorMsg, tileRequest ) {
} }
if ( time < tiledImage.lastResetTime ) { if ( time < tiledImage.lastResetTime ) {
$.console.log( "Ignoring tile %s loaded before reset: %s", tile, tile.url ); $.console.warn( "Ignoring tile %s loaded before reset: %s", tile, tile.url );
tile.loading = false; tile.loading = false;
return; return;
} }
@ -1955,6 +1956,73 @@ function compareTiles( previousBest, tile ) {
return previousBest; return previousBest;
} }
/**
* @private
* @inner
* Defines the value for subpixel rounding to fallback to in case of missing or
* invalid value.
*/
var DEFAULT_SUBPIXEL_ROUNDING_RULE = $.SUBPIXEL_ROUNDING_OCCURRENCES.NEVER;
/**
* @private
* @inner
* Checks whether the input value is an invalid subpixel rounding enum value.
*
* @param {SUBPIXEL_ROUNDING_OCCURRENCES} value - The subpixel rounding enum value to check.
* @returns {Boolean} Returns true if the input value is none of the expected
* {@link SUBPIXEL_ROUNDING_OCCURRENCES.ALWAYS}, {@link SUBPIXEL_ROUNDING_OCCURRENCES.ONLY_AT_REST} or {@link SUBPIXEL_ROUNDING_OCCURRENCES.NEVER} value.
*/
function isSubPixelRoundingRuleUnknown(value) {
return value !== $.SUBPIXEL_ROUNDING_OCCURRENCES.ALWAYS &&
value !== $.SUBPIXEL_ROUNDING_OCCURRENCES.ONLY_AT_REST &&
value !== $.SUBPIXEL_ROUNDING_OCCURRENCES.NEVER;
}
/**
* @private
* @inner
* Ensures the returned value is always a valid subpixel rounding enum value,
* defaulting to {@link SUBPIXEL_ROUNDING_OCCURRENCES.NEVER} if input is missing or invalid.
*
* @param {SUBPIXEL_ROUNDING_OCCURRENCES} value - The subpixel rounding enum value to normalize.
* @returns {SUBPIXEL_ROUNDING_OCCURRENCES} Returns a valid subpixel rounding enum value.
*/
function normalizeSubPixelRoundingRule(value) {
if (isSubPixelRoundingRuleUnknown(value)) {
return DEFAULT_SUBPIXEL_ROUNDING_RULE;
}
return value;
}
/**
* @private
* @inner
* Ensures the returned value is always a valid subpixel rounding enum value,
* defaulting to 'NEVER' if input is missing or invalid.
*
* @param {Object} subPixelRoundingRules - A subpixel rounding enum values dictionary [{@link BROWSERS}] --> {@link SUBPIXEL_ROUNDING_OCCURRENCES}.
* @returns {SUBPIXEL_ROUNDING_OCCURRENCES} Returns the determined subpixel rounding enum value for the
* current browser.
*/
function determineSubPixelRoundingRule(subPixelRoundingRules) {
if (typeof subPixelRoundingRules === 'number') {
return normalizeSubPixelRoundingRule(subPixelRoundingRules);
}
if (!subPixelRoundingRules || !$.Browser) {
return DEFAULT_SUBPIXEL_ROUNDING_RULE;
}
var subPixelRoundingRule = subPixelRoundingRules[$.Browser.vendor];
if (isSubPixelRoundingRuleUnknown(subPixelRoundingRule)) {
subPixelRoundingRule = subPixelRoundingRules['*'];
}
return normalizeSubPixelRoundingRule(subPixelRoundingRule);
}
/** /**
* @private * @private
* @inner * @inner
@ -2103,9 +2171,20 @@ function drawTiles( tiledImage, lastDrawn ) {
tiledImage._drawer.drawRectangle(placeholderRect, fillStyle, useSketch); tiledImage._drawer.drawRectangle(placeholderRect, fillStyle, useSketch);
} }
var subPixelRoundingRule = determineSubPixelRoundingRule(tiledImage.subPixelRoundingForTransparency);
var shouldRoundPositionAndSize = false;
if (subPixelRoundingRule === $.SUBPIXEL_ROUNDING_OCCURRENCES.ALWAYS) {
shouldRoundPositionAndSize = true;
} else if (subPixelRoundingRule === $.SUBPIXEL_ROUNDING_OCCURRENCES.ONLY_AT_REST) {
var isAnimating = tiledImage.viewer && tiledImage.viewer.isAnimating();
shouldRoundPositionAndSize = !isAnimating;
}
for (var i = lastDrawn.length - 1; i >= 0; i--) { for (var i = lastDrawn.length - 1; i >= 0; i--) {
tile = lastDrawn[ i ]; tile = lastDrawn[ i ];
tiledImage._drawer.drawTile( tile, tiledImage._drawingHandler, useSketch, sketchScale, sketchTranslate ); tiledImage._drawer.drawTile( tile, tiledImage._drawingHandler, useSketch, sketchScale, sketchTranslate, shouldRoundPositionAndSize );
tile.beingDrawn = true; tile.beingDrawn = true;
if( tiledImage.viewer ){ if( tiledImage.viewer ){

View File

@ -713,6 +713,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
} }
THIS[ this.hash ].animating = false; THIS[ this.hash ].animating = false;
this.world.removeAll(); this.world.removeAll();
this.imageLoader.clear(); this.imageLoader.clear();
@ -1252,6 +1253,15 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
}, },
//
/**
* @function
* @returns {Boolean} returns true if the viewer is in fullscreen
*/
isFullScreen: function () {
return $.isFullScreen() && this.isFullPage();
},
/** /**
* @function * @function
* @param {Boolean} visible * @param {Boolean} visible
@ -1494,7 +1504,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
ajaxWithCredentials: queueItem.options.ajaxWithCredentials, ajaxWithCredentials: queueItem.options.ajaxWithCredentials,
loadTilesWithAjax: queueItem.options.loadTilesWithAjax, loadTilesWithAjax: queueItem.options.loadTilesWithAjax,
ajaxHeaders: queueItem.options.ajaxHeaders, ajaxHeaders: queueItem.options.ajaxHeaders,
debugMode: _this.debugMode debugMode: _this.debugMode,
subPixelRoundingForTransparency: _this.subPixelRoundingForTransparency
}); });
if (_this.collectionMode) { if (_this.collectionMode) {
@ -2348,6 +2359,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
} }
this.goToPage( next ); this.goToPage( next );
}, },
isAnimating: function () {
return THIS[ this.hash ].animating;
},
}); });
@ -2657,8 +2672,8 @@ function onCanvasKeyDown( event ) {
var canvasKeyDownEventArgs = { var canvasKeyDownEventArgs = {
originalEvent: event.originalEvent, originalEvent: event.originalEvent,
preventDefaultAction: false, preventDefaultAction: false,
preventVerticalPan: event.preventVerticalPan, preventVerticalPan: event.preventVerticalPan || !this.panVertical,
preventHorizontalPan: event.preventHorizontalPan preventHorizontalPan: event.preventHorizontalPan || !this.panHorizontal
}; };
/** /**
@ -2728,8 +2743,8 @@ function onCanvasKeyPress( event ) {
var canvasKeyPressEventArgs = { var canvasKeyPressEventArgs = {
originalEvent: event.originalEvent, originalEvent: event.originalEvent,
preventDefaultAction: false, preventDefaultAction: false,
preventVerticalPan: event.preventVerticalPan, preventVerticalPan: event.preventVerticalPan || !this.panVertical,
preventHorizontalPan: event.preventHorizontalPan preventHorizontalPan: event.preventHorizontalPan || !this.panHorizontal
}; };
// This event is documented in onCanvasKeyDown // This event is documented in onCanvasKeyDown
@ -2779,8 +2794,8 @@ function onCanvasKeyPress( event ) {
break; break;
case 97://a case 97://a
if (!canvasKeyPressEventArgs.preventHorizontalPan) { if (!canvasKeyPressEventArgs.preventHorizontalPan) {
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(-40, 0))); this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(-40, 0)));
this.viewport.applyConstraints(); this.viewport.applyConstraints();
} }
event.preventDefault = true; event.preventDefault = true;
break; break;
@ -3494,7 +3509,9 @@ function updateOnce( viewer ) {
animated = viewer.referenceStrip.update( viewer.viewport ) || animated; animated = viewer.referenceStrip.update( viewer.viewport ) || animated;
} }
if ( !THIS[ viewer.hash ].animating && animated ) { var currentAnimating = THIS[ viewer.hash ].animating;
if ( !currentAnimating && animated ) {
/** /**
* Raised when any spring animation starts (zoom, pan, etc.). * Raised when any spring animation starts (zoom, pan, etc.).
* *
@ -3508,7 +3525,13 @@ function updateOnce( viewer ) {
abortControlsAutoHide( viewer ); abortControlsAutoHide( viewer );
} }
if ( animated || THIS[ viewer.hash ].forceRedraw || viewer.world.needsDraw() ) { var isAnimationFinished = currentAnimating && !animated;
if ( isAnimationFinished ) {
THIS[ viewer.hash ].animating = false;
}
if ( animated || isAnimationFinished || THIS[ viewer.hash ].forceRedraw || viewer.world.needsDraw() ) {
drawWorld( viewer ); drawWorld( viewer );
viewer._drawOverlays(); viewer._drawOverlays();
if( viewer.navigator ){ if( viewer.navigator ){
@ -3532,7 +3555,7 @@ function updateOnce( viewer ) {
} }
} }
if ( THIS[ viewer.hash ].animating && !animated ) { if ( isAnimationFinished ) {
/** /**
* Raised when any spring animation ends (zoom, pan, etc.). * Raised when any spring animation ends (zoom, pan, etc.).
* *

View File

@ -27,7 +27,6 @@
tileSources: "../data/testpattern.dzi", tileSources: "../data/testpattern.dzi",
showNavigator:true showNavigator:true
}); });
</script> </script>
</body> </body>
</html> </html>