mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-24 22:26:10 +03:00
Merge branch 'master' into pr/2258
This commit is contained in:
commit
98fa5ff5c6
1
.browserslistrc
Normal file
1
.browserslistrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
defaults
|
@ -1,14 +1,16 @@
|
|||||||
{
|
{
|
||||||
"root": true,
|
"root": true,
|
||||||
|
"plugins": ["compat"],
|
||||||
"extends": [
|
"extends": [
|
||||||
"eslint:recommended"
|
"eslint:recommended",
|
||||||
|
"plugin:compat/recommended"
|
||||||
],
|
],
|
||||||
"env": {
|
"env": {
|
||||||
"es6": false,
|
"es6": true,
|
||||||
"browser": true
|
"browser": true
|
||||||
},
|
},
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 5,
|
"ecmaVersion": 6,
|
||||||
"sourceType": "script",
|
"sourceType": "script",
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
"globalReturn": false,
|
"globalReturn": false,
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
|
# Specify dist until Travis CI default Runner OS updates to one
|
||||||
|
# with glibc version required by newer Node versions
|
||||||
|
# See: https://github.com/nodejs/node/issues/42351#issuecomment-1068424442
|
||||||
|
dist: jammy
|
||||||
language: node_js
|
language: node_js
|
||||||
sudo: false
|
sudo: false
|
||||||
node_js:
|
node_js:
|
||||||
- "16.14.2"
|
- lts/*
|
||||||
before_install:
|
before_install:
|
||||||
- npm install -g grunt-cli
|
- npm install -g grunt-cli
|
||||||
|
@ -161,8 +161,11 @@ module.exports = function(grunt) {
|
|||||||
normal: {
|
normal: {
|
||||||
options: {
|
options: {
|
||||||
urls: [ "http://localhost:8000/test/test.html" ],
|
urls: [ "http://localhost:8000/test/test.html" ],
|
||||||
timeout: 10000
|
timeout: 10000,
|
||||||
}
|
puppeteer: {
|
||||||
|
headless: 'new'
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
coverage: {
|
coverage: {
|
||||||
options: {
|
options: {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
Copyright (C) 2009 CodePlex Foundation
|
Copyright (C) 2009 CodePlex Foundation
|
||||||
Copyright (C) 2010-2022 OpenSeadragon contributors
|
Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are met:
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
@ -1,9 +1,42 @@
|
|||||||
OPENSEADRAGON CHANGELOG
|
OPENSEADRAGON CHANGELOG
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
3.2.0: (in progress...)
|
5.0.0: (in progress...)
|
||||||
|
|
||||||
* NEW BEHAVIOR: Setting the viewport rotation now animates by default (pass false for the new immediately parameter to disable) (#2136 @jonasengelmann)
|
* BREAKING CHANGE: Dropped support for IE11 (#2300, #2361 @AndrewADev)
|
||||||
|
* DEPRECATION: The OpenSeadragon.createCallback function is no longer recommended (#2367 @akansjain)
|
||||||
|
* Fixed: Sometimes if the viewport was flipped and the user zoomed in far enough, it would flip back (#2364 @SebDelile)
|
||||||
|
* Test improvements (#2382 @AndrewADev)
|
||||||
|
|
||||||
|
4.1.0:
|
||||||
|
|
||||||
|
* NEW BEHAVIOR: When `navigatorRotate` is false, while the navigator image doesn't rotate, the red outline now does (#2356 @lcl45)
|
||||||
|
* The viewer no longer emits `canvas-key` events for both keydown and keypress events; canvas-key is now just for keydown, and the new `canvas-key-press` is for keypress (#2270 @hrghauri)
|
||||||
|
* You can now specify a priority when calling addHandler, to control when your event handler gets called relative to others (#2273 @Aiosa)
|
||||||
|
* Added tileRetryMax and tileRetryDelay options, so the viewer can retry loading failed tiles (#2238 @Ughuuu @paaddyy, #2334 @Ughuuu @Titan21)
|
||||||
|
* All of the viewers keyboard handling is now in response to keydown events (it used to be split between keydown and keypress) (#2291 @MohitBansal321)
|
||||||
|
* Added `canvas-focus` and `canvas-blur` events to Viewer (#2301 @MohitBansal321)
|
||||||
|
* You can now more easily add custom buttons to the viewer (#2306 @MohitBansal321)
|
||||||
|
* The fitBounds function now takes zoom constraints into account (#2293 @pearcetm)
|
||||||
|
* The viewer now has an `after-resize` event what happens after the viewport bounds have been updated, to complement the `resize` event which happens before (#2317 @pearcetm)
|
||||||
|
* IIIFTileSource now uses resolution level dimensions provided in the info.json "sizes" field for more accurate tile requests (#2337 @ruven)
|
||||||
|
* Added setAjaxHeaders method to Viewer and TiledImage (#2346 @uschmidt83)
|
||||||
|
* Improved documentation (#2297 @KevinBritten)
|
||||||
|
* Fixed: The `tile-loaded` event's completionCallback could be called more than once in some circumstances (#2282 @Aiosa, @pearcetm)
|
||||||
|
* Fixed: Navigator display rectangle was off if the page had `box-sizing: border-box` (#2276 @ambujsahu81)
|
||||||
|
* Fixed: Code that required identifying functions would fail for async functions (#2273 @Aiosa)
|
||||||
|
* Fixed: Reference strip click detection was not accurate for long reference strips (#2280 @damonsson)
|
||||||
|
* Fixed: Translation problems in some circumstances with cropping polygons enabled (#2316 @pearcetm)
|
||||||
|
* Fixed: The navigator area rectangle would grow larger when you zoom in very far (#2318 @donotloveshampo)
|
||||||
|
* Fixed: JSON with embedded XML was being incorrectly identified as XML (#2328 @craigberry)
|
||||||
|
* Fixed: Touch/pinch rotate was not working properly on some platforms (#2324 @rsimon, @pearcetm)
|
||||||
|
* Fixed: Navigator rotation didn't honor `immediately` parameter (#2333 @robertjcolley)
|
||||||
|
* Fixed: The navigator didn't update for its new size in certain circumstances (#2347 @pearcetm)
|
||||||
|
|
||||||
|
4.0.0:
|
||||||
|
|
||||||
|
* NEW BEHAVIOR: Setting the viewport rotation now animates by default (pass true for the new `immediately` parameter to disable) (#2136 @jonasengelmann)
|
||||||
|
* NEW BEHAVIOR: The auto resize now takes both width and height into account when scaling the contents proportionally to the viewer (#2256 @pearcetm)
|
||||||
* DEPRECATION: Don't access the viewport's degrees property directly anymore; instead use setRotation and getRotation (#2136 @jonasengelmann)
|
* DEPRECATION: Don't access the viewport's degrees property directly anymore; instead use setRotation and getRotation (#2136 @jonasengelmann)
|
||||||
* New gesture: Double-click and drag to zoom (on by default for touch) (#2225 @HamzaTatheer)
|
* New gesture: Double-click and drag to zoom (on by default for touch) (#2225 @HamzaTatheer)
|
||||||
* You can now provide a pivot point when rotating the viewport (#2233 #2253 @pearcetm)
|
* You can now provide a pivot point when rotating the viewport (#2233 #2253 @pearcetm)
|
||||||
@ -13,8 +46,10 @@ OPENSEADRAGON CHANGELOG
|
|||||||
* We now delegate tile fetching and caching to the TileSource, to allow for custom tile formats (#2148 @Aiosa)
|
* We now delegate tile fetching and caching to the TileSource, to allow for custom tile formats (#2148 @Aiosa)
|
||||||
* Added support for dynamic URLs from tile sources (#2247 @JohnReagan)
|
* Added support for dynamic URLs from tile sources (#2247 @JohnReagan)
|
||||||
* The viewer now emits before-destroy and destroy events (#2239 @pearcetm)
|
* The viewer now emits before-destroy and destroy events (#2239 @pearcetm)
|
||||||
|
* Auto resize detection is now more efficient (#2256 @pearcetm)
|
||||||
* Improved documentation (#2211 @shyamkumaryadav)
|
* Improved documentation (#2211 @shyamkumaryadav)
|
||||||
* Fixed: Cropping tiled images with polygons was broken (#2183 @altert)
|
* Fixed: Cropping tiled images with polygons was broken (#2183 @altert)
|
||||||
|
* Fixed: Boundary constraints were wrong when the viewport was rotated (#2249 @pearcetm)
|
||||||
* Fixed: IIIF tile sizes would be calculated wrong on rare occasions (#2206 @filak)
|
* Fixed: IIIF tile sizes would be calculated wrong on rare occasions (#2206 @filak)
|
||||||
* Fixed: Disabling buttons only changed their appearance, but they were still clickable (#2187 @pearcetm)
|
* Fixed: Disabling buttons only changed their appearance, but they were still clickable (#2187 @pearcetm)
|
||||||
* Fixed: ImageTileSource produced an error having to do with getTileHashKey (#2190 @Aiosa)
|
* Fixed: ImageTileSource produced an error having to do with getTileHashKey (#2190 @Aiosa)
|
||||||
|
7468
package-lock.json
generated
7468
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
15
package.json
15
package.json
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "openseadragon",
|
"name": "openseadragon",
|
||||||
"version": "3.1.0",
|
"version": "4.1.0",
|
||||||
"description": "Provides a smooth, zoomable user interface for HTML/Javascript.",
|
"description": "Provides a smooth, zoomable user interface for HTML/Javascript.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"image",
|
"image",
|
||||||
@ -29,19 +29,20 @@
|
|||||||
"url": "https://github.com/openseadragon/openseadragon.git"
|
"url": "https://github.com/openseadragon/openseadragon.git"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"grunt": "^1.4.1",
|
"eslint-plugin-compat": "^4.1.2",
|
||||||
"grunt-contrib-clean": "^2.0.0",
|
"grunt": "^1.6.1",
|
||||||
|
"grunt-contrib-clean": "^2.0.1",
|
||||||
"grunt-contrib-compress": "^2.0.0",
|
"grunt-contrib-compress": "^2.0.0",
|
||||||
"grunt-contrib-concat": "^2.0.0",
|
"grunt-contrib-concat": "^2.1.0",
|
||||||
"grunt-contrib-connect": "^3.0.0",
|
"grunt-contrib-connect": "^3.0.0",
|
||||||
"grunt-contrib-qunit": "^6.2.0",
|
"grunt-contrib-qunit": "^7.0.1",
|
||||||
"grunt-contrib-uglify": "^5.0.1",
|
"grunt-contrib-uglify": "^5.0.1",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"grunt-eslint": "^24.0.0",
|
"grunt-eslint": "^24.0.1",
|
||||||
"grunt-git-describe": "^2.4.4",
|
"grunt-git-describe": "^2.4.4",
|
||||||
"grunt-istanbul": "^0.8.0",
|
"grunt-istanbul": "^0.8.0",
|
||||||
"grunt-text-replace": "^0.4.0",
|
"grunt-text-replace": "^0.4.0",
|
||||||
"qunitjs": "2.4.1"
|
"qunit": "^2.19.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "grunt test",
|
"test": "grunt test",
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Button
|
* OpenSeadragon - Button
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - ButtonGroup
|
* OpenSeadragon - ButtonGroup
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -112,6 +112,17 @@ $.ButtonGroup = function( options ) {
|
|||||||
/** @lends OpenSeadragon.ButtonGroup.prototype */
|
/** @lends OpenSeadragon.ButtonGroup.prototype */
|
||||||
$.ButtonGroup.prototype = {
|
$.ButtonGroup.prototype = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given button to this button group.
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {OpenSeadragon.Button} button
|
||||||
|
*/
|
||||||
|
addButton: function( button ){
|
||||||
|
this.buttons.push(button);
|
||||||
|
this.element.appendChild(button.element);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Figure out why this is used on the public API and if a more useful
|
* TODO: Figure out why this is used on the public API and if a more useful
|
||||||
* api can be created.
|
* api can be created.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Control
|
* OpenSeadragon - Control
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - ControlDock
|
* OpenSeadragon - ControlDock
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - DisplayRect
|
* OpenSeadragon - DisplayRect
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Drawer
|
* OpenSeadragon - Drawer
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - DziTileSource
|
* OpenSeadragon - DziTileSource
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - EventSource
|
* OpenSeadragon - EventSource
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -58,7 +58,7 @@ $.EventSource.prototype = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an event handler to be triggered only once (or a given number of times)
|
* Add an event handler to be triggered only once (or a given number of times)
|
||||||
* for a given event.
|
* for a given event. It is not removable with removeHandler().
|
||||||
* @function
|
* @function
|
||||||
* @param {String} eventName - Name of event to register.
|
* @param {String} eventName - Name of event to register.
|
||||||
* @param {OpenSeadragon.EventHandler} handler - Function to call when event
|
* @param {OpenSeadragon.EventHandler} handler - Function to call when event
|
||||||
@ -67,8 +67,9 @@ $.EventSource.prototype = {
|
|||||||
* to the handler.
|
* to the handler.
|
||||||
* @param {Number} [times=1] - The number of times to handle the event
|
* @param {Number} [times=1] - The number of times to handle the event
|
||||||
* before removing it.
|
* before removing it.
|
||||||
|
* @param {Number} [priority=0] - Handler priority. By default, all priorities are 0. Higher number = priority.
|
||||||
*/
|
*/
|
||||||
addOnceHandler: function(eventName, handler, userData, times) {
|
addOnceHandler: function(eventName, handler, userData, times, priority) {
|
||||||
var self = this;
|
var self = this;
|
||||||
times = times || 1;
|
times = times || 1;
|
||||||
var count = 0;
|
var count = 0;
|
||||||
@ -77,9 +78,9 @@ $.EventSource.prototype = {
|
|||||||
if (count === times) {
|
if (count === times) {
|
||||||
self.removeHandler(eventName, onceHandler);
|
self.removeHandler(eventName, onceHandler);
|
||||||
}
|
}
|
||||||
handler(event);
|
return handler(event);
|
||||||
};
|
};
|
||||||
this.addHandler(eventName, onceHandler, userData);
|
this.addHandler(eventName, onceHandler, userData, priority);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,14 +89,22 @@ $.EventSource.prototype = {
|
|||||||
* @param {String} eventName - Name of event to register.
|
* @param {String} eventName - Name of event to register.
|
||||||
* @param {OpenSeadragon.EventHandler} handler - Function to call when event is triggered.
|
* @param {OpenSeadragon.EventHandler} handler - Function to call when event is triggered.
|
||||||
* @param {Object} [userData=null] - Arbitrary object to be passed unchanged to the handler.
|
* @param {Object} [userData=null] - Arbitrary object to be passed unchanged to the handler.
|
||||||
|
* @param {Number} [priority=0] - Handler priority. By default, all priorities are 0. Higher number = priority.
|
||||||
*/
|
*/
|
||||||
addHandler: function ( eventName, handler, userData ) {
|
addHandler: function ( eventName, handler, userData, priority ) {
|
||||||
var events = this.events[ eventName ];
|
var events = this.events[ eventName ];
|
||||||
if ( !events ) {
|
if ( !events ) {
|
||||||
this.events[ eventName ] = events = [];
|
this.events[ eventName ] = events = [];
|
||||||
}
|
}
|
||||||
if ( handler && $.isFunction( handler ) ) {
|
if ( handler && $.isFunction( handler ) ) {
|
||||||
events[ events.length ] = { handler: handler, userData: userData || null };
|
var index = events.length,
|
||||||
|
event = { handler: handler, userData: userData || null, priority: priority || 0 };
|
||||||
|
events[ index ] = event;
|
||||||
|
while ( index > 0 && events[ index - 1 ].priority < events[ index ].priority ) {
|
||||||
|
events[ index ] = events[ index - 1 ];
|
||||||
|
events[ index - 1 ] = event;
|
||||||
|
index--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -156,7 +165,7 @@ $.EventSource.prototype = {
|
|||||||
* @function
|
* @function
|
||||||
* @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;
|
||||||
@ -186,15 +195,12 @@ $.EventSource.prototype = {
|
|||||||
raiseEvent: function( eventName, eventArgs ) {
|
raiseEvent: function( eventName, eventArgs ) {
|
||||||
//uncomment if you want to get a log of all events
|
//uncomment if you want to get a log of all events
|
||||||
//$.console.log( eventName );
|
//$.console.log( eventName );
|
||||||
|
|
||||||
var handler = this.getHandler( eventName );
|
var handler = this.getHandler( eventName );
|
||||||
|
|
||||||
if ( handler ) {
|
if ( handler ) {
|
||||||
if ( !eventArgs ) {
|
return handler( this, eventArgs || {} );
|
||||||
eventArgs = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
handler( this, eventArgs );
|
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - full-screen support functions
|
* OpenSeadragon - full-screen support functions
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -67,10 +67,14 @@
|
|||||||
return document.fullscreenElement;
|
return document.fullscreenElement;
|
||||||
};
|
};
|
||||||
fullScreenApi.requestFullScreen = function( element ) {
|
fullScreenApi.requestFullScreen = function( element ) {
|
||||||
return element.requestFullscreen();
|
return element.requestFullscreen().catch(function (msg) {
|
||||||
|
$.console.error('Fullscreen request failed: ', msg);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
fullScreenApi.exitFullScreen = function() {
|
fullScreenApi.exitFullScreen = function() {
|
||||||
document.exitFullscreen();
|
document.exitFullscreen().catch(function (msg) {
|
||||||
|
$.console.error('Error while exiting fullscreen: ', msg);
|
||||||
|
});
|
||||||
};
|
};
|
||||||
fullScreenApi.fullScreenEventName = "fullscreenchange";
|
fullScreenApi.fullScreenEventName = "fullscreenchange";
|
||||||
fullScreenApi.fullScreenErrorEventName = "fullscreenerror";
|
fullScreenApi.fullScreenErrorEventName = "fullscreenerror";
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - IIIFTileSource
|
* OpenSeadragon - IIIFTileSource
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -141,6 +141,18 @@ $.IIIFTileSource = function( options ){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create an array with our exact resolution sizes if these have been supplied
|
||||||
|
if( this.sizes ) {
|
||||||
|
var sizeLength = this.sizes.length;
|
||||||
|
if ( (sizeLength === options.maxLevel) || (sizeLength === options.maxLevel + 1) ) {
|
||||||
|
this.levelSizes = this.sizes;
|
||||||
|
// Need to take into account that the list may or may not include the full resolution size
|
||||||
|
if( sizeLength === options.maxLevel ) {
|
||||||
|
this.levelSizes.push( {width: this.width, height: this.height} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$.TileSource.apply( this, [ options ] );
|
$.TileSource.apply( this, [ options ] );
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -333,7 +345,17 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $.TileSource.prototype.getNumTiles.call(this, level);
|
// Use supplied list of scaled resolution sizes if these exist
|
||||||
|
if( this.levelSizes ) {
|
||||||
|
var levelSize = this.levelSizes[level];
|
||||||
|
var x = Math.ceil( levelSize.width / this.getTileWidth(level) ),
|
||||||
|
y = Math.ceil( levelSize.height / this.getTileHeight(level) );
|
||||||
|
return new $.Point( x, y );
|
||||||
|
}
|
||||||
|
// Otherwise call default TileSource->getNumTiles() function
|
||||||
|
else {
|
||||||
|
return $.TileSource.prototype.getNumTiles.call(this, level);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -348,6 +370,34 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
return new $.Point(0, 0);
|
return new $.Point(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use supplied list of scaled resolution sizes if these exist
|
||||||
|
if( this.levelSizes ) {
|
||||||
|
|
||||||
|
var validPoint = point.x >= 0 && point.x <= 1 &&
|
||||||
|
point.y >= 0 && point.y <= 1 / this.aspectRatio;
|
||||||
|
$.console.assert(validPoint, "[TileSource.getTileAtPoint] must be called with a valid point.");
|
||||||
|
|
||||||
|
var widthScaled = this.levelSizes[level].width;
|
||||||
|
var pixelX = point.x * widthScaled;
|
||||||
|
var pixelY = point.y * widthScaled;
|
||||||
|
|
||||||
|
var x = Math.floor(pixelX / this.getTileWidth(level));
|
||||||
|
var y = Math.floor(pixelY / this.getTileHeight(level));
|
||||||
|
|
||||||
|
// When point.x == 1 or point.y == 1 / this.aspectRatio we want to
|
||||||
|
// return the last tile of the row/column
|
||||||
|
if (point.x >= 1) {
|
||||||
|
x = this.getNumTiles(level).x - 1;
|
||||||
|
}
|
||||||
|
var EPSILON = 1e-15;
|
||||||
|
if (point.y >= 1 / this.aspectRatio - EPSILON) {
|
||||||
|
y = this.getNumTiles(level).y - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new $.Point(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise call default TileSource->getTileAtPoint() function
|
||||||
return $.TileSource.prototype.getTileAtPoint.call(this, level, point);
|
return $.TileSource.prototype.getTileAtPoint.call(this, level, point);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -375,10 +425,9 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
var IIIF_ROTATION = '0',
|
var IIIF_ROTATION = '0',
|
||||||
//## 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 ),
|
||||||
|
|
||||||
//# image dimensions at this level
|
//# image dimensions at this level
|
||||||
levelWidth = Math.round( this.width * scale ),
|
levelWidth,
|
||||||
levelHeight = Math.round( this.height * scale ),
|
levelHeight,
|
||||||
|
|
||||||
//## iiif region
|
//## iiif region
|
||||||
tileWidth,
|
tileWidth,
|
||||||
@ -396,6 +445,17 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
iiifQuality,
|
iiifQuality,
|
||||||
uri;
|
uri;
|
||||||
|
|
||||||
|
// Use supplied list of scaled resolution sizes if these exist
|
||||||
|
if( this.levelSizes ) {
|
||||||
|
levelWidth = this.levelSizes[level].width;
|
||||||
|
levelHeight = this.levelSizes[level].height;
|
||||||
|
}
|
||||||
|
// Otherwise calculate the sizes ourselves
|
||||||
|
else {
|
||||||
|
levelWidth = Math.ceil( this.width * scale );
|
||||||
|
levelHeight = Math.ceil( this.height * scale );
|
||||||
|
}
|
||||||
|
|
||||||
tileWidth = this.getTileWidth(level);
|
tileWidth = this.getTileWidth(level);
|
||||||
tileHeight = this.getTileHeight(level);
|
tileHeight = this.getTileHeight(level);
|
||||||
iiifTileSizeWidth = Math.round( tileWidth / scale );
|
iiifTileSizeWidth = Math.round( tileWidth / scale );
|
||||||
@ -426,8 +486,8 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|||||||
} else {
|
} else {
|
||||||
iiifRegion = [ iiifTileX, iiifTileY, iiifTileW, iiifTileH ].join( ',' );
|
iiifRegion = [ iiifTileX, iiifTileY, iiifTileW, iiifTileH ].join( ',' );
|
||||||
}
|
}
|
||||||
iiifSizeW = Math.round( iiifTileW * scale );
|
iiifSizeW = Math.min( tileWidth, levelWidth - (x * tileWidth) );
|
||||||
iiifSizeH = Math.round( iiifTileH * scale );
|
iiifSizeH = Math.min( tileHeight, levelHeight - (y * tileHeight) );
|
||||||
if ( this.version === 2 && iiifSizeW === this.width ) {
|
if ( this.version === 2 && iiifSizeW === this.width ) {
|
||||||
iiifSize = "full";
|
iiifSize = "full";
|
||||||
} else if ( this.version === 3 && iiifSizeW === this.width && iiifSizeH === this.height ) {
|
} else if ( this.version === 3 && iiifSizeW === this.width && iiifSizeH === this.height ) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - ImageLoader
|
* OpenSeadragon - ImageLoader
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -50,17 +50,19 @@
|
|||||||
* @param {Function} [options.callback] - Called once image has been downloaded.
|
* @param {Function} [options.callback] - Called once image has been downloaded.
|
||||||
* @param {Function} [options.abort] - Called when this image job is aborted.
|
* @param {Function} [options.abort] - Called when this image job is aborted.
|
||||||
* @param {Number} [options.timeout] - The max number of milliseconds that this image job may take to complete.
|
* @param {Number} [options.timeout] - The max number of milliseconds that this image job may take to complete.
|
||||||
|
* @param {Number} [options.tries] - Actual number of the current try.
|
||||||
*/
|
*/
|
||||||
$.ImageJob = function(options) {
|
$.ImageJob = function(options) {
|
||||||
|
|
||||||
$.extend(true, this, {
|
$.extend(true, this, {
|
||||||
timeout: $.DEFAULT_SETTINGS.timeout,
|
timeout: $.DEFAULT_SETTINGS.timeout,
|
||||||
jobId: null
|
jobId: null,
|
||||||
|
tries: 0
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data object which will contain downloaded image data.
|
* Data object which will contain downloaded image data.
|
||||||
* @member {Image|*} image data object, by default an Image object (depends on TileSource)
|
* @member {Image|*} data data object, by default an Image object (depends on TileSource)
|
||||||
* @memberof OpenSeadragon.ImageJob#
|
* @memberof OpenSeadragon.ImageJob#
|
||||||
*/
|
*/
|
||||||
this.data = null;
|
this.data = null;
|
||||||
@ -87,6 +89,8 @@ $.ImageJob.prototype = {
|
|||||||
* @method
|
* @method
|
||||||
*/
|
*/
|
||||||
start: function() {
|
start: function() {
|
||||||
|
this.tries++;
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var selfAbort = this.abort;
|
var selfAbort = this.abort;
|
||||||
|
|
||||||
@ -138,6 +142,7 @@ $.ImageLoader = function(options) {
|
|||||||
jobLimit: $.DEFAULT_SETTINGS.imageLoaderLimit,
|
jobLimit: $.DEFAULT_SETTINGS.imageLoaderLimit,
|
||||||
timeout: $.DEFAULT_SETTINGS.timeout,
|
timeout: $.DEFAULT_SETTINGS.timeout,
|
||||||
jobQueue: [],
|
jobQueue: [],
|
||||||
|
failedTiles: [],
|
||||||
jobsInProgress: 0
|
jobsInProgress: 0
|
||||||
}, options);
|
}, options);
|
||||||
|
|
||||||
@ -220,7 +225,8 @@ $.ImageLoader.prototype = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cleans up ImageJob once completed.
|
* Cleans up ImageJob once completed. Restarts job after tileRetryDelay seconds if failed
|
||||||
|
* but max tileRetryMax times
|
||||||
* @method
|
* @method
|
||||||
* @private
|
* @private
|
||||||
* @param loader - ImageLoader used to start job.
|
* @param loader - ImageLoader used to start job.
|
||||||
@ -228,6 +234,9 @@ $.ImageLoader.prototype = {
|
|||||||
* @param callback - Called once cleanup is finished.
|
* @param callback - Called once cleanup is finished.
|
||||||
*/
|
*/
|
||||||
function completeJob(loader, job, callback) {
|
function completeJob(loader, job, callback) {
|
||||||
|
if (job.errorMsg !== '' && (job.data === null || job.data === undefined) && job.tries < 1 + loader.tileRetryMax) {
|
||||||
|
loader.failedTiles.push(job);
|
||||||
|
}
|
||||||
var nextJob;
|
var nextJob;
|
||||||
|
|
||||||
loader.jobsInProgress--;
|
loader.jobsInProgress--;
|
||||||
@ -238,6 +247,16 @@ function completeJob(loader, job, callback) {
|
|||||||
loader.jobsInProgress++;
|
loader.jobsInProgress++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (loader.tileRetryMax > 0 && loader.jobQueue.length === 0) {
|
||||||
|
if ((!loader.jobLimit || loader.jobsInProgress < loader.jobLimit) && loader.failedTiles.length > 0) {
|
||||||
|
nextJob = loader.failedTiles.shift();
|
||||||
|
setTimeout(function () {
|
||||||
|
nextJob.start();
|
||||||
|
}, loader.tileRetryDelay);
|
||||||
|
loader.jobsInProgress++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callback(job.data, job.errorMsg, job.request);
|
callback(job.data, job.errorMsg, job.request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - ImageTileSource
|
* OpenSeadragon - ImageTileSource
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - LegacyTileSource
|
* OpenSeadragon - LegacyTileSource
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - MouseTracker
|
* OpenSeadragon - MouseTracker
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Navigator
|
* OpenSeadragon - Navigator
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -125,7 +125,8 @@ $.Navigator = function( options ){
|
|||||||
immediateRender: true,
|
immediateRender: true,
|
||||||
blendTime: 0,
|
blendTime: 0,
|
||||||
animationTime: options.animationTime,
|
animationTime: options.animationTime,
|
||||||
autoResize: options.autoResize,
|
// disable autoResize since resize behavior is implemented differently by the navigator
|
||||||
|
autoResize: false,
|
||||||
// prevent resizing the navigator from adding unwanted space around the image
|
// prevent resizing the navigator from adding unwanted space around the image
|
||||||
minZoomImageRatio: 1.0,
|
minZoomImageRatio: 1.0,
|
||||||
background: options.background,
|
background: options.background,
|
||||||
@ -183,6 +184,7 @@ $.Navigator = function( options ){
|
|||||||
style.styleFloat = 'left'; //IE
|
style.styleFloat = 'left'; //IE
|
||||||
style.zIndex = 999999999;
|
style.zIndex = 999999999;
|
||||||
style.cursor = 'default';
|
style.cursor = 'default';
|
||||||
|
style.boxSizing = 'content-box';
|
||||||
}( this.displayRegion.style, this.borderWidth ));
|
}( this.displayRegion.style, this.borderWidth ));
|
||||||
$.setElementPointerEventsNone( this.displayRegion );
|
$.setElementPointerEventsNone( this.displayRegion );
|
||||||
$.setElementTouchActionNone( this.displayRegion );
|
$.setElementTouchActionNone( this.displayRegion );
|
||||||
@ -222,19 +224,19 @@ $.Navigator = function( options ){
|
|||||||
this.displayRegionContainer.appendChild(this.displayRegion);
|
this.displayRegionContainer.appendChild(this.displayRegion);
|
||||||
this.element.getElementsByTagName('div')[0].appendChild(this.displayRegionContainer);
|
this.element.getElementsByTagName('div')[0].appendChild(this.displayRegionContainer);
|
||||||
|
|
||||||
function rotate(degrees) {
|
function rotate(degrees, immediately) {
|
||||||
_setTransformRotate(_this.displayRegionContainer, degrees);
|
_setTransformRotate(_this.displayRegionContainer, degrees);
|
||||||
_setTransformRotate(_this.displayRegion, -degrees);
|
_setTransformRotate(_this.displayRegion, -degrees);
|
||||||
_this.viewport.setRotation(degrees);
|
_this.viewport.setRotation(degrees, immediately);
|
||||||
}
|
}
|
||||||
if (options.navigatorRotate) {
|
if (options.navigatorRotate) {
|
||||||
var degrees = options.viewer.viewport ?
|
var degrees = options.viewer.viewport ?
|
||||||
options.viewer.viewport.getRotation() :
|
options.viewer.viewport.getRotation() :
|
||||||
options.viewer.degrees || 0;
|
options.viewer.degrees || 0;
|
||||||
|
|
||||||
rotate(degrees);
|
rotate(degrees, true);
|
||||||
options.viewer.addHandler("rotate", function (args) {
|
options.viewer.addHandler("rotate", function (args) {
|
||||||
rotate(args.degrees);
|
rotate(args.degrees, args.immediately);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,6 +324,7 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
this.width = width;
|
this.width = width;
|
||||||
this.element.style.width = typeof (width) === "number" ? (width + 'px') : width;
|
this.element.style.width = typeof (width) === "number" ? (width + 'px') : width;
|
||||||
this._resizeWithViewer = false;
|
this._resizeWithViewer = false;
|
||||||
|
this.updateSize();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -332,6 +335,7 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
this.height = height;
|
this.height = height;
|
||||||
this.element.style.height = typeof (height) === "number" ? (height + 'px') : height;
|
this.element.style.height = typeof (height) === "number" ? (height + 'px') : height;
|
||||||
this._resizeWithViewer = false;
|
this._resizeWithViewer = false;
|
||||||
|
this.updateSize();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -393,15 +397,20 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|||||||
bottomright = this.viewport.pixelFromPointNoRotate(bounds.getBottomRight(), false)
|
bottomright = this.viewport.pixelFromPointNoRotate(bounds.getBottomRight(), false)
|
||||||
.minus( this.totalBorderWidths );
|
.minus( this.totalBorderWidths );
|
||||||
|
|
||||||
|
if (!this.navigatorRotate) {
|
||||||
|
var degrees = viewport.getRotation(true);
|
||||||
|
_setTransformRotate(this.displayRegion, -degrees);
|
||||||
|
}
|
||||||
|
|
||||||
//update style for navigator-box
|
//update style for navigator-box
|
||||||
var style = this.displayRegion.style;
|
var style = this.displayRegion.style;
|
||||||
style.display = this.world.getItemCount() ? 'block' : 'none';
|
style.display = this.world.getItemCount() ? 'block' : 'none';
|
||||||
|
|
||||||
style.top = Math.round( topleft.y ) + 'px';
|
style.top = topleft.y.toFixed(2) + "px";
|
||||||
style.left = Math.round( topleft.x ) + 'px';
|
style.left = topleft.x.toFixed(2) + "px";
|
||||||
|
|
||||||
var width = Math.abs( topleft.x - bottomright.x );
|
var width = bottomright.x - topleft.x;
|
||||||
var height = Math.abs( topleft.y - bottomright.y );
|
var height = bottomright.y - topleft.y;
|
||||||
// make sure width and height are non-negative so IE doesn't throw
|
// make sure width and height are non-negative so IE doesn't throw
|
||||||
style.width = Math.round( Math.max( width, 0 ) ) + 'px';
|
style.width = Math.round( Math.max( width, 0 ) ) + 'px';
|
||||||
style.height = Math.round( Math.max( height, 0 ) ) + 'px';
|
style.height = Math.round( Math.max( height, 0 ) ) + 'px';
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon
|
* OpenSeadragon
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -60,7 +60,7 @@
|
|||||||
/*
|
/*
|
||||||
* Portions of this source file taken from mattsnider.com:
|
* Portions of this source file taken from mattsnider.com:
|
||||||
*
|
*
|
||||||
* Copyright (c) 2006-2022 Matt Snider
|
* Copyright (c) 2006-2013 Matt Snider
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
@ -499,6 +499,12 @@
|
|||||||
* @property {Number} [timeout=30000]
|
* @property {Number} [timeout=30000]
|
||||||
* The max number of milliseconds that an image job may take to complete.
|
* The max number of milliseconds that an image job may take to complete.
|
||||||
*
|
*
|
||||||
|
* @property {Number} [tileRetryMax=0]
|
||||||
|
* The max number of retries when a tile download fails. By default it's 0, so retries are disabled.
|
||||||
|
*
|
||||||
|
* @property {Number} [tileRetryDelay=2500]
|
||||||
|
* Milliseconds to wait after each tile retry if tileRetryMax is set.
|
||||||
|
*
|
||||||
* @property {Boolean} [useCanvas=true]
|
* @property {Boolean} [useCanvas=true]
|
||||||
* Set to false to not use an HTML canvas element for image rendering even if canvas is supported.
|
* Set to false to not use an HTML canvas element for image rendering even if canvas is supported.
|
||||||
*
|
*
|
||||||
@ -563,50 +569,50 @@
|
|||||||
* viewing the first image and the 'next' button will wrap to the first
|
* viewing the first image and the 'next' button will wrap to the first
|
||||||
* image when viewing the last image.
|
* image when viewing the last image.
|
||||||
*
|
*
|
||||||
* @property {String} zoomInButton
|
*@property {String|Element} zoomInButton
|
||||||
* Set the id of the custom 'Zoom in' button to use.
|
* Set the id or element of the custom 'Zoom in' button to use.
|
||||||
* This is useful to have a custom button anywhere in the web page.<br>
|
* This is useful to have a custom button anywhere in the web page.<br>
|
||||||
* To only change the button images, consider using
|
* To only change the button images, consider using
|
||||||
* {@link OpenSeadragon.Options.navImages}
|
* {@link OpenSeadragon.Options.navImages}
|
||||||
*
|
*
|
||||||
* @property {String} zoomOutButton
|
* @property {String|Element} zoomOutButton
|
||||||
* Set the id of the custom 'Zoom out' button to use.
|
* Set the id or element of the custom 'Zoom out' button to use.
|
||||||
* This is useful to have a custom button anywhere in the web page.<br>
|
* This is useful to have a custom button anywhere in the web page.<br>
|
||||||
* To only change the button images, consider using
|
* To only change the button images, consider using
|
||||||
* {@link OpenSeadragon.Options.navImages}
|
* {@link OpenSeadragon.Options.navImages}
|
||||||
*
|
*
|
||||||
* @property {String} homeButton
|
* @property {String|Element} homeButton
|
||||||
* Set the id of the custom 'Go home' button to use.
|
* Set the id or element of the custom 'Go home' button to use.
|
||||||
* This is useful to have a custom button anywhere in the web page.<br>
|
* This is useful to have a custom button anywhere in the web page.<br>
|
||||||
* To only change the button images, consider using
|
* To only change the button images, consider using
|
||||||
* {@link OpenSeadragon.Options.navImages}
|
* {@link OpenSeadragon.Options.navImages}
|
||||||
*
|
*
|
||||||
* @property {String} fullPageButton
|
* @property {String|Element} fullPageButton
|
||||||
* Set the id of the custom 'Toggle full page' button to use.
|
* Set the id or element of the custom 'Toggle full page' button to use.
|
||||||
* This is useful to have a custom button anywhere in the web page.<br>
|
* This is useful to have a custom button anywhere in the web page.<br>
|
||||||
* To only change the button images, consider using
|
* To only change the button images, consider using
|
||||||
* {@link OpenSeadragon.Options.navImages}
|
* {@link OpenSeadragon.Options.navImages}
|
||||||
*
|
*
|
||||||
* @property {String} rotateLeftButton
|
* @property {String|Element} rotateLeftButton
|
||||||
* Set the id of the custom 'Rotate left' button to use.
|
* Set the id or element of the custom 'Rotate left' button to use.
|
||||||
* This is useful to have a custom button anywhere in the web page.<br>
|
* This is useful to have a custom button anywhere in the web page.<br>
|
||||||
* To only change the button images, consider using
|
* To only change the button images, consider using
|
||||||
* {@link OpenSeadragon.Options.navImages}
|
* {@link OpenSeadragon.Options.navImages}
|
||||||
*
|
*
|
||||||
* @property {String} rotateRightButton
|
* @property {String|Element} rotateRightButton
|
||||||
* Set the id of the custom 'Rotate right' button to use.
|
* Set the id or element of the custom 'Rotate right' button to use.
|
||||||
* This is useful to have a custom button anywhere in the web page.<br>
|
* This is useful to have a custom button anywhere in the web page.<br>
|
||||||
* To only change the button images, consider using
|
* To only change the button images, consider using
|
||||||
* {@link OpenSeadragon.Options.navImages}
|
* {@link OpenSeadragon.Options.navImages}
|
||||||
*
|
*
|
||||||
* @property {String} previousButton
|
* @property {String|Element} previousButton
|
||||||
* Set the id of the custom 'Previous page' button to use.
|
* Set the id or element of the custom 'Previous page' button to use.
|
||||||
* This is useful to have a custom button anywhere in the web page.<br>
|
* This is useful to have a custom button anywhere in the web page.<br>
|
||||||
* To only change the button images, consider using
|
* To only change the button images, consider using
|
||||||
* {@link OpenSeadragon.Options.navImages}
|
* {@link OpenSeadragon.Options.navImages}
|
||||||
*
|
*
|
||||||
* @property {String} nextButton
|
* @property {String|Element} nextButton
|
||||||
* Set the id of the custom 'Next page' button to use.
|
* Set the id or element of the custom 'Next page' button to use.
|
||||||
* This is useful to have a custom button anywhere in the web page.<br>
|
* This is useful to have a custom button anywhere in the web page.<br>
|
||||||
* To only change the button images, consider using
|
* To only change the button images, consider using
|
||||||
* {@link OpenSeadragon.Options.navImages}
|
* {@link OpenSeadragon.Options.navImages}
|
||||||
@ -830,14 +836,16 @@ function OpenSeadragon( options ){
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
var class2type = {
|
var class2type = {
|
||||||
'[object Boolean]': 'boolean',
|
'[object Boolean]': 'boolean',
|
||||||
'[object Number]': 'number',
|
'[object Number]': 'number',
|
||||||
'[object String]': 'string',
|
'[object String]': 'string',
|
||||||
'[object Function]': 'function',
|
'[object Function]': 'function',
|
||||||
'[object Array]': 'array',
|
'[object AsyncFunction]': 'function',
|
||||||
'[object Date]': 'date',
|
'[object Promise]': 'promise',
|
||||||
'[object RegExp]': 'regexp',
|
'[object Array]': 'array',
|
||||||
'[object Object]': 'object'
|
'[object Date]': 'date',
|
||||||
|
'[object RegExp]': 'regexp',
|
||||||
|
'[object Object]': 'object'
|
||||||
},
|
},
|
||||||
// Save a reference to some core methods
|
// Save a reference to some core methods
|
||||||
toString = Object.prototype.toString,
|
toString = Object.prototype.toString,
|
||||||
@ -853,7 +861,6 @@ function OpenSeadragon( options ){
|
|||||||
return $.type(obj) === "function";
|
return $.type(obj) === "function";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Taken from jQuery 1.6.1
|
* Taken from jQuery 1.6.1
|
||||||
* @function isArray
|
* @function isArray
|
||||||
@ -1359,6 +1366,8 @@ function OpenSeadragon( options ){
|
|||||||
maxImageCacheCount: 200,
|
maxImageCacheCount: 200,
|
||||||
timeout: 30000,
|
timeout: 30000,
|
||||||
useCanvas: true, // Use canvas element for drawing if available
|
useCanvas: true, // Use canvas element for drawing if available
|
||||||
|
tileRetryMax: 0,
|
||||||
|
tileRetryDelay: 2500,
|
||||||
|
|
||||||
//INTERFACE RESOURCE SETTINGS
|
//INTERFACE RESOURCE SETTINGS
|
||||||
prefixUrl: "/images/",
|
prefixUrl: "/images/",
|
||||||
@ -2247,25 +2256,12 @@ function OpenSeadragon( options ){
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Deprecated
|
||||||
/**
|
|
||||||
* Similar to OpenSeadragon.delegate, but it does not immediately call
|
|
||||||
* the method on the object, returning a function which can be called
|
|
||||||
* repeatedly to delegate the method. It also allows additional arguments
|
|
||||||
* to be passed during construction which will be added during each
|
|
||||||
* invocation, and each invocation can add additional arguments as well.
|
|
||||||
*
|
|
||||||
* @function
|
|
||||||
* @param {Object} object
|
|
||||||
* @param {Function} method
|
|
||||||
* @param [args] any additional arguments are passed as arguments to the
|
|
||||||
* created callback
|
|
||||||
* @returns {Function}
|
|
||||||
*/
|
|
||||||
createCallback: function( object, method ) {
|
createCallback: function( object, method ) {
|
||||||
//TODO: This pattern is painful to use and debug. It's much cleaner
|
//TODO: This pattern is painful to use and debug. It's much cleaner
|
||||||
// to use pinning plus anonymous functions. Get rid of this
|
// to use pinning plus anonymous functions. Get rid of this
|
||||||
// pattern!
|
// pattern!
|
||||||
|
console.error('The createCallback function is deprecated and will be removed in future versions. Please use alternativeFunction instead.');
|
||||||
var initialArgs = [],
|
var initialArgs = [],
|
||||||
i;
|
i;
|
||||||
for ( i = 2; i < arguments.length; i++ ) {
|
for ( i = 2; i < arguments.length; i++ ) {
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - OsmTileSource
|
* OpenSeadragon - OsmTileSource
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Overlay
|
* OpenSeadragon - Overlay
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Point
|
* OpenSeadragon - Point
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Profiler
|
* OpenSeadragon - Profiler
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Rect
|
* OpenSeadragon - Rect
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - ReferenceStrip
|
* OpenSeadragon - ReferenceStrip
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -300,7 +300,8 @@ function onStripClick( event ) {
|
|||||||
var page;
|
var page;
|
||||||
|
|
||||||
if ( 'horizontal' === this.scroll ) {
|
if ( 'horizontal' === this.scroll ) {
|
||||||
page = Math.floor(event.position.x / this.panelWidth);
|
// +4px fix to solve problem with precision on thumbnail selection if there is a lot of them
|
||||||
|
page = Math.floor(event.position.x / (this.panelWidth + 4));
|
||||||
} else {
|
} else {
|
||||||
page = Math.floor(event.position.y / this.panelHeight);
|
page = Math.floor(event.position.y / this.panelHeight);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Spring
|
* OpenSeadragon - Spring
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - getString/setString
|
* OpenSeadragon - getString/setString
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Tile
|
* OpenSeadragon - Tile
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -44,7 +44,7 @@
|
|||||||
* 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|() => String} url The URL of this tile's image or a function that returns a url.
|
* @param {String|Function} url The URL of this tile's image or a function that returns a url.
|
||||||
* @param {CanvasRenderingContext2D} context2D The context2D of this tile if it
|
* @param {CanvasRenderingContext2D} context2D The context2D of this tile if it
|
||||||
* is provided directly by the tile source.
|
* is provided directly by the tile source.
|
||||||
* @param {Boolean} loadWithAjax Whether this tile image should be loaded with an AJAX request .
|
* @param {Boolean} loadWithAjax Whether this tile image should be loaded with an AJAX request .
|
||||||
@ -98,7 +98,7 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, aja
|
|||||||
* Private property to hold string url or url retriever function.
|
* Private property to hold string url or url retriever function.
|
||||||
* Consumers should access via Tile.getUrl()
|
* Consumers should access via Tile.getUrl()
|
||||||
* @private
|
* @private
|
||||||
* @member {String|() => String} url
|
* @member {String|Function} url
|
||||||
* @memberof OpenSeadragon.Tile#
|
* @memberof OpenSeadragon.Tile#
|
||||||
*/
|
*/
|
||||||
this._url = url;
|
this._url = url;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - TileCache
|
* OpenSeadragon - TileCache
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - TiledImage
|
* OpenSeadragon - TiledImage
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -147,6 +147,9 @@ $.TiledImage = function( options ) {
|
|||||||
var degrees = options.degrees || 0;
|
var degrees = options.degrees || 0;
|
||||||
delete options.degrees;
|
delete options.degrees;
|
||||||
|
|
||||||
|
var ajaxHeaders = options.ajaxHeaders;
|
||||||
|
delete options.ajaxHeaders;
|
||||||
|
|
||||||
$.extend( true, this, {
|
$.extend( true, this, {
|
||||||
|
|
||||||
//internal state properties
|
//internal state properties
|
||||||
@ -238,6 +241,9 @@ $.TiledImage = function( options ) {
|
|||||||
tiledImage: _this
|
tiledImage: _this
|
||||||
}, args));
|
}, args));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._ownAjaxHeaders = {};
|
||||||
|
this.setAjaxHeaders(ajaxHeaders, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.TiledImage.prototype */{
|
$.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.TiledImage.prototype */{
|
||||||
@ -1003,6 +1009,90 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update headers to include when making AJAX requests.
|
||||||
|
*
|
||||||
|
* Unless `propagate` is set to false (which is likely only useful in rare circumstances),
|
||||||
|
* the updated headers are propagated to all tiles and queued image loader jobs.
|
||||||
|
*
|
||||||
|
* Note that the rules for merging headers still apply, i.e. headers returned by
|
||||||
|
* {@link OpenSeadragon.TileSource#getTileAjaxHeaders} take precedence over
|
||||||
|
* the headers here in the tiled image (`TiledImage.ajaxHeaders`).
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {Object} ajaxHeaders Updated AJAX headers, which will be merged over any headers specified in {@link OpenSeadragon.Options}.
|
||||||
|
* @param {Boolean} [propagate=true] Whether to propagate updated headers to existing tiles and queued image loader jobs.
|
||||||
|
*/
|
||||||
|
setAjaxHeaders: function(ajaxHeaders, propagate) {
|
||||||
|
if (ajaxHeaders === null) {
|
||||||
|
ajaxHeaders = {};
|
||||||
|
}
|
||||||
|
if (!$.isPlainObject(ajaxHeaders)) {
|
||||||
|
console.error('[TiledImage.setAjaxHeaders] Ignoring invalid headers, must be a plain object');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._ownAjaxHeaders = ajaxHeaders;
|
||||||
|
this._updateAjaxHeaders(propagate);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update headers to include when making AJAX requests.
|
||||||
|
*
|
||||||
|
* This function has the same effect as calling {@link OpenSeadragon.TiledImage#setAjaxHeaders},
|
||||||
|
* except that the headers for this tiled image do not change. This is especially useful
|
||||||
|
* for propagating updated headers from {@link OpenSeadragon.TileSource#getTileAjaxHeaders}
|
||||||
|
* to existing tiles.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @function
|
||||||
|
* @param {Boolean} [propagate=true] Whether to propagate updated headers to existing tiles and queued image loader jobs.
|
||||||
|
*/
|
||||||
|
_updateAjaxHeaders: function(propagate) {
|
||||||
|
if (propagate === undefined) {
|
||||||
|
propagate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge with viewer's headers
|
||||||
|
if ($.isPlainObject(this.viewer.ajaxHeaders)) {
|
||||||
|
this.ajaxHeaders = $.extend({}, this.viewer.ajaxHeaders, this._ownAjaxHeaders);
|
||||||
|
} else {
|
||||||
|
this.ajaxHeaders = this._ownAjaxHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
// propagate header updates to all tiles and queued image loader jobs
|
||||||
|
if (propagate) {
|
||||||
|
var numTiles, xMod, yMod, tile;
|
||||||
|
|
||||||
|
for (var level in this.tilesMatrix) {
|
||||||
|
numTiles = this.source.getNumTiles(level);
|
||||||
|
|
||||||
|
for (var x in this.tilesMatrix[level]) {
|
||||||
|
xMod = ( numTiles.x + ( x % numTiles.x ) ) % numTiles.x;
|
||||||
|
|
||||||
|
for (var y in this.tilesMatrix[level][x]) {
|
||||||
|
yMod = ( numTiles.y + ( y % numTiles.y ) ) % numTiles.y;
|
||||||
|
tile = this.tilesMatrix[level][x][y];
|
||||||
|
|
||||||
|
tile.loadWithAjax = this.loadTilesWithAjax;
|
||||||
|
if (tile.loadWithAjax) {
|
||||||
|
var tileAjaxHeaders = this.source.getTileAjaxHeaders( level, xMod, yMod );
|
||||||
|
tile.ajaxHeaders = $.extend({}, this.ajaxHeaders, tileAjaxHeaders);
|
||||||
|
} else {
|
||||||
|
tile.ajaxHeaders = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < this._imageLoader.jobQueue.length; i++) {
|
||||||
|
var job = this._imageLoader.jobQueue[i];
|
||||||
|
job.loadWithAjax = job.tile.loadWithAjax;
|
||||||
|
job.ajaxHeaders = job.tile.loadWithAjax ? job.tile.ajaxHeaders : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
_setScale: function(scale, immediately) {
|
_setScale: function(scale, immediately) {
|
||||||
var sameTarget = (this._scaleSpring.target.value === scale);
|
var sameTarget = (this._scaleSpring.target.value === scale);
|
||||||
@ -1621,6 +1711,8 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
tile.loading = false;
|
tile.loading = false;
|
||||||
tile.exists = false;
|
tile.exists = false;
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
tile.exists = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( time < this.lastResetTime ) {
|
if ( time < this.lastResetTime ) {
|
||||||
@ -1656,9 +1748,14 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
*/
|
*/
|
||||||
_setTileLoaded: function(tile, data, cutoff, tileRequest) {
|
_setTileLoaded: function(tile, data, cutoff, tileRequest) {
|
||||||
var increment = 0,
|
var increment = 0,
|
||||||
|
eventFinished = false,
|
||||||
_this = this;
|
_this = this;
|
||||||
|
|
||||||
function getCompletionCallback() {
|
function getCompletionCallback() {
|
||||||
|
if (eventFinished) {
|
||||||
|
$.console.error("Event 'tile-loaded' argument getCompletionCallback must be called synchronously. " +
|
||||||
|
"Its return value should be called asynchronously.");
|
||||||
|
}
|
||||||
increment++;
|
increment++;
|
||||||
return completionCallback;
|
return completionCallback;
|
||||||
}
|
}
|
||||||
@ -1690,7 +1787,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
* @event tile-loaded
|
* @event tile-loaded
|
||||||
* @memberof OpenSeadragon.Viewer
|
* @memberof OpenSeadragon.Viewer
|
||||||
* @type {object}
|
* @type {object}
|
||||||
* @property {Image || *} image - The image (data) of the tile. Deprecated.
|
* @property {Image|*} image - The image (data) of the tile. Deprecated.
|
||||||
* @property {*} data image data, the data sent to ImageJob.prototype.finish(), by default an Image object
|
* @property {*} data image data, the data sent to ImageJob.prototype.finish(), by default an Image object
|
||||||
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.
|
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.
|
||||||
* @property {OpenSeadragon.Tile} tile - The tile which has been loaded.
|
* @property {OpenSeadragon.Tile} tile - The tile which has been loaded.
|
||||||
@ -1700,6 +1797,8 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
* marked as entirely loaded when the callback has been called once for each
|
* marked as entirely loaded when the callback has been called once for each
|
||||||
* call to getCompletionCallback.
|
* call to getCompletionCallback.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
var fallbackCompletion = getCompletionCallback();
|
||||||
this.viewer.raiseEvent("tile-loaded", {
|
this.viewer.raiseEvent("tile-loaded", {
|
||||||
tile: tile,
|
tile: tile,
|
||||||
tiledImage: this,
|
tiledImage: this,
|
||||||
@ -1711,8 +1810,9 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
data: data,
|
data: data,
|
||||||
getCompletionCallback: getCompletionCallback
|
getCompletionCallback: getCompletionCallback
|
||||||
});
|
});
|
||||||
|
eventFinished = true;
|
||||||
// In case the completion callback is never called, we at least force it once.
|
// In case the completion callback is never called, we at least force it once.
|
||||||
getCompletionCallback()();
|
fallbackCompletion();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1864,7 +1964,8 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
if (lastDrawn.length > 1 &&
|
if (lastDrawn.length > 1 &&
|
||||||
imageZoom > this.smoothTileEdgesMinZoom &&
|
imageZoom > this.smoothTileEdgesMinZoom &&
|
||||||
!this.iOSDevice &&
|
!this.iOSDevice &&
|
||||||
this.getRotation(true) % 360 === 0 && // TODO: support tile edge smoothing with tiled image rotation.
|
this.getRotation(true) % 360 === 0 && // TODO: support tile edge smoothing with tiled image rotation (viewport rotation is not a problem).
|
||||||
|
this._drawer.viewer.viewport.getFlip() === false && // TODO: support tile edge smoothing with viewport flip (tiled image flip is not a problem).
|
||||||
$.supportsCanvas && this.viewer.useCanvas) {
|
$.supportsCanvas && this.viewer.useCanvas) {
|
||||||
// When zoomed in a lot (>100%) the tile edges are visible.
|
// When zoomed in a lot (>100%) the tile edges are visible.
|
||||||
// So we have to composite them at ~100% and scale them up together.
|
// So we have to composite them at ~100% and scale them up together.
|
||||||
@ -1954,6 +2055,9 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|||||||
if (sketchScale) {
|
if (sketchScale) {
|
||||||
clipPoint = clipPoint.times(sketchScale);
|
clipPoint = clipPoint.times(sketchScale);
|
||||||
}
|
}
|
||||||
|
if (sketchTranslate) {
|
||||||
|
clipPoint = clipPoint.plus(sketchTranslate);
|
||||||
|
}
|
||||||
return clipPoint;
|
return clipPoint;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - TileSource
|
* OpenSeadragon - TileSource
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -618,7 +618,7 @@ $.TileSource.prototype = {
|
|||||||
* @param {Number} level
|
* @param {Number} level
|
||||||
* @param {Number} x
|
* @param {Number} x
|
||||||
* @param {Number} y
|
* @param {Number} y
|
||||||
* @returns {String|() => string} url - A string for the url or a function that returns a url string.
|
* @returns {String|Function} url - A string for the url or a function that returns a url string.
|
||||||
* @throws {Error}
|
* @throws {Error}
|
||||||
*/
|
*/
|
||||||
getTileUrl: function( level, x, y ) {
|
getTileUrl: function( level, x, y ) {
|
||||||
@ -663,6 +663,11 @@ $.TileSource.prototype = {
|
|||||||
* The headers returned here will override headers specified at the Viewer or TiledImage level.
|
* The headers returned here will override headers specified at the Viewer or TiledImage level.
|
||||||
* Specifying a falsy value for a header will clear its existing value set at the Viewer or
|
* Specifying a falsy value for a header will clear its existing value set at the Viewer or
|
||||||
* TiledImage level (if any).
|
* TiledImage level (if any).
|
||||||
|
*
|
||||||
|
* Note that the headers of existing tiles don't automatically change when this function
|
||||||
|
* returns updated headers. To do that, you need to call {@link OpenSeadragon.Viewer#setAjaxHeaders}
|
||||||
|
* and propagate the changes.
|
||||||
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {Number} level
|
* @param {Number} level
|
||||||
* @param {Number} x
|
* @param {Number} x
|
||||||
@ -932,7 +937,7 @@ function processResponse( xhr ){
|
|||||||
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 :
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - TileSourceCollection
|
* OpenSeadragon - TileSourceCollection
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - TmsTileSource
|
* OpenSeadragon - TmsTileSource
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
344
src/viewer.js
344
src/viewer.js
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Viewer
|
* OpenSeadragon - Viewer
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -204,6 +204,8 @@ $.Viewer = function( options ) {
|
|||||||
prevContainerSize: null,
|
prevContainerSize: null,
|
||||||
animating: false,
|
animating: false,
|
||||||
forceRedraw: false,
|
forceRedraw: false,
|
||||||
|
needsResize: false,
|
||||||
|
forceResize: false,
|
||||||
mouseInside: false,
|
mouseInside: false,
|
||||||
group: null,
|
group: null,
|
||||||
// whether we should be continuously zooming
|
// whether we should be continuously zooming
|
||||||
@ -306,7 +308,9 @@ $.Viewer = function( options ) {
|
|||||||
nonPrimaryPressHandler: $.delegate( this, onCanvasNonPrimaryPress ),
|
nonPrimaryPressHandler: $.delegate( this, onCanvasNonPrimaryPress ),
|
||||||
nonPrimaryReleaseHandler: $.delegate( this, onCanvasNonPrimaryRelease ),
|
nonPrimaryReleaseHandler: $.delegate( this, onCanvasNonPrimaryRelease ),
|
||||||
scrollHandler: $.delegate( this, onCanvasScroll ),
|
scrollHandler: $.delegate( this, onCanvasScroll ),
|
||||||
pinchHandler: $.delegate( this, onCanvasPinch )
|
pinchHandler: $.delegate( this, onCanvasPinch ),
|
||||||
|
focusHandler: $.delegate( this, onCanvasFocus ),
|
||||||
|
blurHandler: $.delegate( this, onCanvasBlur ),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.outerTracker = new $.MouseTracker({
|
this.outerTracker = new $.MouseTracker({
|
||||||
@ -330,6 +334,17 @@ $.Viewer = function( options ) {
|
|||||||
|
|
||||||
THIS[ this.hash ].prevContainerSize = _getSafeElemSize( this.container );
|
THIS[ this.hash ].prevContainerSize = _getSafeElemSize( this.container );
|
||||||
|
|
||||||
|
if(window.ResizeObserver){
|
||||||
|
this._autoResizePolling = false;
|
||||||
|
this._resizeObserver = new ResizeObserver(function(){
|
||||||
|
THIS[_this.hash].needsResize = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
this._resizeObserver.observe(this.container, {});
|
||||||
|
} else {
|
||||||
|
this._autoResizePolling = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Create the world
|
// Create the world
|
||||||
this.world = new $.World({
|
this.world = new $.World({
|
||||||
viewer: this
|
viewer: this
|
||||||
@ -395,7 +410,9 @@ $.Viewer = function( options ) {
|
|||||||
// Create the image loader
|
// Create the image loader
|
||||||
this.imageLoader = new $.ImageLoader({
|
this.imageLoader = new $.ImageLoader({
|
||||||
jobLimit: this.imageLoaderLimit,
|
jobLimit: this.imageLoaderLimit,
|
||||||
timeout: options.timeout
|
timeout: options.timeout,
|
||||||
|
tileRetryMax: this.tileRetryMax,
|
||||||
|
tileRetryDelay: this.tileRetryDelay
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create the tile cache
|
// Create the tile cache
|
||||||
@ -788,6 +805,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
//TODO: implement this...
|
//TODO: implement this...
|
||||||
//this.unbindSequenceControls()
|
//this.unbindSequenceControls()
|
||||||
//this.unbindStandardControls()
|
//this.unbindStandardControls()
|
||||||
|
if (this._resizeObserver){
|
||||||
|
this._resizeObserver.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
if (this.referenceStrip) {
|
if (this.referenceStrip) {
|
||||||
this.referenceStrip.destroy();
|
this.referenceStrip.destroy();
|
||||||
@ -948,7 +968,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
* Turns debugging mode on or off for this viewer.
|
* Turns debugging mode on or off for this viewer.
|
||||||
*
|
*
|
||||||
* @function
|
* @function
|
||||||
* @param {Boolean} true to turn debug on, false to turn debug off.
|
* @param {Boolean} debugMode true to turn debug on, false to turn debug off.
|
||||||
*/
|
*/
|
||||||
setDebugMode: function(debugMode){
|
setDebugMode: function(debugMode){
|
||||||
|
|
||||||
@ -960,6 +980,63 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
this.forceRedraw();
|
this.forceRedraw();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update headers to include when making AJAX requests.
|
||||||
|
*
|
||||||
|
* Unless `propagate` is set to false (which is likely only useful in rare circumstances),
|
||||||
|
* the updated headers are propagated to all tiled images, each of which will subsequently
|
||||||
|
* propagate the changed headers to all their tiles.
|
||||||
|
* If applicable, the headers of the viewer's navigator and reference strip will also be updated.
|
||||||
|
*
|
||||||
|
* Note that the rules for merging headers still apply, i.e. headers returned by
|
||||||
|
* {@link OpenSeadragon.TileSource#getTileAjaxHeaders} take precedence over
|
||||||
|
* `TiledImage.ajaxHeaders`, which take precedence over the headers here in the viewer.
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {Object} ajaxHeaders Updated AJAX headers.
|
||||||
|
* @param {Boolean} [propagate=true] Whether to propagate updated headers to tiled images, etc.
|
||||||
|
*/
|
||||||
|
setAjaxHeaders: function(ajaxHeaders, propagate) {
|
||||||
|
if (ajaxHeaders === null) {
|
||||||
|
ajaxHeaders = {};
|
||||||
|
}
|
||||||
|
if (!$.isPlainObject(ajaxHeaders)) {
|
||||||
|
console.error('[Viewer.setAjaxHeaders] Ignoring invalid headers, must be a plain object');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (propagate === undefined) {
|
||||||
|
propagate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ajaxHeaders = ajaxHeaders;
|
||||||
|
|
||||||
|
if (propagate) {
|
||||||
|
for (var i = 0; i < this.world.getItemCount(); i++) {
|
||||||
|
this.world.getItemAt(i)._updateAjaxHeaders(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.navigator) {
|
||||||
|
this.navigator.setAjaxHeaders(this.ajaxHeaders, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.referenceStrip && this.referenceStrip.miniViewers) {
|
||||||
|
for (var key in this.referenceStrip.miniViewers) {
|
||||||
|
this.referenceStrip.miniViewers[key].setAjaxHeaders(this.ajaxHeaders, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the given button to this viewer.
|
||||||
|
*
|
||||||
|
* @function
|
||||||
|
* @param {OpenSeadragon.Button} button
|
||||||
|
*/
|
||||||
|
addButton: function( button ){
|
||||||
|
this.buttonGroup.addButton(button);
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
* @returns {Boolean}
|
* @returns {Boolean}
|
||||||
@ -1374,7 +1451,6 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
* A set of headers to include when making tile AJAX requests.
|
* A set of headers to include when making tile AJAX requests.
|
||||||
* Note that these headers will be merged over any headers specified in {@link OpenSeadragon.Options}.
|
* Note that these headers will be merged over any headers specified in {@link OpenSeadragon.Options}.
|
||||||
* Specifying a falsy value for a header will clear its existing value set at the Viewer level (if any).
|
* Specifying a falsy value for a header will clear its existing value set at the Viewer level (if any).
|
||||||
* requests.
|
|
||||||
* @param {Function} [options.success] A function that gets called when the image is
|
* @param {Function} [options.success] A function that gets called when the image is
|
||||||
* successfully added. It's passed the event object which contains a single property:
|
* successfully added. It's passed the event object which contains a single property:
|
||||||
* "item", which is the resulting instance of TiledImage.
|
* "item", which is the resulting instance of TiledImage.
|
||||||
@ -1422,10 +1498,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
if (options.loadTilesWithAjax === undefined) {
|
if (options.loadTilesWithAjax === undefined) {
|
||||||
options.loadTilesWithAjax = this.loadTilesWithAjax;
|
options.loadTilesWithAjax = this.loadTilesWithAjax;
|
||||||
}
|
}
|
||||||
if (options.ajaxHeaders === undefined || options.ajaxHeaders === null) {
|
if (!$.isPlainObject(options.ajaxHeaders)) {
|
||||||
options.ajaxHeaders = this.ajaxHeaders;
|
options.ajaxHeaders = {};
|
||||||
} else if ($.isPlainObject(options.ajaxHeaders) && $.isPlainObject(this.ajaxHeaders)) {
|
|
||||||
options.ajaxHeaders = $.extend({}, this.ajaxHeaders, options.ajaxHeaders);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var myQueueItem = {
|
var myQueueItem = {
|
||||||
@ -1682,6 +1756,14 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Force the viewer to reset its size to match its container.
|
||||||
|
*/
|
||||||
|
forceResize: function() {
|
||||||
|
THIS[this.hash].needsResize = true;
|
||||||
|
THIS[this.hash].forceResize = true;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @function
|
* @function
|
||||||
* @returns {OpenSeadragon.Viewer} Chainable.
|
* @returns {OpenSeadragon.Viewer} Chainable.
|
||||||
@ -2733,7 +2815,7 @@ function onCanvasKeyDown( event ) {
|
|||||||
|
|
||||||
if ( !canvasKeyDownEventArgs.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {
|
if ( !canvasKeyDownEventArgs.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {
|
||||||
switch( event.keyCode ){
|
switch( event.keyCode ){
|
||||||
case 38://up arrow
|
case 38://up arrow/shift uparrow
|
||||||
if (!canvasKeyDownEventArgs.preventVerticalPan) {
|
if (!canvasKeyDownEventArgs.preventVerticalPan) {
|
||||||
if ( event.shift ) {
|
if ( event.shift ) {
|
||||||
this.viewport.zoomBy(1.1);
|
this.viewport.zoomBy(1.1);
|
||||||
@ -2744,7 +2826,7 @@ function onCanvasKeyDown( event ) {
|
|||||||
}
|
}
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
break;
|
break;
|
||||||
case 40://down arrow
|
case 40://down arrow/shift downarrow
|
||||||
if (!canvasKeyDownEventArgs.preventVerticalPan) {
|
if (!canvasKeyDownEventArgs.preventVerticalPan) {
|
||||||
if ( event.shift ) {
|
if ( event.shift ) {
|
||||||
this.viewport.zoomBy(0.9);
|
this.viewport.zoomBy(0.9);
|
||||||
@ -2769,35 +2851,12 @@ function onCanvasKeyDown( event ) {
|
|||||||
}
|
}
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
break;
|
break;
|
||||||
default:
|
case 187://=|+
|
||||||
//console.log( 'navigator keycode %s', event.keyCode );
|
|
||||||
event.preventDefault = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
event.preventDefault = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function onCanvasKeyPress( event ) {
|
|
||||||
var canvasKeyPressEventArgs = {
|
|
||||||
originalEvent: event.originalEvent,
|
|
||||||
preventDefaultAction: false,
|
|
||||||
preventVerticalPan: event.preventVerticalPan || !this.panVertical,
|
|
||||||
preventHorizontalPan: event.preventHorizontalPan || !this.panHorizontal
|
|
||||||
};
|
|
||||||
|
|
||||||
// This event is documented in onCanvasKeyDown
|
|
||||||
this.raiseEvent('canvas-key', canvasKeyPressEventArgs);
|
|
||||||
|
|
||||||
if ( !canvasKeyPressEventArgs.preventDefaultAction && !event.ctrl && !event.alt && !event.meta ) {
|
|
||||||
switch( event.keyCode ){
|
|
||||||
case 43://=|+
|
|
||||||
case 61://=|+
|
|
||||||
this.viewport.zoomBy(1.1);
|
this.viewport.zoomBy(1.1);
|
||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
break;
|
break;
|
||||||
case 45://-|_
|
case 189://-|_
|
||||||
this.viewport.zoomBy(0.9);
|
this.viewport.zoomBy(0.9);
|
||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
@ -2807,74 +2866,71 @@ function onCanvasKeyPress( event ) {
|
|||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
break;
|
break;
|
||||||
case 119://w
|
case 87://W/w
|
||||||
case 87://W
|
if (!canvasKeyDownEventArgs.preventVerticalPan) {
|
||||||
if (!canvasKeyPressEventArgs.preventVerticalPan) {
|
|
||||||
if ( event.shift ) {
|
if ( event.shift ) {
|
||||||
this.viewport.zoomBy(1.1);
|
this.viewport.zoomBy(1.1);
|
||||||
} else {
|
} else {
|
||||||
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(0, -40)));
|
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(0, -40)));
|
||||||
}
|
}
|
||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
}
|
|
||||||
event.preventDefault = true;
|
|
||||||
break;
|
|
||||||
case 115://s
|
|
||||||
case 83://S
|
|
||||||
if (!canvasKeyPressEventArgs.preventVerticalPan) {
|
|
||||||
if ( event.shift ) {
|
|
||||||
this.viewport.zoomBy(0.9);
|
|
||||||
} else {
|
|
||||||
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(0, 40)));
|
|
||||||
}
|
|
||||||
this.viewport.applyConstraints();
|
|
||||||
}
|
}
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
break;
|
break;
|
||||||
case 97://a
|
case 83://S/s
|
||||||
if (!canvasKeyPressEventArgs.preventHorizontalPan) {
|
if (!canvasKeyDownEventArgs.preventVerticalPan) {
|
||||||
|
if ( event.shift ) {
|
||||||
|
this.viewport.zoomBy(0.9);
|
||||||
|
} else {
|
||||||
|
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(0, 40)));
|
||||||
|
}
|
||||||
|
this.viewport.applyConstraints();
|
||||||
|
}
|
||||||
|
event.preventDefault = true;
|
||||||
|
break;
|
||||||
|
case 65://a/A
|
||||||
|
if (!canvasKeyDownEventArgs.preventHorizontalPan) {
|
||||||
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(-40, 0)));
|
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(-40, 0)));
|
||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
}
|
}
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
break;
|
break;
|
||||||
case 100://d
|
case 68://d/D
|
||||||
if (!canvasKeyPressEventArgs.preventHorizontalPan) {
|
if (!canvasKeyDownEventArgs.preventHorizontalPan) {
|
||||||
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(40, 0)));
|
this.viewport.panBy(this.viewport.deltaPointsFromPixels(new $.Point(40, 0)));
|
||||||
this.viewport.applyConstraints();
|
this.viewport.applyConstraints();
|
||||||
}
|
}
|
||||||
event.preventDefault = true;
|
event.preventDefault = true;
|
||||||
break;
|
break;
|
||||||
case 114: //r - clockwise rotation
|
case 82: //r - clockwise rotation/R - counterclockwise rotation
|
||||||
if(this.viewport.flipped){
|
if(event.shift){
|
||||||
this.viewport.setRotation(this.viewport.getRotation() - this.rotationIncrement);
|
if(this.viewport.flipped){
|
||||||
} else{
|
this.viewport.setRotation(this.viewport.getRotation() + this.rotationIncrement);
|
||||||
this.viewport.setRotation(this.viewport.getRotation() + this.rotationIncrement);
|
} else{
|
||||||
}
|
this.viewport.setRotation(this.viewport.getRotation() - this.rotationIncrement);
|
||||||
this.viewport.applyConstraints();
|
}
|
||||||
event.preventDefault = true;
|
}else{
|
||||||
break;
|
if(this.viewport.flipped){
|
||||||
case 82: //R - counterclockwise rotation
|
this.viewport.setRotation(this.viewport.getRotation() - this.rotationIncrement);
|
||||||
if(this.viewport.flipped){
|
} else{
|
||||||
this.viewport.setRotation(this.viewport.getRotation() + this.rotationIncrement);
|
this.viewport.setRotation(this.viewport.getRotation() + this.rotationIncrement);
|
||||||
} else{
|
}
|
||||||
this.viewport.setRotation(this.viewport.getRotation() - this.rotationIncrement);
|
}
|
||||||
}
|
this.viewport.applyConstraints();
|
||||||
this.viewport.applyConstraints();
|
event.preventDefault = true;
|
||||||
event.preventDefault = true;
|
break;
|
||||||
break;
|
case 70: //f/F
|
||||||
case 102: //f
|
this.viewport.toggleFlip();
|
||||||
this.viewport.toggleFlip();
|
event.preventDefault = true;
|
||||||
event.preventDefault = true;
|
break;
|
||||||
break;
|
case 74: //j - previous image source
|
||||||
case 106: //j - previous image source
|
this.goToPreviousPage();
|
||||||
this.goToPreviousPage();
|
break;
|
||||||
break;
|
case 75: //k - next image source
|
||||||
case 107: //k - next image source
|
this.goToNextPage();
|
||||||
this.goToNextPage();
|
break;
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
// console.log( 'navigator keycode %s', event.keyCode );
|
//console.log( 'navigator keycode %s', event.keyCode );
|
||||||
event.preventDefault = false;
|
event.preventDefault = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2883,7 +2939,24 @@ function onCanvasKeyPress( event ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onCanvasKeyPress( event ) {
|
||||||
|
var canvasKeyPressEventArgs = {
|
||||||
|
originalEvent: event.originalEvent,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raised when a keyboard key is pressed and the focus is on the {@link OpenSeadragon.Viewer#canvas} element.
|
||||||
|
*
|
||||||
|
* @event canvas-key-press
|
||||||
|
* @memberof OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
||||||
|
* @property {Object} originalEvent - The original DOM event.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
|
||||||
|
this.raiseEvent('canvas-key-press', canvasKeyPressEventArgs);
|
||||||
|
}
|
||||||
|
|
||||||
function onCanvasClick( event ) {
|
function onCanvasClick( event ) {
|
||||||
var gestureSettings;
|
var gestureSettings;
|
||||||
@ -3051,17 +3124,16 @@ function onCanvasDrag( event ) {
|
|||||||
this.viewport.centerSpringX.target.value += delta.x;
|
this.viewport.centerSpringX.target.value += delta.x;
|
||||||
this.viewport.centerSpringY.target.value += delta.y;
|
this.viewport.centerSpringY.target.value += delta.y;
|
||||||
|
|
||||||
var bounds = this.viewport.getBounds();
|
|
||||||
var constrainedBounds = this.viewport.getConstrainedBounds();
|
var constrainedBounds = this.viewport.getConstrainedBounds();
|
||||||
|
|
||||||
this.viewport.centerSpringX.target.value -= delta.x;
|
this.viewport.centerSpringX.target.value -= delta.x;
|
||||||
this.viewport.centerSpringY.target.value -= delta.y;
|
this.viewport.centerSpringY.target.value -= delta.y;
|
||||||
|
|
||||||
if (bounds.x !== constrainedBounds.x) {
|
if (constrainedBounds.xConstrained) {
|
||||||
event.delta.x = 0;
|
event.delta.x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bounds.y !== constrainedBounds.y) {
|
if (constrainedBounds.yConstrained) {
|
||||||
event.delta.y = 0;
|
event.delta.y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3396,11 +3468,49 @@ function onCanvasPinch( event ) {
|
|||||||
event.gesturePoints[0].currentPos.x - event.gesturePoints[1].currentPos.x);
|
event.gesturePoints[0].currentPos.x - event.gesturePoints[1].currentPos.x);
|
||||||
var angle2 = Math.atan2(event.gesturePoints[0].lastPos.y - event.gesturePoints[1].lastPos.y,
|
var angle2 = Math.atan2(event.gesturePoints[0].lastPos.y - event.gesturePoints[1].lastPos.y,
|
||||||
event.gesturePoints[0].lastPos.x - event.gesturePoints[1].lastPos.x);
|
event.gesturePoints[0].lastPos.x - event.gesturePoints[1].lastPos.x);
|
||||||
this.viewport.setRotation(this.viewport.getRotation() + ((angle1 - angle2) * (180 / Math.PI)));
|
centerPt = this.viewport.pointFromPixel( event.center, true );
|
||||||
|
this.viewport.rotateTo(this.viewport.getRotation(true) + ((angle1 - angle2) * (180 / Math.PI)), centerPt, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onCanvasFocus( event ) {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Raised when the {@link OpenSeadragon.Viewer#canvas} element gets keyboard focus.
|
||||||
|
*
|
||||||
|
* @event canvas-focus
|
||||||
|
* @memberof OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
||||||
|
* @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.
|
||||||
|
* @property {Object} originalEvent - The original DOM event.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
this.raiseEvent( 'canvas-focus', {
|
||||||
|
tracker: event.eventSource,
|
||||||
|
originalEvent: event.originalEvent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCanvasBlur( event ) {
|
||||||
|
/**
|
||||||
|
* Raised when the {@link OpenSeadragon.Viewer#canvas} element loses keyboard focus.
|
||||||
|
*
|
||||||
|
* @event canvas-blur
|
||||||
|
* @memberof OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
||||||
|
* @property {OpenSeadragon.MouseTracker} tracker - A reference to the MouseTracker which originated this event.
|
||||||
|
* @property {Object} originalEvent - The original DOM event.
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
this.raiseEvent( 'canvas-blur', {
|
||||||
|
tracker: event.eventSource,
|
||||||
|
originalEvent: event.originalEvent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function onCanvasScroll( event ) {
|
function onCanvasScroll( event ) {
|
||||||
var canvasScrollEventArgs,
|
var canvasScrollEventArgs,
|
||||||
gestureSettings,
|
gestureSettings,
|
||||||
@ -3550,6 +3660,27 @@ function updateMulti( viewer ) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function doViewerResize(viewer, containerSize){
|
||||||
|
var viewport = viewer.viewport;
|
||||||
|
var zoom = viewport.getZoom();
|
||||||
|
var center = viewport.getCenter();
|
||||||
|
viewport.resize(containerSize, viewer.preserveImageSizeOnResize);
|
||||||
|
viewport.panTo(center, true);
|
||||||
|
var resizeRatio;
|
||||||
|
if (viewer.preserveImageSizeOnResize) {
|
||||||
|
resizeRatio = THIS[viewer.hash].prevContainerSize.x / containerSize.x;
|
||||||
|
} else {
|
||||||
|
var origin = new $.Point(0, 0);
|
||||||
|
var prevDiag = new $.Point(THIS[viewer.hash].prevContainerSize.x, THIS[viewer.hash].prevContainerSize.y).distanceTo(origin);
|
||||||
|
var newDiag = new $.Point(containerSize.x, containerSize.y).distanceTo(origin);
|
||||||
|
resizeRatio = newDiag / prevDiag * THIS[viewer.hash].prevContainerSize.x / containerSize.x;
|
||||||
|
}
|
||||||
|
viewport.zoomTo(zoom * resizeRatio, null, true);
|
||||||
|
THIS[viewer.hash].prevContainerSize = containerSize;
|
||||||
|
THIS[viewer.hash].forceRedraw = true;
|
||||||
|
THIS[viewer.hash].needsResize = false;
|
||||||
|
THIS[viewer.hash].forceResize = false;
|
||||||
|
}
|
||||||
function updateOnce( viewer ) {
|
function updateOnce( viewer ) {
|
||||||
|
|
||||||
//viewer.profiler.beginUpdate();
|
//viewer.profiler.beginUpdate();
|
||||||
@ -3557,30 +3688,23 @@ function updateOnce( viewer ) {
|
|||||||
if (viewer._opening || !THIS[viewer.hash]) {
|
if (viewer._opening || !THIS[viewer.hash]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (viewer.autoResize || THIS[viewer.hash].forceResize){
|
||||||
if (viewer.autoResize) {
|
var containerSize;
|
||||||
var containerSize = _getSafeElemSize(viewer.container);
|
if(viewer._autoResizePolling){
|
||||||
var prevContainerSize = THIS[viewer.hash].prevContainerSize;
|
containerSize = _getSafeElemSize(viewer.container);
|
||||||
if (!containerSize.equals(prevContainerSize)) {
|
var prevContainerSize = THIS[viewer.hash].prevContainerSize;
|
||||||
var viewport = viewer.viewport;
|
if (!containerSize.equals(prevContainerSize)) {
|
||||||
if (viewer.preserveImageSizeOnResize) {
|
THIS[viewer.hash].needsResize = true;
|
||||||
var resizeRatio = prevContainerSize.x / containerSize.x;
|
|
||||||
var zoom = viewport.getZoom() * resizeRatio;
|
|
||||||
var center = viewport.getCenter();
|
|
||||||
viewport.resize(containerSize, false);
|
|
||||||
viewport.zoomTo(zoom, null, true);
|
|
||||||
viewport.panTo(center, true);
|
|
||||||
} else {
|
|
||||||
// maintain image position
|
|
||||||
var oldBounds = viewport.getBounds();
|
|
||||||
viewport.resize(containerSize, true);
|
|
||||||
viewport.fitBoundsWithConstraints(oldBounds, true);
|
|
||||||
}
|
}
|
||||||
THIS[viewer.hash].prevContainerSize = containerSize;
|
|
||||||
THIS[viewer.hash].forceRedraw = true;
|
|
||||||
}
|
}
|
||||||
|
if(THIS[viewer.hash].needsResize){
|
||||||
|
doViewerResize(viewer, containerSize || _getSafeElemSize(viewer.container));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var viewportChange = viewer.viewport.update();
|
var viewportChange = viewer.viewport.update();
|
||||||
var animated = viewer.world.update() || viewportChange;
|
var animated = viewer.world.update() || viewportChange;
|
||||||
|
|
||||||
|
162
src/viewport.js
162
src/viewport.js
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - Viewport
|
* OpenSeadragon - Viewport
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
@ -483,7 +483,7 @@ $.Viewport.prototype = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
newZoomPixel = this._pixelFromPoint(this.zoomPoint, bounds);
|
newZoomPixel = this._pixelFromPoint(this.zoomPoint, bounds);
|
||||||
deltaZoomPixels = newZoomPixel.minus( oldZoomPixel );
|
deltaZoomPixels = newZoomPixel.minus( oldZoomPixel ).rotate(-this.getRotation(true));
|
||||||
deltaZoomPoints = deltaZoomPixels.divide( this._containerInnerSize.x * zoom );
|
deltaZoomPoints = deltaZoomPixels.divide( this._containerInnerSize.x * zoom );
|
||||||
|
|
||||||
return centerTarget.plus( deltaZoomPoints );
|
return centerTarget.plus( deltaZoomPoints );
|
||||||
@ -514,34 +514,37 @@ $.Viewport.prototype = {
|
|||||||
* @param {OpenSeadragon.Rect} bounds
|
* @param {OpenSeadragon.Rect} bounds
|
||||||
* @returns {OpenSeadragon.Rect} constrained bounds.
|
* @returns {OpenSeadragon.Rect} constrained bounds.
|
||||||
*/
|
*/
|
||||||
_applyBoundaryConstraints: function(bounds) {
|
_applyBoundaryConstraints: function(bounds) {
|
||||||
var newBounds = new $.Rect(
|
var newBounds = this.viewportToViewerElementRectangle(bounds).getBoundingBox();
|
||||||
bounds.x,
|
var cb = this.viewportToViewerElementRectangle(this._contentBoundsNoRotate).getBoundingBox();
|
||||||
bounds.y,
|
|
||||||
bounds.width,
|
var xConstrained = false;
|
||||||
bounds.height);
|
var yConstrained = false;
|
||||||
|
|
||||||
if (this.wrapHorizontal) {
|
if (this.wrapHorizontal) {
|
||||||
//do nothing
|
//do nothing
|
||||||
} else {
|
} else {
|
||||||
var boundsRight = newBounds.x + newBounds.width;
|
var boundsRight = newBounds.x + newBounds.width;
|
||||||
var contentRight = this._contentBoundsNoRotate.x + this._contentBoundsNoRotate.width;
|
var contentRight = cb.x + cb.width;
|
||||||
|
|
||||||
var horizontalThreshold, leftDx, rightDx;
|
var horizontalThreshold, leftDx, rightDx;
|
||||||
if (newBounds.width > this._contentBoundsNoRotate.width) {
|
if (newBounds.width > cb.width) {
|
||||||
horizontalThreshold = this.visibilityRatio * this._contentBoundsNoRotate.width;
|
horizontalThreshold = this.visibilityRatio * cb.width;
|
||||||
} else {
|
} else {
|
||||||
horizontalThreshold = this.visibilityRatio * newBounds.width;
|
horizontalThreshold = this.visibilityRatio * newBounds.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
leftDx = this._contentBoundsNoRotate.x - boundsRight + horizontalThreshold;
|
leftDx = cb.x - boundsRight + horizontalThreshold;
|
||||||
rightDx = contentRight - newBounds.x - horizontalThreshold;
|
rightDx = contentRight - newBounds.x - horizontalThreshold;
|
||||||
if (horizontalThreshold > this._contentBoundsNoRotate.width) {
|
if (horizontalThreshold > cb.width) {
|
||||||
newBounds.x += (leftDx + rightDx) / 2;
|
newBounds.x += (leftDx + rightDx) / 2;
|
||||||
|
xConstrained = true;
|
||||||
} else if (rightDx < 0) {
|
} else if (rightDx < 0) {
|
||||||
newBounds.x += rightDx;
|
newBounds.x += rightDx;
|
||||||
|
xConstrained = true;
|
||||||
} else if (leftDx > 0) {
|
} else if (leftDx > 0) {
|
||||||
newBounds.x += leftDx;
|
newBounds.x += leftDx;
|
||||||
|
xConstrained = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -550,28 +553,37 @@ $.Viewport.prototype = {
|
|||||||
//do nothing
|
//do nothing
|
||||||
} else {
|
} else {
|
||||||
var boundsBottom = newBounds.y + newBounds.height;
|
var boundsBottom = newBounds.y + newBounds.height;
|
||||||
var contentBottom = this._contentBoundsNoRotate.y + this._contentBoundsNoRotate.height;
|
var contentBottom = cb.y + cb.height;
|
||||||
|
|
||||||
var verticalThreshold, topDy, bottomDy;
|
var verticalThreshold, topDy, bottomDy;
|
||||||
if (newBounds.height > this._contentBoundsNoRotate.height) {
|
if (newBounds.height > cb.height) {
|
||||||
verticalThreshold = this.visibilityRatio * this._contentBoundsNoRotate.height;
|
verticalThreshold = this.visibilityRatio * cb.height;
|
||||||
} else{
|
} else{
|
||||||
verticalThreshold = this.visibilityRatio * newBounds.height;
|
verticalThreshold = this.visibilityRatio * newBounds.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
topDy = this._contentBoundsNoRotate.y - boundsBottom + verticalThreshold;
|
topDy = cb.y - boundsBottom + verticalThreshold;
|
||||||
bottomDy = contentBottom - newBounds.y - verticalThreshold;
|
bottomDy = contentBottom - newBounds.y - verticalThreshold;
|
||||||
if (verticalThreshold > this._contentBoundsNoRotate.height) {
|
if (verticalThreshold > cb.height) {
|
||||||
newBounds.y += (topDy + bottomDy) / 2;
|
newBounds.y += (topDy + bottomDy) / 2;
|
||||||
|
yConstrained = true;
|
||||||
} else if (bottomDy < 0) {
|
} else if (bottomDy < 0) {
|
||||||
newBounds.y += bottomDy;
|
newBounds.y += bottomDy;
|
||||||
|
yConstrained = true;
|
||||||
} else if (topDy > 0) {
|
} else if (topDy > 0) {
|
||||||
newBounds.y += topDy;
|
newBounds.y += topDy;
|
||||||
|
yConstrained = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return newBounds;
|
var constraintApplied = xConstrained || yConstrained;
|
||||||
|
var newViewportBounds = constraintApplied ? this.viewerElementToViewportRectangle(newBounds) : bounds.clone();
|
||||||
|
newViewportBounds.xConstrained = xConstrained;
|
||||||
|
newViewportBounds.yConstrained = yConstrained;
|
||||||
|
newViewportBounds.constraintApplied = constraintApplied;
|
||||||
|
|
||||||
|
return newViewportBounds;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -605,7 +617,7 @@ $.Viewport.prototype = {
|
|||||||
* @function
|
* @function
|
||||||
* @param {Boolean} [immediately=false]
|
* @param {Boolean} [immediately=false]
|
||||||
* @returns {OpenSeadragon.Viewport} Chainable.
|
* @returns {OpenSeadragon.Viewport} Chainable.
|
||||||
* @fires OpenSeadragon.Viewer.event:constrain
|
* @fires OpenSeadragon.Viewer.event:constrain if constraints were applied
|
||||||
*/
|
*/
|
||||||
applyConstraints: function(immediately) {
|
applyConstraints: function(immediately) {
|
||||||
var actualZoom = this.getZoom();
|
var actualZoom = this.getZoom();
|
||||||
@ -615,17 +627,13 @@ $.Viewport.prototype = {
|
|||||||
this.zoomTo(constrainedZoom, this.zoomPoint, immediately);
|
this.zoomTo(constrainedZoom, this.zoomPoint, immediately);
|
||||||
}
|
}
|
||||||
|
|
||||||
var bounds = this.getBoundsNoRotate();
|
var constrainedBounds = this.getConstrainedBounds(false);
|
||||||
var constrainedBounds = this._applyBoundaryConstraints(bounds);
|
|
||||||
this._raiseConstraintsEvent(immediately);
|
|
||||||
|
|
||||||
if (bounds.x !== constrainedBounds.x ||
|
if(constrainedBounds.constraintApplied){
|
||||||
bounds.y !== constrainedBounds.y ||
|
this.fitBounds(constrainedBounds, immediately);
|
||||||
immediately) {
|
this._raiseConstraintsEvent(immediately);
|
||||||
this.fitBounds(
|
|
||||||
constrainedBounds.rotate(-this.getRotation(true)),
|
|
||||||
immediately);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -675,45 +683,53 @@ $.Viewport.prototype = {
|
|||||||
newBounds.y = center.y - newBounds.height / 2;
|
newBounds.y = center.y - newBounds.height / 2;
|
||||||
var newZoom = 1.0 / newBounds.width;
|
var newZoom = 1.0 / newBounds.width;
|
||||||
|
|
||||||
if (constraints) {
|
|
||||||
var newBoundsAspectRatio = newBounds.getAspectRatio();
|
|
||||||
var newConstrainedZoom = this._applyZoomConstraints(newZoom);
|
|
||||||
|
|
||||||
if (newZoom !== newConstrainedZoom) {
|
|
||||||
newZoom = newConstrainedZoom;
|
|
||||||
newBounds.width = 1.0 / newZoom;
|
|
||||||
newBounds.x = center.x - newBounds.width / 2;
|
|
||||||
newBounds.height = newBounds.width / newBoundsAspectRatio;
|
|
||||||
newBounds.y = center.y - newBounds.height / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
newBounds = this._applyBoundaryConstraints(newBounds);
|
|
||||||
center = newBounds.getCenter();
|
|
||||||
this._raiseConstraintsEvent(immediately);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (immediately) {
|
if (immediately) {
|
||||||
this.panTo(center, true);
|
this.panTo(center, true);
|
||||||
return this.zoomTo(newZoom, null, true);
|
this.zoomTo(newZoom, null, true);
|
||||||
|
if(constraints){
|
||||||
|
this.applyConstraints(true);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.panTo(this.getCenter(true), true);
|
var currentCenter = this.getCenter(true);
|
||||||
this.zoomTo(this.getZoom(true), null, true);
|
var currentZoom = this.getZoom(true);
|
||||||
|
this.panTo(currentCenter, true);
|
||||||
|
this.zoomTo(currentZoom, null, true);
|
||||||
|
|
||||||
var oldBounds = this.getBounds();
|
var oldBounds = this.getBounds();
|
||||||
var oldZoom = this.getZoom();
|
var oldZoom = this.getZoom();
|
||||||
|
|
||||||
if (oldZoom === 0 || Math.abs(newZoom / oldZoom - 1) < 0.00000001) {
|
if (oldZoom === 0 || Math.abs(newZoom / oldZoom - 1) < 0.00000001) {
|
||||||
this.zoomTo(newZoom, true);
|
this.zoomTo(newZoom, null, true);
|
||||||
return this.panTo(center, immediately);
|
this.panTo(center, immediately);
|
||||||
|
if(constraints){
|
||||||
|
this.applyConstraints(false);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
newBounds = newBounds.rotate(-this.getRotation());
|
if(constraints){
|
||||||
var referencePoint = newBounds.getTopLeft().times(newZoom)
|
this.panTo(center, false);
|
||||||
.minus(oldBounds.getTopLeft().times(oldZoom))
|
|
||||||
.divide(newZoom - oldZoom);
|
|
||||||
|
|
||||||
return this.zoomTo(newZoom, referencePoint, immediately);
|
newZoom = this._applyZoomConstraints(newZoom);
|
||||||
|
this.zoomTo(newZoom, null, false);
|
||||||
|
|
||||||
|
var constrainedBounds = this.getConstrainedBounds();
|
||||||
|
|
||||||
|
this.panTo(currentCenter, true);
|
||||||
|
this.zoomTo(currentZoom, null, true);
|
||||||
|
|
||||||
|
this.fitBounds(constrainedBounds);
|
||||||
|
} else {
|
||||||
|
var rotatedNewBounds = newBounds.rotate(-this.getRotation());
|
||||||
|
var referencePoint = rotatedNewBounds.getTopLeft().times(newZoom)
|
||||||
|
.minus(oldBounds.getTopLeft().times(oldZoom))
|
||||||
|
.divide(newZoom - oldZoom);
|
||||||
|
|
||||||
|
this.zoomTo(newZoom, referencePoint, immediately);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -787,7 +803,10 @@ $.Viewport.prototype = {
|
|||||||
* Returns bounds taking constraints into account
|
* Returns bounds taking constraints into account
|
||||||
* Added to improve constrained panning
|
* Added to improve constrained panning
|
||||||
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
||||||
* @returns {OpenSeadragon.Viewport} Chainable.
|
* @returns {OpenSeadragon.Rect} The bounds in viewport coordinates after applying constraints. The returned $.Rect
|
||||||
|
* contains additional properties constraintsApplied, xConstrained and yConstrained.
|
||||||
|
* These flags indicate whether the viewport bounds were modified by the constraints
|
||||||
|
* of the viewer rectangle, and in which dimension(s).
|
||||||
*/
|
*/
|
||||||
getConstrainedBounds: function(current) {
|
getConstrainedBounds: function(current) {
|
||||||
var bounds,
|
var bounds,
|
||||||
@ -1059,7 +1078,10 @@ $.Viewport.prototype = {
|
|||||||
|
|
||||||
if( this.viewer ){
|
if( this.viewer ){
|
||||||
/**
|
/**
|
||||||
* Raised when the viewer is resized (see {@link OpenSeadragon.Viewport#resize}).
|
* Raised when a viewer resize operation is initiated (see {@link OpenSeadragon.Viewport#resize}).
|
||||||
|
* This event happens before the viewport bounds have been updated.
|
||||||
|
* See also {@link OpenSeadragon.Viewer#after-resize} which reflects
|
||||||
|
* the new viewport bounds following the resize action.
|
||||||
*
|
*
|
||||||
* @event resize
|
* @event resize
|
||||||
* @memberof OpenSeadragon.Viewer
|
* @memberof OpenSeadragon.Viewer
|
||||||
@ -1075,7 +1097,29 @@ $.Viewport.prototype = {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.fitBounds( newBounds, true );
|
var output = this.fitBounds( newBounds, true );
|
||||||
|
|
||||||
|
if( this.viewer ){
|
||||||
|
/**
|
||||||
|
* Raised after the viewer is resized (see {@link OpenSeadragon.Viewport#resize}).
|
||||||
|
* See also {@link OpenSeadragon.Viewer#resize} event which happens
|
||||||
|
* before the new bounds have been calculated and applied.
|
||||||
|
*
|
||||||
|
* @event after-resize
|
||||||
|
* @memberof OpenSeadragon.Viewer
|
||||||
|
* @type {object}
|
||||||
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
||||||
|
* @property {OpenSeadragon.Point} newContainerSize
|
||||||
|
* @property {Boolean} maintain
|
||||||
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
||||||
|
*/
|
||||||
|
this.viewer.raiseEvent( 'after-resize', {
|
||||||
|
newContainerSize: newContainerSize,
|
||||||
|
maintain: maintain
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
},
|
},
|
||||||
|
|
||||||
// private
|
// private
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* OpenSeadragon - World
|
* OpenSeadragon - World
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009 CodePlex Foundation
|
* Copyright (C) 2009 CodePlex Foundation
|
||||||
* Copyright (C) 2010-2022 OpenSeadragon contributors
|
* Copyright (C) 2010-2023 OpenSeadragon contributors
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>OpenSeadragon QUnit</title>
|
<title>OpenSeadragon QUnit</title>
|
||||||
<link rel="stylesheet" href="/node_modules/qunitjs/qunit/qunit.css">
|
<link rel="stylesheet" href="/node_modules/qunit/qunit/qunit.css">
|
||||||
<link rel="stylesheet" href="/test/lib/jquery-ui-1.10.2/css/smoothness/jquery-ui-1.10.2.min.css">
|
<link rel="stylesheet" href="/test/lib/jquery-ui-1.10.2/css/smoothness/jquery-ui-1.10.2.min.css">
|
||||||
<link rel="stylesheet" href="/test/helpers/test.css">
|
<link rel="stylesheet" href="/test/helpers/test.css">
|
||||||
</head>
|
</head>
|
||||||
@ -15,7 +15,7 @@
|
|||||||
var isCoverageTest = true;
|
var isCoverageTest = true;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script src="/node_modules/qunitjs/qunit/qunit.js"></script>
|
<script src="/node_modules/qunit/qunit/qunit.js"></script>
|
||||||
<script src="/test/lib/jquery-1.9.1.min.js"></script>
|
<script src="/test/lib/jquery-1.9.1.min.js"></script>
|
||||||
<script src="/test/lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js"></script>
|
<script src="/test/lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js"></script>
|
||||||
<script src="/test/lib/jquery.simulate.js"></script>
|
<script src="/test/lib/jquery.simulate.js"></script>
|
||||||
@ -65,6 +65,7 @@
|
|||||||
<!-- Polyfill must be inserted first because it is testing functions
|
<!-- Polyfill must be inserted first because it is testing functions
|
||||||
reassignments which could be done by other test. -->
|
reassignments which could be done by other test. -->
|
||||||
<script src="/test/modules/polyfills.js"></script>
|
<script src="/test/modules/polyfills.js"></script>
|
||||||
|
<script src="/test/modules/event-source.js"></script>
|
||||||
<script src="/test/modules/basic.js"></script>
|
<script src="/test/modules/basic.js"></script>
|
||||||
<script src="/test/modules/strings.js"></script>
|
<script src="/test/modules/strings.js"></script>
|
||||||
<script src="/test/modules/formats.js"></script>
|
<script src="/test/modules/formats.js"></script>
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
"jpg",
|
"jpg",
|
||||||
"png",
|
"png",
|
||||||
"gif"
|
"gif"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"xmp": "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\">\n <rdf:Description rdf:about=\"\"\n xmlns:xmp=\"http://ns.adobe.com/xap/1.0/\"\n xmlns:aux=\"http://ns.adobe.com/exif/1.0/aux/\"\n xmlns:photoshop=\"http://ns.adobe.com/photoshop/1.0/\"\n xmlns:Iptc4xmpCore=\"http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/\"\n xmlns:tiff=\"http://ns.adobe.com/tiff/1.0/\"\n xmlns:exif=\"http://ns.adobe.com/exif/1.0/\"\n xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n xmp:CreatorTool=\"Capture One 11 Macintosh\"\n xmp:CreateDate=\"2019-08-21T20:54:20\"\n xmp:Rating=\"4\"\n aux:SerialNumber=\"GP001601\"\n aux:ImageNumber=\"30012\"\n aux:Firmware=\"IQ280, Factory Firmware: 8.05.36\"\n photoshop:CaptionWriter=\"\"\n photoshop:Headline=\"\"\n photoshop:City=\"\"\n photoshop:State=\"\"\n photoshop:Country=\"\"\n photoshop:Source=\"\"\n photoshop:Instructions=\"\"\n photoshop:AuthorsPosition=\"\"\n photoshop:TransmissionReference=\"\"\n photoshop:Credit=\"\"\n photoshop:LegacyIPTCDigest=\"B135BFFD6A4CFB049F834A3F370A9AE3\"\n photoshop:DateCreated=\"2019-08-21T20:54:20\"\n Iptc4xmpCore:Location=\"\"\n Iptc4xmpCore:IntellectualGenre=\"\"\n Iptc4xmpCore:CountryCode=\"\"\n tiff:ImageWidth=\"2088\"\n tiff:ImageLength=\"3000\"\n tiff:Compression=\"1\"\n tiff:PhotometricInterpretation=\"2\"\n tiff:Orientation=\"1\"\n tiff:SamplesPerPixel=\"3\"\n tiff:PlanarConfiguration=\"1\"\n tiff:XResolution=\"400/1\"\n tiff:YResolution=\"400/1\"\n tiff:ResolutionUnit=\"2\"\n tiff:Make=\"Phase One\"\n tiff:Model=\"IQ280\"\n tiff:Software=\"Capture One 11 Macintosh\"\n exif:ExifVersion=\"0230\"\n exif:PixelXDimension=\"2088\"\n exif:PixelYDimension=\"3000\"\n exif:ExposureTime=\"1/4\"\n exif:ExposureProgram=\"1\"\n exif:ShutterSpeedValue=\"2/1\"\n exif:MeteringMode=\"1\"\n exif:LightSource=\"255\"\n exif:FocalPlaneXResolution=\"63015385/32768\"\n exif:FocalPlaneYResolution=\"63015385/32768\"\n exif:FocalPlaneResolutionUnit=\"3\"\n exif:FileSource=\"3\"\n exif:SceneType=\"1\"\n exif:WhiteBalance=\"5\"\n exif:ImageUniqueID=\"00E058000075000004019E064100753C\">\n <Iptc4xmpCore:CreatorContactInfo\n Iptc4xmpCore:CiEmailWork=\"digicc@library.illinois.edu\"\n Iptc4xmpCore:CiTelWork=\"+1(217)2442062\"\n Iptc4xmpCore:CiAdrPcode=\"61801\"\n Iptc4xmpCore:CiUrlWork=\"http://www.library.illinois.edu/staff/preservation/digitization/\"\n Iptc4xmpCore:CiAdrExtadr=\"1408 W. Gregory Drive\"\n Iptc4xmpCore:CiAdrCity=\"Urbana\"\n Iptc4xmpCore:CiAdrCtry=\"United States\"\n Iptc4xmpCore:CiAdrRegion=\"Illinois\"/>\n <tiff:BitsPerSample>\n <rdf:Seq>\n <rdf:li>8 8 8</rdf:li>\n </rdf:Seq>\n </tiff:BitsPerSample>\n <exif:ISOSpeedRatings>\n <rdf:Seq>\n <rdf:li>50</rdf:li>\n </rdf:Seq>\n </exif:ISOSpeedRatings>\n <dc:creator>\n <rdf:Seq>\n <rdf:li>University of Illinois Library</rdf:li>\n </rdf:Seq>\n </dc:creator>\n </rdf:Description>\n </rdf:RDF>"
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
id: "contentDiv",
|
id: "contentDiv",
|
||||||
prefixUrl: "../../build/openseadragon/images/",
|
prefixUrl: "../../build/openseadragon/images/",
|
||||||
tileSources: "../data/testpattern.dzi",
|
tileSources: "../data/testpattern.dzi",
|
||||||
showNavigator:true
|
showNavigator: true
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -3,111 +3,163 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>OpenSeadragon fitBoundsWithConstraints() Demo</title>
|
<title>OpenSeadragon fitBoundsWithConstraints() Demo</title>
|
||||||
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
||||||
|
<script type="text/javascript" src='../lib/jquery-1.9.1.min.js'></script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
|
||||||
.openseadragon1 {
|
.openseadragon1 {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: 600px;
|
height: 500px;
|
||||||
|
border:thin black solid;
|
||||||
|
margin-right:20px;
|
||||||
}
|
}
|
||||||
|
#buttons button{
|
||||||
#highlights li {
|
width:10em;
|
||||||
cursor: pointer;
|
text-align:center;
|
||||||
|
margin:5px;
|
||||||
|
}
|
||||||
|
.layout{
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns:auto 1fr;
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
.method{
|
||||||
|
border:medium gray solid;
|
||||||
|
margin:2px;
|
||||||
|
background-color:rgb(240, 240, 240)
|
||||||
|
}
|
||||||
|
.method.selected{
|
||||||
|
border:medium red solid;
|
||||||
|
background-color: lightgoldenrodyellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>
|
<div class="layout">
|
||||||
Simple demo page to show 'viewport.fitBounds().applyConstraints()' issue.
|
<div id="contentDiv" class="openseadragon1"></div>
|
||||||
|
<div id="controls">
|
||||||
|
<div>
|
||||||
|
Simple demo page to show viewport.fitBounds() with and without constraints. The viewer
|
||||||
|
is set up with visibilityRatio = 1 and constrainDuringPan = true to clearly demonstrate the
|
||||||
|
constraints.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Pick a method to use:</h3>
|
||||||
|
<div>
|
||||||
|
<div class="method selected" data-value="0">
|
||||||
|
<pre>viewport.fitBounds(bounds); //Ignores constraints</pre>
|
||||||
|
</div>
|
||||||
|
<div class="method" data-value="1">
|
||||||
|
<pre>viewport.fitBoundsWithConstraints(bounds);</pre>
|
||||||
|
</div>
|
||||||
|
<div class="method" data-value="4">
|
||||||
|
<pre>viewport.fitBoundsWithConstraints(bounds, true); //immediate</pre>
|
||||||
|
</div>
|
||||||
|
<div class="method" data-value="2">
|
||||||
|
<pre>//Initially ignore constraints
|
||||||
|
viewport.fitBounds(bounds);
|
||||||
|
|
||||||
|
//Apply constraints after 1 second delay
|
||||||
|
setTimeout(() => viewport.applyConstraints(), 1000);</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button id="rotate">Rotate the viewer</button>
|
||||||
|
<h3>Click to fit overlay bounds:</h3>
|
||||||
|
<div id="buttons"></div>
|
||||||
|
<h4>overlay.getBounds(viewer.viewport):</h4>
|
||||||
|
<pre class="bounds">Pick an overlay above to show the bounds</pre>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="contentDiv" class="openseadragon1"></div>
|
|
||||||
<div id="highlights"></div>
|
|
||||||
|
|
||||||
<select onchange="changeMethod(this.value);">
|
|
||||||
<option value=0>viewport.fitBoundsWithConstraints(bounds);</option>
|
|
||||||
<option value=1>viewport.fitBounds(bounds);</option>
|
|
||||||
<option value=2>viewport.fitBounds(bounds).applyConstraints();</option>
|
|
||||||
</select>
|
|
||||||
<input type="button" value="Go home" onclick="goHome()"/>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
|
||||||
var _viewer;
|
var viewer;
|
||||||
var _fittingMethod = 0;
|
var _fittingMethod = 0;
|
||||||
|
viewer = window.viewer = OpenSeadragon({
|
||||||
var _highlights = [
|
id: "contentDiv",
|
||||||
{"queryPoint":[0.13789887359998443,0.43710575899579285], "radius":0.004479581945070337,"text":"Pipe"},
|
|
||||||
{"queryPoint":[0.5923298766583593,0.6461653354541856], "radius":0.013175241014912752,"text":"Fuel here"},
|
|
||||||
{"queryPoint":[0.43920338711232304,0.7483181389302148], "radius":0.09222668710438928, "text":"Wheel"},
|
|
||||||
{"queryPoint":[0.07341677959486298,0.9028719921872319], "radius":0.08996845561083797, "text":"Nothing special"}
|
|
||||||
];
|
|
||||||
|
|
||||||
var generateUniqueHash = (function() {
|
|
||||||
var counter = 0;
|
|
||||||
return function() {
|
|
||||||
return "openseadragon_" + (counter++);
|
|
||||||
};
|
|
||||||
})();
|
|
||||||
|
|
||||||
var _viewer = OpenSeadragon({
|
|
||||||
element: document.getElementById("contentDiv"),
|
|
||||||
showNavigationControl: false,
|
|
||||||
prefixUrl: "../../build/openseadragon/images/",
|
prefixUrl: "../../build/openseadragon/images/",
|
||||||
hash: generateUniqueHash(), //this is only needed if you want to instantiate more than one viewer at a time.
|
tileSources: "../data/testpattern.dzi",
|
||||||
tileSources: {
|
minZoomImageRatio: 0,
|
||||||
Image: {
|
maxZoomPixelRatio: 10,
|
||||||
xmlns: "http://schemas.microsoft.com/deepzoom/2008",
|
visibilityRatio:1,
|
||||||
Url: 'http://cdn.photosynth.net/ps2/19d5cf2b-77ed-439f-ac21-d3046320384c/packet/undistorted/img0043/',
|
constrainDuringPan:true,
|
||||||
Format: "jpg",
|
});
|
||||||
Overlap: 1,
|
|
||||||
TileSize: 510,
|
viewer.addHandler("open", function(event) {
|
||||||
Size: {
|
var elt = document.createElement("div");
|
||||||
Width: 4592,
|
elt.className = "runtime-overlay";
|
||||||
Height: 3448
|
elt.style.background = "green";
|
||||||
|
elt.style.outline = "3px solid red";
|
||||||
|
elt.style.opacity = "0.7";
|
||||||
|
elt.textContent = "Within the image";
|
||||||
|
viewer.addOverlay({
|
||||||
|
element: elt,
|
||||||
|
location: new OpenSeadragon.Rect(0.21, 0.21, 0.099, 0.299),
|
||||||
|
rotationMode: OpenSeadragon.OverlayRotationMode.BOUNDING_BOX
|
||||||
|
});
|
||||||
|
|
||||||
|
elt = document.createElement("div");
|
||||||
|
elt.className = "runtime-overlay";
|
||||||
|
elt.style.background = "white";
|
||||||
|
elt.style.opacity = "0.5";
|
||||||
|
elt.style.outline = "5px solid pink";
|
||||||
|
elt.textContent = "Left edge rectangle";
|
||||||
|
viewer.addOverlay({
|
||||||
|
element: elt,
|
||||||
|
location: new OpenSeadragon.Rect(-0.4, 0.7, 0.7, 0.15)
|
||||||
|
});
|
||||||
|
|
||||||
|
var elt = document.createElement("div");
|
||||||
|
elt.className = "runtime-overlay";
|
||||||
|
elt.style.background = "lightblue";
|
||||||
|
elt.style.outline = "3px solid purple";
|
||||||
|
elt.style.opacity = "0.7";
|
||||||
|
elt.textContent = "Top right square";
|
||||||
|
viewer.addOverlay({
|
||||||
|
element: elt,
|
||||||
|
location: new OpenSeadragon.Rect(0.9, -0.1, 0.2, 0.2),
|
||||||
|
rotationMode: OpenSeadragon.OverlayRotationMode.BOUNDING_BOX
|
||||||
|
});
|
||||||
|
|
||||||
|
viewer.currentOverlays.forEach(overlay=>{
|
||||||
|
var text = $(overlay.element).text();
|
||||||
|
var div=$('<div>').appendTo('#buttons');
|
||||||
|
var buttons=$('<button>').text(text).appendTo(div).on('click',()=>{
|
||||||
|
|
||||||
|
var bounds = overlay.getBounds(viewer.viewport);
|
||||||
|
$('.bounds').text(JSON.stringify(bounds,null,2));
|
||||||
|
|
||||||
|
var _fittingMethod = parseInt($('.method.selected').data('value'));
|
||||||
|
|
||||||
|
if (_fittingMethod === 0) {
|
||||||
|
viewer.viewport.fitBounds(bounds, false);
|
||||||
}
|
}
|
||||||
}
|
else if (_fittingMethod === 1) {
|
||||||
}
|
viewer.viewport.fitBoundsWithConstraints(bounds, false);
|
||||||
|
}
|
||||||
|
else if (_fittingMethod === 4) {
|
||||||
|
viewer.viewport.fitBoundsWithConstraints(bounds, true);
|
||||||
|
}
|
||||||
|
else if (_fittingMethod === 2) {
|
||||||
|
viewer.viewport.fitBounds(bounds, false);
|
||||||
|
setTimeout(()=>viewer.viewport.applyConstraints(), 1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
viewer.viewport.zoomTo(0.5, null, true);
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
_viewer.addHandler("open", function() {
|
$('.method').on('click',function(){
|
||||||
var str = "<ul>";
|
$('.method').removeClass('selected');
|
||||||
for (var i=0; i<_highlights.length; ++i) {
|
$(this).addClass('selected');
|
||||||
var highlight = _highlights[i];
|
})
|
||||||
str += "<li onclick='gotoHighlight("+i+")'>"+highlight.text+"</li>";
|
$("#rotate").click(function() {
|
||||||
}
|
viewer.viewport.setRotation(viewer.viewport.getRotation() - 22.5);
|
||||||
str += "</ul>";
|
$("#degrees").text(viewer.viewport.getRotation() + "deg");
|
||||||
document.getElementById("highlights").innerHTML = str;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
function gotoHighlight(index) {
|
|
||||||
var highlight = _highlights[index];
|
|
||||||
|
|
||||||
var viewport = _viewer.viewport;
|
|
||||||
var contentSize = viewport.contentSize;
|
|
||||||
var scaling = 1.0 / viewport.viewportToImageZoom(viewport.getZoom());
|
|
||||||
var radius = highlight.radius*Math.min(contentSize.x, contentSize.y);/*annotation.accurateRadius*scaling;*/
|
|
||||||
var center = new OpenSeadragon.Point(contentSize.x*highlight.queryPoint[0], contentSize.y*highlight.queryPoint[1]);
|
|
||||||
var bounds = viewport.imageToViewportRectangle(new OpenSeadragon.Rect(center.x-radius, center.y-radius, radius*2, radius*2));
|
|
||||||
|
|
||||||
if (_fittingMethod === 0) {
|
|
||||||
viewport.fitBoundsWithConstraints(bounds, false);
|
|
||||||
}
|
|
||||||
else if (_fittingMethod === 1) {
|
|
||||||
viewport.fitBounds(bounds, false);
|
|
||||||
}
|
|
||||||
else if (_fittingMethod === 2) {
|
|
||||||
viewport.fitBounds(bounds, false).applyConstraints();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeMethod(value) {
|
|
||||||
_fittingMethod = parseInt(value, 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
function goHome() {
|
|
||||||
_viewer.viewport.goHome();
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
236
test/demo/resizeviewer.html
Normal file
236
test/demo/resizeviewer.html
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>OpenSeadragon Viewer Resizing Demo</title>
|
||||||
|
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
||||||
|
<script type="text/javascript" src='../lib/jquery-1.9.1.min.js'></script>
|
||||||
|
<script type="text/javascript" src='../lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js'></script>
|
||||||
|
<link rel="stylesheet" href="../lib/jquery-ui-1.10.2/css/smoothness/jquery-ui-1.10.2.min.css">
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
.outer-container{
|
||||||
|
width:800px;
|
||||||
|
height:600px;
|
||||||
|
margin-right:20px;
|
||||||
|
border: medium gray dashed;
|
||||||
|
background-color:beige;
|
||||||
|
position:relative;
|
||||||
|
display:flex;
|
||||||
|
flex-direction:row;
|
||||||
|
}
|
||||||
|
.inner-container{
|
||||||
|
width:800px;
|
||||||
|
height:600px;
|
||||||
|
border: thin black solid;
|
||||||
|
background-color:paleturquoise;
|
||||||
|
position:absolute;
|
||||||
|
left:50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
}
|
||||||
|
.v2-container{
|
||||||
|
display:flex;
|
||||||
|
flex-direction:row;
|
||||||
|
height:400px;
|
||||||
|
}
|
||||||
|
.narrow{
|
||||||
|
width:50px;
|
||||||
|
background-color:pink;
|
||||||
|
height:100%;
|
||||||
|
}
|
||||||
|
.wide{
|
||||||
|
width:150px;
|
||||||
|
background-color:burlywood;
|
||||||
|
height:100%;
|
||||||
|
}
|
||||||
|
.v2-container:not([data-index="1"]) .narrow{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
.v2-container:not([data-index="2"]) .wide{
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
#viewer, #viewer2 {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
#buttons button{
|
||||||
|
width:18em;
|
||||||
|
text-align:center;
|
||||||
|
margin:5px;
|
||||||
|
}
|
||||||
|
.layout{
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns:auto 1fr;
|
||||||
|
row-gap:10px;
|
||||||
|
padding:10px;
|
||||||
|
}
|
||||||
|
.method{
|
||||||
|
border:medium gray solid;
|
||||||
|
margin:2px;
|
||||||
|
background-color:rgb(240, 240, 240)
|
||||||
|
}
|
||||||
|
.method.selected{
|
||||||
|
border:medium red solid;
|
||||||
|
background-color: lightgoldenrodyellow;
|
||||||
|
}
|
||||||
|
.options{
|
||||||
|
display:grid;
|
||||||
|
grid-template-columns: 50% 50%;
|
||||||
|
row-gap:10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="layout">
|
||||||
|
<div class="outer-container">
|
||||||
|
<div class="inner-container">
|
||||||
|
<div id="viewer"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="controls">
|
||||||
|
<div>
|
||||||
|
Simple demo page to show viewer behavior during resizing of the container.
|
||||||
|
The viewers' container elements are styled with width and height of 100%,
|
||||||
|
with dimensions set by CSS properties on a parent element.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Pick options to test:</h3>
|
||||||
|
<p>These options apply to both of the demo viewers on the left (top and bottom).</p>
|
||||||
|
<div class="options">
|
||||||
|
|
||||||
|
<div class="method preserve-method selected" data-value="0">
|
||||||
|
<pre>preserveImageSizeOnResize: false</pre>
|
||||||
|
</div>
|
||||||
|
<div class="method preserve-method" data-value="1">
|
||||||
|
<pre>preserveImageSizeOnResize: true</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="method auto-method selected" data-value="1">
|
||||||
|
<pre>autoResize: true</pre>
|
||||||
|
</div>
|
||||||
|
<div class="method auto-method" data-value="0">
|
||||||
|
<pre>autoResize: false</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<h3>Click to resize the viewer:</h3>
|
||||||
|
<div id="buttons">
|
||||||
|
<div>
|
||||||
|
<button>Resize width only</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button>Resize height only</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button>Resize with constant aspect ratio</button>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<button>Toggle resizable inner container</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
var viewer = window.v1 = OpenSeadragon({
|
||||||
|
id: "viewer",
|
||||||
|
prefixUrl: "../../build/openseadragon/images/",
|
||||||
|
tileSources: "../data/iiif_2_0_sizes/info.json",
|
||||||
|
minZoomImageRatio: 0,
|
||||||
|
maxZoomPixelRatio: 10,
|
||||||
|
visibilityRatio:0.5,
|
||||||
|
constrainDuringPan:false,
|
||||||
|
showNavigator: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
updateViewer();
|
||||||
|
|
||||||
|
|
||||||
|
var buttons=$('#buttons button').on('click',function(){
|
||||||
|
switch($(this).text()){
|
||||||
|
case 'Resize width only': resizeWidth(this); break;
|
||||||
|
case 'Resize height only': resizeHeight(this); break;
|
||||||
|
case 'Resize with constant aspect ratio': resizeBoth(this); break;
|
||||||
|
case 'Toggle resizable inner container': toggleResizable(this); break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function updateViewer(){
|
||||||
|
viewer.preserveImageSizeOnResize = !!parseInt($('.preserve-method.selected').data('value'));
|
||||||
|
viewer.autoResize = !!parseInt($('.auto-method.selected').data('value'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$('.preserve-method').on('click',function(){
|
||||||
|
$('.preserve-method').removeClass('selected');
|
||||||
|
$(this).addClass('selected');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.auto-method').on('click',function(){
|
||||||
|
$('.auto-method').removeClass('selected');
|
||||||
|
$(this).addClass('selected');
|
||||||
|
});
|
||||||
|
|
||||||
|
$('.method').on('click',updateViewer);
|
||||||
|
|
||||||
|
var container = $('.inner-container');
|
||||||
|
function resizeWidth(b){
|
||||||
|
if(container.height() !== 600) return;
|
||||||
|
if(container.width()==800){
|
||||||
|
container.width(600);
|
||||||
|
$('#buttons button').prop('disabled', true);
|
||||||
|
$(b).prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
container.width(800);
|
||||||
|
$('#buttons button').prop('disabled', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function resizeHeight(b){
|
||||||
|
if(container.width() !== 800) return;
|
||||||
|
if(container.height()==600){
|
||||||
|
container.height(450);
|
||||||
|
$('#buttons button').prop('disabled', true);
|
||||||
|
$(b).prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
container.height(600);
|
||||||
|
$('#buttons button').prop('disabled', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function resizeBoth(b){
|
||||||
|
if(container.height()==600){
|
||||||
|
container.width(600);
|
||||||
|
container.height(450);
|
||||||
|
$('#buttons button').prop('disabled', true);
|
||||||
|
$(b).prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
container.width(800);
|
||||||
|
container.height(600);
|
||||||
|
$('#buttons button').prop('disabled', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function toggleResizable(b){
|
||||||
|
if(container.isResizable){
|
||||||
|
container.isResizable = false;
|
||||||
|
container.resizable('destroy');
|
||||||
|
container.width(800);
|
||||||
|
container.height(600);
|
||||||
|
$('#buttons button').prop('disabled', false);
|
||||||
|
} else {
|
||||||
|
container.isResizable = true;
|
||||||
|
// container.resizable({containment:"parent", maxWidth: 800, maxHeight: 600,});
|
||||||
|
container.resizable();
|
||||||
|
$('#buttons button').prop('disabled', true);
|
||||||
|
container.width(800);
|
||||||
|
container.height(600);
|
||||||
|
$(b).prop('disabled', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
34
test/demo/rotating-navigator-region.html
Normal file
34
test/demo/rotating-navigator-region.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>OpenSeadragon Basic Demo</title>
|
||||||
|
<script type="text/javascript" src='../../build/openseadragon/openseadragon.js'></script>
|
||||||
|
<script type="text/javascript" src='../lib/jquery-1.9.1.min.js'></script>
|
||||||
|
<style type="text/css">
|
||||||
|
|
||||||
|
.openseadragon1 {
|
||||||
|
width: 800px;
|
||||||
|
height: 600px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
Simple demo page. The navigator region is expected to rotate when the image is rotated.
|
||||||
|
The default behaviour is to keep the region still as the image below it rotates.
|
||||||
|
</div>
|
||||||
|
<div id="contentDiv" class="openseadragon1"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var viewer = OpenSeadragon({
|
||||||
|
// debugMode: true,
|
||||||
|
id: "contentDiv",
|
||||||
|
prefixUrl: "../../build/openseadragon/images/",
|
||||||
|
tileSources: "../data/testpattern.dzi",
|
||||||
|
showNavigator: true,
|
||||||
|
navigatorRotate: false
|
||||||
|
});
|
||||||
|
viewer.viewport.setRotation(45)
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -245,4 +245,130 @@
|
|||||||
tileSource: staticHeaderTileSource
|
tileSource: staticHeaderTileSource
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QUnit.test('Viewer headers can be updated', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
|
||||||
|
var newHeaders = {
|
||||||
|
'X-Viewer-Header': 'ViewerHeaderValue-Updated',
|
||||||
|
'X-Viewer-Header2': 'ViewerHeaderValue2'
|
||||||
|
}
|
||||||
|
var newHeaders2 = {
|
||||||
|
Range: 'test',
|
||||||
|
}
|
||||||
|
|
||||||
|
var tileLoaded = function tileLoaded(evt) {
|
||||||
|
viewer.removeHandler('tile-loaded', tileLoaded);
|
||||||
|
// set new Viewer headers and propagate to TiledImage and Tile
|
||||||
|
viewer.setAjaxHeaders(newHeaders);
|
||||||
|
viewer.addHandler('tile-loaded', tileLoaded2);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tileLoaded2 = function tileLoaded(evt) {
|
||||||
|
viewer.removeHandler('tile-loaded', tileLoaded2);
|
||||||
|
assert.deepEqual(viewer.ajaxHeaders, newHeaders);
|
||||||
|
assert.deepEqual(evt.tiledImage.ajaxHeaders, newHeaders);
|
||||||
|
assert.deepEqual(
|
||||||
|
evt.tile.ajaxHeaders,
|
||||||
|
OpenSeadragon.extend(
|
||||||
|
{}, viewer.ajaxHeaders, evt.tiledImage.ajaxHeaders,
|
||||||
|
{ Range: getTileRangeHeader(evt.tile.level, evt.tile.x, evt.tile.y) }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
// set new Viewer headers and propagate to TiledImage and Tile
|
||||||
|
viewer.setAjaxHeaders(newHeaders2, true);
|
||||||
|
viewer.addHandler('tile-loaded', tileLoaded3);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tileLoaded3 = function tileLoaded(evt) {
|
||||||
|
viewer.removeHandler('tile-loaded', tileLoaded3);
|
||||||
|
assert.deepEqual(viewer.ajaxHeaders, newHeaders2);
|
||||||
|
assert.deepEqual(evt.tiledImage.ajaxHeaders, newHeaders2);
|
||||||
|
assert.equal(evt.tile.ajaxHeaders['X-Viewer-Header'], undefined);
|
||||||
|
assert.equal(evt.tile.ajaxHeaders['X-Viewer-Header2'], undefined);
|
||||||
|
// 'Range' header entry set per tile and must not be overwritten by Viewer header
|
||||||
|
assert.equal(evt.tile.ajaxHeaders.Range, getTileRangeHeader(evt.tile.level, evt.tile.x, evt.tile.y));
|
||||||
|
// set new Viewer headers but do not propagate to TiledImage and Tile
|
||||||
|
viewer.setAjaxHeaders(newHeaders, false);
|
||||||
|
viewer.addHandler('tile-loaded', tileLoaded4);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tileLoaded4 = function tileLoaded(evt) {
|
||||||
|
viewer.removeHandler('tile-loaded', tileLoaded4);
|
||||||
|
assert.deepEqual(viewer.ajaxHeaders, newHeaders);
|
||||||
|
assert.deepEqual(evt.tiledImage.ajaxHeaders, newHeaders2);
|
||||||
|
assert.equal(evt.tile.ajaxHeaders['X-Viewer-Header'], undefined);
|
||||||
|
assert.equal(evt.tile.ajaxHeaders['X-Viewer-Header2'], undefined);
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('tile-loaded', tileLoaded);
|
||||||
|
viewer.open(customTileSource);
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('TiledImage headers can be updated', function(assert) {
|
||||||
|
var done = assert.async();
|
||||||
|
|
||||||
|
var tileSourceHeaders = {
|
||||||
|
'X-Tile-Header': 'TileHeaderValue'
|
||||||
|
}
|
||||||
|
var newHeaders = {
|
||||||
|
'X-TiledImage-Header': 'TiledImageHeaderValue-Updated',
|
||||||
|
'X-TiledImage-Header2': 'TiledImageHeaderValue2'
|
||||||
|
}
|
||||||
|
var newHeaders2 = {
|
||||||
|
'X-Viewer-Header': 'ViewerHeaderValue-Updated',
|
||||||
|
'X-Tile-Header': 'TileHeaderValue-Updated'
|
||||||
|
}
|
||||||
|
|
||||||
|
var tileLoaded = function tileLoaded(evt) {
|
||||||
|
viewer.removeHandler('tile-loaded', tileLoaded);
|
||||||
|
// set new TiledImage headers and propagate to Tile
|
||||||
|
evt.tiledImage.setAjaxHeaders(newHeaders);
|
||||||
|
viewer.addHandler('tile-loaded', tileLoaded2);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tileLoaded2 = function tileLoaded(evt) {
|
||||||
|
viewer.removeHandler('tile-loaded', tileLoaded2);
|
||||||
|
assert.deepEqual(viewer.ajaxHeaders, { 'X-Viewer-Header': 'ViewerHeaderValue' });
|
||||||
|
assert.deepEqual(evt.tiledImage._ownAjaxHeaders, newHeaders);
|
||||||
|
assert.deepEqual(evt.tiledImage.ajaxHeaders, OpenSeadragon.extend({}, viewer.ajaxHeaders, newHeaders));
|
||||||
|
assert.deepEqual(evt.tile.ajaxHeaders, OpenSeadragon.extend({}, viewer.ajaxHeaders, newHeaders, tileSourceHeaders));
|
||||||
|
// set new TiledImage headers (that overwrite header entries of Viewer and Tile) and propagate to Tile
|
||||||
|
evt.tiledImage.setAjaxHeaders(newHeaders2, true);
|
||||||
|
viewer.addHandler('tile-loaded', tileLoaded3);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tileLoaded3 = function tileLoaded(evt) {
|
||||||
|
viewer.removeHandler('tile-loaded', tileLoaded3);
|
||||||
|
assert.deepEqual(viewer.ajaxHeaders, { 'X-Viewer-Header': 'ViewerHeaderValue' });
|
||||||
|
assert.deepEqual(evt.tiledImage._ownAjaxHeaders, newHeaders2);
|
||||||
|
assert.deepEqual(evt.tiledImage.ajaxHeaders, OpenSeadragon.extend({}, viewer.ajaxHeaders, newHeaders2));
|
||||||
|
assert.deepEqual(evt.tile.ajaxHeaders, OpenSeadragon.extend({}, viewer.ajaxHeaders, newHeaders2, tileSourceHeaders));
|
||||||
|
// set new TiledImage headers but do not propagate to Tile
|
||||||
|
evt.tiledImage.setAjaxHeaders(null, false);
|
||||||
|
viewer.addHandler('tile-loaded', tileLoaded4);
|
||||||
|
};
|
||||||
|
|
||||||
|
var tileLoaded4 = function tileLoaded(evt) {
|
||||||
|
viewer.removeHandler('tile-loaded', tileLoaded4);
|
||||||
|
assert.deepEqual(viewer.ajaxHeaders, { 'X-Viewer-Header': 'ViewerHeaderValue' });
|
||||||
|
assert.deepEqual(evt.tiledImage._ownAjaxHeaders, {});
|
||||||
|
assert.deepEqual(evt.tiledImage.ajaxHeaders, viewer.ajaxHeaders);
|
||||||
|
assert.deepEqual(evt.tile.ajaxHeaders, OpenSeadragon.extend({}, viewer.ajaxHeaders, newHeaders2, tileSourceHeaders));
|
||||||
|
done();
|
||||||
|
};
|
||||||
|
|
||||||
|
viewer.addHandler('tile-loaded', tileLoaded);
|
||||||
|
viewer.addTiledImage({
|
||||||
|
ajaxHeaders: {
|
||||||
|
'X-TiledImage-Header': 'TiledImageHeaderValue'
|
||||||
|
},
|
||||||
|
tileSource: OpenSeadragon.extend({}, customTileSource, {
|
||||||
|
getTileAjaxHeaders: function() {
|
||||||
|
return tileSourceHeaders;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
@ -224,32 +224,43 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('FullScreen', function(assert) {
|
QUnit.test('FullScreen', function(assert) {
|
||||||
var done = assert.async();
|
const done = assert.async();
|
||||||
if (!OpenSeadragon.supportsFullScreen) {
|
if (!OpenSeadragon.supportsFullScreen) {
|
||||||
assert.expect(0);
|
assert.expect(0);
|
||||||
done();
|
done();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
viewer.addHandler("open", function () {
|
viewer.addHandler('open', function () {
|
||||||
assert.ok(!OpenSeadragon.isFullScreen(), 'Started out not fullscreen');
|
assert.ok(!OpenSeadragon.isFullScreen(), 'Started out not fullscreen');
|
||||||
|
|
||||||
var checkEnteringPreFullScreen = function(event) {
|
const checkEnteringPreFullScreen = (event) => {
|
||||||
viewer.removeHandler('pre-full-screen', checkEnteringPreFullScreen);
|
viewer.removeHandler('pre-full-screen', checkEnteringPreFullScreen);
|
||||||
assert.ok(event.fullScreen, 'Switching to fullscreen');
|
assert.ok(event.fullScreen, 'Switching to fullscreen');
|
||||||
assert.ok(!OpenSeadragon.isFullScreen(), 'Not yet fullscreen');
|
assert.ok(!OpenSeadragon.isFullScreen(), 'Not yet fullscreen');
|
||||||
};
|
};
|
||||||
|
|
||||||
// The fullscreen mode is always denied during tests so we are
|
const checkExitingFullScreen = (event) => {
|
||||||
// exiting directly.
|
|
||||||
var checkExitingFullScreen = function(event) {
|
|
||||||
viewer.removeHandler('full-screen', checkExitingFullScreen);
|
viewer.removeHandler('full-screen', checkExitingFullScreen);
|
||||||
assert.ok(!event.fullScreen, 'Exiting fullscreen');
|
assert.ok(!event.fullScreen, 'Disabling fullscreen');
|
||||||
assert.ok(!OpenSeadragon.isFullScreen(), 'Disabled fullscreen');
|
assert.ok(!OpenSeadragon.isFullScreen(), 'Fullscreen disabled');
|
||||||
done();
|
done();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The 'new' headless mode allows us to enter fullscreen, so verify
|
||||||
|
// that we see the correct values returned. We will then close out
|
||||||
|
// of fullscreen to check the same values when exiting.
|
||||||
|
const checkAcquiredFullScreen = (event) => {
|
||||||
|
viewer.removeHandler('full-screen', checkAcquiredFullScreen);
|
||||||
|
viewer.addHandler('full-screen', checkExitingFullScreen);
|
||||||
|
assert.ok(event.fullScreen, 'Acquired fullscreen');
|
||||||
|
assert.ok(OpenSeadragon.isFullScreen(), 'Fullscreen enabled');
|
||||||
|
viewer.setFullScreen(false);
|
||||||
};
|
};
|
||||||
viewer.addHandler("pre-full-screen", checkEnteringPreFullScreen);
|
|
||||||
viewer.addHandler("full-screen", checkExitingFullScreen);
|
|
||||||
|
viewer.addHandler('pre-full-screen', checkEnteringPreFullScreen);
|
||||||
|
viewer.addHandler('full-screen', checkAcquiredFullScreen);
|
||||||
viewer.setFullScreen(true);
|
viewer.setFullScreen(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
85
test/modules/event-source.js
Normal file
85
test/modules/event-source.js
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/* global QUnit, $, TouchUtil, Util, testLog */
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
var context, result=[], eName = "test", eventCounter = 0, finished = false;
|
||||||
|
|
||||||
|
function evaluateTest(e) {
|
||||||
|
if (finished) return;
|
||||||
|
finished = true;
|
||||||
|
e.assert.strictEqual(JSON.stringify(result), JSON.stringify(e.expected), e.message);
|
||||||
|
e.done();
|
||||||
|
}
|
||||||
|
|
||||||
|
function executor(i, ms) {
|
||||||
|
if (ms === undefined) return function (e) {
|
||||||
|
eventCounter++;
|
||||||
|
result.push(i);
|
||||||
|
if (eventCounter === context.numberOfHandlers(eName)) {
|
||||||
|
evaluateTest(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return function (e) {
|
||||||
|
return new Promise(function (resolve) {
|
||||||
|
setTimeout(function () {
|
||||||
|
eventCounter++;
|
||||||
|
result.push(i);
|
||||||
|
if (eventCounter === context.numberOfHandlers(eName)) {
|
||||||
|
evaluateTest(e);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
}, ms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTest(e) {
|
||||||
|
context.raiseEvent(eName, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
QUnit.module( 'EventSource', {
|
||||||
|
beforeEach: function () {
|
||||||
|
context = new OpenSeadragon.EventSource();
|
||||||
|
eventCounter = 0;
|
||||||
|
result = [];
|
||||||
|
finished = false;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
QUnit.test('EventSource: no events', function(assert) {
|
||||||
|
context.addHandler(eName, evaluateTest);
|
||||||
|
runTest({
|
||||||
|
assert: assert,
|
||||||
|
done: assert.async(),
|
||||||
|
expected: [],
|
||||||
|
message: 'No handlers registered - arrays should be empty.'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('EventSource: simple callbacks order', function(assert) {
|
||||||
|
context.addHandler(eName, executor(1));
|
||||||
|
context.addHandler(eName, executor(2));
|
||||||
|
context.addHandler(eName, executor(3));
|
||||||
|
runTest({
|
||||||
|
assert: assert,
|
||||||
|
done: assert.async(),
|
||||||
|
expected: [1, 2, 3],
|
||||||
|
message: 'Simple callback order should follow [1,2,3].'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('EventSource: priority callbacks order', function(assert) {
|
||||||
|
context.addHandler(eName, executor(1), undefined, 20);
|
||||||
|
context.addHandler(eName, executor(2), undefined, 124);
|
||||||
|
context.addHandler(eName, executor(3), undefined, -5);
|
||||||
|
context.addHandler(eName, executor(4));
|
||||||
|
context.addHandler(eName, executor(5), undefined, -2);
|
||||||
|
runTest({
|
||||||
|
assert: assert,
|
||||||
|
done: assert.async(),
|
||||||
|
expected: [2, 1, 4, 5, 3],
|
||||||
|
message: 'Prioritized callback order should follow [2,1,4,5,3].'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} )();
|
@ -248,14 +248,8 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
var dragNavigatorBackToCenter = function () {
|
var dragNavigatorBackToCenter = function () {
|
||||||
var start = viewer.viewport.getBounds().getTopLeft(),
|
var delta = viewer.viewport.getHomeBounds().getCenter().minus(viewer.viewport.getCenter()).times(displayRegionWidth);
|
||||||
target = new OpenSeadragon.Point(0.5 - viewer.viewport.getBounds().width / 2,
|
simulateNavigatorDrag(viewer.navigator, delta.x, delta.y);
|
||||||
1 / viewer.source.aspectRatio / 2 - viewer.viewport.getBounds().height / 2),
|
|
||||||
delta = target.minus(start);
|
|
||||||
if (viewer.source.aspectRatio < 1) {
|
|
||||||
delta.y *= viewer.source.aspectRatio;
|
|
||||||
}
|
|
||||||
simulateNavigatorDrag(viewer.navigator, delta.x * displayRegionWidth, delta.y * displayRegionHeight);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var resizeElement = function ($element, width, height) {
|
var resizeElement = function ($element, width, height) {
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
testLog.reset();
|
testLog.reset();
|
||||||
|
|
||||||
|
// eslint-disable-next-line new-cap
|
||||||
viewer = OpenSeadragon({
|
viewer = OpenSeadragon({
|
||||||
id: 'example',
|
id: 'example',
|
||||||
prefixUrl: '/build/openseadragon/images/',
|
prefixUrl: '/build/openseadragon/images/',
|
||||||
@ -517,12 +518,17 @@
|
|||||||
var image = viewer.world.getItemAt(0);
|
var image = viewer.world.getItemAt(0);
|
||||||
assert.equal(image.getFullyLoaded(), false, 'not fully loaded at first');
|
assert.equal(image.getFullyLoaded(), false, 'not fully loaded at first');
|
||||||
|
|
||||||
|
// Zoom out enough that we don't start out with all the tiles loaded.
|
||||||
|
viewer.viewport.zoomBy(0.5, null, true);
|
||||||
|
|
||||||
var count = 0;
|
var count = 0;
|
||||||
|
|
||||||
var fullyLoadedChangeHandler = function(event) {
|
var fullyLoadedChangeHandler = function(event) {
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
assert.equal(event.fullyLoaded, true, 'event includes true fullyLoaded property');
|
assert.equal(event.fullyLoaded, true, 'event includes true fullyLoaded property');
|
||||||
assert.equal(image.getFullyLoaded(), true, 'image is fully loaded after event');
|
assert.equal(image.getFullyLoaded(), true, 'image is fully loaded after event');
|
||||||
|
|
||||||
|
// Zoom in enough that it needs to load some new tiles.
|
||||||
viewer.viewport.zoomBy(5, null, true);
|
viewer.viewport.zoomBy(5, null, true);
|
||||||
} else if (count === 1) {
|
} else if (count === 1) {
|
||||||
assert.equal(event.fullyLoaded, false, 'event includes false fullyLoaded property');
|
assert.equal(event.fullyLoaded, false, 'event includes false fullyLoaded property');
|
||||||
|
@ -539,7 +539,7 @@
|
|||||||
var bounds = viewport.getBounds();
|
var bounds = viewport.getBounds();
|
||||||
Util.assertRectangleEquals(
|
Util.assertRectangleEquals(
|
||||||
assert,
|
assert,
|
||||||
new OpenSeadragon.Rect(1.2071067811865466, 0.20710678118654746, Math.sqrt(2), Math.sqrt(2), 45),
|
new OpenSeadragon.Rect(1.0, 0.0, Math.sqrt(2), Math.sqrt(2), 45),
|
||||||
bounds,
|
bounds,
|
||||||
EPSILON,
|
EPSILON,
|
||||||
"Viewport.applyConstraints with rotation should move viewport.");
|
"Viewport.applyConstraints with rotation should move viewport.");
|
||||||
@ -564,7 +564,7 @@
|
|||||||
var bounds = viewport.getBounds();
|
var bounds = viewport.getBounds();
|
||||||
Util.assertRectangleEquals(
|
Util.assertRectangleEquals(
|
||||||
assert,
|
assert,
|
||||||
new OpenSeadragon.Rect(1.2071067811865466, 0.20710678118654746, Math.sqrt(2), Math.sqrt(2), 45),
|
new OpenSeadragon.Rect(1.0, 0.0, Math.sqrt(2), Math.sqrt(2), 45),
|
||||||
bounds,
|
bounds,
|
||||||
EPSILON,
|
EPSILON,
|
||||||
"Viewport.applyConstraints flipped and with rotation should move viewport.");
|
"Viewport.applyConstraints flipped and with rotation should move viewport.");
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>OpenSeadragon QUnit</title>
|
<title>OpenSeadragon QUnit</title>
|
||||||
<link rel="stylesheet" href="/node_modules/qunitjs/qunit/qunit.css">
|
<link rel="stylesheet" href="/node_modules/qunit/qunit/qunit.css">
|
||||||
<link rel="stylesheet" href="/test/lib/jquery-ui-1.10.2/css/smoothness/jquery-ui-1.10.2.min.css">
|
<link rel="stylesheet" href="/test/lib/jquery-ui-1.10.2/css/smoothness/jquery-ui-1.10.2.min.css">
|
||||||
<link rel="stylesheet" href="/test/helpers/test.css">
|
<link rel="stylesheet" href="/test/helpers/test.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="qunit"></div>
|
<div id="qunit"></div>
|
||||||
<div id="qunit-fixture"></div>
|
<div id="qunit-fixture"></div>
|
||||||
<script src="/node_modules/qunitjs/qunit/qunit.js"></script>
|
<script src="/node_modules/qunit/qunit/qunit.js"></script>
|
||||||
<script src="/test/lib/jquery-1.9.1.min.js"></script>
|
<script src="/test/lib/jquery-1.9.1.min.js"></script>
|
||||||
<script src="/test/lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js"></script>
|
<script src="/test/lib/jquery-ui-1.10.2/js/jquery-ui-1.10.2.min.js"></script>
|
||||||
<script src="/test/lib/jquery.simulate.js"></script>
|
<script src="/test/lib/jquery.simulate.js"></script>
|
||||||
@ -22,6 +22,7 @@
|
|||||||
<!-- Polyfill must be inserted first because it is testing functions
|
<!-- Polyfill must be inserted first because it is testing functions
|
||||||
reassignments which could be done by other test. -->
|
reassignments which could be done by other test. -->
|
||||||
<script src="/test/modules/polyfills.js"></script>
|
<script src="/test/modules/polyfills.js"></script>
|
||||||
|
<script src="/test/modules/event-source.js"></script>
|
||||||
<script src="/test/modules/viewerretrieval.js"></script>
|
<script src="/test/modules/viewerretrieval.js"></script>
|
||||||
<script src="/test/modules/basic.js"></script>
|
<script src="/test/modules/basic.js"></script>
|
||||||
<script src="/test/modules/strings.js"></script>
|
<script src="/test/modules/strings.js"></script>
|
||||||
@ -50,6 +51,6 @@
|
|||||||
<script src="/test/modules/tilesource-dynamic-url.js"></script>
|
<script src="/test/modules/tilesource-dynamic-url.js"></script>
|
||||||
<!--The navigator tests are the slowest (for now; hopefully they can be sped up)
|
<!--The navigator tests are the slowest (for now; hopefully they can be sped up)
|
||||||
so we put them last. -->
|
so we put them last. -->
|
||||||
<!-- The navigator tests are failing right now, so we have them disabled for the moment <script src="/test/modules/navigator.js"></script> -->
|
<script src="/test/modules/navigator.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
Reference in New Issue
Block a user