Merge branch 'master' into raf

Fixed Conflicts:
	src/viewer.js
This commit is contained in:
Ian Gilman 2013-06-19 11:19:54 -07:00
commit 8e88f36098
31 changed files with 975 additions and 974 deletions

View File

@ -131,6 +131,7 @@ module.exports = function(grunt) {
browser: true, browser: true,
eqeqeq: false, eqeqeq: false,
loopfunc: false, loopfunc: false,
trailing: true,
globals: { globals: {
OpenSeadragon: true OpenSeadragon: true
} }
@ -152,7 +153,7 @@ module.exports = function(grunt) {
// Copies the image files into the appropriate location in the build folder. // Copies the image files into the appropriate location in the build folder.
grunt.registerTask("copy:build", function() { grunt.registerTask("copy:build", function() {
grunt.file.recurse("images", function(abspath, rootdir, subdir, filename) { grunt.file.recurse("images", function(abspath, rootdir, subdir, filename) {
grunt.file.copy(abspath, "build/openseadragon/images/" + (subdir || "") + filename); grunt.file.copy(abspath, "build/openseadragon/images/" + (subdir || "") + filename);
}); });
grunt.file.copy("changelog.txt", "build/changelog.txt"); grunt.file.copy("changelog.txt", "build/changelog.txt");

View File

@ -46,7 +46,7 @@ $.ButtonState = {
}; };
/** /**
* Manages events, hover states for individual buttons, tool-tips, as well * Manages events, hover states for individual buttons, tool-tips, as well
* as fading the bottons out when the user has not interacted with them * as fading the bottons out when the user has not interacted with them
* for a specified period. * for a specified period.
* @class * @class
@ -58,7 +58,7 @@ $.ButtonState = {
* @param {String} options.srcGroup URL of image to use in 'up' state * @param {String} options.srcGroup URL of image to use in 'up' state
* @param {String} options.srcHover URL of image to use in 'hover' state * @param {String} options.srcHover URL of image to use in 'hover' state
* @param {String} options.srcDown URL of image to use in 'down' state * @param {String} options.srcDown URL of image to use in 'down' state
* @param {Element} [options.element] Element to use as a container for the * @param {Element} [options.element] Element to use as a container for the
* button. * button.
* @property {String} tooltip Provides context help for the button we the * @property {String} tooltip Provides context help for the button we the
* user hovers over it. * user hovers over it.
@ -67,12 +67,12 @@ $.ButtonState = {
* @property {String} srcHover URL of image to use in 'hover' state * @property {String} srcHover URL of image to use in 'hover' state
* @property {String} srcDown URL of image to use in 'down' state * @property {String} srcDown URL of image to use in 'down' state
* @property {Object} config Configurable settings for this button. DEPRECATED. * @property {Object} config Configurable settings for this button. DEPRECATED.
* @property {Element} [element] Element to use as a container for the * @property {Element} [element] Element to use as a container for the
* button. * button.
* @property {Number} fadeDelay How long to wait before fading * @property {Number} fadeDelay How long to wait before fading
* @property {Number} fadeLength How long should it take to fade the button. * @property {Number} fadeLength How long should it take to fade the button.
* @property {Number} fadeBeginTime When the button last began to fade. * @property {Number} fadeBeginTime When the button last began to fade.
* @property {Boolean} shouldFade Whether this button should fade after user * @property {Boolean} shouldFade Whether this button should fade after user
* stops interacting with the viewport. * stops interacting with the viewport.
this.fadeDelay = 0; // begin fading immediately this.fadeDelay = 0; // begin fading immediately
this.fadeLength = 2000; // fade over a period of 2 seconds this.fadeLength = 2000; // fade over a period of 2 seconds
@ -86,7 +86,7 @@ $.Button = function( options ) {
$.EventHandler.call( this ); $.EventHandler.call( this );
$.extend( true, this, { $.extend( true, this, {
tooltip: null, tooltip: null,
srcRest: null, srcRest: null,
srcGroup: null, srcGroup: null,
@ -95,8 +95,8 @@ $.Button = function( options ) {
clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThreshold, clickTimeThreshold: $.DEFAULT_SETTINGS.clickTimeThreshold,
clickDistThreshold: $.DEFAULT_SETTINGS.clickDistThreshold, clickDistThreshold: $.DEFAULT_SETTINGS.clickDistThreshold,
// begin fading immediately // begin fading immediately
fadeDelay: 0, fadeDelay: 0,
// fade over a period of 2 seconds // fade over a period of 2 seconds
fadeLength: 2000, fadeLength: 2000,
onPress: null, onPress: null,
onRelease: null, onRelease: null,
@ -110,7 +110,7 @@ $.Button = function( options ) {
this.element = options.element || $.makeNeutralElement( "button" ); this.element = options.element || $.makeNeutralElement( "button" );
this.element.href = this.element.href || '#'; this.element.href = this.element.href || '#';
//if the user has specified the element to bind the control to explicitly //if the user has specified the element to bind the control to explicitly
//then do not add the default control images //then do not add the default control images
if( !options.element ){ if( !options.element ){
@ -118,35 +118,35 @@ $.Button = function( options ) {
this.imgGroup = $.makeTransparentImage( this.srcGroup ); this.imgGroup = $.makeTransparentImage( this.srcGroup );
this.imgHover = $.makeTransparentImage( this.srcHover ); this.imgHover = $.makeTransparentImage( this.srcHover );
this.imgDown = $.makeTransparentImage( this.srcDown ); this.imgDown = $.makeTransparentImage( this.srcDown );
this.element.appendChild( this.imgRest ); this.element.appendChild( this.imgRest );
this.element.appendChild( this.imgGroup ); this.element.appendChild( this.imgGroup );
this.element.appendChild( this.imgHover ); this.element.appendChild( this.imgHover );
this.element.appendChild( this.imgDown ); this.element.appendChild( this.imgDown );
this.imgGroup.style.position = this.imgGroup.style.position =
this.imgHover.style.position = this.imgHover.style.position =
this.imgDown.style.position = this.imgDown.style.position =
"absolute"; "absolute";
this.imgGroup.style.top = this.imgGroup.style.top =
this.imgHover.style.top = this.imgHover.style.top =
this.imgDown.style.top = this.imgDown.style.top =
"0px"; "0px";
this.imgGroup.style.left = this.imgGroup.style.left =
this.imgHover.style.left = this.imgHover.style.left =
this.imgDown.style.left = this.imgDown.style.left =
"0px"; "0px";
this.imgHover.style.visibility = this.imgHover.style.visibility =
this.imgDown.style.visibility = this.imgDown.style.visibility =
"hidden"; "hidden";
if ( $.Browser.vendor == $.BROWSERS.FIREFOX && $.Browser.version < 3 ){ if ( $.Browser.vendor == $.BROWSERS.FIREFOX && $.Browser.version < 3 ){
this.imgGroup.style.top = this.imgGroup.style.top =
this.imgHover.style.top = this.imgHover.style.top =
this.imgDown.style.top = this.imgDown.style.top =
""; "";
} }
} }
@ -171,8 +171,8 @@ $.Button = function( options ) {
this.tracker = new $.MouseTracker({ this.tracker = new $.MouseTracker({
element: this.element, element: this.element,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
enterHandler: function( tracker, position, buttonDownElement, buttonDownAny ) { enterHandler: function( tracker, position, buttonDownElement, buttonDownAny ) {
@ -306,7 +306,7 @@ function updateFade( button ) {
function beginFading( button ) { function beginFading( button ) {
button.shouldFade = true; button.shouldFade = true;
button.fadeBeginTime = +new Date() + button.fadeDelay; button.fadeBeginTime = +new Date() + button.fadeDelay;
window.setTimeout( function(){ window.setTimeout( function(){
scheduleFade( button ); scheduleFade( button );
}, button.fadeDelay ); }, button.fadeDelay );
} }
@ -324,13 +324,13 @@ function inTo( button, newState ) {
return; return;
} }
if ( newState >= $.ButtonState.GROUP && if ( newState >= $.ButtonState.GROUP &&
button.currentState == $.ButtonState.REST ) { button.currentState == $.ButtonState.REST ) {
stopFading( button ); stopFading( button );
button.currentState = $.ButtonState.GROUP; button.currentState = $.ButtonState.GROUP;
} }
if ( newState >= $.ButtonState.HOVER && if ( newState >= $.ButtonState.HOVER &&
button.currentState == $.ButtonState.GROUP ) { button.currentState == $.ButtonState.GROUP ) {
if( button.imgHover ){ if( button.imgHover ){
button.imgHover.style.visibility = ""; button.imgHover.style.visibility = "";
@ -338,7 +338,7 @@ function inTo( button, newState ) {
button.currentState = $.ButtonState.HOVER; button.currentState = $.ButtonState.HOVER;
} }
if ( newState >= $.ButtonState.DOWN && if ( newState >= $.ButtonState.DOWN &&
button.currentState == $.ButtonState.HOVER ) { button.currentState == $.ButtonState.HOVER ) {
if( button.imgDown ){ if( button.imgDown ){
button.imgDown.style.visibility = ""; button.imgDown.style.visibility = "";
@ -354,7 +354,7 @@ function outTo( button, newState ) {
return; return;
} }
if ( newState <= $.ButtonState.HOVER && if ( newState <= $.ButtonState.HOVER &&
button.currentState == $.ButtonState.DOWN ) { button.currentState == $.ButtonState.DOWN ) {
if( button.imgDown ){ if( button.imgDown ){
button.imgDown.style.visibility = "hidden"; button.imgDown.style.visibility = "hidden";
@ -362,7 +362,7 @@ function outTo( button, newState ) {
button.currentState = $.ButtonState.HOVER; button.currentState = $.ButtonState.HOVER;
} }
if ( newState <= $.ButtonState.GROUP && if ( newState <= $.ButtonState.GROUP &&
button.currentState == $.ButtonState.HOVER ) { button.currentState == $.ButtonState.HOVER ) {
if( button.imgHover ){ if( button.imgHover ){
button.imgHover.style.visibility = "hidden"; button.imgHover.style.visibility = "hidden";
@ -370,7 +370,7 @@ function outTo( button, newState ) {
button.currentState = $.ButtonState.GROUP; button.currentState = $.ButtonState.GROUP;
} }
if ( newState <= $.ButtonState.REST && if ( newState <= $.ButtonState.REST &&
button.currentState == $.ButtonState.GROUP ) { button.currentState == $.ButtonState.GROUP ) {
beginFading( button ); beginFading( button );
button.currentState = $.ButtonState.REST; button.currentState = $.ButtonState.REST;

View File

@ -36,17 +36,17 @@
/** /**
* Manages events on groups of buttons. * Manages events on groups of buttons.
* @class * @class
* @param {Object} options - a dictionary of settings applied against the entire * @param {Object} options - a dictionary of settings applied against the entire
* group of buttons * group of buttons
* @param {Array} options.buttons Array of buttons * @param {Array} options.buttons Array of buttons
* @param {Element} [options.group] Element to use as the container, * @param {Element} [options.group] Element to use as the container,
* @param {Object} options.config Object with Viewer settings ( TODO: is * @param {Object} options.config Object with Viewer settings ( TODO: is
* this actually used anywhere? ) * this actually used anywhere? )
* @param {Function} [options.enter] Function callback for when the mouse * @param {Function} [options.enter] Function callback for when the mouse
* enters group * enters group
* @param {Function} [options.exit] Function callback for when mouse leaves * @param {Function} [options.exit] Function callback for when mouse leaves
* the group * the group
* @param {Function} [options.release] Function callback for when mouse is * @param {Function} [options.release] Function callback for when mouse is
* released * released
* @property {Array} buttons - An array containing the buttons themselves. * @property {Array} buttons - An array containing the buttons themselves.
* @property {Element} element - The shared container for the buttons. * @property {Element} element - The shared container for the buttons.
@ -64,12 +64,12 @@ $.ButtonGroup = function( options ) {
}, options ); }, options );
// copy the botton elements // copy the botton elements
var buttons = this.buttons.concat([]), var buttons = this.buttons.concat([]),
_this = this, _this = this,
i; i;
this.element = options.element || $.makeNeutralElement( "fieldgroup" ); this.element = options.element || $.makeNeutralElement( "fieldgroup" );
if( !options.group ){ if( !options.group ){
this.label = $.makeNeutralElement( "label" ); this.label = $.makeNeutralElement( "label" );
//TODO: support labels for ButtonGroups //TODO: support labels for ButtonGroups
@ -82,8 +82,8 @@ $.ButtonGroup = function( options ) {
} }
this.tracker = new $.MouseTracker({ this.tracker = new $.MouseTracker({
element: this.element, element: this.element,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
enterHandler: function() { enterHandler: function() {
var i; var i;
@ -93,8 +93,8 @@ $.ButtonGroup = function( options ) {
}, },
exitHandler: function() { exitHandler: function() {
var i, var i,
buttonDownElement = arguments.length > 2 ? buttonDownElement = arguments.length > 2 ?
arguments[ 2 ] : arguments[ 2 ] :
null; null;
if ( !buttonDownElement ) { if ( !buttonDownElement ) {
for ( i = 0; i < _this.buttons.length; i++ ) { for ( i = 0; i < _this.buttons.length; i++ ) {
@ -104,8 +104,8 @@ $.ButtonGroup = function( options ) {
}, },
releaseHandler: function() { releaseHandler: function() {
var i, var i,
insideElementRelease = arguments.length > 3 ? insideElementRelease = arguments.length > 3 ?
arguments[ 3 ] : arguments[ 3 ] :
null; null;
if ( !insideElementRelease ) { if ( !insideElementRelease ) {
for ( i = 0; i < _this.buttons.length; i++ ) { for ( i = 0; i < _this.buttons.length; i++ ) {

View File

@ -33,7 +33,7 @@
*/ */
(function( $ ){ (function( $ ){
/** /**
* An enumeration of supported locations where controls can be anchored, * An enumeration of supported locations where controls can be anchored,
* including NONE, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT, and BOTTOM_LEFT. * including NONE, TOP_LEFT, TOP_RIGHT, BOTTOM_RIGHT, and BOTTOM_LEFT.
@ -49,8 +49,8 @@ $.ControlAnchor = {
}; };
/** /**
* A Control represents any interface element which is meant to allow the user * A Control represents any interface element which is meant to allow the user
* to interact with the zoomable interface. Any control can be anchored to any * to interact with the zoomable interface. Any control can be anchored to any
* element. * element.
* @class * @class
* @param {Element} element - the control element to be anchored in the container. * @param {Element} element - the control element to be anchored in the container.
@ -64,7 +64,7 @@ $.ControlAnchor = {
* *
* @property {Element} element - the element providing the user interface with * @property {Element} element - the element providing the user interface with
* some type of control. Eg a zoom-in button * some type of control. Eg a zoom-in button
* @property {OpenSeadragon.ControlAnchor} anchor - the position of the control * @property {OpenSeadragon.ControlAnchor} anchor - the position of the control
* relative to the container. * relative to the container.
* @property {Boolean} autoFade - Whether the control should have the autofade behavior * @property {Boolean} autoFade - Whether the control should have the autofade behavior
* @property {Element} container - the element within with the control is * @property {Element} container - the element within with the control is
@ -92,7 +92,7 @@ $.Control = function ( element, options, container ) {
if ( this.anchor == $.ControlAnchor.NONE ) { if ( this.anchor == $.ControlAnchor.NONE ) {
// IE6 fix // IE6 fix
this.wrapper.style.width = this.wrapper.style.height = "100%"; this.wrapper.style.width = this.wrapper.style.height = "100%";
} }
if (options.attachToViewer ) { if (options.attachToViewer ) {
@ -136,8 +136,8 @@ $.Control.prototype = {
* @param {Boolean} visible - true to make visible, false to hide. * @param {Boolean} visible - true to make visible, false to hide.
*/ */
setVisible: function( visible ) { setVisible: function( visible ) {
this.wrapper.style.display = visible ? this.wrapper.style.display = visible ?
"inline-block" : "inline-block" :
"none"; "none";
}, },

View File

@ -36,7 +36,7 @@
//id hash for private properties; //id hash for private properties;
var THIS = {}; var THIS = {};
/** /**
* @class * @class
*/ */
@ -44,7 +44,7 @@
var layouts = [ 'topleft', 'topright', 'bottomright', 'bottomleft'], var layouts = [ 'topleft', 'topright', 'bottomright', 'bottomleft'],
layout, layout,
i; i;
$.extend( true, this, { $.extend( true, this, {
id: 'controldock-'+(+new Date())+'-'+Math.floor(Math.random()*1000000), id: 'controldock-'+(+new Date())+'-'+Math.floor(Math.random()*1000000),
container: $.makeNeutralElement('form'), container: $.makeNeutralElement('form'),
@ -53,8 +53,8 @@
if( this.element ){ if( this.element ){
this.element = $.getElement( this.element ); this.element = $.getElement( this.element );
this.element.appendChild( this.container ); this.element.appendChild( this.container );
this.element.style.position = 'relative'; this.element.style.position = 'relative';
this.container.style.width = '100%'; this.container.style.width = '100%';
this.container.style.height = '100%'; this.container.style.height = '100%';
} }
@ -143,7 +143,7 @@
removeControl: function ( element ) { removeControl: function ( element ) {
element = $.getElement( element ); element = $.getElement( element );
var i = getControlIndex( this, element ); var i = getControlIndex( this, element );
if ( i >= 0 ) { if ( i >= 0 ) {
this.controls[ i ].destroy(); this.controls[ i ].destroy();
this.controls.splice( i, 1 ); this.controls.splice( i, 1 );
@ -160,7 +160,7 @@
while ( this.controls.length > 0 ) { while ( this.controls.length > 0 ) {
this.controls.pop().destroy(); this.controls.pop().destroy();
} }
return this; return this;
}, },
@ -171,7 +171,7 @@
*/ */
areControlsEnabled: function () { areControlsEnabled: function () {
var i; var i;
for ( i = this.controls.length - 1; i >= 0; i-- ) { for ( i = this.controls.length - 1; i >= 0; i-- ) {
if ( this.controls[ i ].isVisible() ) { if ( this.controls[ i ].isVisible() ) {
return true; return true;

View File

@ -33,7 +33,7 @@
*/ */
(function( $ ){ (function( $ ){
var DEVICE_SCREEN = $.getWindowSize(), var DEVICE_SCREEN = $.getWindowSize(),
BROWSER = $.Browser.vendor, BROWSER = $.Browser.vendor,
BROWSER_VERSION = $.Browser.version, BROWSER_VERSION = $.Browser.version,
@ -44,7 +44,7 @@ var DEVICE_SCREEN = $.getWindowSize(),
( BROWSER == $.BROWSERS.SAFARI && BROWSER_VERSION >= 4 ) || ( BROWSER == $.BROWSERS.SAFARI && BROWSER_VERSION >= 4 ) ||
( BROWSER == $.BROWSERS.CHROME && BROWSER_VERSION >= 2 ) || ( BROWSER == $.BROWSERS.CHROME && BROWSER_VERSION >= 2 ) ||
( BROWSER == $.BROWSERS.IE && BROWSER_VERSION >= 9 ) ( BROWSER == $.BROWSERS.IE && BROWSER_VERSION >= 9 )
), ),
USE_CANVAS = SUBPIXEL_RENDERING && USE_CANVAS = SUBPIXEL_RENDERING &&
!( DEVICE_SCREEN.x <= 400 || DEVICE_SCREEN.y <= 400 ) && !( DEVICE_SCREEN.x <= 400 || DEVICE_SCREEN.y <= 400 ) &&
@ -77,8 +77,8 @@ var DEVICE_SCREEN = $.getWindowSize(),
* @property {Element} element - DEPRECATED Alias for container. * @property {Element} element - DEPRECATED Alias for container.
*/ */
$.Drawer = function( options ) { $.Drawer = function( options ) {
//backward compatibility for positional args while prefering more //backward compatibility for positional args while prefering more
//idiomatic javascript options object as the only argument //idiomatic javascript options object as the only argument
var args = arguments, var args = arguments,
i; i;
@ -105,7 +105,7 @@ $.Drawer = function( options ) {
updateAgain: true, updateAgain: true,
//internal state / configurable settings //internal state / configurable settings
overlays: [], overlays: [],
collectionOverlays: {}, collectionOverlays: {},
@ -130,11 +130,11 @@ $.Drawer = function( options ) {
this.normHeight = this.source.dimensions.y / this.source.dimensions.x; this.normHeight = this.source.dimensions.y / this.source.dimensions.x;
this.element = this.container; this.element = this.container;
this.canvas.style.width = "100%"; this.canvas.style.width = "100%";
this.canvas.style.height = "100%"; this.canvas.style.height = "100%";
this.canvas.style.position = "absolute"; this.canvas.style.position = "absolute";
// explicit left-align // explicit left-align
this.container.style.textAlign = "left"; this.container.style.textAlign = "left";
this.container.appendChild( this.canvas ); this.container.appendChild( this.canvas );
@ -143,7 +143,7 @@ $.Drawer = function( options ) {
//are not already OpenSeadragon.Overlays //are not already OpenSeadragon.Overlays
for( i = 0; i < this.overlays.length; i++ ){ for( i = 0; i < this.overlays.length; i++ ){
if( $.isPlainObject( this.overlays[ i ] ) ){ if( $.isPlainObject( this.overlays[ i ] ) ){
this.overlays[ i ] = addOverlayFromConfiguration( this, this.overlays[ i ]); this.overlays[ i ] = addOverlayFromConfiguration( this, this.overlays[ i ]);
} else if ( $.isFunction( this.overlays[ i ] ) ){ } else if ( $.isFunction( this.overlays[ i ] ) ){
@ -163,27 +163,27 @@ $.Drawer.prototype = {
* @method * @method
* @param {Element|String} element - A reference to an element or an id for * @param {Element|String} element - A reference to an element or an id for
* the element which will overlayed. * the element which will overlayed.
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or * @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or
* rectangle which will be overlayed. * rectangle which will be overlayed.
* @param {OpenSeadragon.OverlayPlacement} placement - The position of the * @param {OpenSeadragon.OverlayPlacement} placement - The position of the
* viewport which the location coordinates will be treated as relative * viewport which the location coordinates will be treated as relative
* to. * to.
*/ */
addOverlay: function( element, location, placement ) { addOverlay: function( element, location, placement ) {
element = $.getElement( element ); element = $.getElement( element );
if ( getOverlayIndex( this.overlays, element ) >= 0 ) { if ( getOverlayIndex( this.overlays, element ) >= 0 ) {
// they're trying to add a duplicate overlay // they're trying to add a duplicate overlay
return; return;
} }
this.overlays.push( new $.Overlay( element, location, placement ) ); this.overlays.push( new $.Overlay( element, location, placement ) );
this.updateAgain = true; this.updateAgain = true;
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'add-overlay', { this.viewer.raiseEvent( 'add-overlay', {
viewer: this.viewer, viewer: this.viewer,
element: element, element: element,
location: location, location: location,
placement: placement placement: placement
}); });
} }
@ -191,14 +191,14 @@ $.Drawer.prototype = {
}, },
/** /**
* Updates the overlay represented by the reference to the element or * Updates the overlay represented by the reference to the element or
* element id moving it to the new location, relative to the new placement. * element id moving it to the new location, relative to the new placement.
* @method * @method
* @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or * @param {OpenSeadragon.Point|OpenSeadragon.Rect} location - The point or
* rectangle which will be overlayed. * rectangle which will be overlayed.
* @param {OpenSeadragon.OverlayPlacement} placement - The position of the * @param {OpenSeadragon.OverlayPlacement} placement - The position of the
* viewport which the location coordinates will be treated as relative * viewport which the location coordinates will be treated as relative
* to. * to.
* @return {OpenSeadragon.Drawer} Chainable. * @return {OpenSeadragon.Drawer} Chainable.
*/ */
updateOverlay: function( element, location, placement ) { updateOverlay: function( element, location, placement ) {
@ -212,10 +212,10 @@ $.Drawer.prototype = {
this.updateAgain = true; this.updateAgain = true;
} }
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'update-overlay', { this.viewer.raiseEvent( 'update-overlay', {
viewer: this.viewer, viewer: this.viewer,
element: element, element: element,
location: location, location: location,
placement: placement placement: placement
}); });
} }
@ -223,10 +223,10 @@ $.Drawer.prototype = {
}, },
/** /**
* Removes and overlay identified by the reference element or element id * Removes and overlay identified by the reference element or element id
* and schedules and update. * and schedules and update.
* @method * @method
* @param {Element|String} element - A reference to the element or an * @param {Element|String} element - A reference to the element or an
* element id which represent the ovelay content to be removed. * element id which represent the ovelay content to be removed.
* @return {OpenSeadragon.Drawer} Chainable. * @return {OpenSeadragon.Drawer} Chainable.
*/ */
@ -242,7 +242,7 @@ $.Drawer.prototype = {
this.updateAgain = true; this.updateAgain = true;
} }
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'remove-overlay', { this.viewer.raiseEvent( 'remove-overlay', {
viewer: this.viewer, viewer: this.viewer,
element: element element: element
}); });
@ -262,7 +262,7 @@ $.Drawer.prototype = {
this.updateAgain = true; this.updateAgain = true;
} }
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'clear-overlay', { this.viewer.raiseEvent( 'clear-overlay', {
viewer: this.viewer viewer: this.viewer
}); });
} }
@ -271,10 +271,10 @@ $.Drawer.prototype = {
/** /**
* Returns whether the Drawer is scheduled for an update at the * Returns whether the Drawer is scheduled for an update at the
* soonest possible opportunity. * soonest possible opportunity.
* @method * @method
* @returns {Boolean} - Whether the Drawer is scheduled for an update at the * @returns {Boolean} - Whether the Drawer is scheduled for an update at the
* soonest possible opportunity. * soonest possible opportunity.
*/ */
needsUpdate: function() { needsUpdate: function() {
@ -284,7 +284,7 @@ $.Drawer.prototype = {
/** /**
* Returns the total number of tiles that have been loaded by this Drawer. * Returns the total number of tiles that have been loaded by this Drawer.
* @method * @method
* @returns {Number} - The total number of tiles that have been loaded by * @returns {Number} - The total number of tiles that have been loaded by
* this Drawer. * this Drawer.
*/ */
numTilesLoaded: function() { numTilesLoaded: function() {
@ -292,7 +292,7 @@ $.Drawer.prototype = {
}, },
/** /**
* Clears all tiles and triggers an update on the next call to * Clears all tiles and triggers an update on the next call to
* Drawer.prototype.update(). * Drawer.prototype.update().
* @method * @method
* @return {OpenSeadragon.Drawer} Chainable. * @return {OpenSeadragon.Drawer} Chainable.
@ -319,12 +319,12 @@ $.Drawer.prototype = {
}, },
/** /**
* Used internally to load images when required. May also be used to * Used internally to load images when required. May also be used to
* preload a set of images so the browser will have them available in * preload a set of images so the browser will have them available in
* the local cache to optimize user experience in certain cases. Because * the local cache to optimize user experience in certain cases. Because
* the number of parallel image loads is configurable, if too many images * the number of parallel image loads is configurable, if too many images
* are currently being loaded, the request will be ignored. Since by * are currently being loaded, the request will be ignored. Since by
* default drawer.imageLoaderLimit is 0, the native browser parallel * default drawer.imageLoaderLimit is 0, the native browser parallel
* image loading policy will be used. * image loading policy will be used.
* @method * @method
* @param {String} src - The url of the image to load. * @param {String} src - The url of the image to load.
@ -341,10 +341,10 @@ $.Drawer.prototype = {
image, image,
jobid, jobid,
complete; complete;
if ( !this.imageLoaderLimit || if ( !this.imageLoaderLimit ||
this.downloading < this.imageLoaderLimit ) { this.downloading < this.imageLoaderLimit ) {
this.downloading++; this.downloading++;
image = new Image(); image = new Image();
@ -356,7 +356,7 @@ $.Drawer.prototype = {
callback( resultingImage ); callback( resultingImage );
} catch ( e ) { } catch ( e ) {
$.console.error( $.console.error(
"%s while executing %s callback: %s", "%s while executing %s callback: %s",
e.name, e.name,
src, src,
e.message, e.message,
@ -391,21 +391,21 @@ $.Drawer.prototype = {
* @inner * @inner
*/ */
function addOverlayFromConfiguration( drawer, overlay ){ function addOverlayFromConfiguration( drawer, overlay ){
var element = null, var element = null,
rect = ( overlay.height && overlay.width ) ? new $.Rect( rect = ( overlay.height && overlay.width ) ? new $.Rect(
overlay.x || overlay.px, overlay.x || overlay.px,
overlay.y || overlay.py, overlay.y || overlay.py,
overlay.width, overlay.width,
overlay.height overlay.height
) : new $.Point( ) : new $.Point(
overlay.x || overlay.px, overlay.x || overlay.px,
overlay.y || overlay.py overlay.y || overlay.py
), ),
id = overlay.id ? id = overlay.id ?
overlay.id : overlay.id :
"openseadragon-overlay-"+Math.floor(Math.random()*10000000); "openseadragon-overlay-"+Math.floor(Math.random()*10000000);
element = $.getElement(overlay.id); element = $.getElement(overlay.id);
if( !element ){ if( !element ){
element = document.createElement("a"); element = document.createElement("a");
@ -424,9 +424,9 @@ $.Drawer.prototype = {
rect = drawer.viewport.imageToViewportRectangle( rect ); rect = drawer.viewport.imageToViewportRectangle( rect );
} }
if( overlay.placement ){ if( overlay.placement ){
return new $.Overlay( return new $.Overlay(
element, element,
drawer.viewport.pointFromPixel(rect), drawer.viewport.pointFromPixel(rect),
$.OverlayPlacement[overlay.placement.toUpperCase()] $.OverlayPlacement[overlay.placement.toUpperCase()]
); );
}else{ }else{
@ -443,11 +443,11 @@ $.Drawer.prototype = {
* why there are so many TODO's inside this function. * why there are so many TODO's inside this function.
*/ */
function updateViewport( drawer ) { function updateViewport( drawer ) {
drawer.updateAgain = false; drawer.updateAgain = false;
if( drawer.viewer ){ if( drawer.viewer ){
drawer.viewer.raiseEvent( 'update-viewport', { drawer.viewer.raiseEvent( 'update-viewport', {
viewer: drawer.viewer viewer: drawer.viewer
}); });
} }
@ -461,21 +461,21 @@ function updateViewport( drawer ) {
viewportBounds = drawer.viewport.getBounds( true ), viewportBounds = drawer.viewport.getBounds( true ),
viewportTL = viewportBounds.getTopLeft(), viewportTL = viewportBounds.getTopLeft(),
viewportBR = viewportBounds.getBottomRight(), viewportBR = viewportBounds.getBottomRight(),
zeroRatioC = drawer.viewport.deltaPixelsFromPoints( zeroRatioC = drawer.viewport.deltaPixelsFromPoints(
drawer.source.getPixelRatio( 0 ), drawer.source.getPixelRatio( 0 ),
true true
).x, ).x,
lowestLevel = Math.max( lowestLevel = Math.max(
drawer.source.minLevel, drawer.source.minLevel,
Math.floor( Math.floor(
Math.log( drawer.minZoomImageRatio ) / Math.log( drawer.minZoomImageRatio ) /
Math.log( 2 ) Math.log( 2 )
) )
), ),
highestLevel = Math.min( highestLevel = Math.min(
Math.abs(drawer.source.maxLevel), Math.abs(drawer.source.maxLevel),
Math.abs(Math.floor( Math.abs(Math.floor(
Math.log( zeroRatioC / drawer.minPixelRatio ) / Math.log( zeroRatioC / drawer.minPixelRatio ) /
Math.log( 2 ) Math.log( 2 )
)) ))
), ),
@ -504,10 +504,10 @@ function updateViewport( drawer ) {
} }
//TODO //TODO
if ( !drawer.wrapHorizontal && if ( !drawer.wrapHorizontal &&
( viewportBR.x < 0 || viewportTL.x > 1 ) ) { ( viewportBR.x < 0 || viewportTL.x > 1 ) ) {
return; return;
} else if } else if
( !drawer.wrapVertical && ( !drawer.wrapVertical &&
( viewportBR.y < 0 || viewportTL.y > drawer.normHeight ) ) { ( viewportBR.y < 0 || viewportTL.y > drawer.normHeight ) ) {
return; return;
@ -531,7 +531,7 @@ function updateViewport( drawer ) {
//Avoid calculations for draw if we have already drawn this //Avoid calculations for draw if we have already drawn this
renderPixelRatioC = drawer.viewport.deltaPixelsFromPoints( renderPixelRatioC = drawer.viewport.deltaPixelsFromPoints(
drawer.source.getPixelRatio( level ), drawer.source.getPixelRatio( level ),
true true
).x; ).x;
@ -544,41 +544,41 @@ function updateViewport( drawer ) {
} }
renderPixelRatioT = drawer.viewport.deltaPixelsFromPoints( renderPixelRatioT = drawer.viewport.deltaPixelsFromPoints(
drawer.source.getPixelRatio( level ), drawer.source.getPixelRatio( level ),
false false
).x; ).x;
zeroRatioT = drawer.viewport.deltaPixelsFromPoints( zeroRatioT = drawer.viewport.deltaPixelsFromPoints(
drawer.source.getPixelRatio( drawer.source.getPixelRatio(
Math.max( Math.max(
drawer.source.getClosestLevel( drawer.viewport.containerSize ) - 1, drawer.source.getClosestLevel( drawer.viewport.containerSize ) - 1,
0 0
) )
), ),
false false
).x; ).x;
optimalRatio = drawer.immediateRender ? optimalRatio = drawer.immediateRender ?
1 : 1 :
zeroRatioT; zeroRatioT;
levelOpacity = Math.min( 1, ( renderPixelRatioC - 0.5 ) / 0.5 ); levelOpacity = Math.min( 1, ( renderPixelRatioC - 0.5 ) / 0.5 );
levelVisibility = optimalRatio / Math.abs( levelVisibility = optimalRatio / Math.abs(
optimalRatio - renderPixelRatioT optimalRatio - renderPixelRatioT
); );
//TODO //TODO
best = updateLevel( best = updateLevel(
drawer, drawer,
haveDrawn, haveDrawn,
level, level,
levelOpacity, levelOpacity,
levelVisibility, levelVisibility,
viewportTL, viewportTL,
viewportBR, viewportBR,
currentTime, currentTime,
best best
); );
//TODO //TODO
@ -595,14 +595,14 @@ function updateViewport( drawer ) {
if ( best ) { if ( best ) {
loadTile( drawer, best, currentTime ); loadTile( drawer, best, currentTime );
// because we haven't finished drawing, so // because we haven't finished drawing, so
drawer.updateAgain = true; drawer.updateAgain = true;
} }
} }
function updateLevel( drawer, haveDrawn, level, levelOpacity, levelVisibility, viewportTL, viewportBR, currentTime, best ){ function updateLevel( drawer, haveDrawn, level, levelOpacity, levelVisibility, viewportTL, viewportBR, currentTime, best ){
var x, y, var x, y,
tileTL, tileTL,
tileBR, tileBR,
@ -611,15 +611,15 @@ function updateLevel( drawer, haveDrawn, level, levelOpacity, levelVisibility, v
if( drawer.viewer ){ if( drawer.viewer ){
drawer.viewer.raiseEvent( 'update-level', { drawer.viewer.raiseEvent( 'update-level', {
viewer: drawer.viewer, viewer: drawer.viewer,
havedrawn: haveDrawn, havedrawn: haveDrawn,
level: level, level: level,
opacity: levelOpacity, opacity: levelOpacity,
visibility: levelVisibility, visibility: levelVisibility,
topleft: viewportTL, topleft: viewportTL,
bottomright: viewportBR, bottomright: viewportBR,
currenttime: currentTime, currenttime: currentTime,
best: best best: best
}); });
} }
@ -641,7 +641,7 @@ function updateLevel( drawer, haveDrawn, level, levelOpacity, levelVisibility, v
for ( x = tileTL.x; x <= tileBR.x; x++ ) { for ( x = tileTL.x; x <= tileBR.x; x++ ) {
for ( y = tileTL.y; y <= tileBR.y; y++ ) { for ( y = tileTL.y; y <= tileBR.y; y++ ) {
best = updateTile( best = updateTile(
drawer, drawer,
drawLevel, drawLevel,
haveDrawn, haveDrawn,
@ -662,21 +662,21 @@ function updateLevel( drawer, haveDrawn, level, levelOpacity, levelVisibility, v
} }
function updateTile( drawer, drawLevel, haveDrawn, x, y, level, levelOpacity, levelVisibility, viewportCenter, numberOfTiles, currentTime, best){ function updateTile( drawer, drawLevel, haveDrawn, x, y, level, levelOpacity, levelVisibility, viewportCenter, numberOfTiles, currentTime, best){
var tile = getTile( var tile = getTile(
x, y, x, y,
level, level,
drawer.source, drawer.source,
drawer.tilesMatrix, drawer.tilesMatrix,
currentTime, currentTime,
numberOfTiles, numberOfTiles,
drawer.normHeight drawer.normHeight
), ),
drawTile = drawLevel, drawTile = drawLevel,
newbest; newbest;
if( drawer.viewer ){ if( drawer.viewer ){
drawer.viewer.raiseEvent( 'update-tile', { drawer.viewer.raiseEvent( 'update-tile', {
viewer: drawer.viewer, viewer: drawer.viewer,
tile: tile tile: tile
}); });
@ -700,29 +700,29 @@ function updateTile( drawer, drawLevel, haveDrawn, x, y, level, levelOpacity, le
return best; return best;
} }
positionTile( positionTile(
tile, tile,
drawer.source.tileOverlap, drawer.source.tileOverlap,
drawer.viewport, drawer.viewport,
viewportCenter, viewportCenter,
levelVisibility levelVisibility
); );
if ( tile.loaded ) { if ( tile.loaded ) {
var needsUpdate = blendTile( var needsUpdate = blendTile(
drawer, drawer,
tile, tile,
x, y, x, y,
level, level,
levelOpacity, levelOpacity,
currentTime currentTime
); );
if ( needsUpdate ) { if ( needsUpdate ) {
drawer.updateAgain = true; drawer.updateAgain = true;
} }
} else if ( tile.loading ) { } else if ( tile.loading ) {
// the tile is already in the download queue // the tile is already in the download queue
// thanks josh1093 for finally translating this typo // thanks josh1093 for finally translating this typo
} else { } else {
best = compareTiles( best, tile ); best = compareTiles( best, tile );
@ -757,11 +757,11 @@ function getTile( x, y, level, tileSource, tilesMatrix, time, numTiles, normHeig
bounds.y += normHeight * ( y - yMod ) / numTiles.y; bounds.y += normHeight * ( y - yMod ) / numTiles.y;
tilesMatrix[ level ][ x ][ y ] = new $.Tile( tilesMatrix[ level ][ x ][ y ] = new $.Tile(
level, level,
x, x,
y, y,
bounds, bounds,
exists, exists,
url url
); );
} }
@ -843,7 +843,7 @@ function onTileLoad( drawer, tile, time, image ) {
prevLevel = prevTile.level; prevLevel = prevTile.level;
worstLevel = worstTile.level; worstLevel = worstTile.level;
if ( prevTime < worstTime || if ( prevTime < worstTime ||
( prevTime == worstTime && prevLevel > worstLevel ) ) { ( prevTime == worstTime && prevLevel > worstLevel ) ) {
worstTile = prevTile; worstTile = prevTile;
worstTileIndex = i; worstTileIndex = i;
@ -893,7 +893,7 @@ function blendTile( drawer, tile, x, y, level, levelOpacity, currentTime ){
deltaTime = currentTime - tile.blendStart; deltaTime = currentTime - tile.blendStart;
opacity = blendTimeMillis ? Math.min( 1, deltaTime / ( blendTimeMillis ) ) : 1; opacity = blendTimeMillis ? Math.min( 1, deltaTime / ( blendTimeMillis ) ) : 1;
if ( drawer.alwaysBlend ) { if ( drawer.alwaysBlend ) {
opacity *= levelOpacity; opacity *= levelOpacity;
} }
@ -923,7 +923,7 @@ function clearTiles( drawer ) {
* Returns true if the given tile provides coverage to lower-level tiles of * Returns true if the given tile provides coverage to lower-level tiles of
* lower resolution representing the same content. If neither x nor y is * lower resolution representing the same content. If neither x nor y is
* given, returns true if the entire visible level provides coverage. * given, returns true if the entire visible level provides coverage.
* *
* Note that out-of-bounds tiles provide coverage in this sense, since * Note that out-of-bounds tiles provide coverage in this sense, since
* there's no content that they would need to cover. Tiles at non-existent * there's no content that they would need to cover. Tiles at non-existent
* levels that are within the image bounds, however, do not. * levels that are within the image bounds, however, do not.
@ -988,7 +988,7 @@ function isCovered( coverage, level, x, y ) {
function setCoverage( coverage, level, x, y, covers ) { function setCoverage( coverage, level, x, y, covers ) {
if ( !coverage[ level ] ) { if ( !coverage[ level ] ) {
$.console.warn( $.console.warn(
"Setting coverage for a tile before its level's coverage has been reset: %s", "Setting coverage for a tile before its level's coverage has been reset: %s",
level level
); );
return; return;
@ -1006,7 +1006,7 @@ function setCoverage( coverage, level, x, y, covers ) {
* @inner * @inner
* Resets coverage information for the given level. This should be called * Resets coverage information for the given level. This should be called
* after every draw routine. Note that at the beginning of the next draw * after every draw routine. Note that at the beginning of the next draw
* routine, coverage for every visible tile should be explicitly set. * routine, coverage for every visible tile should be explicitly set.
*/ */
function resetCoverage( coverage, level ) { function resetCoverage( coverage, level ) {
coverage[ level ] = {}; coverage[ level ] = {};
@ -1032,7 +1032,7 @@ function getOverlayIndex( overlays, element ) {
/** /**
* @private * @private
* @inner * @inner
* Determines whether the 'last best' tile for the area is better than the * Determines whether the 'last best' tile for the area is better than the
* tile in question. * tile in question.
*/ */
function compareTiles( previousBest, tile ) { function compareTiles( previousBest, tile ) {
@ -1078,18 +1078,18 @@ function drawOverlays( viewport, overlays, container ){
function drawOverlay( viewport, overlay, container ){ function drawOverlay( viewport, overlay, container ){
overlay.position = viewport.pixelFromPoint( overlay.position = viewport.pixelFromPoint(
overlay.bounds.getTopLeft(), overlay.bounds.getTopLeft(),
true true
); );
overlay.size = viewport.deltaPixelsFromPoints( overlay.size = viewport.deltaPixelsFromPoints(
overlay.bounds.getSize(), overlay.bounds.getSize(),
true true
); );
overlay.drawHTML( container ); overlay.drawHTML( container );
} }
function drawTiles( drawer, lastDrawn ){ function drawTiles( drawer, lastDrawn ){
var i, var i,
tile, tile,
tileKey, tileKey,
viewer, viewer,
@ -1100,21 +1100,21 @@ function drawTiles( drawer, lastDrawn ){
for ( i = lastDrawn.length - 1; i >= 0; i-- ) { for ( i = lastDrawn.length - 1; i >= 0; i-- ) {
tile = lastDrawn[ i ]; tile = lastDrawn[ i ];
//We dont actually 'draw' a collection tile, rather its used to house //We dont actually 'draw' a collection tile, rather its used to house
//an overlay which does the drawing in its own viewport //an overlay which does the drawing in its own viewport
if( drawer.viewport.collectionMode ){ if( drawer.viewport.collectionMode ){
tileKey = tile.x + '/' + tile.y; tileKey = tile.x + '/' + tile.y;
viewport = drawer.viewport; viewport = drawer.viewport;
collectionTileSource = viewport.collectionTileSource; collectionTileSource = viewport.collectionTileSource;
if( !drawer.collectionOverlays[ tileKey ] ){ if( !drawer.collectionOverlays[ tileKey ] ){
position = collectionTileSource.layout == 'horizontal' ? position = collectionTileSource.layout == 'horizontal' ?
tile.y + ( tile.x * collectionTileSource.rows ) : tile.y + ( tile.x * collectionTileSource.rows ) :
tile.x + ( tile.y * collectionTileSource.rows ), tile.x + ( tile.y * collectionTileSource.rows ),
tileSource = position < collectionTileSource.tileSources.length ? tileSource = position < collectionTileSource.tileSources.length ?
collectionTileSource.tileSources[ position ] : collectionTileSource.tileSources[ position ] :
null; null;
@ -1131,24 +1131,24 @@ function drawTiles( drawer, lastDrawn ){
tileSource tileSource
] ]
}); });
//TODO: IE seems to barf on this, not sure if its just the border //TODO: IE seems to barf on this, not sure if its just the border
// but we probably need to clear this up with a better // but we probably need to clear this up with a better
// test of support for various css features // test of support for various css features
if( SUBPIXEL_RENDERING ){ if( SUBPIXEL_RENDERING ){
viewer.element.style.border = '1px solid rgba(255,255,255,0.38)'; viewer.element.style.border = '1px solid rgba(255,255,255,0.38)';
viewer.element.style['-webkit-box-reflect'] = viewer.element.style['-webkit-box-reflect'] =
'below 0px -webkit-gradient('+ 'below 0px -webkit-gradient('+
'linear,left '+ 'linear,left '+
'top,left '+ 'top,left '+
'bottom,from(transparent),color-stop(62%,transparent),to(rgba(255,255,255,0.62))'+ 'bottom,from(transparent),color-stop(62%,transparent),to(rgba(255,255,255,0.62))'+
')'; ')';
} }
drawer.addOverlay( drawer.addOverlay(
viewer.element, viewer.element,
tile.bounds tile.bounds
); );
} }
}else{ }else{
@ -1180,7 +1180,7 @@ function drawTiles( drawer, lastDrawn ){
} }
if( drawer.viewer ){ if( drawer.viewer ){
drawer.viewer.raiseEvent( 'tile-drawn', { drawer.viewer.raiseEvent( 'tile-drawn', {
viewer: drawer.viewer, viewer: drawer.viewer,
tile: tile tile: tile
}); });
@ -1197,52 +1197,52 @@ function drawDebugInfo( drawer, tile, count, i ){
drawer.context.font = 'small-caps bold 13px ariel'; drawer.context.font = 'small-caps bold 13px ariel';
drawer.context.strokeStyle = drawer.debugGridColor; drawer.context.strokeStyle = drawer.debugGridColor;
drawer.context.fillStyle = drawer.debugGridColor; drawer.context.fillStyle = drawer.debugGridColor;
drawer.context.strokeRect( drawer.context.strokeRect(
tile.position.x, tile.position.x,
tile.position.y, tile.position.y,
tile.size.x, tile.size.x,
tile.size.y tile.size.y
); );
if( tile.x === 0 && tile.y === 0 ){ if( tile.x === 0 && tile.y === 0 ){
drawer.context.fillText( drawer.context.fillText(
"Zoom: " + drawer.viewport.getZoom(), "Zoom: " + drawer.viewport.getZoom(),
tile.position.x, tile.position.x,
tile.position.y - 30 tile.position.y - 30
); );
drawer.context.fillText( drawer.context.fillText(
"Pan: " + drawer.viewport.getBounds().toString(), "Pan: " + drawer.viewport.getBounds().toString(),
tile.position.x, tile.position.x,
tile.position.y - 20 tile.position.y - 20
); );
} }
drawer.context.fillText( drawer.context.fillText(
"Level: " + tile.level, "Level: " + tile.level,
tile.position.x + 10, tile.position.x + 10,
tile.position.y + 20 tile.position.y + 20
); );
drawer.context.fillText( drawer.context.fillText(
"Column: " + tile.x, "Column: " + tile.x,
tile.position.x + 10, tile.position.x + 10,
tile.position.y + 30 tile.position.y + 30
); );
drawer.context.fillText( drawer.context.fillText(
"Row: " + tile.y, "Row: " + tile.y,
tile.position.x + 10, tile.position.x + 10,
tile.position.y + 40 tile.position.y + 40
); );
drawer.context.fillText( drawer.context.fillText(
"Order: " + i + " of " + count, "Order: " + i + " of " + count,
tile.position.x + 10, tile.position.x + 10,
tile.position.y + 50 tile.position.y + 50
); );
drawer.context.fillText( drawer.context.fillText(
"Size: " + tile.size.toString(), "Size: " + tile.size.toString(),
tile.position.x + 10, tile.position.x + 10,
tile.position.y + 60 tile.position.y + 60
); );
drawer.context.fillText( drawer.context.fillText(
"Position: " + tile.position.toString(), "Position: " + tile.position.toString(),
tile.position.x + 10, tile.position.x + 10,
tile.position.y + 70 tile.position.y + 70
); );
drawer.context.restore(); drawer.context.restore();

View File

@ -33,7 +33,7 @@
*/ */
(function( $ ){ (function( $ ){
/** /**
* @class * @class
* @extends OpenSeadragon.TileSource * @extends OpenSeadragon.TileSource
@ -48,13 +48,13 @@
* @property {String} tilesUrl * @property {String} tilesUrl
* @property {String} fileFormat * @property {String} fileFormat
* @property {OpenSeadragon.DisplayRect[]} displayRects * @property {OpenSeadragon.DisplayRect[]} displayRects
*/ */
$.DziTileSource = function( width, height, tileSize, tileOverlap, tilesUrl, fileFormat, displayRects, minLevel, maxLevel ) { $.DziTileSource = function( width, height, tileSize, tileOverlap, tilesUrl, fileFormat, displayRects, minLevel, maxLevel ) {
var i, var i,
rect, rect,
level, level,
options; options;
if( $.isPlainObject( width ) ){ if( $.isPlainObject( width ) ){
options = width; options = width;
}else{ }else{
@ -66,7 +66,7 @@ $.DziTileSource = function( width, height, tileSize, tileOverlap, tilesUrl, file
tilesUrl: arguments[ 4 ], tilesUrl: arguments[ 4 ],
fileFormat: arguments[ 5 ], fileFormat: arguments[ 5 ],
displayRects: arguments[ 6 ], displayRects: arguments[ 6 ],
minLevel: arguments[ 7 ], minLevel: arguments[ 7 ],
maxLevel: arguments[ 8 ] maxLevel: arguments[ 8 ]
}; };
} }
@ -75,7 +75,7 @@ $.DziTileSource = function( width, height, tileSize, tileOverlap, tilesUrl, file
this.tilesUrl = options.tilesUrl; this.tilesUrl = options.tilesUrl;
this.fileFormat = options.fileFormat; this.fileFormat = options.fileFormat;
this.displayRects = options.displayRects; this.displayRects = options.displayRects;
if ( this.displayRects ) { if ( this.displayRects ) {
for ( i = this.displayRects.length - 1; i >= 0; i-- ) { for ( i = this.displayRects.length - 1; i >= 0; i-- ) {
rect = this.displayRects[ i ]; rect = this.displayRects[ i ];
@ -87,7 +87,7 @@ $.DziTileSource = function( width, height, tileSize, tileOverlap, tilesUrl, file
} }
} }
} }
$.TileSource.apply( this, [ options ] ); $.TileSource.apply( this, [ options ] );
}; };
@ -116,12 +116,12 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, {
}, },
/** /**
* *
* @function * @function
* @name OpenSeadragon.DziTileSource.prototype.configure * @name OpenSeadragon.DziTileSource.prototype.configure
* @param {Object|XMLDocument} data - the raw configuration * @param {Object|XMLDocument} data - the raw configuration
* @param {String} url - the url the data was retreived from if any. * @param {String} url - the url the data was retreived from if any.
* @return {Object} options - A dictionary of keyword arguments sufficient * @return {Object} options - A dictionary of keyword arguments sufficient
* to configure this tile sources constructor. * to configure this tile sources constructor.
*/ */
configure: function( data, url ){ configure: function( data, url ){
@ -216,7 +216,7 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, {
* @function * @function
*/ */
function configureFromXML( tileSource, xmlDoc ){ function configureFromXML( tileSource, xmlDoc ){
if ( !xmlDoc || !xmlDoc.documentElement ) { if ( !xmlDoc || !xmlDoc.documentElement ) {
throw new Error( $.getString( "Errors.Xml" ) ); throw new Error( $.getString( "Errors.Xml" ) );
} }
@ -232,7 +232,7 @@ function configureFromXML( tileSource, xmlDoc ){
i; i;
if ( rootName == "Image" ) { if ( rootName == "Image" ) {
try { try {
sizeNode = root.getElementsByTagName( "Size" )[ 0 ]; sizeNode = root.getElementsByTagName( "Size" )[ 0 ];
configuration = { configuration = {
@ -241,7 +241,7 @@ function configureFromXML( tileSource, xmlDoc ){
Url: root.getAttribute( "Url" ), Url: root.getAttribute( "Url" ),
Format: root.getAttribute( "Format" ), Format: root.getAttribute( "Format" ),
DisplayRect: null, DisplayRect: null,
Overlap: parseInt( root.getAttribute( "Overlap" ), 10 ), Overlap: parseInt( root.getAttribute( "Overlap" ), 10 ),
TileSize: parseInt( root.getAttribute( "TileSize" ), 10 ), TileSize: parseInt( root.getAttribute( "TileSize" ), 10 ),
Size: { Size: {
Height: parseInt( sizeNode.getAttribute( "Height" ), 10 ), Height: parseInt( sizeNode.getAttribute( "Height" ), 10 ),
@ -255,7 +255,7 @@ function configureFromXML( tileSource, xmlDoc ){
$.getString( "Errors.ImageFormat", configuration.Image.Format.toUpperCase() ) $.getString( "Errors.ImageFormat", configuration.Image.Format.toUpperCase() )
); );
} }
dispRectNodes = root.getElementsByTagName( "DisplayRect" ); dispRectNodes = root.getElementsByTagName( "DisplayRect" );
for ( i = 0; i < dispRectNodes.length; i++ ) { for ( i = 0; i < dispRectNodes.length; i++ ) {
dispRectNode = dispRectNodes[ i ]; dispRectNode = dispRectNodes[ i ];
@ -280,8 +280,8 @@ function configureFromXML( tileSource, xmlDoc ){
return configureFromObject( tileSource, configuration ); return configureFromObject( tileSource, configuration );
} catch ( e ) { } catch ( e ) {
throw (e instanceof Error) ? throw (e instanceof Error) ?
e : e :
new Error( $.getString("Errors.Dzi") ); new Error( $.getString("Errors.Dzi") );
} }
} else if ( rootName == "Collection" ) { } else if ( rootName == "Collection" ) {
@ -314,7 +314,7 @@ function configureFromObject( tileSource, configuration ){
//TODO: need to figure out out to better handle image format compatibility //TODO: need to figure out out to better handle image format compatibility
// which actually includes additional file formats like xml and pdf // which actually includes additional file formats like xml and pdf
// and plain text for various tilesource implementations to avoid low // and plain text for various tilesource implementations to avoid low
// level errors. // level errors.
// //
// For now, just don't perform the check. // For now, just don't perform the check.

View File

@ -37,10 +37,10 @@
/** /**
* For use by classes which want to support custom, non-browser events. * For use by classes which want to support custom, non-browser events.
* TODO: This is an aweful name! This thing represents an "event source", * TODO: This is an aweful name! This thing represents an "event source",
* not an "event handler". PLEASE change the to EventSource. Also please * not an "event handler". PLEASE change the to EventSource. Also please
* change 'addHandler', 'removeHandler' and 'raiseEvent' to 'bind', * change 'addHandler', 'removeHandler' and 'raiseEvent' to 'bind',
* 'unbind', and 'trigger' respectively. Finally add a method 'one' which * 'unbind', and 'trigger' respectively. Finally add a method 'one' which
* automatically unbinds a listener after the first triggered event that * automatically unbinds a listener after the first triggered event that
* matches. * matches.
* @class * @class
*/ */
@ -76,15 +76,15 @@ $.EventHandler.prototype = {
var events = this.events[ eventName ], var events = this.events[ eventName ],
handlers = [], handlers = [],
i; i;
if ( !events ){ if ( !events ){
return; return;
} }
if( $.isArray( events ) ){ if( $.isArray( events ) ){
for( i = 0; i < events.length; i++ ){ for( i = 0; i < events.length; i++ ){
if( events[ i ] !== handler ){ if( events[ i ] !== handler ){
handlers.push( events[ i ] ); handlers.push( events[ i ] );
} }
} }
this.events[ eventName ] = handlers; this.events[ eventName ] = handlers;
} }
}, },
@ -97,7 +97,7 @@ $.EventHandler.prototype = {
*/ */
removeAllHandlers: function( eventName ){ removeAllHandlers: function( eventName ){
this.events[ eventName ] = []; this.events[ eventName ] = [];
}, },
/** /**
@ -106,15 +106,15 @@ $.EventHandler.prototype = {
* @param {String} eventName - Name of event to get handlers for. * @param {String} eventName - Name of event to get handlers for.
*/ */
getHandler: function( eventName ) { getHandler: function( eventName ) {
var events = this.events[ eventName ]; var events = this.events[ eventName ];
if ( !events || !events.length ){ if ( !events || !events.length ){
return null; return null;
} }
events = events.length === 1 ? events = events.length === 1 ?
[ events[ 0 ] ] : [ events[ 0 ] ] :
Array.apply( null, events ); Array.apply( null, events );
return function( source, args ) { return function( source, args ) {
var i, var i,
length = events.length; length = events.length;
for ( i = 0; i < length; i++ ) { for ( i = 0; i < length; i++ ) {
if( events[ i ] ){ if( events[ i ] ){

View File

@ -61,7 +61,7 @@
/** /**
* Determines the appropriate level of native full screen support we can get * Determines the appropriate level of native full screen support we can get
* from the browser. * from the browser.
* @name $.supportsFullScreen * @name $.supportsFullScreen
*/ */
@ -75,7 +75,7 @@
prefix: '' prefix: ''
}, },
browserPrefixes = 'webkit moz o ms khtml'.split(' '); browserPrefixes = 'webkit moz o ms khtml'.split(' ');
// check for native support // check for native support
if (typeof document.cancelFullScreen != 'undefined') { if (typeof document.cancelFullScreen != 'undefined') {
fullScreenApi.supportsFullScreen = true; fullScreenApi.supportsFullScreen = true;
@ -83,19 +83,19 @@
// check for fullscreen support by vendor prefix // check for fullscreen support by vendor prefix
for (var i = 0, il = browserPrefixes.length; i < il; i++ ) { for (var i = 0, il = browserPrefixes.length; i < il; i++ ) {
fullScreenApi.prefix = browserPrefixes[i]; fullScreenApi.prefix = browserPrefixes[i];
if (typeof document[fullScreenApi.prefix + 'CancelFullScreen' ] != 'undefined' ) { if (typeof document[fullScreenApi.prefix + 'CancelFullScreen' ] != 'undefined' ) {
fullScreenApi.supportsFullScreen = true; fullScreenApi.supportsFullScreen = true;
break; break;
} }
} }
} }
// update methods to do something useful // update methods to do something useful
if (fullScreenApi.supportsFullScreen) { if (fullScreenApi.supportsFullScreen) {
fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange'; fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
fullScreenApi.isFullScreen = function() { fullScreenApi.isFullScreen = function() {
switch (this.prefix) { switch (this.prefix) {
case '': case '':
@ -107,14 +107,14 @@
} }
}; };
fullScreenApi.requestFullScreen = function( element ) { fullScreenApi.requestFullScreen = function( element ) {
return (this.prefix === '') ? return (this.prefix === '') ?
element.requestFullScreen() : element.requestFullScreen() :
element[this.prefix + 'RequestFullScreen'](); element[this.prefix + 'RequestFullScreen']();
}; };
fullScreenApi.cancelFullScreen = function( element ) { fullScreenApi.cancelFullScreen = function( element ) {
return (this.prefix === '') ? return (this.prefix === '') ?
document.cancelFullScreen() : document.cancelFullScreen() :
document[this.prefix + 'CancelFullScreen'](); document[this.prefix + 'CancelFullScreen']();
}; };
} else if ( typeof window.ActiveXObject !== "undefined" ){ } else if ( typeof window.ActiveXObject !== "undefined" ){
@ -130,7 +130,7 @@
fullScreenApi.cancelFullScreen = fullScreenApi.requestFullScreen; fullScreenApi.cancelFullScreen = fullScreenApi.requestFullScreen;
} }
// export api // export api
$.extend( $, fullScreenApi ); $.extend( $, fullScreenApi );

View File

@ -40,11 +40,11 @@
(function( $ ){ (function( $ ){
/** /**
* A client implementation of the International Image Interoperability * A client implementation of the International Image Interoperability
* Format: Image API Draft 0.2 - Please read more about the specification * Format: Image API Draft 0.2 - Please read more about the specification
* at * at
* *
* @class * @class
* @extends OpenSeadragon.TileSource * @extends OpenSeadragon.TileSource
@ -65,10 +65,10 @@ $.IIIFTileSource = function( options ){
// to preserve backward compatibility. // to preserve backward compatibility.
options.tileSize = this.tile_width; options.tileSize = this.tile_width;
options.maxLevel = options.maxLevel ? options.maxLevel : Number( options.maxLevel = options.maxLevel ? options.maxLevel : Number(
Math.ceil( Math.log( Math.max( this.width, this.height ), 2 ) ) Math.ceil( Math.log( Math.max( this.width, this.height ), 2 ) )
); );
$.TileSource.apply( this, [ options ] ); $.TileSource.apply( this, [ options ] );
}; };
@ -82,15 +82,15 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
* @param {String} optional - url * @param {String} optional - url
*/ */
supports: function( data, url ){ supports: function( data, url ){
return ( return (
data.ns && data.ns &&
"http://library.stanford.edu/iiif/image-api/ns/" == data.ns "http://library.stanford.edu/iiif/image-api/ns/" == data.ns
) || ( ) || (
data.profile && ( data.profile && (
"http://library.stanford.edu/iiif/image-api/compliance.html#level1" == data.profile || "http://library.stanford.edu/iiif/image-api/compliance.html#level1" == data.profile ||
"http://library.stanford.edu/iiif/image-api/compliance.html#level2" == data.profile || "http://library.stanford.edu/iiif/image-api/compliance.html#level2" == data.profile ||
"http://library.stanford.edu/iiif/image-api/compliance.html#level3" == data.profile || "http://library.stanford.edu/iiif/image-api/compliance.html#level3" == data.profile ||
"http://library.stanford.edu/iiif/image-api/compliance.html" == data.profile "http://library.stanford.edu/iiif/image-api/compliance.html" == data.profile
) )
) || ( ) || (
data.documentElement && data.documentElement &&
@ -101,12 +101,12 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
}, },
/** /**
* *
* @function * @function
* @name OpenSeadragon.IIIFTileSource.prototype.configure * @name OpenSeadragon.IIIFTileSource.prototype.configure
* @param {Object|XMLDocument} data - the raw configuration * @param {Object|XMLDocument} data - the raw configuration
* @param {String} url - the url the data was retreived from if any. * @param {String} url - the url the data was retreived from if any.
* @return {Object} options - A dictionary of keyword arguments sufficient * @return {Object} options - A dictionary of keyword arguments sufficient
* to configure this tile source via it's constructor. * to configure this tile source via it's constructor.
*/ */
configure: function( data, url ){ configure: function( data, url ){
@ -142,7 +142,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
}, },
/** /**
* Responsible for retreiving the url which will return an image for the * Responsible for retreiving the url which will return an image for the
* region speified by the given x, y, and level components. * region speified by the given x, y, and level components.
* @function * @function
* @name OpenSeadragon.IIIFTileSource.prototype.getTileUrl * @name OpenSeadragon.IIIFTileSource.prototype.getTileUrl
@ -152,21 +152,21 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
* @throws {Error} * @throws {Error}
*/ */
getTileUrl: function( level, x, y ){ getTileUrl: function( level, x, y ){
//# constants //# constants
var IIIF_ROTATION = '0', var IIIF_ROTATION = '0',
IIIF_QUALITY = 'native.jpg', IIIF_QUALITY = 'native.jpg',
//## get the scale (level as a decimal) //## get the scale (level as a decimal)
scale = Math.pow( 0.5, this.maxLevel - level ), scale = Math.pow( 0.5, this.maxLevel - level ),
//## get iiif size //## get iiif size
iiif_size = 'pct:' + ( scale * 100 ), iiif_size = 'pct:' + ( scale * 100 ),
//# image dimensions at this level //# image dimensions at this level
level_width = Math.ceil( this.width * scale ), level_width = Math.ceil( this.width * scale ),
level_height = Math.ceil( this.height * scale ), level_height = Math.ceil( this.height * scale ),
//## iiif region //## iiif region
iiif_tile_size_width = Math.ceil( this.tileSize / scale ), iiif_tile_size_width = Math.ceil( this.tileSize / scale ),
iiif_tile_size_height = Math.ceil( this.tileSize / scale ), iiif_tile_size_height = Math.ceil( this.tileSize / scale ),
@ -175,8 +175,8 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
iiif_tile_y, iiif_tile_y,
iiif_tile_w, iiif_tile_w,
iiif_tile_h; iiif_tile_h;
if ( level_width < this.tile_width || level_height < this.tile_height ){ if ( level_width < this.tile_width || level_height < this.tile_height ){
iiif_region = 'full'; iiif_region = 'full';
} else { } else {
@ -186,14 +186,14 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
iiif_tile_h = Math.min( iiif_tile_size_height, this.height - iiif_tile_y ); iiif_tile_h = Math.min( iiif_tile_size_height, this.height - iiif_tile_y );
iiif_region = [ iiif_tile_x, iiif_tile_y, iiif_tile_w, iiif_tile_h ].join(','); iiif_region = [ iiif_tile_x, iiif_tile_y, iiif_tile_w, iiif_tile_h ].join(',');
} }
return [ return [
this.tilesUrl, this.tilesUrl,
this.identifier, this.identifier,
iiif_region, iiif_region,
iiif_size, iiif_size,
IIIF_ROTATION, IIIF_ROTATION,
IIIF_QUALITY IIIF_QUALITY
].join('/'); ].join('/');
} }
@ -204,7 +204,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, {
* @private * @private
* @inner * @inner
* @function * @function
* *
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<info xmlns="http://library.stanford.edu/iiif/image-api/ns/"> <info xmlns="http://library.stanford.edu/iiif/image-api/ns/">
<identifier>1E34750D-38DB-4825-A38A-B60A345E591C</identifier> <identifier>1E34750D-38DB-4825-A38A-B60A345E591C</identifier>
@ -243,7 +243,7 @@ function configureFromXml( tileSource, xmlDoc ){
i; i;
if ( rootName == "info" ) { if ( rootName == "info" ) {
try { try {
configuration = { configuration = {
@ -255,8 +255,8 @@ function configureFromXml( tileSource, xmlDoc ){
return configureFromObject( tileSource, configuration ); return configureFromObject( tileSource, configuration );
} catch ( e ) { } catch ( e ) {
throw (e instanceof Error) ? throw (e instanceof Error) ?
e : e :
new Error( $.getString("Errors.IIIF") ); new Error( $.getString("Errors.IIIF") );
} }
} }
@ -299,8 +299,8 @@ function parseXML( node, configuration, property ){
* @private * @private
* @inner * @inner
* @function * @function
* *
{ {
"profile" : "http://library.stanford.edu/iiif/image-api/compliance.html#level1", "profile" : "http://library.stanford.edu/iiif/image-api/compliance.html#level1",
"identifier" : "1E34750D-38DB-4825-A38A-B60A345E591C", "identifier" : "1E34750D-38DB-4825-A38A-B60A345E591C",
"width" : 6000, "width" : 6000,
@ -310,7 +310,7 @@ function parseXML( node, configuration, property ){
"tile_height" : 1024, "tile_height" : 1024,
"formats" : [ "jpg", "png" ], "formats" : [ "jpg", "png" ],
"quality" : [ "native", "grey" ] "quality" : [ "native", "grey" ]
} }
*/ */
function configureFromObject( tileSource, configuration ){ function configureFromObject( tileSource, configuration ){
//the image_host property is not part of the iiif standard but is included here to //the image_host property is not part of the iiif standard but is included here to

View File

@ -38,7 +38,7 @@
* The LegacyTileSource allows simple, traditional image pyramids to be loaded * The LegacyTileSource allows simple, traditional image pyramids to be loaded
* into an OpenSeadragon Viewer. Basically, this translates to the historically * into an OpenSeadragon Viewer. Basically, this translates to the historically
* common practice of starting with a 'master' image, maybe a tiff for example, * common practice of starting with a 'master' image, maybe a tiff for example,
* and generating a set of 'service' images like one or more thumbnails, a medium * and generating a set of 'service' images like one or more thumbnails, a medium
* resolution image and a high resolution image in standard web formats like * resolution image and a high resolution image in standard web formats like
* png or jpg. * png or jpg.
* @class * @class
@ -55,7 +55,7 @@
* @property {Number} minLevel * @property {Number} minLevel
* @property {Number} maxLevel * @property {Number} maxLevel
* @property {Array} levels * @property {Array} levels
*/ */
$.LegacyTileSource = function( levels ) { $.LegacyTileSource = function( levels ) {
var options, var options,
@ -98,8 +98,8 @@ $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, {
* @param {String} optional - url * @param {String} optional - url
*/ */
supports: function( data, url ){ supports: function( data, url ){
return ( return (
data.type && data.type &&
"legacy-image-pyramid" == data.type "legacy-image-pyramid" == data.type
) || ( ) || (
data.documentElement && data.documentElement &&
@ -109,12 +109,12 @@ $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, {
/** /**
* *
* @function * @function
* @name OpenSeadragon.LegacyTileSource.prototype.configure * @name OpenSeadragon.LegacyTileSource.prototype.configure
* @param {Object|XMLDocument} configuration - the raw configuration * @param {Object|XMLDocument} configuration - the raw configuration
* @param {String} dataUrl - the url the data was retreived from if any. * @param {String} dataUrl - the url the data was retreived from if any.
* @return {Object} options - A dictionary of keyword arguments sufficient * @return {Object} options - A dictionary of keyword arguments sufficient
* to configure this tile sources constructor. * to configure this tile sources constructor.
*/ */
configure: function( configuration, dataUrl ){ configure: function( configuration, dataUrl ){
@ -133,7 +133,7 @@ $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, {
return options; return options;
}, },
/** /**
* @function * @function
* @name OpenSeadragon.LegacyTileSource.prototype.getLevelScale * @name OpenSeadragon.LegacyTileSource.prototype.getLevelScale
@ -142,10 +142,10 @@ $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, {
getLevelScale: function( level ) { getLevelScale: function( level ) {
var levelScale = NaN; var levelScale = NaN;
if ( level >= this.minLevel && level <= this.maxLevel ){ if ( level >= this.minLevel && level <= this.maxLevel ){
levelScale = levelScale =
this.levels[ level ].width / this.levels[ level ].width /
this.levels[ this.maxLevel ].width; this.levels[ this.maxLevel ].width;
} }
return levelScale; return levelScale;
}, },
@ -176,7 +176,7 @@ $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, {
/** /**
* This method is not implemented by this class other than to throw an Error * This method is not implemented by this class other than to throw an Error
* announcing you have to implement it. Because of the variety of tile * announcing you have to implement it. Because of the variety of tile
* server technologies, and various specifications for building image * server technologies, and various specifications for building image
* pyramids, this method is here to allow easy integration. * pyramids, this method is here to allow easy integration.
* @function * @function
@ -188,7 +188,7 @@ $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, {
*/ */
getTileUrl: function( level, x, y ) { getTileUrl: function( level, x, y ) {
var url = null; var url = null;
if( level >= this.minLevel && level <= this.maxLevel ){ if( level >= this.minLevel && level <= this.maxLevel ){
url = this.levels[ level ].url; url = this.levels[ level ].url;
} }
return url; return url;
@ -208,12 +208,12 @@ function filterFiles( files ){
i; i;
for( i = 0; i < files.length; i++ ){ for( i = 0; i < files.length; i++ ){
file = files[ i ]; file = files[ i ];
if( file.height && if( file.height &&
file.width && file.width &&
file.url && ( file.url && (
file.url.toLowerCase().match(/^.*\.(png|jpg|jpeg|gif)$/) || ( file.url.toLowerCase().match(/^.*\.(png|jpg|jpeg|gif)$/) || (
file.mimetype && file.mimetype &&
file.mimetype.toLowerCase().match(/^.*\/(png|jpg|jpeg|gif)$/) file.mimetype.toLowerCase().match(/^.*\/(png|jpg|jpeg|gif)$/)
) )
) ){ ) ){
//This is sufficient to serve as a level //This is sufficient to serve as a level
@ -237,7 +237,7 @@ function filterFiles( files ){
* @function * @function
*/ */
function configureFromXML( tileSource, xmlDoc ){ function configureFromXML( tileSource, xmlDoc ){
if ( !xmlDoc || !xmlDoc.documentElement ) { if ( !xmlDoc || !xmlDoc.documentElement ) {
throw new Error( $.getString( "Errors.Xml" ) ); throw new Error( $.getString( "Errors.Xml" ) );
} }
@ -250,13 +250,13 @@ function configureFromXML( tileSource, xmlDoc ){
i; i;
if ( rootName == "image" ) { if ( rootName == "image" ) {
try { try {
conf = { conf = {
type: root.getAttribute( "type" ), type: root.getAttribute( "type" ),
levels: [] levels: []
}; };
levels = root.getElementsByTagName( "level" ); levels = root.getElementsByTagName( "level" );
for ( i = 0; i < levels.length; i++ ) { for ( i = 0; i < levels.length; i++ ) {
level = levels[ i ]; level = levels[ i ];
@ -271,8 +271,8 @@ function configureFromXML( tileSource, xmlDoc ){
return configureFromObject( tileSource, conf ); return configureFromObject( tileSource, conf );
} catch ( e ) { } catch ( e ) {
throw (e instanceof Error) ? throw (e instanceof Error) ?
e : e :
new Error( 'Unknown error parsing Legacy Image Pyramid XML.' ); new Error( 'Unknown error parsing Legacy Image Pyramid XML.' );
} }
} else if ( rootName == "collection" ) { } else if ( rootName == "collection" ) {
@ -290,7 +290,7 @@ function configureFromXML( tileSource, xmlDoc ){
* @function * @function
*/ */
function configureFromObject( tileSource, configuration ){ function configureFromObject( tileSource, configuration ){
return configuration.levels; return configuration.levels;
} }

View File

@ -33,36 +33,36 @@
*/ */
(function( $ ){ (function( $ ){
// is any button currently being pressed while mouse events occur // is any button currently being pressed while mouse events occur
var IS_BUTTON_DOWN = false, var IS_BUTTON_DOWN = false,
// is any tracker currently capturing? // is any tracker currently capturing?
IS_CAPTURING = false, IS_CAPTURING = false,
// dictionary from hash to MouseTracker // dictionary from hash to MouseTracker
ACTIVE = {}, ACTIVE = {},
// list of trackers interested in capture // list of trackers interested in capture
CAPTURING = [], CAPTURING = [],
// dictionary from hash to private properties // dictionary from hash to private properties
THIS = {}; THIS = {};
/** /**
* The MouseTracker allows other classes to set handlers for common mouse * The MouseTracker allows other classes to set handlers for common mouse
* events on a specific element like, 'enter', 'exit', 'press', 'release', * events on a specific element like, 'enter', 'exit', 'press', 'release',
* 'scroll', 'click', and 'drag'. * 'scroll', 'click', and 'drag'.
* @class * @class
* @param {Object} options * @param {Object} options
* Allows configurable properties to be entirely specified by passing * Allows configurable properties to be entirely specified by passing
* an options object to the constructor. The constructor also supports * an options object to the constructor. The constructor also supports
* the original positional arguments 'elements', 'clickTimeThreshold', * the original positional arguments 'elements', 'clickTimeThreshold',
* and 'clickDistThreshold' in that order. * and 'clickDistThreshold' in that order.
* @param {Element|String} options.element * @param {Element|String} options.element
* A reference to an element or an element id for which the mouse * A reference to an element or an element id for which the mouse
* events will be monitored. * events will be monitored.
* @param {Number} options.clickTimeThreshold * @param {Number} options.clickTimeThreshold
* The number of milliseconds within which mutliple mouse clicks * The number of milliseconds within which mutliple mouse clicks
* will be treated as a single event. * will be treated as a single event.
* @param {Number} options.clickDistThreshold * @param {Number} options.clickDistThreshold
* The distance between mouse click within multiple mouse clicks * The distance between mouse click within multiple mouse clicks
* will be treated as a single event. * will be treated as a single event.
* @param {Function} options.enterHandler * @param {Function} options.enterHandler
* An optional handler for mouse enter. * An optional handler for mouse enter.
@ -78,15 +78,15 @@
* An optional handler for mouse click. * An optional handler for mouse click.
* @param {Function} options.dragHandler * @param {Function} options.dragHandler
* An optional handler for mouse drag. * An optional handler for mouse drag.
* @property {Number} hash * @property {Number} hash
* An unique hash for this tracker. * An unique hash for this tracker.
* @property {Element} element * @property {Element} element
* The element for which mouse event are being monitored. * The element for which mouse event are being monitored.
* @property {Number} clickTimeThreshold * @property {Number} clickTimeThreshold
* The number of milliseconds within which mutliple mouse clicks * The number of milliseconds within which mutliple mouse clicks
* will be treated as a single event. * will be treated as a single event.
* @property {Number} clickDistThreshold * @property {Number} clickDistThreshold
* The distance between mouse click within multiple mouse clicks * The distance between mouse click within multiple mouse clicks
* will be treated as a single event. * will be treated as a single event.
*/ */
$.MouseTracker = function ( options ) { $.MouseTracker = function ( options ) {
@ -101,7 +101,7 @@
}; };
} }
this.hash = Math.random(); this.hash = Math.random();
this.element = $.getElement( options.element ); this.element = $.getElement( options.element );
this.clickTimeThreshold = options.clickTimeThreshold; this.clickTimeThreshold = options.clickTimeThreshold;
this.clickDistThreshold = options.clickDistThreshold; this.clickDistThreshold = options.clickDistThreshold;
@ -128,15 +128,15 @@
* @property {Boolean} capturing * @property {Boolean} capturing
* Are we curruently capturing mouse events. * Are we curruently capturing mouse events.
* @property {Boolean} buttonDown * @property {Boolean} buttonDown
* True if the left mouse button is currently being pressed and was * True if the left mouse button is currently being pressed and was
* initiated inside the tracked element, otherwise false. * initiated inside the tracked element, otherwise false.
* @property {Boolean} insideElement * @property {Boolean} insideElement
* Are we currently inside the screen area of the tracked element. * Are we currently inside the screen area of the tracked element.
* @property {OpenSeadragon.Point} lastPoint * @property {OpenSeadragon.Point} lastPoint
* Position of last mouse down/move * Position of last mouse down/move
* @property {Number} lastMouseDownTime * @property {Number} lastMouseDownTime
* Time of last mouse down. * Time of last mouse down.
* @property {OpenSeadragon.Point} lastMouseDownPoint * @property {OpenSeadragon.Point} lastMouseDownPoint
* Position of last mouse down * Position of last mouse down
*/ */
THIS[ this.hash ] = { THIS[ this.hash ] = {
@ -196,17 +196,17 @@
//chain //chain
return this; return this;
}, },
/** /**
* Implement or assign implmentation to these handlers during or after * Implement or assign implmentation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @param {OpenSeadragon.MouseTracker} tracker * @param {OpenSeadragon.MouseTracker} tracker
* A reference to the tracker instance. * A reference to the tracker instance.
* @param {OpenSeadragon.Point} position * @param {OpenSeadragon.Point} position
* The poistion of the event on the screen. * The poistion of the event on the screen.
* @param {Boolean} buttonDown * @param {Boolean} buttonDown
* True if the left mouse button is currently being pressed and was * True if the left mouse button is currently being pressed and was
* initiated inside the tracked element, otherwise false. * initiated inside the tracked element, otherwise false.
* @param {Boolean} buttonDownAny * @param {Boolean} buttonDownAny
* Was the button down anywhere in the screen during the event. * Was the button down anywhere in the screen during the event.
@ -217,12 +217,12 @@
* Implement or assign implmentation to these handlers during or after * Implement or assign implmentation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @param {OpenSeadragon.MouseTracker} tracker * @param {OpenSeadragon.MouseTracker} tracker
* A reference to the tracker instance. * A reference to the tracker instance.
* @param {OpenSeadragon.Point} position * @param {OpenSeadragon.Point} position
* The poistion of the event on the screen. * The poistion of the event on the screen.
* @param {Boolean} buttonDown * @param {Boolean} buttonDown
* True if the left mouse button is currently being pressed and was * True if the left mouse button is currently being pressed and was
* initiated inside the tracked element, otherwise false. * initiated inside the tracked element, otherwise false.
* @param {Boolean} buttonDownAny * @param {Boolean} buttonDownAny
* Was the button down anywhere in the screen during the event. * Was the button down anywhere in the screen during the event.
@ -233,7 +233,7 @@
* Implement or assign implmentation to these handlers during or after * Implement or assign implmentation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @param {OpenSeadragon.MouseTracker} tracker * @param {OpenSeadragon.MouseTracker} tracker
* A reference to the tracker instance. * A reference to the tracker instance.
* @param {OpenSeadragon.Point} position * @param {OpenSeadragon.Point} position
* The poistion of the event on the screen. * The poistion of the event on the screen.
@ -244,12 +244,12 @@
* Implement or assign implmentation to these handlers during or after * Implement or assign implmentation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @param {OpenSeadragon.MouseTracker} tracker * @param {OpenSeadragon.MouseTracker} tracker
* A reference to the tracker instance. * A reference to the tracker instance.
* @param {OpenSeadragon.Point} position * @param {OpenSeadragon.Point} position
* The poistion of the event on the screen. * The poistion of the event on the screen.
* @param {Boolean} buttonDown * @param {Boolean} buttonDown
* True if the left mouse button is currently being pressed and was * True if the left mouse button is currently being pressed and was
* initiated inside the tracked element, otherwise false. * initiated inside the tracked element, otherwise false.
* @param {Boolean} insideElementRelease * @param {Boolean} insideElementRelease
* Was the mouse still inside the tracked element when the button * Was the mouse still inside the tracked element when the button
@ -261,7 +261,7 @@
* Implement or assign implmentation to these handlers during or after * Implement or assign implmentation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @param {OpenSeadragon.MouseTracker} tracker * @param {OpenSeadragon.MouseTracker} tracker
* A reference to the tracker instance. * A reference to the tracker instance.
* @param {OpenSeadragon.Point} position * @param {OpenSeadragon.Point} position
* The poistion of the event on the screen. * The poistion of the event on the screen.
@ -274,14 +274,14 @@
/** /**
* Implement or assign implmentation to these handlers during or after * Implement or assign implmentation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @param {OpenSeadragon.MouseTracker} tracker * @param {OpenSeadragon.MouseTracker} tracker
* A reference to the tracker instance. * A reference to the tracker instance.
* @param {OpenSeadragon.Point} position * @param {OpenSeadragon.Point} position
* The poistion of the event on the screen. * The poistion of the event on the screen.
* @param {Boolean} quick * @param {Boolean} quick
* True only if the clickDistThreshold and clickDeltaThreshold are * True only if the clickDistThreshold and clickDeltaThreshold are
* both pased. Useful for ignoring events. * both pased. Useful for ignoring events.
* @param {Boolean} shift * @param {Boolean} shift
* Was the shift key being pressed during this event? * Was the shift key being pressed during this event?
@ -290,9 +290,9 @@
/** /**
* Implement or assign implmentation to these handlers during or after * Implement or assign implmentation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @param {OpenSeadragon.MouseTracker} tracker * @param {OpenSeadragon.MouseTracker} tracker
* A reference to the tracker instance. * A reference to the tracker instance.
* @param {OpenSeadragon.Point} position * @param {OpenSeadragon.Point} position
* The poistion of the event on the screen. * The poistion of the event on the screen.
@ -306,9 +306,9 @@
/** /**
* Implement or assign implmentation to these handlers during or after * Implement or assign implmentation to these handlers during or after
* calling the constructor. * calling the constructor.
* @function * @function
* @param {OpenSeadragon.MouseTracker} tracker * @param {OpenSeadragon.MouseTracker} tracker
* A reference to the tracker instance. * A reference to the tracker instance.
* @param {Number} keyCode * @param {Number} keyCode
* The key code that was pressed. * The key code that was pressed.
@ -329,24 +329,24 @@
*/ */
function startTracking( tracker ) { function startTracking( tracker ) {
var events = [ var events = [
"mouseover", "mouseout", "mousedown", "mouseup", "mouseover", "mouseout", "mousedown", "mouseup",
"click", "click",
"DOMMouseScroll", "mousewheel", "DOMMouseScroll", "mousewheel",
"touchstart", "touchmove", "touchend", "touchstart", "touchmove", "touchend",
"keypress", "keypress",
"focus", "blur" "focus", "blur"
], ],
delegate = THIS[ tracker.hash ], delegate = THIS[ tracker.hash ],
event, event,
i; i;
if ( !delegate.tracking ) { if ( !delegate.tracking ) {
for( i = 0; i < events.length; i++ ){ for( i = 0; i < events.length; i++ ){
event = events[ i ]; event = events[ i ];
$.addEvent( $.addEvent(
tracker.element, tracker.element,
event, event,
delegate[ event ], delegate[ event ],
false false
); );
} }
@ -362,24 +362,24 @@
*/ */
function stopTracking( tracker ) { function stopTracking( tracker ) {
var events = [ var events = [
"mouseover", "mouseout", "mousedown", "mouseup", "mouseover", "mouseout", "mousedown", "mouseup",
"click", "click",
"DOMMouseScroll", "mousewheel", "DOMMouseScroll", "mousewheel",
"touchstart", "touchmove", "touchend", "touchstart", "touchmove", "touchend",
"keypress", "keypress",
"focus", "blur" "focus", "blur"
], ],
delegate = THIS[ tracker.hash ], delegate = THIS[ tracker.hash ],
event, event,
i; i;
if ( delegate.tracking ) { if ( delegate.tracking ) {
for( i = 0; i < events.length; i++ ){ for( i = 0; i < events.length; i++ ){
event = events[ i ]; event = events[ i ];
$.removeEvent( $.removeEvent(
tracker.element, tracker.element,
event, event,
delegate[ event ], delegate[ event ],
false false
); );
} }
@ -408,43 +408,43 @@
if ( !delegate.capturing ) { if ( !delegate.capturing ) {
if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) { if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) {
$.removeEvent( $.removeEvent(
tracker.element, tracker.element,
"mouseup", "mouseup",
delegate.mouseup, delegate.mouseup,
false false
); );
$.addEvent( $.addEvent(
tracker.element, tracker.element,
"mouseup", "mouseup",
delegate.mouseupie, delegate.mouseupie,
true true
); );
$.addEvent( $.addEvent(
tracker.element, tracker.element,
"mousemove", "mousemove",
delegate.mousemoveie, delegate.mousemoveie,
true true
); );
} else { } else {
$.addEvent( $.addEvent(
window, window,
"mouseup", "mouseup",
delegate.mouseupwindow, delegate.mouseupwindow,
true true
); );
$.addEvent( $.addEvent(
window, window,
"mousemove", "mousemove",
delegate.mousemove, delegate.mousemove,
true true
); );
} }
delegate.capturing = true; delegate.capturing = true;
} }
} }
/** /**
* Stop capturing mouse events on this element. * Stop capturing mouse events on this element.
* @private * @private
@ -455,36 +455,36 @@
if ( delegate.capturing ) { if ( delegate.capturing ) {
if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) { if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) {
$.removeEvent( $.removeEvent(
tracker.element, tracker.element,
"mousemove", "mousemove",
delegate.mousemoveie, delegate.mousemoveie,
true true
); );
$.removeEvent( $.removeEvent(
tracker.element, tracker.element,
"mouseup", "mouseup",
delegate.mouseupie, delegate.mouseupie,
true true
); );
$.addEvent( $.addEvent(
tracker.element, tracker.element,
"mouseup", "mouseup",
delegate.mouseup, delegate.mouseup,
false false
); );
} else { } else {
$.removeEvent( $.removeEvent(
window, window,
"mousemove", "mousemove",
delegate.mousemove, delegate.mousemove,
true true
); );
$.removeEvent( $.removeEvent(
window, window,
"mouseup", "mouseup",
delegate.mouseupwindow, delegate.mouseupwindow,
true true
); );
} }
delegate.capturing = false; delegate.capturing = false;
@ -514,8 +514,8 @@
//console.log( "focus %s", event ); //console.log( "focus %s", event );
var propagate; var propagate;
if ( tracker.focusHandler ) { if ( tracker.focusHandler ) {
propagate = tracker.focusHandler( propagate = tracker.focusHandler(
tracker, tracker,
event event
); );
if( propagate === false ){ if( propagate === false ){
@ -533,8 +533,8 @@
//console.log( "blur %s", event ); //console.log( "blur %s", event );
var propagate; var propagate;
if ( tracker.blurHandler ) { if ( tracker.blurHandler ) {
propagate = tracker.blurHandler( propagate = tracker.blurHandler(
tracker, tracker,
event event
); );
if( propagate === false ){ if( propagate === false ){
@ -543,7 +543,7 @@
} }
} }
/** /**
* @private * @private
* @inner * @inner
@ -552,8 +552,8 @@
//console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey ); //console.log( "keypress %s %s %s %s %s", event.keyCode, event.charCode, event.ctrlKey, event.shiftKey, event.altKey );
var propagate; var propagate;
if ( tracker.keyHandler ) { if ( tracker.keyHandler ) {
propagate = tracker.keyHandler( propagate = tracker.keyHandler(
tracker, tracker,
event.keyCode ? event.keyCode : event.charCode, event.keyCode ? event.keyCode : event.charCode,
event.shiftKey event.shiftKey
); );
@ -575,22 +575,22 @@
event = $.getEvent( event ); event = $.getEvent( event );
if ( $.Browser.vendor == $.BROWSERS.IE && if ( $.Browser.vendor == $.BROWSERS.IE &&
$.Browser.version < 9 && $.Browser.version < 9 &&
delegate.capturing && delegate.capturing &&
!isChild( event.srcElement, tracker.element ) ) { !isChild( event.srcElement, tracker.element ) ) {
triggerOthers( tracker, onMouseOver, event ); triggerOthers( tracker, onMouseOver, event );
} }
var to = event.target ? var to = event.target ?
event.target : event.target :
event.srcElement, event.srcElement,
from = event.relatedTarget ? from = event.relatedTarget ?
event.relatedTarget : event.relatedTarget :
event.fromElement; event.fromElement;
if ( !isChild( tracker.element, to ) || if ( !isChild( tracker.element, to ) ||
isChild( tracker.element, from ) ) { isChild( tracker.element, from ) ) {
return; return;
} }
@ -599,9 +599,9 @@
if ( tracker.enterHandler ) { if ( tracker.enterHandler ) {
propagate = tracker.enterHandler( propagate = tracker.enterHandler(
tracker, tracker,
getMouseRelative( event, tracker.element ), getMouseRelative( event, tracker.element ),
delegate.buttonDown, delegate.buttonDown,
IS_BUTTON_DOWN IS_BUTTON_DOWN
); );
if( propagate === false ){ if( propagate === false ){
@ -621,23 +621,23 @@
event = $.getEvent( event ); event = $.getEvent( event );
if ( $.Browser.vendor == $.BROWSERS.IE && if ( $.Browser.vendor == $.BROWSERS.IE &&
$.Browser.version < 9 && $.Browser.version < 9 &&
delegate.capturing && delegate.capturing &&
!isChild( event.srcElement, tracker.element ) ) { !isChild( event.srcElement, tracker.element ) ) {
triggerOthers( tracker, onMouseOut, event ); triggerOthers( tracker, onMouseOut, event );
} }
var from = event.target ? var from = event.target ?
event.target : event.target :
event.srcElement, event.srcElement,
to = event.relatedTarget ? to = event.relatedTarget ?
event.relatedTarget : event.relatedTarget :
event.toElement; event.toElement;
if ( !isChild( tracker.element, from ) || if ( !isChild( tracker.element, from ) ||
isChild( tracker.element, to ) ) { isChild( tracker.element, to ) ) {
return; return;
} }
@ -645,10 +645,10 @@
delegate.insideElement = false; delegate.insideElement = false;
if ( tracker.exitHandler ) { if ( tracker.exitHandler ) {
propagate = tracker.exitHandler( propagate = tracker.exitHandler(
tracker, tracker,
getMouseRelative( event, tracker.element ), getMouseRelative( event, tracker.element ),
delegate.buttonDown, delegate.buttonDown,
IS_BUTTON_DOWN IS_BUTTON_DOWN
); );
@ -680,8 +680,8 @@
delegate.lastMouseDownTime = +new Date(); delegate.lastMouseDownTime = +new Date();
if ( tracker.pressHandler ) { if ( tracker.pressHandler ) {
propagate = tracker.pressHandler( propagate = tracker.pressHandler(
tracker, tracker,
getMouseRelative( event, tracker.element ) getMouseRelative( event, tracker.element )
); );
if( propagate === false ){ if( propagate === false ){
@ -693,15 +693,15 @@
$.cancelEvent( event ); $.cancelEvent( event );
} }
if ( !( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) || if ( !( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) ||
!IS_CAPTURING ) { !IS_CAPTURING ) {
captureMouse( tracker ); captureMouse( tracker );
IS_CAPTURING = true; IS_CAPTURING = true;
// reset to empty & add us // reset to empty & add us
CAPTURING = [ tracker ]; CAPTURING = [ tracker ];
} else if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) { } else if ( $.Browser.vendor == $.BROWSERS.IE && $.Browser.version < 9 ) {
// add us to the list // add us to the list
CAPTURING.push( tracker ); CAPTURING.push( tracker );
} }
} }
@ -714,19 +714,19 @@
touchB; touchB;
if( event.touches.length == 1 && if( event.touches.length == 1 &&
event.targetTouches.length == 1 && event.targetTouches.length == 1 &&
event.changedTouches.length == 1 ){ event.changedTouches.length == 1 ){
THIS[ tracker.hash ].lastTouch = event.touches[ 0 ]; THIS[ tracker.hash ].lastTouch = event.touches[ 0 ];
onMouseOver( tracker, event.changedTouches[ 0 ] ); onMouseOver( tracker, event.changedTouches[ 0 ] );
onMouseDown( tracker, event.touches[ 0 ] ); onMouseDown( tracker, event.touches[ 0 ] );
} }
if( event.touches.length == 2 ){ if( event.touches.length == 2 ){
touchA = getMouseAbsolute( event.touches[ 0 ] ); touchA = getMouseAbsolute( event.touches[ 0 ] );
touchB = getMouseAbsolute( event.touches[ 1 ] ); touchB = getMouseAbsolute( event.touches[ 1 ] );
THIS[ tracker.hash ].lastPinchDelta = THIS[ tracker.hash ].lastPinchDelta =
Math.abs( touchA.x - touchB.x ) + Math.abs( touchA.x - touchB.x ) +
Math.abs( touchA.y - touchB.y ); Math.abs( touchA.y - touchB.y );
THIS[ tracker.hash ].pinchMidpoint = new $.Point( THIS[ tracker.hash ].pinchMidpoint = new $.Point(
@ -762,9 +762,9 @@
if ( tracker.releaseHandler ) { if ( tracker.releaseHandler ) {
propagate = tracker.releaseHandler( propagate = tracker.releaseHandler(
tracker, tracker,
getMouseRelative( event, tracker.element ), getMouseRelative( event, tracker.element ),
insideElementPress, insideElementPress,
insideElementRelease insideElementRelease
); );
if( propagate === false ){ if( propagate === false ){
@ -785,7 +785,7 @@
function onTouchEnd( tracker, event ) { function onTouchEnd( tracker, event ) {
if( event.touches.length === 0 && if( event.touches.length === 0 &&
event.targetTouches.length === 0 && event.targetTouches.length === 0 &&
event.changedTouches.length == 1 ){ event.changedTouches.length == 1 ){
THIS[ tracker.hash ].lastTouch = null; THIS[ tracker.hash ].lastTouch = null;
@ -874,7 +874,7 @@
function onMouseWheelSpin( tracker, event ) { function onMouseWheelSpin( tracker, event ) {
var nDelta = 0, var nDelta = 0,
propagate; propagate;
if ( !event ) { // For IE, access the global (window) event object if ( !event ) { // For IE, access the global (window) event object
event = window.event; event = window.event;
} }
@ -894,9 +894,9 @@
if ( tracker.scrollHandler ) { if ( tracker.scrollHandler ) {
propagate = tracker.scrollHandler( propagate = tracker.scrollHandler(
tracker, tracker,
getMouseRelative( event, tracker.element ), getMouseRelative( event, tracker.element ),
nDelta, nDelta,
event.shiftKey event.shiftKey
); );
if( propagate === false ){ if( propagate === false ){
@ -923,14 +923,14 @@
var time = +new Date() - delegate.lastMouseDownTime, var time = +new Date() - delegate.lastMouseDownTime,
point = getMouseAbsolute( event ), point = getMouseAbsolute( event ),
distance = delegate.lastMouseDownPoint.distanceTo( point ), distance = delegate.lastMouseDownPoint.distanceTo( point ),
quick = time <= tracker.clickTimeThreshold && quick = time <= tracker.clickTimeThreshold &&
distance <= tracker.clickDistThreshold; distance <= tracker.clickDistThreshold;
if ( tracker.clickHandler ) { if ( tracker.clickHandler ) {
propagate = tracker.clickHandler( propagate = tracker.clickHandler(
tracker, tracker,
getMouseRelative( event, tracker.element ), getMouseRelative( event, tracker.element ),
quick, quick,
event.shiftKey event.shiftKey
); );
if( propagate === false ){ if( propagate === false ){
@ -958,9 +958,9 @@
if ( tracker.dragHandler ) { if ( tracker.dragHandler ) {
propagate = tracker.dragHandler( propagate = tracker.dragHandler(
tracker, tracker,
getMouseRelative( event, tracker.element ), getMouseRelative( event, tracker.element ),
delta, delta,
event.shiftKey event.shiftKey
); );
if( propagate === false ){ if( propagate === false ){
@ -980,8 +980,8 @@
pinchDelta; pinchDelta;
if( event.touches.length === 1 && if( event.touches.length === 1 &&
event.targetTouches.length === 1 && event.targetTouches.length === 1 &&
event.changedTouches.length === 1 && event.changedTouches.length === 1 &&
THIS[ tracker.hash ].lastTouch.identifier === event.touches[ 0 ].identifier){ THIS[ tracker.hash ].lastTouch.identifier === event.touches[ 0 ].identifier){
onMouseMove( tracker, event.touches[ 0 ] ); onMouseMove( tracker, event.touches[ 0 ] );
@ -993,7 +993,7 @@
pinchDelta = pinchDelta =
Math.abs( touchA.x - touchB.x ) + Math.abs( touchA.x - touchB.x ) +
Math.abs( touchA.y - touchB.y ); Math.abs( touchA.y - touchB.y );
//TODO: make the 75px pinch threshold configurable //TODO: make the 75px pinch threshold configurable
if( Math.abs( THIS[ tracker.hash ].lastPinchDelta - pinchDelta ) > 75 ){ if( Math.abs( THIS[ tracker.hash ].lastPinchDelta - pinchDelta ) > 75 ){
//$.console.debug( "pinch delta : " + pinchDelta + " | previous : " + THIS[ tracker.hash ].lastPinchDelta); //$.console.debug( "pinch delta : " + pinchDelta + " | previous : " + THIS[ tracker.hash ].lastPinchDelta);
@ -1002,8 +1002,8 @@
shift: false, shift: false,
pageX: THIS[ tracker.hash ].pinchMidpoint.x, pageX: THIS[ tracker.hash ].pinchMidpoint.x,
pageY: THIS[ tracker.hash ].pinchMidpoint.y, pageY: THIS[ tracker.hash ].pinchMidpoint.y,
detail:( detail:(
THIS[ tracker.hash ].lastPinchDelta > pinchDelta THIS[ tracker.hash ].lastPinchDelta > pinchDelta
) ? 1 : -1 ) ? 1 : -1
}); });
@ -1093,5 +1093,5 @@
$.addEvent( window, "mouseup", onGlobalMouseUp, true ); $.addEvent( window, "mouseup", onGlobalMouseUp, true );
} }
})(); })();
}( OpenSeadragon )); }( OpenSeadragon ));

View File

@ -33,14 +33,14 @@
*/ */
(function( $ ){ (function( $ ){
/** /**
* The Navigator provides a small view of the current image as fixed * The Navigator provides a small view of the current image as fixed
* while representing the viewport as a moving box serving as a frame * while representing the viewport as a moving box serving as a frame
* of reference in the larger viewport as to which portion of the image * of reference in the larger viewport as to which portion of the image
* is currently being examined. The navigator's viewport can be interacted * is currently being examined. The navigator's viewport can be interacted
* with using the keyboard or the mouse. * with using the keyboard or the mouse.
* @class * @class
* @name OpenSeadragon.Navigator * @name OpenSeadragon.Navigator
* @extends OpenSeadragon.Viewer * @extends OpenSeadragon.Viewer
* @extends OpenSeadragon.EventHandler * @extends OpenSeadragon.EventHandler
@ -121,14 +121,14 @@ $.Navigator = function( options ){
style.padding = '0px'; style.padding = '0px';
//TODO: IE doesnt like this property being set //TODO: IE doesnt like this property being set
//try{ style.outline = '2px auto #909'; }catch(e){/*ignore*/} //try{ style.outline = '2px auto #909'; }catch(e){/*ignore*/}
style.background = 'transparent'; style.background = 'transparent';
// We use square bracket notation on the statement below, because float is a keyword. // We use square bracket notation on the statement below, because float is a keyword.
// This is important for the Google Closure compiler, if nothing else. // This is important for the Google Closure compiler, if nothing else.
/*jshint sub:true */ /*jshint sub:true */
style['float'] = 'left'; //Webkit style['float'] = 'left'; //Webkit
style.cssFloat = 'left'; //Firefox style.cssFloat = 'left'; //Firefox
style.styleFloat = 'left'; //IE style.styleFloat = 'left'; //IE
style.zIndex = 999999999; style.zIndex = 999999999;
@ -149,8 +149,8 @@ $.Navigator = function( options ){
}).setTracking( true ); }).setTracking( true );
/*this.displayRegion.outerTracker = new $.MouseTracker({ /*this.displayRegion.outerTracker = new $.MouseTracker({
element: this.container, element: this.container,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
enterHandler: $.delegate( this, onContainerEnter ), enterHandler: $.delegate( this, onContainerEnter ),
exitHandler: $.delegate( this, onContainerExit ), exitHandler: $.delegate( this, onContainerExit ),
@ -158,8 +158,8 @@ $.Navigator = function( options ){
}).setTracking( this.mouseNavEnabled ? true : false ); // always tracking*/ }).setTracking( this.mouseNavEnabled ? true : false ); // always tracking*/
viewer.addControl( viewer.addControl(
this.element, this.element,
options.controlOptions options.controlOptions
); );
@ -171,7 +171,7 @@ $.Navigator = function( options ){
this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px'; this.element.style.height = ( viewerSize.y * options.sizeRatio ) + 'px';
} }
$.Viewer.apply( this, [ options ] ); $.Viewer.apply( this, [ options ] );
this.element.getElementsByTagName('form')[0].appendChild( this.displayRegion ); this.element.getElementsByTagName('form')[0].appendChild( this.displayRegion );
unneededElement = this.element.getElementsByTagName('textarea')[0]; unneededElement = this.element.getElementsByTagName('textarea')[0];
@ -198,7 +198,7 @@ $.extend( $.Navigator.prototype, $.EventHandler.prototype, $.Viewer.prototype, {
topleft = this.viewport.pixelFromPoint( bounds.getTopLeft()); topleft = this.viewport.pixelFromPoint( bounds.getTopLeft());
bottomright = this.viewport.pixelFromPoint( bounds.getBottomRight()).minus(this.totalBorderWidths); bottomright = this.viewport.pixelFromPoint( bounds.getBottomRight()).minus(this.totalBorderWidths);
//update style for navigator-box //update style for navigator-box
(function(style, borderWidth){ (function(style, borderWidth){
style.top = topleft.y + 'px'; style.top = topleft.y + 'px';
@ -211,17 +211,17 @@ $.extend( $.Navigator.prototype, $.EventHandler.prototype, $.Viewer.prototype, {
style.height = Math.max( height, 0 ) + 'px'; style.height = Math.max( height, 0 ) + 'px';
}( this.displayRegion.style, this.borderWidth)); }( this.displayRegion.style, this.borderWidth));
} }
}, },
open: function( source ){ open: function( source ){
var containerSize = this.viewer.viewport.containerSize.times( this.sizeRatio ); var containerSize = this.viewer.viewport.containerSize.times( this.sizeRatio );
if( source.tileSize > containerSize.x || if( source.tileSize > containerSize.x ||
source.tileSize > containerSize.y ){ source.tileSize > containerSize.y ){
this.minPixelRatio = Math.min( this.minPixelRatio = Math.min(
containerSize.x, containerSize.x,
containerSize.y containerSize.y
) / source.tileSize; ) / source.tileSize;
} else { } else {
this.minPixelRatio = this.viewer.minPixelRatio; this.minPixelRatio = this.viewer.minPixelRatio;
@ -279,10 +279,10 @@ function onCanvasDrag( tracker, position, delta, shift ) {
if( !this.panVertical ){ if( !this.panVertical ){
delta.y = 0; delta.y = 0;
} }
this.viewer.viewport.panBy( this.viewer.viewport.panBy(
this.viewport.deltaPointsFromPixels( this.viewport.deltaPointsFromPixels(
delta delta
) )
); );
} }
} }
@ -309,8 +309,8 @@ function onCanvasScroll( tracker, position, scroll, shift ) {
var factor; var factor;
if ( this.viewer.viewport ) { if ( this.viewer.viewport ) {
factor = Math.pow( this.zoomPerScroll, scroll ); factor = Math.pow( this.zoomPerScroll, scroll );
this.viewer.viewport.zoomBy( this.viewer.viewport.zoomBy(
factor, factor,
this.viewport.getCenter() this.viewport.getCenter()
); );
this.viewer.viewport.applyConstraints(); this.viewer.viewport.applyConstraints();

View File

@ -85,16 +85,16 @@
/** /**
* @version <%= pkg.name %> <%= pkg.version %> * @version <%= pkg.name %> <%= pkg.version %>
* *
* @fileOverview * @fileOverview
* <h2> * <h2>
* <strong> * <strong>
* OpenSeadragon - Javascript Deep Zooming * OpenSeadragon - Javascript Deep Zooming
* </strong> * </strong>
* </h2> * </h2>
* <p> * <p>
* OpenSeadragon is provides an html interface for creating * OpenSeadragon is provides an html interface for creating
* deep zoom user interfaces. The simplest examples include deep * deep zoom user interfaces. The simplest examples include deep
* zoom for large resolution images, and complex examples include * zoom for large resolution images, and complex examples include
* zoomable map interfaces driven by SVG files. * zoomable map interfaces driven by SVG files.
* </p> * </p>
@ -102,9 +102,9 @@
/** /**
* The root namespace for OpenSeadragon, this function also serves as a single * The root namespace for OpenSeadragon, this function also serves as a single
* point of instantiation for an {@link OpenSeadragon.Viewer}, including all * point of instantiation for an {@link OpenSeadragon.Viewer}, including all
* combinations of out-of-the-box configurable features. All utility methods * combinations of out-of-the-box configurable features. All utility methods
* and classes are defined on or below this namespace. * and classes are defined on or below this namespace.
* *
* @namespace * @namespace
* @function * @function
@ -112,20 +112,20 @@
* @exports $ as OpenSeadragon * @exports $ as OpenSeadragon
* *
* @param {Object} options All required and optional settings for instantiating * @param {Object} options All required and optional settings for instantiating
* a new instance of an OpenSeadragon image viewer. * a new instance of an OpenSeadragon image viewer.
* *
* @param {String} options.xmlPath * @param {String} options.xmlPath
* DEPRECATED. A relative path to load a DZI file from the server. * DEPRECATED. A relative path to load a DZI file from the server.
* Prefer the newer options.tileSources. * Prefer the newer options.tileSources.
* *
* @param {Array|String|Function|Object[]|Array[]|String[]|Function[]} options.tileSources * @param {Array|String|Function|Object[]|Array[]|String[]|Function[]} options.tileSources
* As an Array, the tileSource can hold either be all Objects or mixed * As an Array, the tileSource can hold either be all Objects or mixed
* types of Arrays of Objects, String, Function. When a value is a String, * types of Arrays of Objects, String, Function. When a value is a String,
* the tileSource is used to create a {@link OpenSeadragon.DziTileSource}. * the tileSource is used to create a {@link OpenSeadragon.DziTileSource}.
* When a value is a Function, the function is used to create a new * When a value is a Function, the function is used to create a new
* {@link OpenSeadragon.TileSource} whose abstract method * {@link OpenSeadragon.TileSource} whose abstract method
* getUrl( level, x, y ) is implemented by the function. Finally, when it * getUrl( level, x, y ) is implemented by the function. Finally, when it
* is an Array of objects, it is used to create a * is an Array of objects, it is used to create a
* {@link OpenSeadragon.LegacyTileSource}. * {@link OpenSeadragon.LegacyTileSource}.
* *
* @param {Boolean} [options.debugMode=true] * @param {Boolean} [options.debugMode=true]
@ -136,7 +136,7 @@
* Specifies the animation duration per each {@link OpenSeadragon.Spring} * Specifies the animation duration per each {@link OpenSeadragon.Spring}
* which occur when the image is dragged or zoomed. * which occur when the image is dragged or zoomed.
* *
* @param {Number} [options.blendTime=0.5] * @param {Number} [options.blendTime=0.5]
* Specifies the duration of animation as higher or lower level tiles are * Specifies the duration of animation as higher or lower level tiles are
* replacing the existing tile. * replacing the existing tile.
* *
@ -146,13 +146,13 @@
* not complete the blend. * not complete the blend.
* *
* @param {Boolean} [options.autoHideControls=true] * @param {Boolean} [options.autoHideControls=true]
* If the user stops interacting with the viewport, fade the navigation * If the user stops interacting with the viewport, fade the navigation
* controls. Useful for presentation since the controls are by default * controls. Useful for presentation since the controls are by default
* floated on top of the image the user is viewing. * floated on top of the image the user is viewing.
* *
* @param {Boolean} [options.immediateRender=false] * @param {Boolean} [options.immediateRender=false]
* Render the best closest level first, ignoring the lowering levels which * Render the best closest level first, ignoring the lowering levels which
* provide the effect of very blurry to sharp. It is recommended to change * provide the effect of very blurry to sharp. It is recommended to change
* setting to true for mobile devices. * setting to true for mobile devices.
* *
* @param {Boolean} [options.wrapHorizontal=false] * @param {Boolean} [options.wrapHorizontal=false]
@ -164,20 +164,20 @@
* Useful for maps or images representing the surface of a sphere or cylinder. * Useful for maps or images representing the surface of a sphere or cylinder.
* *
* @param {Number} [options.minZoomImageRatio=0.8] * @param {Number} [options.minZoomImageRatio=0.8]
* The minimum percentage ( expressed as a number between 0 and 1 ) of * The minimum percentage ( expressed as a number between 0 and 1 ) of
* the viewport height or width at which the zoom out will be constrained. * the viewport height or width at which the zoom out will be constrained.
* Setting it to 0, for example will allow you to zoom out infinitly. * Setting it to 0, for example will allow you to zoom out infinitly.
* *
* @param {Number} [options.maxZoomPixelRatio=2] * @param {Number} [options.maxZoomPixelRatio=2]
* The maximum ratio to allow a zoom-in to affect the highest level pixel * The maximum ratio to allow a zoom-in to affect the highest level pixel
* ratio. This can be set to Infinity to allow 'infinite' zooming into the * ratio. This can be set to Infinity to allow 'infinite' zooming into the
* image though it is less effective visually if the HTML5 Canvas is not * image though it is less effective visually if the HTML5 Canvas is not
* availble on the viewing device. * availble on the viewing device.
* *
* @param {Number} [options.visibilityRatio=0.5] * @param {Number} [options.visibilityRatio=0.5]
* The percentage ( as a number from 0 to 1 ) of the source image which * The percentage ( as a number from 0 to 1 ) of the source image which
* must be kept within the viewport. If the image is dragged beyond that * must be kept within the viewport. If the image is dragged beyond that
* limit, it will 'bounce' back until the minimum visibility ration is * limit, it will 'bounce' back until the minimum visibility ration is
* achieved. Setting this to 0 and wrapHorizontal ( or wrapVertical ) to * achieved. Setting this to 0 and wrapHorizontal ( or wrapVertical ) to
* true will provide the effect of an infinitely scrolling viewport. * true will provide the effect of an infinitely scrolling viewport.
* *
@ -189,7 +189,7 @@
* image requests in parallel as allowed by the browsers policy. * image requests in parallel as allowed by the browsers policy.
* *
* @param {Number} [options.clickTimeThreshold=200] * @param {Number} [options.clickTimeThreshold=200]
* If multiple mouse clicks occurs within less than this number of * If multiple mouse clicks occurs within less than this number of
* milliseconds, treat them as a single click. * milliseconds, treat them as a single click.
* *
* @param {Number} [options.clickDistThreshold=5] * @param {Number} [options.clickDistThreshold=5]
@ -229,11 +229,11 @@
* @param {Number} [options.minPixelRatio=0.5] * @param {Number} [options.minPixelRatio=0.5]
* The higher the minPixelRatio, the lower the quality of the image that * The higher the minPixelRatio, the lower the quality of the image that
* is considered sufficient to stop rendering a given zoom level. For * is considered sufficient to stop rendering a given zoom level. For
* example, if you are targeting mobile devices with less bandwith you may * example, if you are targeting mobile devices with less bandwith you may
* try setting this to 1.5 or higher. * try setting this to 1.5 or higher.
* *
* @param {Boolean} [options.mouseNavEnabled=true] * @param {Boolean} [options.mouseNavEnabled=true]
* Is the user able to interact with the image via mouse or touch. Default * Is the user able to interact with the image via mouse or touch. Default
* interactions include draging the image in a plane, and zooming in toward * interactions include draging the image in a plane, and zooming in toward
* and away from the image. * and away from the image.
* *
@ -255,7 +255,7 @@
* or navigation control, eg 'REST', 'GROUP', 'HOVER', 'PRESS'. Finally the * or navigation control, eg 'REST', 'GROUP', 'HOVER', 'PRESS'. Finally the
* image paths, by default assume there is a folder on the servers root path * image paths, by default assume there is a folder on the servers root path
* called '/images', eg '/images/zoomin_rest.png'. If you need to adjust * called '/images', eg '/images/zoomin_rest.png'. If you need to adjust
* these paths, prefer setting the option.prefixUrl rather than overriding * these paths, prefer setting the option.prefixUrl rather than overriding
* every image path directly through this setting. * every image path directly through this setting.
* *
* @param {Boolean} [options.navPrevNextWrap=false] * @param {Boolean} [options.navPrevNextWrap=false]
@ -266,13 +266,13 @@
* @returns {OpenSeadragon.Viewer} * @returns {OpenSeadragon.Viewer}
*/ */
window.OpenSeadragon = window.OpenSeadragon || function( options ){ window.OpenSeadragon = window.OpenSeadragon || function( options ){
return new OpenSeadragon.Viewer( options ); return new OpenSeadragon.Viewer( options );
}; };
(function( $ ){ (function( $ ){
/** /**
* Taken from jquery 1.6.1 * Taken from jquery 1.6.1
@ -395,13 +395,13 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
/** /**
* This closure defines all static methods available to the OpenSeadragon * This closure defines all static methods available to the OpenSeadragon
* namespace. Many, if not most, are taked directly from jQuery for use * namespace. Many, if not most, are taked directly from jQuery for use
* to simplify and reduce common programming patterns. More static methods * to simplify and reduce common programming patterns. More static methods
* from jQuery may eventually make their way into this though we are * from jQuery may eventually make their way into this though we are
* attempting to avoid an explicit dependency on jQuery only because * attempting to avoid an explicit dependency on jQuery only because
* OpenSeadragon is a broadly useful code base and would be made less broad * OpenSeadragon is a broadly useful code base and would be made less broad
* by requiring jQuery fully. * by requiring jQuery fully.
* *
* Some static methods have also been refactored from the original OpenSeadragon * Some static methods have also been refactored from the original OpenSeadragon
* project. * project.
*/ */
(function( $ ){ (function( $ ){
@ -411,11 +411,11 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
* @see <a href='http://www.jquery.com/'>jQuery</a> * @see <a href='http://www.jquery.com/'>jQuery</a>
*/ */
$.extend = function() { $.extend = function() {
var options, var options,
name, name,
src, src,
copy, copy,
copyIsArray, copyIsArray,
clone, clone,
target = arguments[ 0 ] || {}, target = arguments[ 0 ] || {},
length = arguments.length, length = arguments.length,
@ -479,7 +479,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
// Return the modified object // Return the modified object
return target; return target;
}; };
$.extend( $, { $.extend( $, {
/** /**
@ -491,9 +491,9 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
DEFAULT_SETTINGS: { DEFAULT_SETTINGS: {
//DATA SOURCE DETAILS //DATA SOURCE DETAILS
xmlPath: null, xmlPath: null,
tileSources: null, tileSources: null,
tileHost: null, tileHost: null,
//PAN AND ZOOM SETTINGS AND CONSTRAINTS //PAN AND ZOOM SETTINGS AND CONSTRAINTS
panHorizontal: true, panHorizontal: true,
panVertical: true, panVertical: true,
@ -504,7 +504,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
minPixelRatio: 0.5, //->closer to 0 draws tiles meant for a higher zoom at this zoom minPixelRatio: 0.5, //->closer to 0 draws tiles meant for a higher zoom at this zoom
defaultZoomLevel: 0, defaultZoomLevel: 0,
minZoomLevel: null, minZoomLevel: null,
maxZoomLevel: null, maxZoomLevel: null,
//UI RESPONSIVENESS AND FEEL //UI RESPONSIVENESS AND FEEL
springStiffness: 7.0, springStiffness: 7.0,
@ -528,7 +528,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
controlsFadeDelay: 2000, //ZOOM/HOME/FULL/SEQUENCE controlsFadeDelay: 2000, //ZOOM/HOME/FULL/SEQUENCE
controlsFadeLength: 1500, //ZOOM/HOME/FULL/SEQUENCE controlsFadeLength: 1500, //ZOOM/HOME/FULL/SEQUENCE
mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITY mouseNavEnabled: true, //GENERAL MOUSE INTERACTIVITY
//VIEWPORT NAVIGATOR SETTINGS //VIEWPORT NAVIGATOR SETTINGS
showNavigator: false, showNavigator: false,
navigatorId: null, navigatorId: null,
@ -538,7 +538,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
navigatorSizeRatio: 0.2, navigatorSizeRatio: 0.2,
//REFERENCE STRIP SETTINGS //REFERENCE STRIP SETTINGS
showReferenceStrip: false, showReferenceStrip: false,
referenceStripScroll: 'horizontal', referenceStripScroll: 'horizontal',
referenceStripElement: null, referenceStripElement: null,
referenceStripHeight: null, referenceStripHeight: null,
@ -553,8 +553,8 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
collectionTileSize: 800, collectionTileSize: 800,
//EVENT RELATED CALLBACKS //EVENT RELATED CALLBACKS
onPageChange: null, onPageChange: null,
//PERFORMANCE SETTINGS //PERFORMANCE SETTINGS
imageLoaderLimit: 0, imageLoaderLimit: 0,
maxImageCacheCount: 200, maxImageCacheCount: 200,
@ -621,7 +621,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
* Invokes the the method as if it where a method belonging to the object. * Invokes the the method as if it where a method belonging to the object.
* @name $.delegate * @name $.delegate
* @function * @function
* @param {Object} object * @param {Object} object
* @param {Function} method * @param {Function} method
*/ */
delegate: function( object, method ) { delegate: function( object, method ) {
@ -633,8 +633,8 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
return method.apply( object, args ); return method.apply( object, args );
}; };
}, },
/** /**
* An enumeration of Browser vendors including UNKNOWN, IE, FIREFOX, * An enumeration of Browser vendors including UNKNOWN, IE, FIREFOX,
* SAFARI, CHROME, and OPERA. * SAFARI, CHROME, and OPERA.
@ -658,7 +658,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
* @param {String|Element} element Accepts an id or element. * @param {String|Element} element Accepts an id or element.
* @returns {Element} The element with the given id, null, or the element itself. * @returns {Element} The element with the given id, null, or the element itself.
*/ */
getElement: function( element ) { getElement: function( element ) {
if ( typeof ( element ) == "string" ) { if ( typeof ( element ) == "string" ) {
element = document.getElementById( element ); element = document.getElementById( element );
} }
@ -671,7 +671,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
* @function * @function
* @name OpenSeadragon.getElementPosition * @name OpenSeadragon.getElementPosition
* @param {Element|String} element - the elemenet we want the position for. * @param {Element|String} element - the elemenet we want the position for.
* @returns {Point} - the position of the upper left corner of the element. * @returns {Point} - the position of the upper left corner of the element.
*/ */
getElementPosition: function( element ) { getElementPosition: function( element ) {
var result = new $.Point(), var result = new $.Point(),
@ -711,7 +711,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
element = $.getElement( element ); element = $.getElement( element );
return new $.Point( return new $.Point(
element.clientWidth, element.clientWidth,
element.clientHeight element.clientHeight
); );
}, },
@ -724,12 +724,12 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
* @param {Element|String} element * @param {Element|String} element
* @returns {CSSStyle} * @returns {CSSStyle}
*/ */
getElementStyle: getElementStyle:
document.documentElement.currentStyle ? document.documentElement.currentStyle ?
function( element ) { function( element ) {
element = $.getElement( element ); element = $.getElement( element );
return element.currentStyle; return element.currentStyle;
} : } :
function( element ) { function( element ) {
element = $.getElement( element ); element = $.getElement( element );
return window.getComputedStyle( element, "" ); return window.getComputedStyle( element, "" );
@ -737,7 +737,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
/** /**
* Gets the latest event, really only useful internally since its * Gets the latest event, really only useful internally since its
* specific to IE behavior. TODO: Deprecate this from the api and * specific to IE behavior. TODO: Deprecate this from the api and
* use it internally. * use it internally.
* @function * @function
@ -783,13 +783,13 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
var result = new $.Point(); var result = new $.Point();
event = $.getEvent( event ); event = $.getEvent( event );
result.x = result.x =
event.clientX + event.clientX +
document.body.scrollLeft + document.body.scrollLeft +
document.documentElement.scrollLeft; document.documentElement.scrollLeft;
result.y = result.y =
event.clientY + event.clientY +
document.body.scrollTop + document.body.scrollTop +
document.documentElement.scrollTop; document.documentElement.scrollTop;
return result; return result;
@ -954,7 +954,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
/** /**
* Ensures an image is loaded correctly to support alpha transparency. * Ensures an image is loaded correctly to support alpha transparency.
* Generally only IE has issues doing this correctly for formats like * Generally only IE has issues doing this correctly for formats like
* png. * png.
* @function * @function
* @name OpenSeadragon.makeTransparentImage * @name OpenSeadragon.makeTransparentImage
@ -965,9 +965,9 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
$.makeTransparentImage = function( src ){ $.makeTransparentImage = function( src ){
var img = $.makeNeutralElement( "img" ); var img = $.makeNeutralElement( "img" );
img.src = src; img.src = src;
return img; return img;
}; };
@ -991,13 +991,13 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
img.src = src; img.src = src;
element.style.filter = element.style.filter =
"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
src + src +
"', sizingMethod='scale')"; "', sizingMethod='scale')";
return element; return element;
}; };
} }
return $.makeTransparentImage( src ); return $.makeTransparentImage( src );
}, },
@ -1096,7 +1096,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
if ( element.addEventListener ) { if ( element.addEventListener ) {
$.addEvent = function( element, eventName, handler, useCapture ){ $.addEvent = function( element, eventName, handler, useCapture ){
element = $.getElement( element ); element = $.getElement( element );
element.addEventListener( eventName, handler, useCapture ); element.addEventListener( eventName, handler, useCapture );
}; };
} else if ( element.attachEvent ) { } else if ( element.attachEvent ) {
$.addEvent = function( element, eventName, handler, useCapture ){ $.addEvent = function( element, eventName, handler, useCapture ){
@ -1104,7 +1104,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
element.attachEvent( "on" + eventName, handler ); element.attachEvent( "on" + eventName, handler );
if ( useCapture && element.setCapture ) { if ( useCapture && element.setCapture ) {
element.setCapture(); element.setCapture();
} }
}; };
} else { } else {
throw new Error( throw new Error(
@ -1117,7 +1117,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
/** /**
* Remove a given event listener for the given element, event type and * Remove a given event listener for the given element, event type and
* handler. * handler.
* @function * @function
* @name OpenSeadragon.removeEvent * @name OpenSeadragon.removeEvent
@ -1191,18 +1191,18 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
stopEvent: function( event ) { stopEvent: function( event ) {
event = $.getEvent( event ); event = $.getEvent( event );
if ( event.stopPropagation ) { if ( event.stopPropagation ) {
// W3C for stopping propagation // W3C for stopping propagation
$.stopEvent = function( event ){ $.stopEvent = function( event ){
event.stopPropagation(); event.stopPropagation();
}; };
} else { } else {
// IE for stopping propagation // IE for stopping propagation
$.stopEvent = function( event ){ $.stopEvent = function( event ){
event = $.getEvent( event ); event = $.getEvent( event );
event.cancelBubble = true; event.cancelBubble = true;
}; };
} }
$.stopEvent( event ); $.stopEvent( event );
@ -1210,17 +1210,17 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
/** /**
* Similar to OpenSeadragon.delegate, but it does not immediately call * Similar to OpenSeadragon.delegate, but it does not immediately call
* the method on the object, returning a function which can be called * the method on the object, returning a function which can be called
* repeatedly to delegate the method. It also allows additonal arguments * repeatedly to delegate the method. It also allows additonal arguments
* to be passed during construction which will be added during each * to be passed during construction which will be added during each
* invocation, and each invocation can add additional arguments as well. * invocation, and each invocation can add additional arguments as well.
* *
* @function * @function
* @name OpenSeadragon.createCallback * @name OpenSeadragon.createCallback
* @param {Object} object * @param {Object} object
* @param {Function} method * @param {Function} method
* @param [args] any additional arguments are passed as arguments to the * @param [args] any additional arguments are passed as arguments to the
* created callback * created callback
* @returns {Function} * @returns {Function}
*/ */
@ -1289,12 +1289,12 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
return request; return request;
}, },
/** /**
* Makes an AJAX request. * Makes an AJAX request.
* @function * @function
* @name OpenSeadragon.makeAjaxRequest * @name OpenSeadragon.makeAjaxRequest
* @param {String} url - the url to request * @param {String} url - the url to request
* @param {Function} [callback] - a function to call when complete * @param {Function} [callback] - a function to call when complete
* @throws {Error} * @throws {Error}
*/ */
@ -1334,7 +1334,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
} catch (e) { } catch (e) {
$.console.log( $.console.log(
"%s while making AJAX request: %s", "%s while making AJAX request: %s",
e.name, e.name,
e.message e.message
); );
@ -1369,8 +1369,8 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
jsonp: function( options ){ jsonp: function( options ){
var script, var script,
url = options.url, url = options.url,
head = document.head || head = document.head ||
document.getElementsByTagName( "head" )[ 0 ] || document.getElementsByTagName( "head" )[ 0 ] ||
document.documentElement, document.documentElement,
jsonpCallback = options.callbackName || 'openseadragon' + (+new Date()), jsonpCallback = options.callbackName || 'openseadragon' + (+new Date()),
previous = window[ jsonpCallback ], previous = window[ jsonpCallback ],
@ -1431,7 +1431,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
// Use insertBefore instead of appendChild to circumvent an IE6 bug. // Use insertBefore instead of appendChild to circumvent an IE6 bug.
// This arises when a base node is used (#2709 and #4378). // This arises when a base node is used (#2709 and #4378).
head.insertBefore( script, head.firstChild ); head.insertBefore( script, head.firstChild );
}, },
@ -1472,7 +1472,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
}; };
} else if ( window.DOMParser ) { } else if ( window.DOMParser ) {
$.parseXml = function( string ){ $.parseXml = function( string ){
var xmlDoc = null, var xmlDoc = null,
parser; parser;
@ -1509,7 +1509,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
/** /**
* The current browser vendor, version, and related information regarding * The current browser vendor, version, and related information regarding
* detected features. Features include <br/> * detected features. Features include <br/>
* <strong>'alpha'</strong> - Does the browser support image alpha * <strong>'alpha'</strong> - Does the browser support image alpha
* transparency.<br/> * transparency.<br/>
* @name $.Browser * @name $.Browser
* @static * @static
@ -1522,10 +1522,10 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
var ACTIVEX = [ var ACTIVEX = [
"Msxml2.XMLHTTP", "Msxml2.XMLHTTP",
"Msxml3.XMLHTTP", "Msxml3.XMLHTTP",
"Microsoft.XMLHTTP" "Microsoft.XMLHTTP"
], ],
FILEFORMATS = { FILEFORMATS = {
"bmp": false, "bmp": false,
"jpeg": true, "jpeg": true,
@ -1537,7 +1537,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
URLPARAMS = {}; URLPARAMS = {};
(function() { (function() {
//A small auto-executing routine to determine the browser vendor, //A small auto-executing routine to determine the browser vendor,
//version and supporting feature sets. //version and supporting feature sets.
var app = navigator.appName, var app = navigator.appName,
ver = navigator.appVersion, ver = navigator.appVersion,
@ -1549,13 +1549,13 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
switch( navigator.appName ){ switch( navigator.appName ){
case "Microsoft Internet Explorer": case "Microsoft Internet Explorer":
if( !!window.attachEvent && if( !!window.attachEvent &&
!!window.ActiveXObject ) { !!window.ActiveXObject ) {
$.Browser.vendor = $.BROWSERS.IE; $.Browser.vendor = $.BROWSERS.IE;
$.Browser.version = parseFloat( $.Browser.version = parseFloat(
ua.substring( ua.substring(
ua.indexOf( "MSIE" ) + 5, ua.indexOf( "MSIE" ) + 5,
ua.indexOf( ";", ua.indexOf( "MSIE" ) ) ) ua.indexOf( ";", ua.indexOf( "MSIE" ) ) )
); );
} }
@ -1568,12 +1568,12 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
ua.substring( ua.indexOf( "Firefox" ) + 8 ) ua.substring( ua.indexOf( "Firefox" ) + 8 )
); );
} else if ( ua.indexOf( "Safari" ) >= 0 ) { } else if ( ua.indexOf( "Safari" ) >= 0 ) {
$.Browser.vendor = ua.indexOf( "Chrome" ) >= 0 ? $.Browser.vendor = ua.indexOf( "Chrome" ) >= 0 ?
$.BROWSERS.CHROME : $.BROWSERS.CHROME :
$.BROWSERS.SAFARI; $.BROWSERS.SAFARI;
$.Browser.version = parseFloat( $.Browser.version = parseFloat(
ua.substring( ua.substring(
ua.substring( 0, ua.indexOf( "Safari" ) ).lastIndexOf( "/" ) + 1, ua.substring( 0, ua.indexOf( "Safari" ) ).lastIndexOf( "/" ) + 1,
ua.indexOf( "Safari" ) ua.indexOf( "Safari" )
) )
); );
@ -1604,12 +1604,12 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
} }
//determine if this browser supports image alpha transparency //determine if this browser supports image alpha transparency
$.Browser.alpha = !( $.Browser.alpha = !(
( (
$.Browser.vendor == $.BROWSERS.IE && $.Browser.vendor == $.BROWSERS.IE &&
$.Browser.version < 9 $.Browser.version < 9
) || ( ) || (
$.Browser.vendor == $.BROWSERS.CHROME && $.Browser.vendor == $.BROWSERS.CHROME &&
$.Browser.version < 2 $.Browser.version < 2
) )
); );
@ -1629,7 +1629,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
// I eventually was convinced that errors should naturally propogate in // I eventually was convinced that errors should naturally propogate in
// all but the most special cases. // all but the most special cases.
/** /**
* A convenient alias for console when available, and a simple null * A convenient alias for console when available, and a simple null
* function when console is unavailable. * function when console is unavailable.
* @static * @static
* @private * @private
@ -1645,7 +1645,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
warn: nullfunction, warn: nullfunction,
error: nullfunction error: nullfunction
}; };
// Adding support for HTML5's requestAnimationFrame as suggested by acdha. // Adding support for HTML5's requestAnimationFrame as suggested by acdha.
// Implementation taken from matt synder's post here: // Implementation taken from matt synder's post here:
@ -1654,12 +1654,12 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
// most browsers have an implementation // most browsers have an implementation
var requestAnimationFrame = w.requestAnimationFrame || var requestAnimationFrame = w.requestAnimationFrame ||
w.mozRequestAnimationFrame || w.mozRequestAnimationFrame ||
w.webkitRequestAnimationFrame || w.webkitRequestAnimationFrame ||
w.msRequestAnimationFrame; w.msRequestAnimationFrame;
var cancelAnimationFrame = w.cancelAnimationFrame || var cancelAnimationFrame = w.cancelAnimationFrame ||
w.mozCancelAnimationFrame || w.mozCancelAnimationFrame ||
w.webkitCancelAnimationFrame || w.webkitCancelAnimationFrame ||
w.msCancelAnimationFrame; w.msCancelAnimationFrame;
@ -1737,7 +1737,7 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
* @private * @private
* @inner * @inner
* @function * @function
* @param {Element} element * @param {Element} element
* @param {Boolean} [isFixed] * @param {Boolean} [isFixed]
* @returns {Element} * @returns {Element}
*/ */
@ -1766,8 +1766,8 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
throw new Error( $.getString( "Errors.Security" ) ); throw new Error( $.getString( "Errors.Security" ) );
} else if ( xhr.status !== 200 && xhr.status !== 0 ) { } else if ( xhr.status !== 200 && xhr.status !== 0 ) {
status = xhr.status; status = xhr.status;
statusText = ( status == 404 ) ? statusText = ( status == 404 ) ?
"Not Found" : "Not Found" :
xhr.statusText; xhr.statusText;
throw new Error( $.getString( "Errors.Status", status, statusText ) ); throw new Error( $.getString( "Errors.Status", status, statusText ) );
} }
@ -1802,8 +1802,8 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
try { try {
return processDZI( root, tilesUrl ); return processDZI( root, tilesUrl );
} catch ( e ) { } catch ( e ) {
throw (e instanceof Error) ? throw (e instanceof Error) ?
e : e :
new Error( $.getString("Errors.Dzi") ); new Error( $.getString("Errors.Dzi") );
} }
} else if ( rootName == "Collection" ) { } else if ( rootName == "Collection" ) {
@ -1856,12 +1856,12 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
)); ));
} }
return new $.DziTileSource( return new $.DziTileSource(
width, width,
height, height,
tileSize, tileSize,
tileOverlap, tileOverlap,
tilesUrl, tilesUrl,
fileFormat, fileFormat,
dispRects dispRects
); );
} }
@ -1905,12 +1905,12 @@ window.OpenSeadragon = window.OpenSeadragon || function( options ){
)); ));
} }
return new $.DziTileSource( return new $.DziTileSource(
width, width,
height, height,
tileSize, tileSize,
tileOverlap, tileOverlap,
tilesUrl, tilesUrl,
fileFormat, fileFormat,
dispRects dispRects
); );
} }

View File

@ -41,16 +41,16 @@
(function( $ ){ (function( $ ){
/** /**
* A tilesource implementation for OpenStreetMap. * A tilesource implementation for OpenStreetMap.
* *
* Note 1. Zoomlevels. Deep Zoom and OSM define zoom levels differently. In Deep * Note 1. Zoomlevels. Deep Zoom and OSM define zoom levels differently. In Deep
* Zoom, level 0 equals an image of 1x1 pixels. In OSM, level 0 equals an image of * Zoom, level 0 equals an image of 1x1 pixels. In OSM, level 0 equals an image of
* 256x256 levels (see http://gasi.ch/blog/inside-deep-zoom-2). I.e. there is a * 256x256 levels (see http://gasi.ch/blog/inside-deep-zoom-2). I.e. there is a
* difference of log2(256)=8 levels. * difference of log2(256)=8 levels.
* *
* Note 2. Image dimension. According to the OSM Wiki * Note 2. Image dimension. According to the OSM Wiki
* (http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels) * (http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Zoom_levels)
* the highest Mapnik zoom level has 256.144x256.144 tiles, with a 256x256 * the highest Mapnik zoom level has 256.144x256.144 tiles, with a 256x256
* pixel size. I.e. the Deep Zoom image dimension is 65.572.864x65.572.864 * pixel size. I.e. the Deep Zoom image dimension is 65.572.864x65.572.864
@ -64,7 +64,7 @@
* @param {Number} tileSize * @param {Number} tileSize
* @param {Number} tileOverlap * @param {Number} tileOverlap
* @param {String} tilesUrl * @param {String} tilesUrl
*/ */
$.OsmTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) { $.OsmTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) {
var options; var options;
@ -94,7 +94,7 @@ $.OsmTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) {
options.tilesUrl = "http://tile.openstreetmap.org/"; options.tilesUrl = "http://tile.openstreetmap.org/";
} }
options.minLevel = 8; options.minLevel = 8;
$.TileSource.apply( this, [ options ] ); $.TileSource.apply( this, [ options ] );
}; };
@ -111,19 +111,19 @@ $.extend( $.OsmTileSource.prototype, $.TileSource.prototype, {
* @param {String} optional - url * @param {String} optional - url
*/ */
supports: function( data, url ){ supports: function( data, url ){
return ( return (
data.type && data.type &&
"openstreetmaps" == data.type "openstreetmaps" == data.type
); );
}, },
/** /**
* *
* @function * @function
* @name OpenSeadragon.OsmTileSource.prototype.configure * @name OpenSeadragon.OsmTileSource.prototype.configure
* @param {Object} data - the raw configuration * @param {Object} data - the raw configuration
* @param {String} url - the url the data was retreived from if any. * @param {String} url - the url the data was retreived from if any.
* @return {Object} options - A dictionary of keyword arguments sufficient * @return {Object} options - A dictionary of keyword arguments sufficient
* to configure this tile sources constructor. * to configure this tile sources constructor.
*/ */
configure: function( data, url ){ configure: function( data, url ){

View File

@ -53,31 +53,31 @@
}; };
/** /**
* An Overlay provides a * An Overlay provides a
* @class * @class
*/ */
$.Overlay = function( element, location, placement ) { $.Overlay = function( element, location, placement ) {
this.element = element; this.element = element;
this.scales = location instanceof $.Rect; this.scales = location instanceof $.Rect;
this.bounds = new $.Rect( this.bounds = new $.Rect(
location.x, location.x,
location.y, location.y,
location.width, location.width,
location.height location.height
); );
this.position = new $.Point( this.position = new $.Point(
location.x, location.x,
location.y location.y
); );
this.size = new $.Point( this.size = new $.Point(
location.width, location.width,
location.height location.height
); );
this.style = element.style; this.style = element.style;
// rects are always top-left // rects are always top-left
this.placement = location instanceof $.Point ? this.placement = location instanceof $.Point ?
placement : placement :
$.OverlayPlacement.TOP_LEFT; $.OverlayPlacement.TOP_LEFT;
}; };
$.Overlay.prototype = { $.Overlay.prototype = {
@ -136,7 +136,7 @@
//pages //pages
if( element.prevElementParent ){ if( element.prevElementParent ){
style.display = 'none'; style.display = 'none';
//element.prevElementParent.insertBefore( //element.prevElementParent.insertBefore(
// element, // element,
// element.prevNextSibling // element.prevNextSibling
//); //);
@ -202,16 +202,16 @@
*/ */
update: function( location, placement ) { update: function( location, placement ) {
this.scales = location instanceof $.Rect; this.scales = location instanceof $.Rect;
this.bounds = new $.Rect( this.bounds = new $.Rect(
location.x, location.x,
location.y, location.y,
location.width, location.width,
location.height location.height
); );
// rects are always top-left // rects are always top-left
this.placement = location instanceof $.Point ? this.placement = location instanceof $.Point ?
placement : placement :
$.OverlayPlacement.TOP_LEFT; $.OverlayPlacement.TOP_LEFT;
} }
}; };

View File

@ -35,13 +35,13 @@
(function( $ ){ (function( $ ){
/** /**
* A Point is really used as a 2-dimensional vector, equally useful for * A Point is really used as a 2-dimensional vector, equally useful for
* representing a point on a plane, or the height and width of a plane * representing a point on a plane, or the height and width of a plane
* not requiring any other frame of reference. * not requiring any other frame of reference.
* @class * @class
* @param {Number} [x] The vector component 'x'. Defaults to the origin at 0. * @param {Number} [x] The vector component 'x'. Defaults to the origin at 0.
* @param {Number} [y] The vector component 'y'. Defaults to the origin at 0. * @param {Number} [y] The vector component 'y'. Defaults to the origin at 0.
* @property {Number} [x] The vector component 'x'. * @property {Number} [x] The vector component 'x'.
* @property {Number} [y] The vector component 'y'. * @property {Number} [y] The vector component 'y'.
*/ */
$.Point = function( x, y ) { $.Point = function( x, y ) {
@ -60,7 +60,7 @@ $.Point.prototype = {
*/ */
plus: function( point ) { plus: function( point ) {
return new $.Point( return new $.Point(
this.x + point.x, this.x + point.x,
this.y + point.y this.y + point.y
); );
}, },
@ -74,7 +74,7 @@ $.Point.prototype = {
*/ */
minus: function( point ) { minus: function( point ) {
return new $.Point( return new $.Point(
this.x - point.x, this.x - point.x,
this.y - point.y this.y - point.y
); );
}, },
@ -88,7 +88,7 @@ $.Point.prototype = {
*/ */
times: function( factor ) { times: function( factor ) {
return new $.Point( return new $.Point(
this.x * factor, this.x * factor,
this.y * factor this.y * factor
); );
}, },
@ -102,7 +102,7 @@ $.Point.prototype = {
*/ */
divide: function( factor ) { divide: function( factor ) {
return new $.Point( return new $.Point(
this.x / factor, this.x / factor,
this.y / factor this.y / factor
); );
}, },
@ -151,12 +151,12 @@ $.Point.prototype = {
* vector components * vector components
*/ */
equals: function( point ) { equals: function( point ) {
return ( return (
point instanceof $.Point point instanceof $.Point
) && ( ) && (
this.x === point.x this.x === point.x
) && ( ) && (
this.y === point.y this.y === point.y
); );
}, },

View File

@ -35,7 +35,7 @@
(function( $ ){ (function( $ ){
/** /**
* A utility class useful for developers to establish baseline performance * A utility class useful for developers to establish baseline performance
* metrics of rendering routines. * metrics of rendering routines.
* @class * @class
* @property {Boolean} midUpdate * @property {Boolean} midUpdate

View File

@ -33,11 +33,11 @@
*/ */
(function( $ ){ (function( $ ){
/** /**
* A Rectangle really represents a 2x2 matrix where each row represents a * A Rectangle really represents a 2x2 matrix where each row represents a
* 2 dimensional vector component, the first is (x,y) and the second is * 2 dimensional vector component, the first is (x,y) and the second is
* (width, height). The latter component implies the equation of a simple * (width, height). The latter component implies the equation of a simple
* plane. * plane.
* *
* @class * @class
@ -88,7 +88,7 @@ $.Rect.prototype = {
*/ */
getBottomRight: function() { getBottomRight: function() {
return new $.Point( return new $.Point(
this.x + this.width, this.x + this.width,
this.y + this.height this.y + this.height
); );
}, },
@ -96,7 +96,7 @@ $.Rect.prototype = {
/** /**
* Computes the center of the rectangle. * Computes the center of the rectangle.
* @function * @function
* @returns {OpenSeadragon.Point} The center of the rectangle as represnted * @returns {OpenSeadragon.Point} The center of the rectangle as represnted
* as represented by a 2-dimensional vector (x,y) * as represented by a 2-dimensional vector (x,y)
*/ */
getCenter: function() { getCenter: function() {
@ -117,31 +117,31 @@ $.Rect.prototype = {
}, },
/** /**
* Determines if two Rectanlges have equivalent components. * Determines if two Rectanlges have equivalent components.
* @function * @function
* @param {OpenSeadragon.Rect} rectangle The Rectangle to compare to. * @param {OpenSeadragon.Rect} rectangle The Rectangle to compare to.
* @return {Boolean} 'true' if all components are equal, otherwise 'false'. * @return {Boolean} 'true' if all components are equal, otherwise 'false'.
*/ */
equals: function( other ) { equals: function( other ) {
return ( other instanceof $.Rect ) && return ( other instanceof $.Rect ) &&
( this.x === other.x ) && ( this.x === other.x ) &&
( this.y === other.y ) && ( this.y === other.y ) &&
( this.width === other.width ) && ( this.width === other.width ) &&
( this.height === other.height ); ( this.height === other.height );
}, },
/** /**
* Provides a string representation of the retangle which is useful for * Provides a string representation of the retangle which is useful for
* debugging. * debugging.
* @function * @function
* @returns {String} A string representation of the rectangle. * @returns {String} A string representation of the rectangle.
*/ */
toString: function() { toString: function() {
return "[" + return "[" +
Math.round(this.x*100) + "," + Math.round(this.x*100) + "," +
Math.round(this.y*100) + "," + Math.round(this.y*100) + "," +
Math.round(this.width*100) + "x" + Math.round(this.width*100) + "x" +
Math.round(this.height*100) + Math.round(this.height*100) +
"]"; "]";
} }
}; };

View File

@ -33,16 +33,16 @@
*/ */
(function( $ ){ (function( $ ){
// dictionary from id to private properties // dictionary from id to private properties
var THIS = {}; var THIS = {};
/** /**
* The CollectionDrawer is a reimplementation if the Drawer API that * The CollectionDrawer is a reimplementation if the Drawer API that
* focuses on allowing a viewport to be redefined as a collection * focuses on allowing a viewport to be redefined as a collection
* of smaller viewports, defined by a clear number of rows and / or * of smaller viewports, defined by a clear number of rows and / or
* columns of which each item in the matrix of viewports has its own * columns of which each item in the matrix of viewports has its own
* source. * source.
* *
* This idea is a reexpression of the idea of dzi collections * This idea is a reexpression of the idea of dzi collections
* which allows a clearer algorithm to reuse the tile sources already * which allows a clearer algorithm to reuse the tile sources already
@ -51,8 +51,8 @@ var THIS = {};
* for the purpose of image sequnces. * for the purpose of image sequnces.
* *
* TODO: The difficult part of this feature is figuring out how to express * TODO: The difficult part of this feature is figuring out how to express
* this functionality as a combination of the functionality already * this functionality as a combination of the functionality already
* provided by Drawer, Viewport, TileSource, and Navigator. It may * provided by Drawer, Viewport, TileSource, and Navigator. It may
* require better abstraction at those points in order to effeciently * require better abstraction at those points in order to effeciently
* reuse those paradigms. * reuse those paradigms.
*/ */
@ -66,7 +66,7 @@ $.ReferenceStrip = function( options ){
element, element,
style, style,
i; i;
//We may need to create a new element and id if they did not //We may need to create a new element and id if they did not
//provide the id for the existing element //provide the id for the existing element
if( !options.id ){ if( !options.id ){
@ -123,46 +123,46 @@ $.ReferenceStrip = function( options ){
keyHandler: $.delegate( this, onKeyPress ) keyHandler: $.delegate( this, onKeyPress )
}).setTracking( true ); }).setTracking( true );
//Controls the position and orientation of the reference strip and sets the //Controls the position and orientation of the reference strip and sets the
//appropriate width and height //appropriate width and height
if( options.width && options.height ){ if( options.width && options.height ){
this.element.style.width = options.width + 'px'; this.element.style.width = options.width + 'px';
this.element.style.height = options.height + 'px'; this.element.style.height = options.height + 'px';
viewer.addControl( viewer.addControl(
this.element, this.element,
{anchor: $.ControlAnchor.BOTTOM_LEFT} {anchor: $.ControlAnchor.BOTTOM_LEFT}
); );
} else { } else {
if( "horizontal" == options.scroll ){ if( "horizontal" == options.scroll ){
this.element.style.width = ( this.element.style.width = (
viewerSize.x * viewerSize.x *
options.sizeRatio * options.sizeRatio *
viewer.tileSources.length viewer.tileSources.length
) + ( 12 * viewer.tileSources.length ) + 'px'; ) + ( 12 * viewer.tileSources.length ) + 'px';
this.element.style.height = ( this.element.style.height = (
viewerSize.y * viewerSize.y *
options.sizeRatio options.sizeRatio
) + 'px'; ) + 'px';
viewer.addControl( viewer.addControl(
this.element, this.element,
{anchor: $.ControlAnchor.BOTTOM_LEFT} {anchor: $.ControlAnchor.BOTTOM_LEFT}
); );
}else { }else {
this.element.style.height = ( this.element.style.height = (
viewerSize.y * viewerSize.y *
options.sizeRatio * options.sizeRatio *
viewer.tileSources.length viewer.tileSources.length
) + ( 12 * viewer.tileSources.length ) + 'px'; ) + ( 12 * viewer.tileSources.length ) + 'px';
this.element.style.width = ( this.element.style.width = (
viewerSize.x * viewerSize.x *
options.sizeRatio options.sizeRatio
) + 'px'; ) + 'px';
viewer.addControl( viewer.addControl(
this.element, this.element,
{anchor: $.ControlAnchor.TOP_LEFT} {anchor: $.ControlAnchor.TOP_LEFT}
); );
@ -175,7 +175,7 @@ $.ReferenceStrip = function( options ){
/*jshint loopfunc:true*/ /*jshint loopfunc:true*/
for( i = 0; i < viewer.tileSources.length; i++ ){ for( i = 0; i < viewer.tileSources.length; i++ ){
element = $.makeNeutralElement('div'); element = $.makeNeutralElement('div');
element.id = this.element.id + "-" + i; element.id = this.element.id + "-" + i;
@ -189,7 +189,7 @@ $.ReferenceStrip = function( options ){
element.innerTracker = new $.MouseTracker({ element.innerTracker = new $.MouseTracker({
element: element, element: element,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
pressHandler: function( tracker ){ pressHandler: function( tracker ){
tracker.dragging = +new Date(); tracker.dragging = +new Date();
@ -198,9 +198,9 @@ $.ReferenceStrip = function( options ){
var id = tracker.element.id, var id = tracker.element.id,
page = Number( id.split( '-' )[ 2 ] ), page = Number( id.split( '-' )[ 2 ] ),
now = +new Date(); now = +new Date();
if ( insideElementPress && if ( insideElementPress &&
insideElementRelease && insideElementRelease &&
tracker.dragging && tracker.dragging &&
( now - tracker.dragging ) < tracker.clickTimeThreshold ){ ( now - tracker.dragging ) < tracker.clickTimeThreshold ){
tracker.dragging = null; tracker.dragging = null;
@ -294,7 +294,7 @@ $.extend( $.ReferenceStrip.prototype, $.EventHandler.prototype, $.Viewer.prototy
* @function * @function
*/ */
function onStripDrag( tracker, position, delta, shift ) { function onStripDrag( tracker, position, delta, shift ) {
var offsetLeft = Number(this.element.style.marginLeft.replace('px','')), var offsetLeft = Number(this.element.style.marginLeft.replace('px','')),
offsetTop = Number(this.element.style.marginTop.replace('px','')), offsetTop = Number(this.element.style.marginTop.replace('px','')),
scrollWidth = Number(this.element.style.width.replace('px','')), scrollWidth = Number(this.element.style.width.replace('px','')),
@ -417,7 +417,7 @@ function loadPanels(strip, viewerSize, scroll){
immediateRender: true, immediateRender: true,
blendTime: 0, blendTime: 0,
animationTime: 0 animationTime: 0
} ); } );
miniViewer.displayRegion = $.makeNeutralElement( "textarea" ); miniViewer.displayRegion = $.makeNeutralElement( "textarea" );
miniViewer.displayRegion.id = element.id + '-displayregion'; miniViewer.displayRegion.id = element.id + '-displayregion';
@ -441,8 +441,8 @@ function loadPanels(strip, viewerSize, scroll){
element: miniViewer.displayRegion element: miniViewer.displayRegion
}); });
element.getElementsByTagName('form')[ 0 ].appendChild( element.getElementsByTagName('form')[ 0 ].appendChild(
miniViewer.displayRegion miniViewer.displayRegion
); );
element.activePanel = true; element.activePanel = true;
@ -469,7 +469,7 @@ function onStripEnter( tracker ) {
tracker.element.style.marginBottom = "0px"; tracker.element.style.marginBottom = "0px";
} else { } else {
//tracker.element.style.paddingRight = "0px"; //tracker.element.style.paddingRight = "0px";
tracker.element.style.marginLeft = "0px"; tracker.element.style.marginLeft = "0px";
@ -490,18 +490,18 @@ function onStripExit( tracker ) {
//$.setElementOpacity(tracker.element, 0.4); //$.setElementOpacity(tracker.element, 0.4);
//tracker.element.style.border = 'none'; //tracker.element.style.border = 'none';
//tracker.element.style.background = '#fff'; //tracker.element.style.background = '#fff';
if( 'horizontal' == this.scroll ){ if( 'horizontal' == this.scroll ){
//tracker.element.style.paddingTop = "10px"; //tracker.element.style.paddingTop = "10px";
tracker.element.style.marginBottom = "-" + ( $.getElementSize( tracker.element ).y / 2 ) + "px"; tracker.element.style.marginBottom = "-" + ( $.getElementSize( tracker.element ).y / 2 ) + "px";
} else { } else {
//tracker.element.style.paddingRight = "10px"; //tracker.element.style.paddingRight = "10px";
tracker.element.style.marginLeft = "-" + ( $.getElementSize( tracker.element ).x / 2 )+ "px"; tracker.element.style.marginLeft = "-" + ( $.getElementSize( tracker.element ).x / 2 )+ "px";
} }
return false; return false;
} }

View File

@ -33,20 +33,20 @@
*/ */
(function( $ ){ (function( $ ){
/** /**
* @class * @class
* @param {Object} options - Spring configuration settings. * @param {Object} options - Spring configuration settings.
* @param {Number} options.initial - Initial value of spring, default to 0 so * @param {Number} options.initial - Initial value of spring, default to 0 so
* spring is not in motion initally by default. * spring is not in motion initally by default.
* @param {Number} options.springStiffness - Spring stiffness. * @param {Number} options.springStiffness - Spring stiffness.
* @param {Number} options.animationTime - Animation duration per spring. * @param {Number} options.animationTime - Animation duration per spring.
* *
* @property {Number} initial - Initial value of spring, default to 0 so * @property {Number} initial - Initial value of spring, default to 0 so
* spring is not in motion initally by default. * spring is not in motion initally by default.
* @property {Number} springStiffness - Spring stiffness. * @property {Number} springStiffness - Spring stiffness.
* @property {Number} animationTime - Animation duration per spring. * @property {Number} animationTime - Animation duration per spring.
* @property {Object} current * @property {Object} current
* @property {Number} start * @property {Number} start
* @property {Number} target * @property {Number} target
*/ */
@ -54,17 +54,17 @@ $.Spring = function( options ) {
var args = arguments; var args = arguments;
if( typeof( options ) != 'object' ){ if( typeof( options ) != 'object' ){
//allows backward compatible use of ( initialValue, config ) as //allows backward compatible use of ( initialValue, config ) as
//constructor parameters //constructor parameters
options = { options = {
initial: args.length && typeof ( args[ 0 ] ) == "number" ? initial: args.length && typeof ( args[ 0 ] ) == "number" ?
args[ 0 ] : args[ 0 ] :
0, 0,
springStiffness: args.length > 1 ? springStiffness: args.length > 1 ?
args[ 1 ].springStiffness : args[ 1 ].springStiffness :
5.0, 5.0,
animationTime: args.length > 1 ? animationTime: args.length > 1 ?
args[ 1 ].animationTime : args[ 1 ].animationTime :
1.5 1.5
}; };
} }
@ -73,8 +73,8 @@ $.Spring = function( options ) {
this.current = { this.current = {
value: typeof ( this.initial ) == "number" ? value: typeof ( this.initial ) == "number" ?
this.initial : this.initial :
0, 0,
time: new Date().getTime() // always work in milliseconds time: new Date().getTime() // always work in milliseconds
}; };
@ -128,13 +128,13 @@ $.Spring.prototype = {
*/ */
update: function() { update: function() {
this.current.time = new Date().getTime(); this.current.time = new Date().getTime();
this.current.value = (this.current.time >= this.target.time) ? this.current.value = (this.current.time >= this.target.time) ?
this.target.value : this.target.value :
this.start.value + this.start.value +
( this.target.value - this.start.value ) * ( this.target.value - this.start.value ) *
transform( transform(
this.springStiffness, this.springStiffness,
( this.current.time - this.start.time ) / ( this.current.time - this.start.time ) /
( this.target.time - this.start.time ) ( this.target.time - this.start.time )
); );
} }
@ -144,7 +144,7 @@ $.Spring.prototype = {
* @private * @private
*/ */
function transform( stiffness, x ) { function transform( stiffness, x ) {
return ( 1.0 - Math.exp( stiffness * -x ) ) / return ( 1.0 - Math.exp( stiffness * -x ) ) /
( 1.0 - Math.exp( -stiffness ) ); ( 1.0 - Math.exp( -stiffness ) );
} }

View File

@ -33,8 +33,8 @@
*/ */
(function( $ ){ (function( $ ){
//TODO: I guess this is where the i18n needs to be reimplemented. I'll look //TODO: I guess this is where the i18n needs to be reimplemented. I'll look
// into existing patterns for i18n in javascript but i think that mimicking // into existing patterns for i18n in javascript but i think that mimicking
// pythons gettext might be a reasonable approach. // pythons gettext might be a reasonable approach.
var I18N = { var I18N = {
@ -66,7 +66,7 @@ $.extend( $, {
* @param {String} property * @param {String} property
*/ */
getString: function( prop ) { getString: function( prop ) {
var props = prop.split('.'), var props = prop.split('.'),
string = null, string = null,
args = arguments, args = arguments,
@ -85,8 +85,8 @@ $.extend( $, {
return string.replace(/\{\d+\}/g, function(capture) { return string.replace(/\{\d+\}/g, function(capture) {
var i = parseInt( capture.match( /\d+/ ), 10 ) + 1; var i = parseInt( capture.match( /\d+/ ), 10 ) + 1;
return i < args.length ? return i < args.length ?
args[ i ] : args[ i ] :
""; "";
}); });
}, },

View File

@ -39,18 +39,18 @@
* @param {Number} level The zoom level this tile belongs to. * @param {Number} level The zoom level this tile belongs to.
* @param {Number} x The vector component 'x'. * @param {Number} x The vector component 'x'.
* @param {Number} y The vector component 'y'. * @param {Number} y The vector component 'y'.
* @param {OpenSeadragon.Point} bounds Where this tile fits, in normalized * @param {OpenSeadragon.Point} bounds Where this tile fits, in normalized
* coordinates. * coordinates.
* @param {Boolean} exists Is this tile a part of a sparse image? ( Also has * @param {Boolean} exists Is this tile a part of a sparse image? ( Also has
* this tile failed to load? ) * this tile failed to load? )
* @param {String} url The URL of this tile's image. * @param {String} url The URL of this tile's image.
* *
* @property {Number} level The zoom level this tile belongs to. * @property {Number} level The zoom level this tile belongs to.
* @property {Number} x The vector component 'x'. * @property {Number} x The vector component 'x'.
* @property {Number} y The vector component 'y'. * @property {Number} y The vector component 'y'.
* @property {OpenSeadragon.Point} bounds Where this tile fits, in normalized * @property {OpenSeadragon.Point} bounds Where this tile fits, in normalized
* coordinates * coordinates
* @property {Boolean} exists Is this tile a part of a sparse image? ( Also has * @property {Boolean} exists Is this tile a part of a sparse image? ( Also has
* this tile failed to load? * this tile failed to load?
* @property {String} url The URL of this tile's image. * @property {String} url The URL of this tile's image.
* @property {Boolean} loaded Is this tile loaded? * @property {Boolean} loaded Is this tile loaded?
@ -93,9 +93,9 @@ $.Tile = function(level, x, y, bounds, exists, url) {
}; };
$.Tile.prototype = { $.Tile.prototype = {
/** /**
* Provides a string representation of this tiles level and (x,y) * Provides a string representation of this tiles level and (x,y)
* components. * components.
* @function * @function
* @returns {String} * @returns {String}
@ -171,11 +171,11 @@ $.Tile.prototype = {
if( context.globalAlpha == 1 && this.url.match('.png') ){ if( context.globalAlpha == 1 && this.url.match('.png') ){
//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(
position.x+1, position.x+1,
position.y+1, position.y+1,
size.x-2, size.x-2,
size.y-2 size.y-2
); );
} }
@ -193,18 +193,18 @@ $.Tile.prototype = {
} }
rendered = TILE_CACHE[ this.url ]; rendered = TILE_CACHE[ this.url ];
//rendered.save(); //rendered.save();
context.drawImage( context.drawImage(
rendered.canvas, rendered.canvas,
0, 0,
0, 0,
rendered.canvas.width, rendered.canvas.width,
rendered.canvas.height, rendered.canvas.height,
position.x, position.x,
position.y, position.y,
size.x, size.x,
size.y size.y
); );
//rendered.restore(); //rendered.restore();
@ -218,7 +218,7 @@ $.Tile.prototype = {
unload: function() { unload: function() {
if ( this.element && this.element.parentNode ) { if ( this.element && this.element.parentNode ) {
this.element.parentNode.removeChild( this.element ); this.element.parentNode.removeChild( this.element );
} }
if ( TILE_CACHE[ this.url ]){ if ( TILE_CACHE[ this.url ]){
delete TILE_CACHE[ this.url ]; delete TILE_CACHE[ this.url ];
} }

View File

@ -37,22 +37,22 @@
/** /**
* The TileSource contains the most basic implementation required to create a * The TileSource contains the most basic implementation required to create a
* smooth transition between layer in an image pyramid. It has only a single key * smooth transition between layer in an image pyramid. It has only a single key
* interface that must be implemented to complete it key functionality: * interface that must be implemented to complete it key functionality:
* 'getTileUrl'. It also has several optional interfaces that can be * 'getTileUrl'. It also has several optional interfaces that can be
* implemented if a new TileSource wishes to support configuration via a simple * implemented if a new TileSource wishes to support configuration via a simple
* object or array ('configure') and if the tile source supports or requires * object or array ('configure') and if the tile source supports or requires
* configuration via retreival of a document on the network ala AJAX or JSONP, * configuration via retreival of a document on the network ala AJAX or JSONP,
* ('getImageInfo'). * ('getImageInfo').
* <br/> * <br/>
* By default the image pyramid is split into N layers where the images longest * By default the image pyramid is split into N layers where the images longest
* side in M (in pixels), where N is the smallest integer which satisfies * side in M (in pixels), where N is the smallest integer which satisfies
* <strong>2^(N+1) >= M</strong>. * <strong>2^(N+1) >= M</strong>.
* @class * @class
* @extends OpenSeadragon.EventHandler * @extends OpenSeadragon.EventHandler
* @param {Number|Object|Array|String} width * @param {Number|Object|Array|String} width
* If more than a single argument is supplied, the traditional use of * If more than a single argument is supplied, the traditional use of
* positional parameters is supplied and width is expected to be the width * positional parameters is supplied and width is expected to be the width
* source image at it's max resolution in pixels. If a single argument is supplied and * source image at it's max resolution in pixels. If a single argument is supplied and
* it is an Object or Array, the construction is assumed to occur through * it is an Object or Array, the construction is assumed to occur through
* the extending classes implementation of 'configure'. Finally if only a * the extending classes implementation of 'configure'. Finally if only a
@ -62,7 +62,7 @@
* Width of the source image at max resolution in pixels. * Width of the source image at max resolution in pixels.
* @param {Number} tileSize * @param {Number} tileSize
* The size of the tiles to assumed to make up each pyramid layer in pixels. * The size of the tiles to assumed to make up each pyramid layer in pixels.
* Tile size determines the point at which the image pyramid must be * Tile size determines the point at which the image pyramid must be
* divided into a matrix of smaller images. * divided into a matrix of smaller images.
* @param {Number} tileOverlap * @param {Number} tileOverlap
* The number of pixels each tile is expected to overlap touching tiles. * The number of pixels each tile is expected to overlap touching tiles.
@ -82,7 +82,7 @@
* The minimum pyramid level this tile source supports or should attempt to load. * The minimum pyramid level this tile source supports or should attempt to load.
* @property {Number} maxLevel * @property {Number} maxLevel
* The maximum pyramid level this tile source supports or should attempt to load. * The maximum pyramid level this tile source supports or should attempt to load.
*/ */
$.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) { $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLevel ) {
var _this = this, var _this = this,
callback = null, callback = null,
@ -137,26 +137,26 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
this.minLevel = 0; this.minLevel = 0;
this.maxLevel = 0; this.maxLevel = 0;
this.ready = false; this.ready = false;
//configuration via url implies the extending class //configuration via url implies the extending class
//implements and 'configure' //implements and 'configure'
this.getImageInfo( arguments[ 0 ] ); this.getImageInfo( arguments[ 0 ] );
} else { } else {
//explicit configuration via positional args in constructor //explicit configuration via positional args in constructor
//or the more idiomatic 'options' object //or the more idiomatic 'options' object
this.ready = true; this.ready = true;
this.aspectRatio = ( options.width && options.height ) ? this.aspectRatio = ( options.width && options.height ) ?
( options.width / options.height ) : 1; ( options.width / options.height ) : 1;
this.dimensions = new $.Point( options.width, options.height ); this.dimensions = new $.Point( options.width, options.height );
this.tileSize = options.tileSize ? options.tileSize : 0; this.tileSize = options.tileSize ? options.tileSize : 0;
this.tileOverlap = options.tileOverlap ? options.tileOverlap : 0; this.tileOverlap = options.tileOverlap ? options.tileOverlap : 0;
this.minLevel = options.minLevel ? options.minLevel : 0; this.minLevel = options.minLevel ? options.minLevel : 0;
this.maxLevel = ( undefined !== options.maxLevel && null !== options.maxLevel ) ? this.maxLevel = ( undefined !== options.maxLevel && null !== options.maxLevel ) ?
options.maxLevel : ( options.maxLevel : (
( options.width && options.height ) ? Math.ceil( ( options.width && options.height ) ? Math.ceil(
Math.log( Math.max( options.width, options.height ) ) / Math.log( Math.max( options.width, options.height ) ) /
Math.log( 2 ) Math.log( 2 )
) : 0 ) : 0
); );
if( callback && $.isFunction( callback ) ){ if( callback && $.isFunction( callback ) ){
@ -169,7 +169,7 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
$.TileSource.prototype = { $.TileSource.prototype = {
/** /**
* @function * @function
* @param {Number} level * @param {Number} level
@ -264,7 +264,7 @@ $.TileSource.prototype = {
return new $.Rect( px * scale, py * scale, sx * scale, sy * scale ); return new $.Rect( px * scale, py * scale, sx * scale, sy * scale );
}, },
/** /**
* Responsible for retrieving, and caching the * Responsible for retrieving, and caching the
@ -294,7 +294,7 @@ $.TileSource.prototype = {
urlParts[ urlParts.length - 1 ] = filename.slice( 0, lastDot ); urlParts[ urlParts.length - 1 ] = filename.slice( 0, lastDot );
} }
} }
callback = function( data ){ callback = function( data ){
var $TileSource = $.TileSource.determineType( _this, data, url ); var $TileSource = $.TileSource.determineType( _this, data, url );
options = $TileSource.prototype.configure.apply( _this, [ data, url ]); options = $TileSource.prototype.configure.apply( _this, [ data, url ]);
@ -334,7 +334,7 @@ $.TileSource.prototype = {
* and sufficient mechanisim for clear determination. * and sufficient mechanisim for clear determination.
* @function * @function
* @param {String|Object|Array|Document} data * @param {String|Object|Array|Document} data
* @param {String} url - the url the data was loaded * @param {String} url - the url the data was loaded
* from if any. * from if any.
* @return {Boolean} * @return {Boolean}
*/ */
@ -346,14 +346,14 @@ $.TileSource.prototype = {
* Responsible for parsing and configuring the * Responsible for parsing and configuring the
* image metadata pertinent to this TileSources implementation. * image metadata pertinent to this TileSources implementation.
* This method is not implemented by this class other than to throw an Error * This method is not implemented by this class other than to throw an Error
* announcing you have to implement it. Because of the variety of tile * announcing you have to implement it. Because of the variety of tile
* server technologies, and various specifications for building image * server technologies, and various specifications for building image
* pyramids, this method is here to allow easy integration. * pyramids, this method is here to allow easy integration.
* @function * @function
* @param {String|Object|Array|Document} data * @param {String|Object|Array|Document} data
* @param {String} url - the url the data was loaded * @param {String} url - the url the data was loaded
* from if any. * from if any.
* @return {Object} options - A dictionary of keyword arguments sufficient * @return {Object} options - A dictionary of keyword arguments sufficient
* to configure this tile sources constructor. * to configure this tile sources constructor.
* @throws {Error} * @throws {Error}
*/ */
@ -362,10 +362,10 @@ $.TileSource.prototype = {
}, },
/** /**
* Responsible for retriving the url which will return an image for the * Responsible for retriving the url which will return an image for the
* region speified by the given x, y, and level components. * region speified by the given x, y, and level components.
* This method is not implemented by this class other than to throw an Error * This method is not implemented by this class other than to throw an Error
* announcing you have to implement it. Because of the variety of tile * announcing you have to implement it. Because of the variety of tile
* server technologies, and various specifications for building image * server technologies, and various specifications for building image
* pyramids, this method is here to allow easy integration. * pyramids, this method is here to allow easy integration.
* @function * @function
@ -386,11 +386,11 @@ $.TileSource.prototype = {
*/ */
tileExists: function( level, x, y ) { tileExists: function( level, x, y ) {
var numTiles = this.getNumTiles( level ); var numTiles = this.getNumTiles( level );
return level >= this.minLevel && return level >= this.minLevel &&
level <= this.maxLevel && level <= this.maxLevel &&
x >= 0 && x >= 0 &&
y >= 0 && y >= 0 &&
x < numTiles.x && x < numTiles.x &&
y < numTiles.y; y < numTiles.y;
} }
}; };
@ -417,16 +417,16 @@ function processResponse( xhr ){
throw new Error( $.getString( "Errors.Security" ) ); throw new Error( $.getString( "Errors.Security" ) );
} else if ( xhr.status !== 200 && xhr.status !== 0 ) { } else if ( xhr.status !== 200 && xhr.status !== 0 ) {
status = xhr.status; status = xhr.status;
statusText = ( status == 404 ) ? statusText = ( status == 404 ) ?
"Not Found" : "Not Found" :
xhr.statusText; xhr.statusText;
throw new Error( $.getString( "Errors.Status", status, statusText ) ); throw new Error( $.getString( "Errors.Status", status, statusText ) );
} }
if( responseText.match(/\s*<.*/) ){ if( responseText.match(/\s*<.*/) ){
try{ try{
data = ( xhr.responseXML && xhr.responseXML.documentElement ) ? data = ( xhr.responseXML && xhr.responseXML.documentElement ) ?
xhr.responseXML : xhr.responseXML :
$.parseXml( responseText ); $.parseXml( responseText );
} catch (e){ } catch (e){
data = xhr.responseText; data = xhr.responseText;

View File

@ -33,14 +33,14 @@
*/ */
(function( $ ){ (function( $ ){
/** /**
* @class * @class
* @extends OpenSeadragon.TileSource * @extends OpenSeadragon.TileSource
*/ */
$.TileSourceCollection = function( tileSize, tileSources, rows, layout ) { $.TileSourceCollection = function( tileSize, tileSources, rows, layout ) {
if( $.isPlainObject( tileSize ) ){ if( $.isPlainObject( tileSize ) ){
options = tileSize; options = tileSize;
}else{ }else{
@ -85,7 +85,7 @@ $.TileSourceCollection = function( tileSize, tileSources, rows, layout ) {
options.minLevel = minLevel; options.minLevel = minLevel;
//for( var name in options ){ //for( var name in options ){
// $.console.log( 'Collection %s %s', name, options[ name ] ); // $.console.log( 'Collection %s %s', name, options[ name ] );
//} //}
$.TileSource.apply( this, [ options ] ); $.TileSource.apply( this, [ options ] );
@ -116,7 +116,7 @@ $.extend( $.TileSourceCollection.prototype, $.TileSource.prototype, {
}, },
/** /**
* *
* @function * @function
* @name OpenSeadragon.TileSourceCollection.prototype.configure * @name OpenSeadragon.TileSourceCollection.prototype.configure
*/ */
@ -138,7 +138,7 @@ $.extend( $.TileSourceCollection.prototype, $.TileSource.prototype, {
} }
}); });

View File

@ -41,7 +41,7 @@
(function( $ ){ (function( $ ){
/** /**
* A tilesource implementation for Tiled Map Services (TMS). * A tilesource implementation for Tiled Map Services (TMS).
* TMS tile scheme ( [ as supported by OpenLayers ] is described here * TMS tile scheme ( [ as supported by OpenLayers ] is described here
@ -55,7 +55,7 @@
* @param {Number} tileSize * @param {Number} tileSize
* @param {Number} tileOverlap * @param {Number} tileOverlap
* @param {String} tilesUrl * @param {String} tilesUrl
*/ */
$.TmsTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) { $.TmsTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) {
var options; var options;
@ -86,7 +86,7 @@ $.TmsTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) {
options.tileSize = 256; options.tileSize = 256;
options.width = bufferedWidth; options.width = bufferedWidth;
options.height = bufferedHeight; options.height = bufferedHeight;
$.TileSource.apply( this, [ options ] ); $.TileSource.apply( this, [ options ] );
}; };
@ -107,12 +107,12 @@ $.extend( $.TmsTileSource.prototype, $.TileSource.prototype, {
}, },
/** /**
* *
* @function * @function
* @name OpenSeadragon.TmsTileSource.prototype.configure * @name OpenSeadragon.TmsTileSource.prototype.configure
* @param {Object} data - the raw configuration * @param {Object} data - the raw configuration
* @param {String} url - the url the data was retreived from if any. * @param {String} url - the url the data was retreived from if any.
* @return {Object} options - A dictionary of keyword arguments sufficient * @return {Object} options - A dictionary of keyword arguments sufficient
* to configure this tile sources constructor. * to configure this tile sources constructor.
*/ */
configure: function( data, url ){ configure: function( data, url ){

View File

@ -33,12 +33,12 @@
*/ */
(function( $ ){ (function( $ ){
// dictionary from hash to private properties // dictionary from hash to private properties
var THIS = {}, var THIS = {},
// We keep a list of viewers so we can 'wake-up' each viewer on // We keep a list of viewers so we can 'wake-up' each viewer on
// a page after toggling between fullpage modes // a page after toggling between fullpage modes
VIEWERS = {}; VIEWERS = {};
/** /**
* *
@ -56,16 +56,16 @@ var THIS = {},
* @param {Object} options * @param {Object} options
* @param {String} options.element Id of Element to attach to, * @param {String} options.element Id of Element to attach to,
* @param {String} options.xmlPath Xpath ( TODO: not sure! ), * @param {String} options.xmlPath Xpath ( TODO: not sure! ),
* @param {String} options.prefixUrl Url used to prepend to paths, eg button * @param {String} options.prefixUrl Url used to prepend to paths, eg button
* images, etc. * images, etc.
* @param {OpenSeadragon.Control[]} options.controls Array of OpenSeadragon.Control, * @param {OpenSeadragon.Control[]} options.controls Array of OpenSeadragon.Control,
* @param {OpenSeadragon.Overlay[]} options.overlays Array of OpenSeadragon.Overlay, * @param {OpenSeadragon.Overlay[]} options.overlays Array of OpenSeadragon.Overlay,
* @param {OpenSeadragon.Control[]} options.overlayControls An Array of ( TODO: * @param {OpenSeadragon.Control[]} options.overlayControls An Array of ( TODO:
* not sure! ) * not sure! )
* @property {OpenSeadragon.Viewport} viewport The viewer's viewport, where you * @property {OpenSeadragon.Viewport} viewport The viewer's viewport, where you
* can access zoom, pan, etc. * can access zoom, pan, etc.
* *
**/ **/
$.Viewer = function( options ) { $.Viewer = function( options ) {
var args = arguments, var args = arguments,
@ -73,7 +73,7 @@ $.Viewer = function( options ) {
i; i;
//backward compatibility for positional args while prefering more //backward compatibility for positional args while prefering more
//idiomatic javascript options object as the only argument //idiomatic javascript options object as the only argument
if( !$.isPlainObject( options ) ){ if( !$.isPlainObject( options ) ){
options = { options = {
@ -93,10 +93,10 @@ $.Viewer = function( options ) {
$.extend( true, options, options.config ); $.extend( true, options, options.config );
delete options.config; delete options.config;
} }
//Public properties //Public properties
//Allow the options object to override global defaults //Allow the options object to override global defaults
$.extend( true, this, { $.extend( true, this, {
//internal state and dom identifiers //internal state and dom identifiers
id: options.id, id: options.id,
@ -125,12 +125,12 @@ $.Viewer = function( options ) {
//These are originally not part options but declared as members //These are originally not part options but declared as members
//in initialize. Its still considered idiomatic to put them here //in initialize. Its still considered idiomatic to put them here
source: null, source: null,
drawer: null, drawer: null,
drawers: [], drawers: [],
viewport: null, viewport: null,
navigator: null, navigator: null,
//A collection viewport is a seperate viewport used to provide //A collection viewport is a seperate viewport used to provide
//simultanious rendering of sets of tiless //simultanious rendering of sets of tiless
collectionViewport: null, collectionViewport: null,
collectionDrawer: null, collectionDrawer: null,
@ -140,7 +140,7 @@ $.Viewer = function( options ) {
navImages: null, navImages: null,
//interface button controls //interface button controls
buttons: null, buttons: null,
//TODO: this is defunct so safely remove it //TODO: this is defunct so safely remove it
profiler: null profiler: null
@ -158,12 +158,12 @@ $.Viewer = function( options ) {
// whether we should be continuously zooming // whether we should be continuously zooming
"zooming": false, "zooming": false,
// how much we should be continuously zooming by // how much we should be continuously zooming by
"zoomFactor": null, "zoomFactor": null,
"lastZoomTime": null, "lastZoomTime": null,
// did we decide this viewer has a sequence of tile sources // did we decide this viewer has a sequence of tile sources
"sequenced": false, "sequenced": false,
"sequence": 0, "sequence": 0,
"fullPage": false, "fullPage": false,
"onfullscreenchange": null "onfullscreenchange": null
}; };
@ -184,17 +184,17 @@ $.Viewer = function( options ) {
if ( this.tileSources ){ if ( this.tileSources ){
// tileSources is a complex option... // tileSources is a complex option...
// //
// It can be a string, object, or an array of any of strings and objects. // It can be a string, object, or an array of any of strings and objects.
// At this point we only care about if it is an Array or not. // At this point we only care about if it is an Array or not.
// //
if( $.isArray( this.tileSources ) ){ if( $.isArray( this.tileSources ) ){
//must be a sequence of tileSource since the first item //must be a sequence of tileSource since the first item
//is a legacy tile source //is a legacy tile source
if( this.tileSources.length > 1 ){ if( this.tileSources.length > 1 ){
THIS[ this.hash ].sequenced = true; THIS[ this.hash ].sequenced = true;
} }
initialTileSource = this.tileSources[ 0 ]; initialTileSource = this.tileSources[ 0 ];
} else { } else {
initialTileSource = this.tileSources; initialTileSource = this.tileSources;
@ -311,8 +311,8 @@ $.Viewer = function( options ) {
this.innerTracker = new $.MouseTracker({ this.innerTracker = new $.MouseTracker({
element: this.canvas, element: this.canvas,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
clickHandler: $.delegate( this, onCanvasClick ), clickHandler: $.delegate( this, onCanvasClick ),
dragHandler: $.delegate( this, onCanvasDrag ), dragHandler: $.delegate( this, onCanvasDrag ),
@ -321,24 +321,24 @@ $.Viewer = function( options ) {
}).setTracking( this.mouseNavEnabled ? true : false ); // default state }).setTracking( this.mouseNavEnabled ? true : false ); // default state
this.outerTracker = new $.MouseTracker({ this.outerTracker = new $.MouseTracker({
element: this.container, element: this.container,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
enterHandler: $.delegate( this, onContainerEnter ), enterHandler: $.delegate( this, onContainerEnter ),
exitHandler: $.delegate( this, onContainerExit ), exitHandler: $.delegate( this, onContainerExit ),
releaseHandler: $.delegate( this, onContainerRelease ) releaseHandler: $.delegate( this, onContainerRelease )
}).setTracking( this.mouseNavEnabled ? true : false ); // always tracking }).setTracking( this.mouseNavEnabled ? true : false ); // always tracking
if( this.toolbar ){ if( this.toolbar ){
this.toolbar = new $.ControlDock({ element: this.toolbar }); this.toolbar = new $.ControlDock({ element: this.toolbar });
} }
this.bindStandardControls(); this.bindStandardControls();
this.bindSequenceControls(); this.bindSequenceControls();
for ( i = 0; i < this.customControls.length; i++ ) { for ( i = 0; i < this.customControls.length; i++ ) {
this.addControl( this.addControl(
this.customControls[ i ].id, this.customControls[ i ].id,
{anchor: this.customControls[ i ].anchor} {anchor: this.customControls[ i ].anchor}
); );
} }
@ -362,8 +362,8 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
}, },
/** /**
* A deprecated function, renamed to 'open' to match event name and * A deprecated function, renamed to 'open' to match event name and
* match current 'close' method. * match current 'close' method.
* @function * @function
* @name OpenSeadragon.Viewer.prototype.openDzi * @name OpenSeadragon.Viewer.prototype.openDzi
* @param {String} dzi xml string or the url to a DZI xml document. * @param {String} dzi xml string or the url to a DZI xml document.
@ -376,7 +376,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
}, },
/** /**
* A deprecated function, renamed to 'open' to match event name and * A deprecated function, renamed to 'open' to match event name and
* match current 'close' method. * match current 'close' method.
* @function * @function
* @name OpenSeadragon.Viewer.prototype.openTileSource * @name OpenSeadragon.Viewer.prototype.openTileSource
@ -393,15 +393,15 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
* Open a TileSource object into the viewer. * Open a TileSource object into the viewer.
* *
* tileSources is a complex option... * tileSources is a complex option...
* *
* It can be a string, object, function, or an array of any of these: * It can be a string, object, function, or an array of any of these:
* *
* - A String implies a url used to determine the tileSource implementation * - A String implies a url used to determine the tileSource implementation
* based on the file extension of url. JSONP is implied by *.js, * based on the file extension of url. JSONP is implied by *.js,
* otherwise the url is retrieved as text and the resulting text is * otherwise the url is retrieved as text and the resulting text is
* introspected to determine if its json, xml, or text and parsed. * introspected to determine if its json, xml, or text and parsed.
* - An Object implies an inline configuration which has a single * - An Object implies an inline configuration which has a single
* property sufficient for being able to determine tileSource * property sufficient for being able to determine tileSource
* implementation. If the object has a property which is a function * implementation. If the object has a property which is a function
* named 'getTileUrl', it is treated as a custom TileSource. * named 'getTileUrl', it is treated as a custom TileSource.
* @function * @function
@ -455,7 +455,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
return this; return this;
}, },
/** /**
* @function * @function
* @name OpenSeadragon.Viewer.prototype.close * @name OpenSeadragon.Viewer.prototype.close
@ -486,7 +486,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
delete VIEWERS[ this.hash ]; delete VIEWERS[ this.hash ];
this.raiseEvent( 'close', { viewer: this } ); this.raiseEvent( 'close', { viewer: this } );
return this; return this;
}, },
@ -529,7 +529,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
/** /**
* Shows or hides the controls (e.g. the default navigation buttons). * Shows or hides the controls (e.g. the default navigation buttons).
* *
* @function * @function
* @name OpenSeadragon.Viewer.prototype.setControlsEnabled * @name OpenSeadragon.Viewer.prototype.setControlsEnabled
* @param {Boolean} true to show, false to hide. * @param {Boolean} true to show, false to hide.
@ -545,7 +545,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
return this; return this;
}, },
/** /**
* @function * @function
* @name OpenSeadragon.Viewer.prototype.isFullPage * @name OpenSeadragon.Viewer.prototype.isFullPage
@ -578,7 +578,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
hash, hash,
nodes, nodes,
i; i;
//dont bother modifying the DOM if we are already in full page mode. //dont bother modifying the DOM if we are already in full page mode.
if ( fullPage == this.isFullPage() ) { if ( fullPage == this.isFullPage() ) {
return; return;
@ -586,7 +586,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
if ( fullPage ) { if ( fullPage ) {
this.bodyOverflow = bodyStyle.overflow; this.bodyOverflow = bodyStyle.overflow;
this.docOverflow = docStyle.overflow; this.docOverflow = docStyle.overflow;
bodyStyle.overflow = "hidden"; bodyStyle.overflow = "hidden";
@ -603,7 +603,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
//containerStyle.position = "fixed"; //containerStyle.position = "fixed";
//when entering full screen on the ipad it wasnt sufficient to leave //when entering full screen on the ipad it wasnt sufficient to leave
//the body intact as only only the top half of the screen would //the body intact as only only the top half of the screen would
//respond to touch events on the canvas, while the bottom half treated //respond to touch events on the canvas, while the bottom half treated
//them as touch events on the document body. Thus we remove and store //them as touch events on the document body. Thus we remove and store
//the bodies elements and replace them when we leave full screen. //the bodies elements and replace them when we leave full screen.
@ -616,7 +616,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
this.previousBody.push( body.childNodes[ 0 ] ); this.previousBody.push( body.childNodes[ 0 ] );
body.removeChild( body.childNodes[ 0 ] ); body.removeChild( body.childNodes[ 0 ] );
} }
//If we've got a toolbar, we need to enable the user to use css to //If we've got a toolbar, we need to enable the user to use css to
//preserve it in fullpage mode //preserve it in fullpage mode
if( this.toolbar && this.toolbar.element ){ if( this.toolbar && this.toolbar.element ){
@ -630,13 +630,13 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
//on the mode //on the mode
$.addClass( this.toolbar.element, 'fullpage' ); $.addClass( this.toolbar.element, 'fullpage' );
} }
$.addClass( this.element, 'fullpage' ); $.addClass( this.element, 'fullpage' );
body.appendChild( this.element ); body.appendChild( this.element );
if( $.supportsFullScreen ){ if( $.supportsFullScreen ){
THIS[ this.hash ].onfullscreenchange = function( event ) { THIS[ this.hash ].onfullscreenchange = function( event ) {
// The event object doesn't carry information about the // The event object doesn't carry information about the
// fullscreen state of the browser, but it is possible to // fullscreen state of the browser, but it is possible to
// retrieve it through the fullscreen API // retrieve it through the fullscreen API
if( $.isFullScreen() ){ if( $.isFullScreen() ){
@ -652,7 +652,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
// but it is possible to retrieve the fullscreen element through the API // but it is possible to retrieve the fullscreen element through the API
// Note that the API is still vendor-prefixed in browsers implementing it // Note that the API is still vendor-prefixed in browsers implementing it
document.addEventListener( document.addEventListener(
$.fullScreenEventName, $.fullScreenEventName,
THIS[ this.hash ].onfullscreenchange THIS[ this.hash ].onfullscreenchange
); );
this.element.style.height = '100%'; this.element.style.height = '100%';
@ -677,8 +677,8 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
} else { } else {
if( $.supportsFullScreen ){ if( $.supportsFullScreen ){
document.removeEventListener( document.removeEventListener(
$.fullScreenEventName, $.fullScreenEventName,
THIS[ this.hash ].onfullscreenchange THIS[ this.hash ].onfullscreenchange
); );
$.cancelFullScreen( document ); $.cancelFullScreen( document );
@ -707,9 +707,9 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
this.element, this.element,
THIS[ this.hash ].prevNextSibling THIS[ this.hash ].prevNextSibling
); );
//If we've got a toolbar, we need to enable the user to use css to //If we've got a toolbar, we need to enable the user to use css to
//reset it to its original state //reset it to its original state
if( this.toolbar && this.toolbar.element ){ if( this.toolbar && this.toolbar.element ){
body.removeChild( this.toolbar.element ); body.removeChild( this.toolbar.element );
@ -717,7 +717,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
//on the mode //on the mode
$.removeClass( this.toolbar.element, 'fullpage' ); $.removeClass( this.toolbar.element, 'fullpage' );
//this.toolbar.element.style.position = 'relative'; //this.toolbar.element.style.position = 'relative';
this.toolbar.parentNode.insertBefore( this.toolbar.parentNode.insertBefore(
this.toolbar.element, this.toolbar.element,
this.toolbar.nextSibling this.toolbar.nextSibling
); );
@ -752,11 +752,11 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
} else { } else {
this.viewport.update(); this.viewport.update();
this.viewport.zoomBy( this.viewport.zoomBy(
Math.max( Math.max(
THIS[ this.hash ].fsBoundsDelta.x, THIS[ this.hash ].fsBoundsDelta.x,
THIS[ this.hash ].fsBoundsDelta.y THIS[ this.hash ].fsBoundsDelta.y
), ),
null, null,
true true
); );
//Ensures that if multiple viewers are on a page, the viewers that //Ensures that if multiple viewers are on a page, the viewers that
@ -779,7 +779,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
return this; return this;
}, },
/** /**
* @function * @function
* @name OpenSeadragon.Viewer.prototype.isVisible * @name OpenSeadragon.Viewer.prototype.isVisible
@ -808,7 +808,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
* @return {OpenSeadragon.Viewer} Chainable. * @return {OpenSeadragon.Viewer} Chainable.
*/ */
bindSequenceControls: function(){ bindSequenceControls: function(){
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
// Image Sequence Controls // Image Sequence Controls
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -821,14 +821,14 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
useGroup = true ; useGroup = true ;
if( this.showSequenceControl && THIS[ this.hash ].sequenced ){ if( this.showSequenceControl && THIS[ this.hash ].sequenced ){
if( this.previousButton || this.nextButton ){ if( this.previousButton || this.nextButton ){
//if we are binding to custom buttons then layout and //if we are binding to custom buttons then layout and
//grouping is the responsibility of the page author //grouping is the responsibility of the page author
useGroup = false; useGroup = false;
} }
this.previousButton = new $.Button({ this.previousButton = new $.Button({
element: this.previousButton ? $.getElement( this.previousButton ) : null, element: this.previousButton ? $.getElement( this.previousButton ) : null,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
@ -842,7 +842,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
onBlur: onBlurHandler onBlur: onBlurHandler
}); });
this.nextButton = new $.Button({ this.nextButton = new $.Button({
element: this.nextButton ? $.getElement( this.nextButton ) : null, element: this.nextButton ? $.getElement( this.nextButton ) : null,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
@ -862,9 +862,9 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
if( useGroup ){ if( useGroup ){
this.paging = new $.ButtonGroup({ this.paging = new $.ButtonGroup({
buttons: [ buttons: [
this.previousButton, this.previousButton,
this.nextButton this.nextButton
], ],
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold clickDistThreshold: this.clickDistThreshold
@ -873,13 +873,13 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
this.pagingControl = this.paging.element; this.pagingControl = this.paging.element;
if( this.toolbar ){ if( this.toolbar ){
this.toolbar.addControl( this.toolbar.addControl(
this.pagingControl, this.pagingControl,
{anchor: $.ControlAnchor.BOTTOM_RIGHT} {anchor: $.ControlAnchor.BOTTOM_RIGHT}
); );
}else{ }else{
this.addControl( this.addControl(
this.pagingControl, this.pagingControl,
{anchor: $.ControlAnchor.TOP_LEFT} {anchor: $.ControlAnchor.TOP_LEFT}
); );
} }
@ -915,16 +915,16 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
if( this.showNavigationControl ){ if( this.showNavigationControl ){
if( this.zoomInButton || this.zoomOutButton || this.homeButton || this.fullPageButton ){ if( this.zoomInButton || this.zoomOutButton || this.homeButton || this.fullPageButton ){
//if we are binding to custom buttons then layout and //if we are binding to custom buttons then layout and
//grouping is the responsibility of the page author //grouping is the responsibility of the page author
useGroup = false; useGroup = false;
} }
buttons.push( this.zoomInButton = new $.Button({ buttons.push( this.zoomInButton = new $.Button({
element: this.zoomInButton ? $.getElement( this.zoomInButton ) : null, element: this.zoomInButton ? $.getElement( this.zoomInButton ) : null,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
tooltip: $.getString( "Tooltips.ZoomIn" ), tooltip: $.getString( "Tooltips.ZoomIn" ),
srcRest: resolveUrl( this.prefixUrl, navImages.zoomIn.REST ), srcRest: resolveUrl( this.prefixUrl, navImages.zoomIn.REST ),
srcGroup: resolveUrl( this.prefixUrl, navImages.zoomIn.GROUP ), srcGroup: resolveUrl( this.prefixUrl, navImages.zoomIn.GROUP ),
srcHover: resolveUrl( this.prefixUrl, navImages.zoomIn.HOVER ), srcHover: resolveUrl( this.prefixUrl, navImages.zoomIn.HOVER ),
@ -938,39 +938,39 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
onBlur: onBlurHandler onBlur: onBlurHandler
})); }));
buttons.push( this.zoomOutButton = new $.Button({ buttons.push( this.zoomOutButton = new $.Button({
element: this.zoomOutButton ? $.getElement( this.zoomOutButton ) : null, element: this.zoomOutButton ? $.getElement( this.zoomOutButton ) : null,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
tooltip: $.getString( "Tooltips.ZoomOut" ), tooltip: $.getString( "Tooltips.ZoomOut" ),
srcRest: resolveUrl( this.prefixUrl, navImages.zoomOut.REST ), srcRest: resolveUrl( this.prefixUrl, navImages.zoomOut.REST ),
srcGroup: resolveUrl( this.prefixUrl, navImages.zoomOut.GROUP ), srcGroup: resolveUrl( this.prefixUrl, navImages.zoomOut.GROUP ),
srcHover: resolveUrl( this.prefixUrl, navImages.zoomOut.HOVER ), srcHover: resolveUrl( this.prefixUrl, navImages.zoomOut.HOVER ),
srcDown: resolveUrl( this.prefixUrl, navImages.zoomOut.DOWN ), srcDown: resolveUrl( this.prefixUrl, navImages.zoomOut.DOWN ),
onPress: beginZoomingOutHandler, onPress: beginZoomingOutHandler,
onRelease: endZoomingHandler, onRelease: endZoomingHandler,
onClick: doSingleZoomOutHandler, onClick: doSingleZoomOutHandler,
onEnter: beginZoomingOutHandler, onEnter: beginZoomingOutHandler,
onExit: endZoomingHandler, onExit: endZoomingHandler,
onFocus: onFocusHandler, onFocus: onFocusHandler,
onBlur: onBlurHandler onBlur: onBlurHandler
})); }));
buttons.push( this.homeButton = new $.Button({ buttons.push( this.homeButton = new $.Button({
element: this.homeButton ? $.getElement( this.homeButton ) : null, element: this.homeButton ? $.getElement( this.homeButton ) : null,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
tooltip: $.getString( "Tooltips.Home" ), tooltip: $.getString( "Tooltips.Home" ),
srcRest: resolveUrl( this.prefixUrl, navImages.home.REST ), srcRest: resolveUrl( this.prefixUrl, navImages.home.REST ),
srcGroup: resolveUrl( this.prefixUrl, navImages.home.GROUP ), srcGroup: resolveUrl( this.prefixUrl, navImages.home.GROUP ),
srcHover: resolveUrl( this.prefixUrl, navImages.home.HOVER ), srcHover: resolveUrl( this.prefixUrl, navImages.home.HOVER ),
srcDown: resolveUrl( this.prefixUrl, navImages.home.DOWN ), srcDown: resolveUrl( this.prefixUrl, navImages.home.DOWN ),
onRelease: onHomeHandler, onRelease: onHomeHandler,
onFocus: onFocusHandler, onFocus: onFocusHandler,
onBlur: onBlurHandler onBlur: onBlurHandler
})); }));
buttons.push( this.fullPageButton = new $.Button({ buttons.push( this.fullPageButton = new $.Button({
element: this.fullPageButton ? $.getElement( this.fullPageButton ) : null, element: this.fullPageButton ? $.getElement( this.fullPageButton ) : null,
clickTimeThreshold: this.clickTimeThreshold, clickTimeThreshold: this.clickTimeThreshold,
clickDistThreshold: this.clickDistThreshold, clickDistThreshold: this.clickDistThreshold,
@ -995,18 +995,18 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
this.addHandler( 'open', $.delegate( this, lightUp ) ); this.addHandler( 'open', $.delegate( this, lightUp ) );
if( this.toolbar ){ if( this.toolbar ){
this.toolbar.addControl( this.toolbar.addControl(
this.navControl, this.navControl,
{anchor: $.ControlAnchor.TOP_LEFT} {anchor: $.ControlAnchor.TOP_LEFT}
); );
}else{ }else{
this.addControl( this.addControl(
this.navControl, this.navControl,
{anchor: $.ControlAnchor.TOP_LEFT} {anchor: $.ControlAnchor.TOP_LEFT}
); );
} }
} }
} }
return this; return this;
}, },
@ -1023,7 +1023,7 @@ $.extend( $.Viewer.prototype, $.EventHandler.prototype, $.ControlDock.prototype,
this.raiseEvent( 'page', { page: page, viewer: this } ); this.raiseEvent( 'page', { page: page, viewer: this } );
if( this.tileSources.length > page ){ if( this.tileSources.length > page ){
THIS[ this.hash ].sequence = page; THIS[ this.hash ].sequence = page;
if( this.nextButton ){ if( this.nextButton ){
@ -1076,7 +1076,7 @@ function openTileSource( viewer, source ) {
if ( _this.source ) { if ( _this.source ) {
_this.close( ); _this.close( );
} }
_this.canvas.innerHTML = ""; _this.canvas.innerHTML = "";
THIS[ _this.hash ].prevContainerSize = $.getElementSize( _this.container ); THIS[ _this.hash ].prevContainerSize = $.getElementSize( _this.container );
@ -1092,8 +1092,8 @@ function openTileSource( viewer, source ) {
_this.viewport = _this.viewport ? _this.viewport : new $.Viewport({ _this.viewport = _this.viewport ? _this.viewport : new $.Viewport({
collectionMode: true, collectionMode: true,
collectionTileSource: _this.source, collectionTileSource: _this.source,
containerSize: THIS[ _this.hash ].prevContainerSize, containerSize: THIS[ _this.hash ].prevContainerSize,
contentSize: _this.source.dimensions, contentSize: _this.source.dimensions,
springStiffness: _this.springStiffness, springStiffness: _this.springStiffness,
animationTime: _this.animationTime, animationTime: _this.animationTime,
showNavigator: false, showNavigator: false,
@ -1109,8 +1109,8 @@ function openTileSource( viewer, source ) {
_this.source = source; _this.source = source;
} }
_this.viewport = _this.viewport ? _this.viewport : new $.Viewport({ _this.viewport = _this.viewport ? _this.viewport : new $.Viewport({
containerSize: THIS[ _this.hash ].prevContainerSize, containerSize: THIS[ _this.hash ].prevContainerSize,
contentSize: _this.source.dimensions, contentSize: _this.source.dimensions,
springStiffness: _this.springStiffness, springStiffness: _this.springStiffness,
animationTime: _this.animationTime, animationTime: _this.animationTime,
minZoomImageRatio: _this.minZoomImageRatio, minZoomImageRatio: _this.minZoomImageRatio,
@ -1124,17 +1124,17 @@ function openTileSource( viewer, source ) {
viewer: _this viewer: _this
}); });
} }
if( _this.preserveViewport ){ if( _this.preserveViewport ){
_this.viewport.resetContentSize( _this.source.dimensions ); _this.viewport.resetContentSize( _this.source.dimensions );
} }
_this.source.overlays = _this.source.overlays || []; _this.source.overlays = _this.source.overlays || [];
_this.drawer = new $.Drawer({ _this.drawer = new $.Drawer({
viewer: _this, viewer: _this,
source: _this.source, source: _this.source,
viewport: _this.viewport, viewport: _this.viewport,
element: _this.canvas, element: _this.canvas,
overlays: [].concat( _this.overlays ).concat( _this.source.overlays ), overlays: [].concat( _this.overlays ).concat( _this.source.overlays ),
maxImageCacheCount: _this.maxImageCacheCount, maxImageCacheCount: _this.maxImageCacheCount,
@ -1199,33 +1199,33 @@ function openTileSource( viewer, source ) {
//Assuming you had programatically created a bunch of overlays //Assuming you had programatically created a bunch of overlays
//and added them via configuration //and added them via configuration
for ( i = 0; i < _this.overlayControls.length; i++ ) { for ( i = 0; i < _this.overlayControls.length; i++ ) {
overlay = _this.overlayControls[ i ]; overlay = _this.overlayControls[ i ];
if ( overlay.point ) { if ( overlay.point ) {
_this.drawer.addOverlay( _this.drawer.addOverlay(
overlay.id, overlay.id,
new $.Point( new $.Point(
overlay.point.X, overlay.point.X,
overlay.point.Y overlay.point.Y
), ),
$.OverlayPlacement.TOP_LEFT $.OverlayPlacement.TOP_LEFT
); );
} else { } else {
_this.drawer.addOverlay( _this.drawer.addOverlay(
overlay.id, overlay.id,
new $.Rect( new $.Rect(
overlay.rect.Point.X, overlay.rect.Point.X,
overlay.rect.Point.Y, overlay.rect.Point.Y,
overlay.rect.Width, overlay.rect.Width,
overlay.rect.Height overlay.rect.Height
), ),
overlay.placement overlay.placement
); );
} }
} }
VIEWERS[ _this.hash ] = _this; VIEWERS[ _this.hash ] = _this;
@ -1262,8 +1262,8 @@ function beginControlsAutoHide( viewer ) {
return; return;
} }
viewer.controlsShouldFade = true; viewer.controlsShouldFade = true;
viewer.controlsFadeBeginTime = viewer.controlsFadeBeginTime =
+new Date() + +new Date() +
viewer.controlsFadeDelay; viewer.controlsFadeDelay;
window.setTimeout( function(){ window.setTimeout( function(){
@ -1294,7 +1294,7 @@ function updateControlsFade( viewer ) {
if ( opacity > 0 ) { if ( opacity > 0 ) {
// fade again // fade again
scheduleControlsFade( viewer ); scheduleControlsFade( viewer );
} }
} }
} }
@ -1320,22 +1320,22 @@ function onFocus(){
function onBlur(){ function onBlur(){
beginControlsAutoHide( this ); beginControlsAutoHide( this );
} }
function onCanvasClick( tracker, position, quick, shift ) { function onCanvasClick( tracker, position, quick, shift ) {
var zoomPreClick, var zoomPreClick,
factor; factor;
if ( this.viewport && quick ) { // ignore clicks where mouse moved if ( this.viewport && quick ) { // ignore clicks where mouse moved
zoomPerClick = this.zoomPerClick; zoomPerClick = this.zoomPerClick;
factor = shift ? 1.0 / zoomPerClick : zoomPerClick; factor = shift ? 1.0 / zoomPerClick : zoomPerClick;
this.viewport.zoomBy( this.viewport.zoomBy(
factor, factor,
this.viewport.pointFromPixel( position, true ) this.viewport.pointFromPixel( position, true )
); );
this.viewport.applyConstraints(); this.viewport.applyConstraints();
} }
this.raiseEvent( 'canvas-click', { this.raiseEvent( 'canvas-click', {
tracker: tracker, tracker: tracker,
position: position, position: position,
quick: quick, quick: quick,
@ -1351,16 +1351,16 @@ function onCanvasDrag( tracker, position, delta, shift ) {
if( !this.panVertical ){ if( !this.panVertical ){
delta.y = 0; delta.y = 0;
} }
this.viewport.panBy( this.viewport.panBy(
this.viewport.deltaPointsFromPixels( this.viewport.deltaPointsFromPixels(
delta.negate() delta.negate()
) )
); );
if( this.constrainDuringPan ){ if( this.constrainDuringPan ){
this.viewport.applyConstraints(); this.viewport.applyConstraints();
} }
} }
this.raiseEvent( 'canvas-click', { this.raiseEvent( 'canvas-click', {
tracker: tracker, tracker: tracker,
position: position, position: position,
delta: delta, delta: delta,
@ -1372,7 +1372,7 @@ function onCanvasRelease( tracker, position, insideElementPress, insideElementRe
if ( insideElementPress && this.viewport ) { if ( insideElementPress && this.viewport ) {
this.viewport.applyConstraints(); this.viewport.applyConstraints();
} }
this.raiseEvent( 'canvas-release', { this.raiseEvent( 'canvas-release', {
tracker: tracker, tracker: tracker,
position: position, position: position,
insideElementPress: insideElementPress, insideElementPress: insideElementPress,
@ -1384,13 +1384,13 @@ function onCanvasScroll( tracker, position, scroll, shift ) {
var factor; var factor;
if ( this.viewport ) { if ( this.viewport ) {
factor = Math.pow( this.zoomPerScroll, scroll ); factor = Math.pow( this.zoomPerScroll, scroll );
this.viewport.zoomBy( this.viewport.zoomBy(
factor, factor,
this.viewport.pointFromPixel( position, true ) this.viewport.pointFromPixel( position, true )
); );
this.viewport.applyConstraints(); this.viewport.applyConstraints();
} }
this.raiseEvent( 'canvas-scroll', { this.raiseEvent( 'canvas-scroll', {
tracker: tracker, tracker: tracker,
position: position, position: position,
scroll: scroll, scroll: scroll,
@ -1407,7 +1407,7 @@ function onContainerExit( tracker, position, buttonDownElement, buttonDownAny )
beginControlsAutoHide( this ); beginControlsAutoHide( this );
} }
} }
this.raiseEvent( 'container-exit', { this.raiseEvent( 'container-exit', {
tracker: tracker, tracker: tracker,
position: position, position: position,
buttonDownElement: buttonDownElement, buttonDownElement: buttonDownElement,
@ -1422,7 +1422,7 @@ function onContainerRelease( tracker, position, insideElementPress, insideElemen
beginControlsAutoHide( this ); beginControlsAutoHide( this );
} }
} }
this.raiseEvent( 'container-release', { this.raiseEvent( 'container-release', {
tracker: tracker, tracker: tracker,
position: position, position: position,
insideElementPress: insideElementPress, insideElementPress: insideElementPress,
@ -1433,7 +1433,7 @@ function onContainerRelease( tracker, position, insideElementPress, insideElemen
function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny ) { function onContainerEnter( tracker, position, buttonDownElement, buttonDownAny ) {
THIS[ this.hash ].mouseInside = true; THIS[ this.hash ].mouseInside = true;
abortControlsAutoHide( this ); abortControlsAutoHide( this );
this.raiseEvent( 'container-enter', { this.raiseEvent( 'container-enter', {
tracker: tracker, tracker: tracker,
position: position, position: position,
buttonDownElement: buttonDownElement, buttonDownElement: buttonDownElement,
@ -1474,7 +1474,7 @@ function updateOnce( viewer ) {
containerSize = $.getElementSize( viewer.container ); containerSize = $.getElementSize( viewer.container );
if ( !containerSize.equals( THIS[ viewer.hash ].prevContainerSize ) ) { if ( !containerSize.equals( THIS[ viewer.hash ].prevContainerSize ) ) {
// maintain image position // maintain image position
viewer.viewport.resize( containerSize, true ); viewer.viewport.resize( containerSize, true );
THIS[ viewer.hash ].prevContainerSize = containerSize; THIS[ viewer.hash ].prevContainerSize = containerSize;
} }
@ -1501,7 +1501,7 @@ function updateOnce( viewer ) {
viewer.navigator.update( viewer.viewport ); viewer.navigator.update( viewer.viewport );
} }
THIS[ viewer.hash ].forceRedraw = false; THIS[ viewer.hash ].forceRedraw = false;
} }
if ( THIS[ viewer.hash ].animating && !animated ) { if ( THIS[ viewer.hash ].animating && !animated ) {
viewer.raiseEvent( "animationfinish" ); viewer.raiseEvent( "animationfinish" );
@ -1574,8 +1574,8 @@ function doZoom() {
function doSingleZoomIn() { function doSingleZoomIn() {
if ( this.viewport ) { if ( this.viewport ) {
THIS[ this.hash ].zooming = false; THIS[ this.hash ].zooming = false;
this.viewport.zoomBy( this.viewport.zoomBy(
this.zoomPerClick / 1.0 this.zoomPerClick / 1.0
); );
this.viewport.applyConstraints(); this.viewport.applyConstraints();
} }

View File

@ -40,7 +40,7 @@
*/ */
$.Viewport = function( options ) { $.Viewport = function( options ) {
//backward compatibility for positional args while prefering more //backward compatibility for positional args while prefering more
//idiomatic javascript options object as the only argument //idiomatic javascript options object as the only argument
var args = arguments; var args = arguments;
if( args.length && args[ 0 ] instanceof $.Point ){ if( args.length && args[ 0 ] instanceof $.Point ){
@ -60,7 +60,7 @@ $.Viewport = function( options ) {
} }
$.extend( true, this, { $.extend( true, this, {
//required settings //required settings
containerSize: null, containerSize: null,
contentSize: null, contentSize: null,
@ -84,17 +84,17 @@ $.Viewport = function( options ) {
}, options ); }, options );
this.centerSpringX = new $.Spring({ this.centerSpringX = new $.Spring({
initial: 0, initial: 0,
springStiffness: this.springStiffness, springStiffness: this.springStiffness,
animationTime: this.animationTime animationTime: this.animationTime
}); });
this.centerSpringY = new $.Spring({ this.centerSpringY = new $.Spring({
initial: 0, initial: 0,
springStiffness: this.springStiffness, springStiffness: this.springStiffness,
animationTime: this.animationTime animationTime: this.animationTime
}); });
this.zoomSpring = new $.Spring({ this.zoomSpring = new $.Spring({
initial: 1, initial: 1,
springStiffness: this.springStiffness, springStiffness: this.springStiffness,
animationTime: this.animationTime animationTime: this.animationTime
}); });
@ -120,12 +120,12 @@ $.Viewport.prototype = {
this.homeBounds = new $.Rect( 0, 0, 1, this.contentAspectY ); this.homeBounds = new $.Rect( 0, 0, 1, this.contentAspectY );
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'reset-size', { this.viewer.raiseEvent( 'reset-size', {
contentSize: contentSize, contentSize: contentSize,
viewer: this.viewer viewer: this.viewer
}); });
} }
return this; return this;
}, },
@ -133,14 +133,14 @@ $.Viewport.prototype = {
* @function * @function
*/ */
getHomeZoom: function() { getHomeZoom: function() {
var aspectFactor = var aspectFactor =
this.contentAspectX / this.getAspectRatio(); this.contentAspectX / this.getAspectRatio();
if( this.defaultZoomLevel ){ if( this.defaultZoomLevel ){
return this.defaultZoomLevel; return this.defaultZoomLevel;
} else { } else {
return ( aspectFactor >= 1 ) ? return ( aspectFactor >= 1 ) ?
1 : 1 :
aspectFactor; aspectFactor;
} }
}, },
@ -154,9 +154,9 @@ $.Viewport.prototype = {
height = width / this.getAspectRatio(); height = width / this.getAspectRatio();
return new $.Rect( return new $.Rect(
center.x - ( width / 2.0 ), center.x - ( width / 2.0 ),
center.y - ( height / 2.0 ), center.y - ( height / 2.0 ),
width, width,
height height
); );
}, },
@ -167,7 +167,7 @@ $.Viewport.prototype = {
*/ */
goHome: function( immediately ) { goHome: function( immediately ) {
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'home', { this.viewer.raiseEvent( 'home', {
immediately: immediately, immediately: immediately,
viewer: this.viewer viewer: this.viewer
}); });
@ -180,8 +180,8 @@ $.Viewport.prototype = {
*/ */
getMinZoom: function() { getMinZoom: function() {
var homeZoom = this.getHomeZoom(), var homeZoom = this.getHomeZoom(),
zoom = this.minZoomLevel ? zoom = this.minZoomLevel ?
this.minZoomLevel : this.minZoomLevel :
this.minZoomImageRatio * homeZoom; this.minZoomImageRatio * homeZoom;
return Math.min( zoom, homeZoom ); return Math.min( zoom, homeZoom );
@ -210,7 +210,7 @@ $.Viewport.prototype = {
*/ */
getContainerSize: function() { getContainerSize: function() {
return new $.Point( return new $.Point(
this.containerSize.x, this.containerSize.x,
this.containerSize.y this.containerSize.y
); );
}, },
@ -224,9 +224,9 @@ $.Viewport.prototype = {
height = width / this.getAspectRatio(); height = width / this.getAspectRatio();
return new $.Rect( return new $.Rect(
center.x - ( width / 2.0 ), center.x - ( width / 2.0 ),
center.y - ( height / 2.0 ), center.y - ( height / 2.0 ),
width, width,
height height
); );
}, },
@ -265,8 +265,8 @@ $.Viewport.prototype = {
height = width / this.getAspectRatio(); height = width / this.getAspectRatio();
bounds = new $.Rect( bounds = new $.Rect(
centerCurrent.x - width / 2.0, centerCurrent.x - width / 2.0,
centerCurrent.y - height / 2.0, centerCurrent.y - height / 2.0,
width, width,
height height
); );
@ -299,7 +299,7 @@ $.Viewport.prototype = {
applyConstraints: function( immediately ) { applyConstraints: function( immediately ) {
var actualZoom = this.getZoom(), var actualZoom = this.getZoom(),
constrainedZoom = Math.max( constrainedZoom = Math.max(
Math.min( actualZoom, this.getMaxZoom() ), Math.min( actualZoom, this.getMaxZoom() ),
this.getMinZoom() this.getMinZoom()
), ),
bounds, bounds,
@ -333,9 +333,9 @@ $.Viewport.prototype = {
} else { } else {
if ( left < horizontalThreshold ) { if ( left < horizontalThreshold ) {
dx = horizontalThreshold - left; dx = horizontalThreshold - left;
} }
if ( right < horizontalThreshold ) { if ( right < horizontalThreshold ) {
dx = dx ? dx = dx ?
( dx + right - horizontalThreshold ) / 2 : ( dx + right - horizontalThreshold ) / 2 :
( right - horizontalThreshold ); ( right - horizontalThreshold );
} }
@ -346,9 +346,9 @@ $.Viewport.prototype = {
} else { } else {
if ( top < verticalThreshold ) { if ( top < verticalThreshold ) {
dy = ( verticalThreshold - top ); dy = ( verticalThreshold - top );
} }
if ( bottom < verticalThreshold ) { if ( bottom < verticalThreshold ) {
dy = dy ? dy = dy ?
( dy + bottom - verticalThreshold ) / 2 : ( dy + bottom - verticalThreshold ) / 2 :
( bottom - verticalThreshold ); ( bottom - verticalThreshold );
} }
@ -367,7 +367,7 @@ $.Viewport.prototype = {
} }
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'constrain', { this.viewer.raiseEvent( 'constrain', {
immediately: immediately, immediately: immediately,
viewer: this.viewer viewer: this.viewer
}); });
@ -394,9 +394,9 @@ $.Viewport.prototype = {
var aspect = this.getAspectRatio(), var aspect = this.getAspectRatio(),
center = bounds.getCenter(), center = bounds.getCenter(),
newBounds = new $.Rect( newBounds = new $.Rect(
bounds.x, bounds.x,
bounds.y, bounds.y,
bounds.width, bounds.width,
bounds.height bounds.height
), ),
oldBounds, oldBounds,
@ -422,20 +422,20 @@ $.Viewport.prototype = {
return this.panTo( center, immediately ); return this.panTo( center, immediately );
} }
referencePoint = oldBounds.getTopLeft().times( referencePoint = oldBounds.getTopLeft().times(
this.containerSize.x / oldBounds.width this.containerSize.x / oldBounds.width
).minus( ).minus(
newBounds.getTopLeft().times( newBounds.getTopLeft().times(
this.containerSize.x / newBounds.width this.containerSize.x / newBounds.width
) )
).divide( ).divide(
this.containerSize.x / oldBounds.width - this.containerSize.x / oldBounds.width -
this.containerSize.x / newBounds.width this.containerSize.x / newBounds.width
); );
return this.zoomTo( newZoom, referencePoint, immediately ); return this.zoomTo( newZoom, referencePoint, immediately );
}, },
/** /**
* @function * @function
@ -471,8 +471,8 @@ $.Viewport.prototype = {
var center = this.getCenter(); var center = this.getCenter();
if ( this.wrapHorizontal ) { if ( this.wrapHorizontal ) {
center.x = ( center.x = (
this.contentAspectX + ( center.x % this.contentAspectX ) this.contentAspectX + ( center.x % this.contentAspectX )
) % this.contentAspectX; ) % this.contentAspectX;
this.centerSpringX.resetTo( center.x ); this.centerSpringX.resetTo( center.x );
this.centerSpringX.update(); this.centerSpringX.update();
@ -518,7 +518,7 @@ $.Viewport.prototype = {
} }
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'pan', { this.viewer.raiseEvent( 'pan', {
center: center, center: center,
immediately: immediately, immediately: immediately,
viewer: this.viewer viewer: this.viewer
@ -542,18 +542,18 @@ $.Viewport.prototype = {
*/ */
zoomTo: function( zoom, refPoint, immediately ) { zoomTo: function( zoom, refPoint, immediately ) {
this.zoomPoint = refPoint instanceof $.Point ? this.zoomPoint = refPoint instanceof $.Point ?
refPoint : refPoint :
null; null;
if ( immediately ) { if ( immediately ) {
this.zoomSpring.resetTo( zoom ); this.zoomSpring.resetTo( zoom );
} else { } else {
this.zoomSpring.springTo( zoom ); this.zoomSpring.springTo( zoom );
} }
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'zoom', { this.viewer.raiseEvent( 'zoom', {
zoom: zoom, zoom: zoom,
refPoint: refPoint, refPoint: refPoint,
immediately: immediately, immediately: immediately,
@ -574,7 +574,7 @@ $.Viewport.prototype = {
widthDeltaFactor = newContainerSize.x / this.containerSize.x; widthDeltaFactor = newContainerSize.x / this.containerSize.x;
this.containerSize = new $.Point( this.containerSize = new $.Point(
newContainerSize.x, newContainerSize.x,
newContainerSize.y newContainerSize.y
); );
@ -584,7 +584,7 @@ $.Viewport.prototype = {
} }
if( this.viewer ){ if( this.viewer ){
this.viewer.raiseEvent( 'resize', { this.viewer.raiseEvent( 'resize', {
newContainerSize: newContainerSize, newContainerSize: newContainerSize,
maintain: maintain, maintain: maintain,
viewer: this.viewer viewer: this.viewer
@ -675,8 +675,8 @@ $.Viewport.prototype = {
}, },
/** /**
* Translates from Seajax viewer coordinate * Translates from Seajax viewer coordinate
* system to image coordinate system * system to image coordinate system
*/ */
viewportToImageCoordinates: function(viewerX, viewerY) { viewportToImageCoordinates: function(viewerX, viewerY) {
return new $.Point(viewerX * this.contentSize.x, viewerY * this.contentSize.y * this.contentAspectX); return new $.Point(viewerX * this.contentSize.x, viewerY * this.contentSize.y * this.contentAspectX);
@ -684,7 +684,7 @@ $.Viewport.prototype = {
/** /**
* Translates from image coordinate system to * Translates from image coordinate system to
* Seajax viewer coordinate system * Seajax viewer coordinate system
*/ */
imageToViewportCoordinates: function( imageX, imageY ) { imageToViewportCoordinates: function( imageX, imageY ) {
return new $.Point( imageX / this.contentSize.x, imageY / this.contentSize.y / this.contentAspectX); return new $.Point( imageX / this.contentSize.x, imageY / this.contentSize.y / this.contentAspectX);
@ -710,7 +710,7 @@ $.Viewport.prototype = {
coordB = this.imageToViewportCoordinates( coordB = this.imageToViewportCoordinates(
pixelWidth, pixelHeight pixelWidth, pixelHeight
); );
return new $.Rect( return new $.Rect(
coordA.x, coordA.x,
coordA.y, coordA.y,
coordA.x + coordB.x, coordA.x + coordB.x,

View File

@ -1,7 +1,7 @@
(function() { (function() {
module('Basic'); module('Basic');
// TODO: Test drag // TODO: Test drag
var viewer = null; var viewer = null;
@ -137,5 +137,5 @@
viewer.addHandler('close', closeHandler); viewer.addHandler('close', closeHandler);
viewer.close(); viewer.close();
}); });
})(); })();

View File

@ -2,9 +2,9 @@ testpattern({
Image: { Image: {
xmlns: 'http://schemas.microsoft.com/deepzoom/2008', xmlns: 'http://schemas.microsoft.com/deepzoom/2008',
Format: 'jpg', Format: 'jpg',
Overlap: 1, Overlap: 1,
TileSize: 254, TileSize: 254,
Size:{ Size:{
Height: 1000, Height: 1000,
Width: 1000 Width: 1000
} }

View File

@ -7,7 +7,7 @@
if (widthFactor === undefined) { if (widthFactor === undefined) {
widthFactor = 0.5; widthFactor = 0.5;
} }
//TODO Redefine to be the middle by default //TODO Redefine to be the middle by default
if (heightFactor === undefined) { if (heightFactor === undefined) {
heightFactor = 0.5; heightFactor = 0.5;