mirror of
https://github.com/openseadragon/openseadragon.git
synced 2025-02-22 01:33:14 +03:00
Expanding support for improved simple configuration options. Allows OpenSeadragon Viewer to be more flexibly created without direct use of API, rather focuses more on inversion of control by introspection of options passed to OpenSeadragon constructor.
This commit is contained in:
parent
1a7c96732f
commit
26fb61cc65
@ -6,7 +6,7 @@
|
|||||||
PROJECT: openseadragon
|
PROJECT: openseadragon
|
||||||
BUILD_MAJOR: 0
|
BUILD_MAJOR: 0
|
||||||
BUILD_MINOR: 9
|
BUILD_MINOR: 9
|
||||||
BUILD_ID: 12
|
BUILD_ID: 13
|
||||||
BUILD: ${PROJECT}.${BUILD_MAJOR}.${BUILD_MINOR}.${BUILD_ID}
|
BUILD: ${PROJECT}.${BUILD_MAJOR}.${BUILD_MINOR}.${BUILD_ID}
|
||||||
VERSION: ${BUILD_MAJOR}.${BUILD_MINOR}.${BUILD_ID}
|
VERSION: ${BUILD_MAJOR}.${BUILD_MINOR}.${BUILD_ID}
|
||||||
|
|
||||||
|
173
openseadragon.js
173
openseadragon.js
@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* @version OpenSeadragon 0.9.12
|
* @version OpenSeadragon 0.9.13
|
||||||
*
|
*
|
||||||
* @fileOverview
|
* @fileOverview
|
||||||
* <h2>
|
* <h2>
|
||||||
@ -2410,6 +2410,10 @@ $.Control.prototype = {
|
|||||||
}( OpenSeadragon ));
|
}( OpenSeadragon ));
|
||||||
|
|
||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
|
// dictionary from hash to private properties
|
||||||
|
var THIS = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The main point of entry into creating a zoomable image on the page.
|
* The main point of entry into creating a zoomable image on the page.
|
||||||
@ -2457,6 +2461,8 @@ $.Viewer = function( options ) {
|
|||||||
$.extend( true, this, {
|
$.extend( true, this, {
|
||||||
id: options.id,
|
id: options.id,
|
||||||
xmlPath: null,
|
xmlPath: null,
|
||||||
|
dzis: null,
|
||||||
|
images: null,
|
||||||
prefixUrl: '',
|
prefixUrl: '',
|
||||||
controls: [],
|
controls: [],
|
||||||
overlays: [],
|
overlays: [],
|
||||||
@ -2538,19 +2544,25 @@ $.Viewer = function( options ) {
|
|||||||
this.canvas = $.makeNeutralElement( "div" );
|
this.canvas = $.makeNeutralElement( "div" );
|
||||||
|
|
||||||
//Used for toggling between fullscreen and default container size
|
//Used for toggling between fullscreen and default container size
|
||||||
|
//TODO: these can be closure private and shared across Viewer
|
||||||
|
// instances.
|
||||||
this.bodyWidth = document.body.style.width;
|
this.bodyWidth = document.body.style.width;
|
||||||
this.bodyHeight = document.body.style.height;
|
this.bodyHeight = document.body.style.height;
|
||||||
this.bodyOverflow = document.body.style.overflow;
|
this.bodyOverflow = document.body.style.overflow;
|
||||||
this.docOverflow = document.documentElement.style.overflow;
|
this.docOverflow = document.documentElement.style.overflow;
|
||||||
this.previousBody = [];
|
this.previousBody = [];
|
||||||
|
|
||||||
this._fsBoundsDelta = new $.Point( 1, 1 );
|
this.hash = Math.random();
|
||||||
this._prevContainerSize = null;
|
|
||||||
this._lastOpenStartTime = 0;
|
THIS[ this.hash ] = {
|
||||||
this._lastOpenEndTime = 0;
|
"fsBoundsDelta": new $.Point( 1, 1 ),
|
||||||
this._animating = false;
|
"prevContainerSize": null,
|
||||||
this._forceRedraw = false;
|
"lastOpenStartTime": 0,
|
||||||
this._mouseInside = false;
|
"lastOpenEndTime": 0,
|
||||||
|
"animating": false,
|
||||||
|
"forceRedraw": false,
|
||||||
|
"mouseInside": false
|
||||||
|
};
|
||||||
|
|
||||||
this.innerTracker = new $.MouseTracker({
|
this.innerTracker = new $.MouseTracker({
|
||||||
element: this.canvas,
|
element: this.canvas,
|
||||||
@ -2614,13 +2626,15 @@ $.Viewer = function( options ) {
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Navigation Controls
|
// Navigation Controls
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
this._group = null;
|
$.extend( THIS[ this.hash ], {
|
||||||
// whether we should be continuously zooming
|
"group": null,
|
||||||
this._zooming = false;
|
// whether we should be continuously zooming
|
||||||
// how much we should be continuously zooming by
|
"zooming": false,
|
||||||
this._zoomFactor = null;
|
// how much we should be continuously zooming by
|
||||||
this._lastZoomTime = null;
|
"zoomFactor": null,
|
||||||
|
"lastZoomTime": null
|
||||||
|
});
|
||||||
|
|
||||||
var beginZoomingInHandler = $.delegate( this, beginZoomingIn ),
|
var beginZoomingInHandler = $.delegate( this, beginZoomingIn ),
|
||||||
endZoomingHandler = $.delegate( this, endZooming ),
|
endZoomingHandler = $.delegate( this, endZooming ),
|
||||||
doSingleZoomInHandler = $.delegate( this, doSingleZoomIn ),
|
doSingleZoomInHandler = $.delegate( this, doSingleZoomIn ),
|
||||||
@ -2686,7 +2700,7 @@ $.Viewer = function( options ) {
|
|||||||
if ( this.config.showNavigationControl ) {
|
if ( this.config.showNavigationControl ) {
|
||||||
this.navControl.style.marginRight = "4px";
|
this.navControl.style.marginRight = "4px";
|
||||||
this.navControl.style.marginBottom = "4px";
|
this.navControl.style.marginBottom = "4px";
|
||||||
this.addControl(this.navControl, $.ControlAnchor.BOTTOM_RIGHT);
|
this.addControl( this.navControl, $.ControlAnchor.BOTTOM_RIGHT );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( i = 0; i < this.customControls.length; i++ ) {
|
for ( i = 0; i < this.customControls.length; i++ ) {
|
||||||
@ -2707,8 +2721,47 @@ $.Viewer = function( options ) {
|
|||||||
beginControlsAutoHide( _this );
|
beginControlsAutoHide( _this );
|
||||||
}, 1 ); // initial fade out
|
}, 1 ); // initial fade out
|
||||||
|
|
||||||
if ( this.xmlPath ){
|
var initialTileSource,
|
||||||
|
customTileSource;
|
||||||
|
|
||||||
|
if ( this.xmlPath ){
|
||||||
|
//Deprecated option. Now it is preferred to use the tileSources option
|
||||||
this.openDzi( this.xmlPath );
|
this.openDzi( this.xmlPath );
|
||||||
|
} else if ( this.tileSources ){
|
||||||
|
//tileSource is a complex option...
|
||||||
|
//It can be a string, object, function, or an array of any of these.
|
||||||
|
//A string implies a DZI
|
||||||
|
//An object implies a simple image
|
||||||
|
//A function implies a custom tile source callback
|
||||||
|
//An array implies a sequence of tile sources which can be any of the
|
||||||
|
//above
|
||||||
|
if( $.isArray( this.tileSources ) ){
|
||||||
|
if( $.isPlainObject( this.tileSources[ 0 ] ) ){
|
||||||
|
//This is a non-sequenced legacy tile source
|
||||||
|
initialTileSource = this.tileSources;
|
||||||
|
} else {
|
||||||
|
//Sequenced tile source
|
||||||
|
initialTileSource = this.tileSources[ 0 ];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initialTileSource = this.tileSources
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $.type( initialTileSource ) == 'string ') {
|
||||||
|
//Standard DZI format
|
||||||
|
this.openDzi( initialTileSource );
|
||||||
|
} else if ( $.isArray( initialTileSource ) ){
|
||||||
|
//Legacy image pyramid
|
||||||
|
this.open( new $.LegacyTileSource( initialTileSource ) );
|
||||||
|
} else if ( $.isFunction( initialTileSource ) ){
|
||||||
|
//Custom tile source
|
||||||
|
customTileSource = new TileSource();
|
||||||
|
customTileSource.getTileUrl = initialTileSource;
|
||||||
|
this.open( customTileSource );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -2813,23 +2866,23 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// to ignore earlier opens
|
// to ignore earlier opens
|
||||||
this._lastOpenStartTime = +new Date();
|
THIS[ this.hash ].lastOpenStartTime = +new Date();
|
||||||
|
|
||||||
window.setTimeout( function () {
|
window.setTimeout( function () {
|
||||||
if ( _this._lastOpenStartTime > _this._lastOpenEndTime ) {
|
if ( THIS[ _this.hash ].lastOpenStartTime > THIS[ _this.hash ].lastOpenEndTime ) {
|
||||||
_this._setMessage( $.getString( "Messages.Loading" ) );
|
THIS[ _this.hash ].setMessage( $.getString( "Messages.Loading" ) );
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
this._lastOpenEndTime = +new Date();
|
THIS[ this.hash ].lastOpenEndTime = +new Date();
|
||||||
this.canvas.innerHTML = "";
|
this.canvas.innerHTML = "";
|
||||||
this._prevContainerSize = $.getElementSize( this.container );
|
THIS[ this.hash ].prevContainerSize = $.getElementSize( this.container );
|
||||||
|
|
||||||
if( source ){
|
if( source ){
|
||||||
this.source = source;
|
this.source = source;
|
||||||
}
|
}
|
||||||
this.viewport = new $.Viewport(
|
this.viewport = new $.Viewport(
|
||||||
this._prevContainerSize,
|
THIS[ this.hash ].prevContainerSize,
|
||||||
this.source.dimensions,
|
this.source.dimensions,
|
||||||
this.config
|
this.config
|
||||||
);
|
);
|
||||||
@ -2841,8 +2894,8 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
|
|
||||||
//this.profiler = new $.Profiler();
|
//this.profiler = new $.Profiler();
|
||||||
|
|
||||||
this._animating = false;
|
THIS[ this.hash ].animating = false;
|
||||||
this._forceRedraw = true;
|
THIS[ this.hash ].forceRedraw = true;
|
||||||
scheduleUpdate( this, updateMulti );
|
scheduleUpdate( this, updateMulti );
|
||||||
|
|
||||||
for ( i = 0; i < this.overlayControls.length; i++ ) {
|
for ( i = 0; i < this.overlayControls.length; i++ ) {
|
||||||
@ -3035,7 +3088,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
document.body.removeChild( document.body.childNodes[ 0 ] );
|
document.body.removeChild( document.body.childNodes[ 0 ] );
|
||||||
}
|
}
|
||||||
body.appendChild( this.container );
|
body.appendChild( this.container );
|
||||||
this._prevContainerSize = $.getWindowSize();
|
THIS[ this.hash ].prevContainerSize = $.getWindowSize();
|
||||||
|
|
||||||
// mouse will be inside container now
|
// mouse will be inside container now
|
||||||
$.delegate( this, onContainerEnter )();
|
$.delegate( this, onContainerEnter )();
|
||||||
@ -3061,7 +3114,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
document.body.appendChild( this.previousBody.shift() );
|
document.body.appendChild( this.previousBody.shift() );
|
||||||
}
|
}
|
||||||
this.element.appendChild( this.container );
|
this.element.appendChild( this.container );
|
||||||
this._prevContainerSize = $.getElementSize( this.element );
|
THIS[ this.hash ].prevContainerSize = $.getElementSize( this.element );
|
||||||
|
|
||||||
// mouse will likely be outside now
|
// mouse will likely be outside now
|
||||||
$.delegate( this, onContainerExit )();
|
$.delegate( this, onContainerExit )();
|
||||||
@ -3070,11 +3123,11 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
|
|
||||||
if ( this.viewport ) {
|
if ( this.viewport ) {
|
||||||
oldBounds = this.viewport.getBounds();
|
oldBounds = this.viewport.getBounds();
|
||||||
this.viewport.resize( this._prevContainerSize );
|
this.viewport.resize( THIS[ this.hash ].prevContainerSize );
|
||||||
newBounds = this.viewport.getBounds();
|
newBounds = this.viewport.getBounds();
|
||||||
|
|
||||||
if ( fullPage ) {
|
if ( fullPage ) {
|
||||||
this._fsBoundsDelta = new $.Point(
|
THIS[ this.hash ].fsBoundsDelta = new $.Point(
|
||||||
newBounds.width / oldBounds.width,
|
newBounds.width / oldBounds.width,
|
||||||
newBounds.height / oldBounds.height
|
newBounds.height / oldBounds.height
|
||||||
);
|
);
|
||||||
@ -3082,15 +3135,15 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
this.viewport.update();
|
this.viewport.update();
|
||||||
this.viewport.zoomBy(
|
this.viewport.zoomBy(
|
||||||
Math.max(
|
Math.max(
|
||||||
this._fsBoundsDelta.x,
|
THIS[ this.hash ].fsBoundsDelta.x,
|
||||||
this._fsBoundsDelta.y
|
THIS[ this.hash ].fsBoundsDelta.y
|
||||||
),
|
),
|
||||||
null,
|
null,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._forceRedraw = true;
|
THIS[ this.hash ].forceRedraw = true;
|
||||||
this.raiseEvent( "resize", this );
|
this.raiseEvent( "resize", this );
|
||||||
updateOnce( this );
|
updateOnce( this );
|
||||||
}
|
}
|
||||||
@ -3128,7 +3181,7 @@ function scheduleUpdate( viewer, updateFunc, prevUpdateTime ){
|
|||||||
targetTime,
|
targetTime,
|
||||||
deltaTime;
|
deltaTime;
|
||||||
|
|
||||||
if ( this._animating ) {
|
if ( THIS[ viewer.hash ].animating ) {
|
||||||
return window.setTimeout( function(){
|
return window.setTimeout( function(){
|
||||||
updateFunc( viewer );
|
updateFunc( viewer );
|
||||||
}, 1 );
|
}, 1 );
|
||||||
@ -3250,8 +3303,8 @@ function onCanvasScroll( tracker, position, scroll, shift ) {
|
|||||||
|
|
||||||
function onContainerExit( tracker, position, buttonDownElement, buttonDownAny ) {
|
function onContainerExit( tracker, position, buttonDownElement, buttonDownAny ) {
|
||||||
if ( !buttonDownElement ) {
|
if ( !buttonDownElement ) {
|
||||||
this._mouseInside = false;
|
THIS[ this.hash ].mouseInside = false;
|
||||||
if ( !this._animating ) {
|
if ( !THIS[ this.hash ].animating ) {
|
||||||
beginControlsAutoHide( this );
|
beginControlsAutoHide( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3259,15 +3312,15 @@ function onContainerExit( tracker, position, buttonDownElement, buttonDownAny )
|
|||||||
|
|
||||||
function onContainerRelease( tracker, position, insideElementPress, insideElementRelease ) {
|
function onContainerRelease( tracker, position, insideElementPress, insideElementRelease ) {
|
||||||
if ( !insideElementRelease ) {
|
if ( !insideElementRelease ) {
|
||||||
this._mouseInside = false;
|
THIS[ this.hash ].mouseInside = false;
|
||||||
if ( !this._animating ) {
|
if ( !THIS[ this.hash ].animating ) {
|
||||||
beginControlsAutoHide( this );
|
beginControlsAutoHide( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny ) {
|
function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny ) {
|
||||||
this._mouseInside = true;
|
THIS[ this.hash ].mouseInside = true;
|
||||||
abortControlsAutoHide( this );
|
abortControlsAutoHide( this );
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3313,15 +3366,15 @@ function updateOnce( viewer ) {
|
|||||||
//viewer.profiler.beginUpdate();
|
//viewer.profiler.beginUpdate();
|
||||||
|
|
||||||
containerSize = $.getElementSize( viewer.container );
|
containerSize = $.getElementSize( viewer.container );
|
||||||
if ( !containerSize.equals( viewer._prevContainerSize ) ) {
|
if ( !containerSize.equals( THIS[ viewer.hash ].prevContainerSize ) ) {
|
||||||
// maintain image position
|
// maintain image position
|
||||||
viewer.viewport.resize( containerSize, true );
|
viewer.viewport.resize( containerSize, true );
|
||||||
viewer._prevContainerSize = containerSize;
|
THIS[ viewer.hash ].prevContainerSize = containerSize;
|
||||||
viewer.raiseEvent( "resize" );
|
viewer.raiseEvent( "resize" );
|
||||||
}
|
}
|
||||||
|
|
||||||
animated = viewer.viewport.update();
|
animated = viewer.viewport.update();
|
||||||
if ( !viewer._animating && animated ) {
|
if ( !THIS[ viewer.hash ].animating && animated ) {
|
||||||
viewer.raiseEvent( "animationstart" );
|
viewer.raiseEvent( "animationstart" );
|
||||||
abortControlsAutoHide( viewer );
|
abortControlsAutoHide( viewer );
|
||||||
}
|
}
|
||||||
@ -3329,20 +3382,20 @@ function updateOnce( viewer ) {
|
|||||||
if ( animated ) {
|
if ( animated ) {
|
||||||
viewer.drawer.update();
|
viewer.drawer.update();
|
||||||
viewer.raiseEvent( "animation" );
|
viewer.raiseEvent( "animation" );
|
||||||
} else if ( viewer._forceRedraw || viewer.drawer.needsUpdate() ) {
|
} else if ( THIS[ viewer.hash ].forceRedraw || viewer.drawer.needsUpdate() ) {
|
||||||
viewer.drawer.update();
|
viewer.drawer.update();
|
||||||
viewer._forceRedraw = false;
|
THIS[ viewer.hash ].forceRedraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( viewer._animating && !animated ) {
|
if ( THIS[ viewer.hash ].animating && !animated ) {
|
||||||
viewer.raiseEvent( "animationfinish" );
|
viewer.raiseEvent( "animationfinish" );
|
||||||
|
|
||||||
if ( !viewer._mouseInside ) {
|
if ( !THIS[ viewer.hash ].mouseInside ) {
|
||||||
beginControlsAutoHide( viewer );
|
beginControlsAutoHide( viewer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer._animating = animated;
|
THIS[ viewer.hash ].animating = animated;
|
||||||
|
|
||||||
//viewer.profiler.endUpdate();
|
//viewer.profiler.endUpdate();
|
||||||
};
|
};
|
||||||
@ -3357,21 +3410,21 @@ function resolveUrl( prefix, url ) {
|
|||||||
|
|
||||||
|
|
||||||
function beginZoomingIn() {
|
function beginZoomingIn() {
|
||||||
this._lastZoomTime = +new Date();
|
THIS[ this.hash ].lastZoomTime = +new Date();
|
||||||
this._zoomFactor = this.config.zoomPerSecond;
|
THIS[ this.hash ].zoomFactor = this.config.zoomPerSecond;
|
||||||
this._zooming = true;
|
THIS[ this.hash ].zooming = true;
|
||||||
scheduleZoom( this );
|
scheduleZoom( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
function beginZoomingOut() {
|
function beginZoomingOut() {
|
||||||
this._lastZoomTime = +new Date();
|
THIS[ this.hash ].lastZoomTime = +new Date();
|
||||||
this._zoomFactor = 1.0 / this.config.zoomPerSecond;
|
THIS[ this.hash ].zoomFactor = 1.0 / this.config.zoomPerSecond;
|
||||||
this._zooming = true;
|
THIS[ this.hash ].zooming = true;
|
||||||
scheduleZoom( this );
|
scheduleZoom( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
function endZooming() {
|
function endZooming() {
|
||||||
this._zooming = false;
|
THIS[ this.hash ].zooming = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function scheduleZoom( viewer ) {
|
function scheduleZoom( viewer ) {
|
||||||
@ -3383,21 +3436,21 @@ function doZoom() {
|
|||||||
deltaTime,
|
deltaTime,
|
||||||
adjustFactor;
|
adjustFactor;
|
||||||
|
|
||||||
if ( this._zooming && this.viewport) {
|
if ( THIS[ this.hash ].zooming && this.viewport) {
|
||||||
currentTime = +new Date();
|
currentTime = +new Date();
|
||||||
deltaTime = currentTime - this._lastZoomTime;
|
deltaTime = currentTime - THIS[ this.hash ].lastZoomTime;
|
||||||
adjustedFactor = Math.pow( this._zoomFactor, deltaTime / 1000 );
|
adjustedFactor = Math.pow( THIS[ this.hash ].zoomFactor, deltaTime / 1000 );
|
||||||
|
|
||||||
this.viewport.zoomBy( adjustedFactor );
|
this.viewport.zoomBy( adjustedFactor );
|
||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
this._lastZoomTime = currentTime;
|
THIS[ this.hash ].lastZoomTime = currentTime;
|
||||||
scheduleZoom( this );
|
scheduleZoom( this );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function doSingleZoomIn() {
|
function doSingleZoomIn() {
|
||||||
if ( this.viewport ) {
|
if ( this.viewport ) {
|
||||||
this._zooming = false;
|
THIS[ this.hash ].zooming = false;
|
||||||
this.viewport.zoomBy(
|
this.viewport.zoomBy(
|
||||||
this.config.zoomPerClick / 1.0
|
this.config.zoomPerClick / 1.0
|
||||||
);
|
);
|
||||||
@ -3407,7 +3460,7 @@ function doSingleZoomIn() {
|
|||||||
|
|
||||||
function doSingleZoomOut() {
|
function doSingleZoomOut() {
|
||||||
if ( this.viewport ) {
|
if ( this.viewport ) {
|
||||||
this._zooming = false;
|
THIS[ this.hash ].zooming = false;
|
||||||
this.viewport.zoomBy(
|
this.viewport.zoomBy(
|
||||||
1.0 / this.config.zoomPerClick
|
1.0 / this.config.zoomPerClick
|
||||||
);
|
);
|
||||||
@ -3930,7 +3983,7 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, {
|
|||||||
* @property {Number} maxLevel
|
* @property {Number} maxLevel
|
||||||
* @property {Array} files
|
* @property {Array} files
|
||||||
*/
|
*/
|
||||||
$.LegacyTileSource = function( files, viewer ) {
|
$.LegacyTileSource = function( files ) {
|
||||||
var width = files[ files.length - 1 ].width,
|
var width = files[ files.length - 1 ].width,
|
||||||
height = files[ files.length - 1 ].height;
|
height = files[ files.length - 1 ].height;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
* @property {Number} maxLevel
|
* @property {Number} maxLevel
|
||||||
* @property {Array} files
|
* @property {Array} files
|
||||||
*/
|
*/
|
||||||
$.LegacyTileSource = function( files, viewer ) {
|
$.LegacyTileSource = function( files ) {
|
||||||
var width = files[ files.length - 1 ].width,
|
var width = files[ files.length - 1 ].width,
|
||||||
height = files[ files.length - 1 ].height;
|
height = files[ files.length - 1 ].height;
|
||||||
|
|
||||||
|
169
src/viewer.js
169
src/viewer.js
@ -1,5 +1,9 @@
|
|||||||
|
|
||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
|
// dictionary from hash to private properties
|
||||||
|
var THIS = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* The main point of entry into creating a zoomable image on the page.
|
* The main point of entry into creating a zoomable image on the page.
|
||||||
@ -47,6 +51,8 @@ $.Viewer = function( options ) {
|
|||||||
$.extend( true, this, {
|
$.extend( true, this, {
|
||||||
id: options.id,
|
id: options.id,
|
||||||
xmlPath: null,
|
xmlPath: null,
|
||||||
|
dzis: null,
|
||||||
|
images: null,
|
||||||
prefixUrl: '',
|
prefixUrl: '',
|
||||||
controls: [],
|
controls: [],
|
||||||
overlays: [],
|
overlays: [],
|
||||||
@ -128,19 +134,25 @@ $.Viewer = function( options ) {
|
|||||||
this.canvas = $.makeNeutralElement( "div" );
|
this.canvas = $.makeNeutralElement( "div" );
|
||||||
|
|
||||||
//Used for toggling between fullscreen and default container size
|
//Used for toggling between fullscreen and default container size
|
||||||
|
//TODO: these can be closure private and shared across Viewer
|
||||||
|
// instances.
|
||||||
this.bodyWidth = document.body.style.width;
|
this.bodyWidth = document.body.style.width;
|
||||||
this.bodyHeight = document.body.style.height;
|
this.bodyHeight = document.body.style.height;
|
||||||
this.bodyOverflow = document.body.style.overflow;
|
this.bodyOverflow = document.body.style.overflow;
|
||||||
this.docOverflow = document.documentElement.style.overflow;
|
this.docOverflow = document.documentElement.style.overflow;
|
||||||
this.previousBody = [];
|
this.previousBody = [];
|
||||||
|
|
||||||
this._fsBoundsDelta = new $.Point( 1, 1 );
|
this.hash = Math.random();
|
||||||
this._prevContainerSize = null;
|
|
||||||
this._lastOpenStartTime = 0;
|
THIS[ this.hash ] = {
|
||||||
this._lastOpenEndTime = 0;
|
"fsBoundsDelta": new $.Point( 1, 1 ),
|
||||||
this._animating = false;
|
"prevContainerSize": null,
|
||||||
this._forceRedraw = false;
|
"lastOpenStartTime": 0,
|
||||||
this._mouseInside = false;
|
"lastOpenEndTime": 0,
|
||||||
|
"animating": false,
|
||||||
|
"forceRedraw": false,
|
||||||
|
"mouseInside": false
|
||||||
|
};
|
||||||
|
|
||||||
this.innerTracker = new $.MouseTracker({
|
this.innerTracker = new $.MouseTracker({
|
||||||
element: this.canvas,
|
element: this.canvas,
|
||||||
@ -204,13 +216,15 @@ $.Viewer = function( options ) {
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Navigation Controls
|
// Navigation Controls
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
this._group = null;
|
$.extend( THIS[ this.hash ], {
|
||||||
// whether we should be continuously zooming
|
"group": null,
|
||||||
this._zooming = false;
|
// whether we should be continuously zooming
|
||||||
// how much we should be continuously zooming by
|
"zooming": false,
|
||||||
this._zoomFactor = null;
|
// how much we should be continuously zooming by
|
||||||
this._lastZoomTime = null;
|
"zoomFactor": null,
|
||||||
|
"lastZoomTime": null
|
||||||
|
});
|
||||||
|
|
||||||
var beginZoomingInHandler = $.delegate( this, beginZoomingIn ),
|
var beginZoomingInHandler = $.delegate( this, beginZoomingIn ),
|
||||||
endZoomingHandler = $.delegate( this, endZooming ),
|
endZoomingHandler = $.delegate( this, endZooming ),
|
||||||
doSingleZoomInHandler = $.delegate( this, doSingleZoomIn ),
|
doSingleZoomInHandler = $.delegate( this, doSingleZoomIn ),
|
||||||
@ -276,7 +290,7 @@ $.Viewer = function( options ) {
|
|||||||
if ( this.config.showNavigationControl ) {
|
if ( this.config.showNavigationControl ) {
|
||||||
this.navControl.style.marginRight = "4px";
|
this.navControl.style.marginRight = "4px";
|
||||||
this.navControl.style.marginBottom = "4px";
|
this.navControl.style.marginBottom = "4px";
|
||||||
this.addControl(this.navControl, $.ControlAnchor.BOTTOM_RIGHT);
|
this.addControl( this.navControl, $.ControlAnchor.BOTTOM_RIGHT );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( i = 0; i < this.customControls.length; i++ ) {
|
for ( i = 0; i < this.customControls.length; i++ ) {
|
||||||
@ -297,8 +311,47 @@ $.Viewer = function( options ) {
|
|||||||
beginControlsAutoHide( _this );
|
beginControlsAutoHide( _this );
|
||||||
}, 1 ); // initial fade out
|
}, 1 ); // initial fade out
|
||||||
|
|
||||||
if ( this.xmlPath ){
|
var initialTileSource,
|
||||||
|
customTileSource;
|
||||||
|
|
||||||
|
if ( this.xmlPath ){
|
||||||
|
//Deprecated option. Now it is preferred to use the tileSources option
|
||||||
this.openDzi( this.xmlPath );
|
this.openDzi( this.xmlPath );
|
||||||
|
} else if ( this.tileSources ){
|
||||||
|
//tileSource is a complex option...
|
||||||
|
//It can be a string, object, function, or an array of any of these.
|
||||||
|
//A string implies a DZI
|
||||||
|
//An object implies a simple image
|
||||||
|
//A function implies a custom tile source callback
|
||||||
|
//An array implies a sequence of tile sources which can be any of the
|
||||||
|
//above
|
||||||
|
if( $.isArray( this.tileSources ) ){
|
||||||
|
if( $.isPlainObject( this.tileSources[ 0 ] ) ){
|
||||||
|
//This is a non-sequenced legacy tile source
|
||||||
|
initialTileSource = this.tileSources;
|
||||||
|
} else {
|
||||||
|
//Sequenced tile source
|
||||||
|
initialTileSource = this.tileSources[ 0 ];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initialTileSource = this.tileSources
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $.type( initialTileSource ) == 'string ') {
|
||||||
|
//Standard DZI format
|
||||||
|
this.openDzi( initialTileSource );
|
||||||
|
} else if ( $.isArray( initialTileSource ) ){
|
||||||
|
//Legacy image pyramid
|
||||||
|
this.open( new $.LegacyTileSource( initialTileSource ) );
|
||||||
|
} else if ( $.isFunction( initialTileSource ) ){
|
||||||
|
//Custom tile source
|
||||||
|
customTileSource = new TileSource();
|
||||||
|
customTileSource.getTileUrl = initialTileSource;
|
||||||
|
this.open( customTileSource );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -403,23 +456,23 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// to ignore earlier opens
|
// to ignore earlier opens
|
||||||
this._lastOpenStartTime = +new Date();
|
THIS[ this.hash ].lastOpenStartTime = +new Date();
|
||||||
|
|
||||||
window.setTimeout( function () {
|
window.setTimeout( function () {
|
||||||
if ( _this._lastOpenStartTime > _this._lastOpenEndTime ) {
|
if ( THIS[ _this.hash ].lastOpenStartTime > THIS[ _this.hash ].lastOpenEndTime ) {
|
||||||
_this._setMessage( $.getString( "Messages.Loading" ) );
|
THIS[ _this.hash ].setMessage( $.getString( "Messages.Loading" ) );
|
||||||
}
|
}
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
this._lastOpenEndTime = +new Date();
|
THIS[ this.hash ].lastOpenEndTime = +new Date();
|
||||||
this.canvas.innerHTML = "";
|
this.canvas.innerHTML = "";
|
||||||
this._prevContainerSize = $.getElementSize( this.container );
|
THIS[ this.hash ].prevContainerSize = $.getElementSize( this.container );
|
||||||
|
|
||||||
if( source ){
|
if( source ){
|
||||||
this.source = source;
|
this.source = source;
|
||||||
}
|
}
|
||||||
this.viewport = new $.Viewport(
|
this.viewport = new $.Viewport(
|
||||||
this._prevContainerSize,
|
THIS[ this.hash ].prevContainerSize,
|
||||||
this.source.dimensions,
|
this.source.dimensions,
|
||||||
this.config
|
this.config
|
||||||
);
|
);
|
||||||
@ -431,8 +484,8 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
|
|
||||||
//this.profiler = new $.Profiler();
|
//this.profiler = new $.Profiler();
|
||||||
|
|
||||||
this._animating = false;
|
THIS[ this.hash ].animating = false;
|
||||||
this._forceRedraw = true;
|
THIS[ this.hash ].forceRedraw = true;
|
||||||
scheduleUpdate( this, updateMulti );
|
scheduleUpdate( this, updateMulti );
|
||||||
|
|
||||||
for ( i = 0; i < this.overlayControls.length; i++ ) {
|
for ( i = 0; i < this.overlayControls.length; i++ ) {
|
||||||
@ -625,7 +678,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
document.body.removeChild( document.body.childNodes[ 0 ] );
|
document.body.removeChild( document.body.childNodes[ 0 ] );
|
||||||
}
|
}
|
||||||
body.appendChild( this.container );
|
body.appendChild( this.container );
|
||||||
this._prevContainerSize = $.getWindowSize();
|
THIS[ this.hash ].prevContainerSize = $.getWindowSize();
|
||||||
|
|
||||||
// mouse will be inside container now
|
// mouse will be inside container now
|
||||||
$.delegate( this, onContainerEnter )();
|
$.delegate( this, onContainerEnter )();
|
||||||
@ -651,7 +704,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
document.body.appendChild( this.previousBody.shift() );
|
document.body.appendChild( this.previousBody.shift() );
|
||||||
}
|
}
|
||||||
this.element.appendChild( this.container );
|
this.element.appendChild( this.container );
|
||||||
this._prevContainerSize = $.getElementSize( this.element );
|
THIS[ this.hash ].prevContainerSize = $.getElementSize( this.element );
|
||||||
|
|
||||||
// mouse will likely be outside now
|
// mouse will likely be outside now
|
||||||
$.delegate( this, onContainerExit )();
|
$.delegate( this, onContainerExit )();
|
||||||
@ -660,11 +713,11 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
|
|
||||||
if ( this.viewport ) {
|
if ( this.viewport ) {
|
||||||
oldBounds = this.viewport.getBounds();
|
oldBounds = this.viewport.getBounds();
|
||||||
this.viewport.resize( this._prevContainerSize );
|
this.viewport.resize( THIS[ this.hash ].prevContainerSize );
|
||||||
newBounds = this.viewport.getBounds();
|
newBounds = this.viewport.getBounds();
|
||||||
|
|
||||||
if ( fullPage ) {
|
if ( fullPage ) {
|
||||||
this._fsBoundsDelta = new $.Point(
|
THIS[ this.hash ].fsBoundsDelta = new $.Point(
|
||||||
newBounds.width / oldBounds.width,
|
newBounds.width / oldBounds.width,
|
||||||
newBounds.height / oldBounds.height
|
newBounds.height / oldBounds.height
|
||||||
);
|
);
|
||||||
@ -672,15 +725,15 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, {
|
|||||||
this.viewport.update();
|
this.viewport.update();
|
||||||
this.viewport.zoomBy(
|
this.viewport.zoomBy(
|
||||||
Math.max(
|
Math.max(
|
||||||
this._fsBoundsDelta.x,
|
THIS[ this.hash ].fsBoundsDelta.x,
|
||||||
this._fsBoundsDelta.y
|
THIS[ this.hash ].fsBoundsDelta.y
|
||||||
),
|
),
|
||||||
null,
|
null,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._forceRedraw = true;
|
THIS[ this.hash ].forceRedraw = true;
|
||||||
this.raiseEvent( "resize", this );
|
this.raiseEvent( "resize", this );
|
||||||
updateOnce( this );
|
updateOnce( this );
|
||||||
}
|
}
|
||||||
@ -718,7 +771,7 @@ function scheduleUpdate( viewer, updateFunc, prevUpdateTime ){
|
|||||||
targetTime,
|
targetTime,
|
||||||
deltaTime;
|
deltaTime;
|
||||||
|
|
||||||
if ( this._animating ) {
|
if ( THIS[ viewer.hash ].animating ) {
|
||||||
return window.setTimeout( function(){
|
return window.setTimeout( function(){
|
||||||
updateFunc( viewer );
|
updateFunc( viewer );
|
||||||
}, 1 );
|
}, 1 );
|
||||||
@ -840,8 +893,8 @@ function onCanvasScroll( tracker, position, scroll, shift ) {
|
|||||||
|
|
||||||
function onContainerExit( tracker, position, buttonDownElement, buttonDownAny ) {
|
function onContainerExit( tracker, position, buttonDownElement, buttonDownAny ) {
|
||||||
if ( !buttonDownElement ) {
|
if ( !buttonDownElement ) {
|
||||||
this._mouseInside = false;
|
THIS[ this.hash ].mouseInside = false;
|
||||||
if ( !this._animating ) {
|
if ( !THIS[ this.hash ].animating ) {
|
||||||
beginControlsAutoHide( this );
|
beginControlsAutoHide( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -849,15 +902,15 @@ function onContainerExit( tracker, position, buttonDownElement, buttonDownAny )
|
|||||||
|
|
||||||
function onContainerRelease( tracker, position, insideElementPress, insideElementRelease ) {
|
function onContainerRelease( tracker, position, insideElementPress, insideElementRelease ) {
|
||||||
if ( !insideElementRelease ) {
|
if ( !insideElementRelease ) {
|
||||||
this._mouseInside = false;
|
THIS[ this.hash ].mouseInside = false;
|
||||||
if ( !this._animating ) {
|
if ( !THIS[ this.hash ].animating ) {
|
||||||
beginControlsAutoHide( this );
|
beginControlsAutoHide( this );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny ) {
|
function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny ) {
|
||||||
this._mouseInside = true;
|
THIS[ this.hash ].mouseInside = true;
|
||||||
abortControlsAutoHide( this );
|
abortControlsAutoHide( this );
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -903,15 +956,15 @@ function updateOnce( viewer ) {
|
|||||||
//viewer.profiler.beginUpdate();
|
//viewer.profiler.beginUpdate();
|
||||||
|
|
||||||
containerSize = $.getElementSize( viewer.container );
|
containerSize = $.getElementSize( viewer.container );
|
||||||
if ( !containerSize.equals( viewer._prevContainerSize ) ) {
|
if ( !containerSize.equals( THIS[ viewer.hash ].prevContainerSize ) ) {
|
||||||
// maintain image position
|
// maintain image position
|
||||||
viewer.viewport.resize( containerSize, true );
|
viewer.viewport.resize( containerSize, true );
|
||||||
viewer._prevContainerSize = containerSize;
|
THIS[ viewer.hash ].prevContainerSize = containerSize;
|
||||||
viewer.raiseEvent( "resize" );
|
viewer.raiseEvent( "resize" );
|
||||||
}
|
}
|
||||||
|
|
||||||
animated = viewer.viewport.update();
|
animated = viewer.viewport.update();
|
||||||
if ( !viewer._animating && animated ) {
|
if ( !THIS[ viewer.hash ].animating && animated ) {
|
||||||
viewer.raiseEvent( "animationstart" );
|
viewer.raiseEvent( "animationstart" );
|
||||||
abortControlsAutoHide( viewer );
|
abortControlsAutoHide( viewer );
|
||||||
}
|
}
|
||||||
@ -919,20 +972,20 @@ function updateOnce( viewer ) {
|
|||||||
if ( animated ) {
|
if ( animated ) {
|
||||||
viewer.drawer.update();
|
viewer.drawer.update();
|
||||||
viewer.raiseEvent( "animation" );
|
viewer.raiseEvent( "animation" );
|
||||||
} else if ( viewer._forceRedraw || viewer.drawer.needsUpdate() ) {
|
} else if ( THIS[ viewer.hash ].forceRedraw || viewer.drawer.needsUpdate() ) {
|
||||||
viewer.drawer.update();
|
viewer.drawer.update();
|
||||||
viewer._forceRedraw = false;
|
THIS[ viewer.hash ].forceRedraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( viewer._animating && !animated ) {
|
if ( THIS[ viewer.hash ].animating && !animated ) {
|
||||||
viewer.raiseEvent( "animationfinish" );
|
viewer.raiseEvent( "animationfinish" );
|
||||||
|
|
||||||
if ( !viewer._mouseInside ) {
|
if ( !THIS[ viewer.hash ].mouseInside ) {
|
||||||
beginControlsAutoHide( viewer );
|
beginControlsAutoHide( viewer );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer._animating = animated;
|
THIS[ viewer.hash ].animating = animated;
|
||||||
|
|
||||||
//viewer.profiler.endUpdate();
|
//viewer.profiler.endUpdate();
|
||||||
};
|
};
|
||||||
@ -947,21 +1000,21 @@ function resolveUrl( prefix, url ) {
|
|||||||
|
|
||||||
|
|
||||||
function beginZoomingIn() {
|
function beginZoomingIn() {
|
||||||
this._lastZoomTime = +new Date();
|
THIS[ this.hash ].lastZoomTime = +new Date();
|
||||||
this._zoomFactor = this.config.zoomPerSecond;
|
THIS[ this.hash ].zoomFactor = this.config.zoomPerSecond;
|
||||||
this._zooming = true;
|
THIS[ this.hash ].zooming = true;
|
||||||
scheduleZoom( this );
|
scheduleZoom( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
function beginZoomingOut() {
|
function beginZoomingOut() {
|
||||||
this._lastZoomTime = +new Date();
|
THIS[ this.hash ].lastZoomTime = +new Date();
|
||||||
this._zoomFactor = 1.0 / this.config.zoomPerSecond;
|
THIS[ this.hash ].zoomFactor = 1.0 / this.config.zoomPerSecond;
|
||||||
this._zooming = true;
|
THIS[ this.hash ].zooming = true;
|
||||||
scheduleZoom( this );
|
scheduleZoom( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
function endZooming() {
|
function endZooming() {
|
||||||
this._zooming = false;
|
THIS[ this.hash ].zooming = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function scheduleZoom( viewer ) {
|
function scheduleZoom( viewer ) {
|
||||||
@ -973,21 +1026,21 @@ function doZoom() {
|
|||||||
deltaTime,
|
deltaTime,
|
||||||
adjustFactor;
|
adjustFactor;
|
||||||
|
|
||||||
if ( this._zooming && this.viewport) {
|
if ( THIS[ this.hash ].zooming && this.viewport) {
|
||||||
currentTime = +new Date();
|
currentTime = +new Date();
|
||||||
deltaTime = currentTime - this._lastZoomTime;
|
deltaTime = currentTime - THIS[ this.hash ].lastZoomTime;
|
||||||
adjustedFactor = Math.pow( this._zoomFactor, deltaTime / 1000 );
|
adjustedFactor = Math.pow( THIS[ this.hash ].zoomFactor, deltaTime / 1000 );
|
||||||
|
|
||||||
this.viewport.zoomBy( adjustedFactor );
|
this.viewport.zoomBy( adjustedFactor );
|
||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
this._lastZoomTime = currentTime;
|
THIS[ this.hash ].lastZoomTime = currentTime;
|
||||||
scheduleZoom( this );
|
scheduleZoom( this );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function doSingleZoomIn() {
|
function doSingleZoomIn() {
|
||||||
if ( this.viewport ) {
|
if ( this.viewport ) {
|
||||||
this._zooming = false;
|
THIS[ this.hash ].zooming = false;
|
||||||
this.viewport.zoomBy(
|
this.viewport.zoomBy(
|
||||||
this.config.zoomPerClick / 1.0
|
this.config.zoomPerClick / 1.0
|
||||||
);
|
);
|
||||||
@ -997,7 +1050,7 @@ function doSingleZoomIn() {
|
|||||||
|
|
||||||
function doSingleZoomOut() {
|
function doSingleZoomOut() {
|
||||||
if ( this.viewport ) {
|
if ( this.viewport ) {
|
||||||
this._zooming = false;
|
THIS[ this.hash ].zooming = false;
|
||||||
this.viewport.zoomBy(
|
this.viewport.zoomBy(
|
||||||
1.0 / this.config.zoomPerClick
|
1.0 / this.config.zoomPerClick
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user