openseadragon 0.3.3 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/openseadragon/version.rb +1 -1
- data/vendor/assets/images/openseadragon/button_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/button_hover.png +0 -0
- data/vendor/assets/images/openseadragon/button_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/button_rest.png +0 -0
- data/vendor/assets/images/openseadragon/fullpage_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/fullpage_hover.png +0 -0
- data/vendor/assets/images/openseadragon/fullpage_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/fullpage_rest.png +0 -0
- data/vendor/assets/images/openseadragon/home_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/home_hover.png +0 -0
- data/vendor/assets/images/openseadragon/home_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/home_rest.png +0 -0
- data/vendor/assets/images/openseadragon/next_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/next_hover.png +0 -0
- data/vendor/assets/images/openseadragon/next_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/next_rest.png +0 -0
- data/vendor/assets/images/openseadragon/previous_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/previous_hover.png +0 -0
- data/vendor/assets/images/openseadragon/previous_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/previous_rest.png +0 -0
- data/vendor/assets/images/openseadragon/rotateleft_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/rotateleft_hover.png +0 -0
- data/vendor/assets/images/openseadragon/rotateleft_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/rotateleft_rest.png +0 -0
- data/vendor/assets/images/openseadragon/rotateright_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/rotateright_hover.png +0 -0
- data/vendor/assets/images/openseadragon/rotateright_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/rotateright_rest.png +0 -0
- data/vendor/assets/images/openseadragon/zoomin_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/zoomin_hover.png +0 -0
- data/vendor/assets/images/openseadragon/zoomin_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/zoomin_rest.png +0 -0
- data/vendor/assets/images/openseadragon/zoomout_grouphover.png +0 -0
- data/vendor/assets/images/openseadragon/zoomout_hover.png +0 -0
- data/vendor/assets/images/openseadragon/zoomout_pressed.png +0 -0
- data/vendor/assets/images/openseadragon/zoomout_rest.png +0 -0
- data/vendor/assets/javascripts/openseadragon/openseadragon.js +1807 -636
- data/vendor/assets/javascripts/openseadragon/openseadragon.js.map +1 -1
- metadata +7 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9c1293c3a2424f19cf39c77892b3d3fad7447211
|
|
4
|
+
data.tar.gz: c3a989f62d49e246f644700e022eed592f00da41
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 27f131316b63cc5aeed1bd97fa24a7221303ba53ae77bcd45d408311d73448e22d267fd1f3b5575ea1c79b719478c28b8099d9220821ab9a13347f4c769e3208
|
|
7
|
+
data.tar.gz: 0a6bf8f4ae55f16e4fca9dce29a25443b3c0dcfbacb3cdd442bada81990bf6a8792bd5f7e221ea0fdff2551d0bfc07a4f9cc9b1560d1778580322a12bc9e0492
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
//! openseadragon 2.
|
|
2
|
-
//! Built on
|
|
3
|
-
//! Git commit: v2.
|
|
1
|
+
//! openseadragon 2.3.0
|
|
2
|
+
//! Built on 2017-07-14
|
|
3
|
+
//! Git commit: v2.3.0-2-b49fef3
|
|
4
4
|
//! http://openseadragon.github.io
|
|
5
5
|
//! License: http://openseadragon.github.io/license/
|
|
6
6
|
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* @namespace OpenSeadragon
|
|
93
|
-
* @version openseadragon 2.
|
|
93
|
+
* @version openseadragon 2.3.0
|
|
94
94
|
* @classdesc The root namespace for OpenSeadragon. All utility methods
|
|
95
95
|
* and classes are defined on or below this namespace.
|
|
96
96
|
*
|
|
@@ -191,7 +191,11 @@
|
|
|
191
191
|
* If 0, adjusts to fit viewer.
|
|
192
192
|
*
|
|
193
193
|
* @property {Number} [opacity=1]
|
|
194
|
-
* Default opacity of the tiled images (1=opaque, 0=
|
|
194
|
+
* Default proportional opacity of the tiled images (1=opaque, 0=hidden)
|
|
195
|
+
* Hidden images do not draw and only load when preloading is allowed.
|
|
196
|
+
*
|
|
197
|
+
* @property {Boolean} [preload=false]
|
|
198
|
+
* Default switch for loading hidden images (true loads, false blocks)
|
|
195
199
|
*
|
|
196
200
|
* @property {String} [compositeOperation=null]
|
|
197
201
|
* Valid values are 'source-over', 'source-atop', 'source-in', 'source-out',
|
|
@@ -417,6 +421,7 @@
|
|
|
417
421
|
* The max number of images we should keep in memory (per drawer).
|
|
418
422
|
*
|
|
419
423
|
* @property {Number} [timeout=30000]
|
|
424
|
+
* The max number of milliseconds that an image job may take to complete.
|
|
420
425
|
*
|
|
421
426
|
* @property {Boolean} [useCanvas=true]
|
|
422
427
|
* Set to false to not use an HTML canvas element for image rendering even if canvas is supported.
|
|
@@ -590,9 +595,16 @@
|
|
|
590
595
|
* not use CORS, and the canvas will be tainted.
|
|
591
596
|
*
|
|
592
597
|
* @property {Boolean} [ajaxWithCredentials=false]
|
|
593
|
-
* Whether to set the withCredentials XHR flag for AJAX requests
|
|
598
|
+
* Whether to set the withCredentials XHR flag for AJAX requests.
|
|
599
|
+
* Note that this can be overridden at the {@link OpenSeadragon.TileSource} level.
|
|
600
|
+
*
|
|
601
|
+
* @property {Boolean} [loadTilesWithAjax=false]
|
|
602
|
+
* Whether to load tile data using AJAX requests.
|
|
594
603
|
* Note that this can be overridden at the {@link OpenSeadragon.TileSource} level.
|
|
595
604
|
*
|
|
605
|
+
* @property {Object} [ajaxHeaders={}]
|
|
606
|
+
* A set of headers to include when making AJAX requests for tile sources or tiles.
|
|
607
|
+
*
|
|
596
608
|
*/
|
|
597
609
|
|
|
598
610
|
/**
|
|
@@ -691,19 +703,10 @@
|
|
|
691
703
|
* @param {OpenSeadragon.Options} options - Viewer options.
|
|
692
704
|
* @returns {OpenSeadragon.Viewer}
|
|
693
705
|
*/
|
|
694
|
-
|
|
695
|
-
|
|
706
|
+
function OpenSeadragon( options ){
|
|
696
707
|
return new OpenSeadragon.Viewer( options );
|
|
697
|
-
|
|
698
|
-
};
|
|
699
|
-
|
|
700
|
-
if (typeof define === 'function' && define.amd) {
|
|
701
|
-
define(function () {
|
|
702
|
-
return (window.OpenSeadragon);
|
|
703
|
-
});
|
|
704
708
|
}
|
|
705
709
|
|
|
706
|
-
|
|
707
710
|
(function( $ ){
|
|
708
711
|
|
|
709
712
|
|
|
@@ -718,10 +721,10 @@ if (typeof define === 'function' && define.amd) {
|
|
|
718
721
|
* @since 1.0.0
|
|
719
722
|
*/
|
|
720
723
|
$.version = {
|
|
721
|
-
versionStr: '2.
|
|
724
|
+
versionStr: '2.3.0',
|
|
722
725
|
major: parseInt('2', 10),
|
|
723
|
-
minor: parseInt('
|
|
724
|
-
revision: parseInt('
|
|
726
|
+
minor: parseInt('3', 10),
|
|
727
|
+
revision: parseInt('0', 10)
|
|
725
728
|
};
|
|
726
729
|
|
|
727
730
|
|
|
@@ -874,7 +877,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
874
877
|
try {
|
|
875
878
|
// We test if the canvas is tainted by retrieving data from it.
|
|
876
879
|
// An exception will be raised if the canvas is tainted.
|
|
877
|
-
|
|
880
|
+
canvas.getContext('2d').getImageData(0, 0, 1, 1);
|
|
878
881
|
} catch (e) {
|
|
879
882
|
isTainted = true;
|
|
880
883
|
}
|
|
@@ -882,7 +885,8 @@ if (typeof define === 'function' && define.amd) {
|
|
|
882
885
|
};
|
|
883
886
|
|
|
884
887
|
/**
|
|
885
|
-
* A ratio comparing the device screen's pixel density to the canvas's backing store pixel density
|
|
888
|
+
* A ratio comparing the device screen's pixel density to the canvas's backing store pixel density,
|
|
889
|
+
* clamped to a minimum of 1. Defaults to 1 if canvas isn't supported by the browser.
|
|
886
890
|
* @member {Number} pixelDensityRatio
|
|
887
891
|
* @memberof OpenSeadragon
|
|
888
892
|
*/
|
|
@@ -895,7 +899,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
895
899
|
context.msBackingStorePixelRatio ||
|
|
896
900
|
context.oBackingStorePixelRatio ||
|
|
897
901
|
context.backingStorePixelRatio || 1;
|
|
898
|
-
return devicePixelRatio / backingStoreRatio;
|
|
902
|
+
return Math.max(devicePixelRatio, 1) / backingStoreRatio;
|
|
899
903
|
} else {
|
|
900
904
|
return 1;
|
|
901
905
|
}
|
|
@@ -1020,6 +1024,8 @@ if (typeof define === 'function' && define.amd) {
|
|
|
1020
1024
|
initialPage: 0,
|
|
1021
1025
|
crossOriginPolicy: false,
|
|
1022
1026
|
ajaxWithCredentials: false,
|
|
1027
|
+
loadTilesWithAjax: false,
|
|
1028
|
+
ajaxHeaders: {},
|
|
1023
1029
|
|
|
1024
1030
|
//PAN AND ZOOM SETTINGS AND CONSTRAINTS
|
|
1025
1031
|
panHorizontal: true,
|
|
@@ -1041,10 +1047,46 @@ if (typeof define === 'function' && define.amd) {
|
|
|
1041
1047
|
dblClickDistThreshold: 20,
|
|
1042
1048
|
springStiffness: 6.5,
|
|
1043
1049
|
animationTime: 1.2,
|
|
1044
|
-
gestureSettingsMouse: {
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1050
|
+
gestureSettingsMouse: {
|
|
1051
|
+
scrollToZoom: true,
|
|
1052
|
+
clickToZoom: true,
|
|
1053
|
+
dblClickToZoom: false,
|
|
1054
|
+
pinchToZoom: false,
|
|
1055
|
+
flickEnabled: false,
|
|
1056
|
+
flickMinSpeed: 120,
|
|
1057
|
+
flickMomentum: 0.25,
|
|
1058
|
+
pinchRotate: false
|
|
1059
|
+
},
|
|
1060
|
+
gestureSettingsTouch: {
|
|
1061
|
+
scrollToZoom: false,
|
|
1062
|
+
clickToZoom: false,
|
|
1063
|
+
dblClickToZoom: true,
|
|
1064
|
+
pinchToZoom: true,
|
|
1065
|
+
flickEnabled: true,
|
|
1066
|
+
flickMinSpeed: 120,
|
|
1067
|
+
flickMomentum: 0.25,
|
|
1068
|
+
pinchRotate: false
|
|
1069
|
+
},
|
|
1070
|
+
gestureSettingsPen: {
|
|
1071
|
+
scrollToZoom: false,
|
|
1072
|
+
clickToZoom: true,
|
|
1073
|
+
dblClickToZoom: false,
|
|
1074
|
+
pinchToZoom: false,
|
|
1075
|
+
flickEnabled: false,
|
|
1076
|
+
flickMinSpeed: 120,
|
|
1077
|
+
flickMomentum: 0.25,
|
|
1078
|
+
pinchRotate: false
|
|
1079
|
+
},
|
|
1080
|
+
gestureSettingsUnknown: {
|
|
1081
|
+
scrollToZoom: false,
|
|
1082
|
+
clickToZoom: false,
|
|
1083
|
+
dblClickToZoom: true,
|
|
1084
|
+
pinchToZoom: true,
|
|
1085
|
+
flickEnabled: true,
|
|
1086
|
+
flickMinSpeed: 120,
|
|
1087
|
+
flickMomentum: 0.25,
|
|
1088
|
+
pinchRotate: false
|
|
1089
|
+
},
|
|
1048
1090
|
zoomPerClick: 2,
|
|
1049
1091
|
zoomPerScroll: 1.2,
|
|
1050
1092
|
zoomPerSecond: 1.0,
|
|
@@ -1096,6 +1138,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
1096
1138
|
|
|
1097
1139
|
// APPEARANCE
|
|
1098
1140
|
opacity: 1,
|
|
1141
|
+
preload: false,
|
|
1099
1142
|
compositeOperation: null,
|
|
1100
1143
|
placeholderFillStyle: null,
|
|
1101
1144
|
|
|
@@ -1390,6 +1433,21 @@ if (typeof define === 'function' && define.amd) {
|
|
|
1390
1433
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
1391
1434
|
},
|
|
1392
1435
|
|
|
1436
|
+
/**
|
|
1437
|
+
* Compute the modulo of a number but makes sure to always return
|
|
1438
|
+
* a positive value.
|
|
1439
|
+
* @param {Number} number the number to computes the modulo of
|
|
1440
|
+
* @param {Number} modulo the modulo
|
|
1441
|
+
* @returns {Number} the result of the modulo of number
|
|
1442
|
+
*/
|
|
1443
|
+
positiveModulo: function(number, modulo) {
|
|
1444
|
+
var result = number % modulo;
|
|
1445
|
+
if (result < 0) {
|
|
1446
|
+
result += modulo;
|
|
1447
|
+
}
|
|
1448
|
+
return result;
|
|
1449
|
+
},
|
|
1450
|
+
|
|
1393
1451
|
/**
|
|
1394
1452
|
* Determines if a point is within the bounding rectangle of the given element (hit-test).
|
|
1395
1453
|
* @function
|
|
@@ -1504,7 +1562,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
1504
1562
|
};
|
|
1505
1563
|
} else {
|
|
1506
1564
|
// We can't reassign the function yet, as there was no scroll.
|
|
1507
|
-
return new $.Point(0,0);
|
|
1565
|
+
return new $.Point(0, 0);
|
|
1508
1566
|
}
|
|
1509
1567
|
|
|
1510
1568
|
return $.getPageScroll();
|
|
@@ -1672,13 +1730,15 @@ if (typeof define === 'function' && define.amd) {
|
|
|
1672
1730
|
* @function
|
|
1673
1731
|
*/
|
|
1674
1732
|
now: function( ) {
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1733
|
+
if (Date.now) {
|
|
1734
|
+
$.now = Date.now;
|
|
1735
|
+
} else {
|
|
1736
|
+
$.now = function() {
|
|
1737
|
+
return new Date().getTime();
|
|
1738
|
+
};
|
|
1739
|
+
}
|
|
1680
1740
|
|
|
1681
|
-
|
|
1741
|
+
return $.now();
|
|
1682
1742
|
},
|
|
1683
1743
|
|
|
1684
1744
|
|
|
@@ -1788,7 +1848,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
1788
1848
|
addClass: function( element, className ) {
|
|
1789
1849
|
element = $.getElement( element );
|
|
1790
1850
|
|
|
1791
|
-
if (
|
|
1851
|
+
if (!element.className) {
|
|
1792
1852
|
element.className = className;
|
|
1793
1853
|
} else if ( ( ' ' + element.className + ' ' ).
|
|
1794
1854
|
indexOf( ' ' + className + ' ' ) === -1 ) {
|
|
@@ -2012,6 +2072,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2012
2072
|
* @returns {String} The value of the url parameter or null if no param matches.
|
|
2013
2073
|
*/
|
|
2014
2074
|
getUrlParameter: function( key ) {
|
|
2075
|
+
// eslint-disable-next-line no-use-before-define
|
|
2015
2076
|
var value = URLPARAMS[ key ];
|
|
2016
2077
|
return value ? value : null;
|
|
2017
2078
|
},
|
|
@@ -2081,11 +2142,16 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2081
2142
|
* @param {String} options.url - the url to request
|
|
2082
2143
|
* @param {Function} options.success - a function to call on a successful response
|
|
2083
2144
|
* @param {Function} options.error - a function to call on when an error occurs
|
|
2145
|
+
* @param {Object} options.headers - headers to add to the AJAX request
|
|
2146
|
+
* @param {String} options.responseType - the response type of the the AJAX request
|
|
2084
2147
|
* @param {Boolean} [options.withCredentials=false] - whether to set the XHR's withCredentials
|
|
2085
2148
|
* @throws {Error}
|
|
2149
|
+
* @returns {XMLHttpRequest}
|
|
2086
2150
|
*/
|
|
2087
2151
|
makeAjaxRequest: function( url, onSuccess, onError ) {
|
|
2088
2152
|
var withCredentials;
|
|
2153
|
+
var headers;
|
|
2154
|
+
var responseType;
|
|
2089
2155
|
|
|
2090
2156
|
// Note that our preferred API is that you pass in a single object; the named
|
|
2091
2157
|
// arguments are for legacy support.
|
|
@@ -2093,6 +2159,8 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2093
2159
|
onSuccess = url.success;
|
|
2094
2160
|
onError = url.error;
|
|
2095
2161
|
withCredentials = url.withCredentials;
|
|
2162
|
+
headers = url.headers;
|
|
2163
|
+
responseType = url.responseType || null;
|
|
2096
2164
|
url = url.url;
|
|
2097
2165
|
}
|
|
2098
2166
|
|
|
@@ -2108,9 +2176,9 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2108
2176
|
if ( request.readyState == 4 ) {
|
|
2109
2177
|
request.onreadystatechange = function(){};
|
|
2110
2178
|
|
|
2111
|
-
// With protocols other than http/https,
|
|
2112
|
-
// on Firefox and 0 on other browsers
|
|
2113
|
-
if ( request.status
|
|
2179
|
+
// With protocols other than http/https, a successful request status is in
|
|
2180
|
+
// the 200's on Firefox and 0 on other browsers
|
|
2181
|
+
if ( (request.status >= 200 && request.status < 300) ||
|
|
2114
2182
|
( request.status === 0 &&
|
|
2115
2183
|
protocol !== "http:" &&
|
|
2116
2184
|
protocol !== "https:" )) {
|
|
@@ -2125,13 +2193,26 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2125
2193
|
}
|
|
2126
2194
|
};
|
|
2127
2195
|
|
|
2128
|
-
if (withCredentials) {
|
|
2129
|
-
request.withCredentials = true;
|
|
2130
|
-
}
|
|
2131
|
-
|
|
2132
2196
|
try {
|
|
2133
2197
|
request.open( "GET", url, true );
|
|
2134
|
-
|
|
2198
|
+
|
|
2199
|
+
if (responseType) {
|
|
2200
|
+
request.responseType = responseType;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
if (headers) {
|
|
2204
|
+
for (var headerName in headers) {
|
|
2205
|
+
if (headers.hasOwnProperty(headerName) && headers[headerName]) {
|
|
2206
|
+
request.setRequestHeader(headerName, headers[headerName]);
|
|
2207
|
+
}
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
|
|
2211
|
+
if (withCredentials) {
|
|
2212
|
+
request.withCredentials = true;
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
request.send(null);
|
|
2135
2216
|
} catch (e) {
|
|
2136
2217
|
var msg = e.message;
|
|
2137
2218
|
|
|
@@ -2168,7 +2249,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2168
2249
|
}
|
|
2169
2250
|
};
|
|
2170
2251
|
xdr.onerror = function (e) {
|
|
2171
|
-
if (
|
|
2252
|
+
if ($.isFunction(onError)) {
|
|
2172
2253
|
onError({ // Faking an xhr object
|
|
2173
2254
|
responseText: xdr.responseText,
|
|
2174
2255
|
status: 444, // 444 No Response
|
|
@@ -2191,6 +2272,8 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2191
2272
|
}
|
|
2192
2273
|
}
|
|
2193
2274
|
}
|
|
2275
|
+
|
|
2276
|
+
return request;
|
|
2194
2277
|
},
|
|
2195
2278
|
|
|
2196
2279
|
/**
|
|
@@ -2331,6 +2414,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2331
2414
|
// Should only be used by IE8 in non standards mode
|
|
2332
2415
|
$.parseJSON = function(string) {
|
|
2333
2416
|
/*jshint evil:true*/
|
|
2417
|
+
//eslint-disable-next-line no-eval
|
|
2334
2418
|
return eval('(' + string + ')');
|
|
2335
2419
|
};
|
|
2336
2420
|
}
|
|
@@ -2346,6 +2430,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2346
2430
|
*/
|
|
2347
2431
|
imageFormatSupported: function( extension ) {
|
|
2348
2432
|
extension = extension ? extension : "";
|
|
2433
|
+
// eslint-disable-next-line no-use-before-define
|
|
2349
2434
|
return !!FILEFORMATS[ extension.toLowerCase() ];
|
|
2350
2435
|
}
|
|
2351
2436
|
|
|
@@ -2382,8 +2467,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2382
2467
|
(function() {
|
|
2383
2468
|
//A small auto-executing routine to determine the browser vendor,
|
|
2384
2469
|
//version and supporting feature sets.
|
|
2385
|
-
var
|
|
2386
|
-
ver = navigator.appVersion,
|
|
2470
|
+
var ver = navigator.appVersion,
|
|
2387
2471
|
ua = navigator.userAgent,
|
|
2388
2472
|
regex;
|
|
2389
2473
|
|
|
@@ -2405,7 +2489,7 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2405
2489
|
}
|
|
2406
2490
|
break;
|
|
2407
2491
|
case "Netscape":
|
|
2408
|
-
if(
|
|
2492
|
+
if (window.addEventListener) {
|
|
2409
2493
|
if ( ua.indexOf( "Firefox" ) >= 0 ) {
|
|
2410
2494
|
$.Browser.vendor = $.BROWSERS.FIREFOX;
|
|
2411
2495
|
$.Browser.version = parseFloat(
|
|
@@ -2602,6 +2686,23 @@ if (typeof define === 'function' && define.amd) {
|
|
|
2602
2686
|
|
|
2603
2687
|
}(OpenSeadragon));
|
|
2604
2688
|
|
|
2689
|
+
|
|
2690
|
+
// Universal Module Definition, supports CommonJS, AMD and simple script tag
|
|
2691
|
+
(function (root, factory) {
|
|
2692
|
+
if (typeof define === 'function' && define.amd) {
|
|
2693
|
+
// expose as amd module
|
|
2694
|
+
define([], factory);
|
|
2695
|
+
} else if (typeof module === 'object' && module.exports) {
|
|
2696
|
+
// expose as commonjs module
|
|
2697
|
+
module.exports = factory();
|
|
2698
|
+
} else {
|
|
2699
|
+
// expose as window.OpenSeadragon
|
|
2700
|
+
root.OpenSeadragon = factory();
|
|
2701
|
+
}
|
|
2702
|
+
}(this, function () {
|
|
2703
|
+
return OpenSeadragon;
|
|
2704
|
+
}));
|
|
2705
|
+
|
|
2605
2706
|
/*
|
|
2606
2707
|
* OpenSeadragon - full-screen support functions
|
|
2607
2708
|
*
|
|
@@ -3100,6 +3201,7 @@ $.EventSource.prototype = {
|
|
|
3100
3201
|
* @memberof OpenSeadragon.MouseTracker#
|
|
3101
3202
|
*/
|
|
3102
3203
|
this.dblClickDistThreshold = options.dblClickDistThreshold || $.DEFAULT_SETTINGS.dblClickDistThreshold;
|
|
3204
|
+
/*eslint-disable no-multi-spaces*/
|
|
3103
3205
|
this.userData = options.userData || null;
|
|
3104
3206
|
this.stopDelay = options.stopDelay || 50;
|
|
3105
3207
|
|
|
@@ -3122,6 +3224,7 @@ $.EventSource.prototype = {
|
|
|
3122
3224
|
this.keyHandler = options.keyHandler || null;
|
|
3123
3225
|
this.focusHandler = options.focusHandler || null;
|
|
3124
3226
|
this.blurHandler = options.blurHandler || null;
|
|
3227
|
+
/*eslint-enable no-multi-spaces*/
|
|
3125
3228
|
|
|
3126
3229
|
//Store private properties in a scope sealed hash map
|
|
3127
3230
|
var _this = this;
|
|
@@ -3255,6 +3358,25 @@ $.EventSource.prototype = {
|
|
|
3255
3358
|
return this;
|
|
3256
3359
|
},
|
|
3257
3360
|
|
|
3361
|
+
/**
|
|
3362
|
+
* Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for all but the given pointer device type.
|
|
3363
|
+
* @function
|
|
3364
|
+
* @param {String} type - The pointer device type: "mouse", "touch", "pen", etc.
|
|
3365
|
+
* @returns {Array.<OpenSeadragon.MouseTracker.GesturePointList>}
|
|
3366
|
+
*/
|
|
3367
|
+
getActivePointersListsExceptType: function ( type ) {
|
|
3368
|
+
var delegate = THIS[ this.hash ];
|
|
3369
|
+
var listArray = [];
|
|
3370
|
+
|
|
3371
|
+
for (var i = 0; i < delegate.activePointersLists.length; ++i) {
|
|
3372
|
+
if (delegate.activePointersLists[i].type !== type) {
|
|
3373
|
+
listArray.push(delegate.activePointersLists[i]);
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
|
|
3377
|
+
return listArray;
|
|
3378
|
+
},
|
|
3379
|
+
|
|
3258
3380
|
/**
|
|
3259
3381
|
* Returns the {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} for the given pointer device type,
|
|
3260
3382
|
* creating and caching a new {@link OpenSeadragon.MouseTracker.GesturePointList|GesturePointList} if one doesn't already exist for the type.
|
|
@@ -3800,6 +3922,21 @@ $.EventSource.prototype = {
|
|
|
3800
3922
|
blurHandler: function () { }
|
|
3801
3923
|
};
|
|
3802
3924
|
|
|
3925
|
+
/**
|
|
3926
|
+
* Resets all active mousetrakers. (Added to patch issue #697 "Mouse up outside map will cause "canvas-drag" event to stick")
|
|
3927
|
+
*
|
|
3928
|
+
* @private
|
|
3929
|
+
* @member resetAllMouseTrackers
|
|
3930
|
+
* @memberof OpenSeadragon.MouseTracker
|
|
3931
|
+
*/
|
|
3932
|
+
$.MouseTracker.resetAllMouseTrackers = function(){
|
|
3933
|
+
for(var i = 0; i < MOUSETRACKERS.length; i++){
|
|
3934
|
+
if (MOUSETRACKERS[i].isTracking()){
|
|
3935
|
+
MOUSETRACKERS[i].setTracking(false);
|
|
3936
|
+
MOUSETRACKERS[i].setTracking(true);
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
};
|
|
3803
3940
|
|
|
3804
3941
|
/**
|
|
3805
3942
|
* Provides continuous computation of velocity (speed and direction) of active pointers.
|
|
@@ -4139,6 +4276,30 @@ $.EventSource.prototype = {
|
|
|
4139
4276
|
}
|
|
4140
4277
|
}
|
|
4141
4278
|
return null;
|
|
4279
|
+
},
|
|
4280
|
+
|
|
4281
|
+
/**
|
|
4282
|
+
* @function Increment this pointer's contact count.
|
|
4283
|
+
* It will evaluate whether this pointer type is allowed to have multiple contacts.
|
|
4284
|
+
*/
|
|
4285
|
+
addContact: function() {
|
|
4286
|
+
++this.contacts;
|
|
4287
|
+
|
|
4288
|
+
if (this.contacts > 1 && (this.type === "mouse" || this.type === "pen")) {
|
|
4289
|
+
this.contacts = 1;
|
|
4290
|
+
}
|
|
4291
|
+
},
|
|
4292
|
+
|
|
4293
|
+
/**
|
|
4294
|
+
* @function Decrement this pointer's contact count.
|
|
4295
|
+
* It will make sure the count does not go below 0.
|
|
4296
|
+
*/
|
|
4297
|
+
removeContact: function() {
|
|
4298
|
+
--this.contacts;
|
|
4299
|
+
|
|
4300
|
+
if (this.contacts < 0) {
|
|
4301
|
+
this.contacts = 0;
|
|
4302
|
+
}
|
|
4142
4303
|
}
|
|
4143
4304
|
};
|
|
4144
4305
|
|
|
@@ -4310,6 +4471,7 @@ $.EventSource.prototype = {
|
|
|
4310
4471
|
eventParams = getCaptureEventParams( tracker, $.MouseTracker.havePointerEvents ? 'pointerevent' : pointerType );
|
|
4311
4472
|
// We emulate mouse capture by hanging listeners on the document object.
|
|
4312
4473
|
// (Note we listen on the capture phase so the captured handlers will get called first)
|
|
4474
|
+
// eslint-disable-next-line no-use-before-define
|
|
4313
4475
|
if (isInIframe && canAccessEvents(window.top)) {
|
|
4314
4476
|
$.addEvent(
|
|
4315
4477
|
window.top,
|
|
@@ -4353,6 +4515,7 @@ $.EventSource.prototype = {
|
|
|
4353
4515
|
eventParams = getCaptureEventParams( tracker, $.MouseTracker.havePointerEvents ? 'pointerevent' : pointerType );
|
|
4354
4516
|
// We emulate mouse capture by hanging listeners on the document object.
|
|
4355
4517
|
// (Note we listen on the capture phase so the captured handlers will get called first)
|
|
4518
|
+
// eslint-disable-next-line no-use-before-define
|
|
4356
4519
|
if (isInIframe && canAccessEvents(window.top)) {
|
|
4357
4520
|
$.removeEvent(
|
|
4358
4521
|
window.top,
|
|
@@ -4643,7 +4806,7 @@ $.EventSource.prototype = {
|
|
|
4643
4806
|
|
|
4644
4807
|
// Calculate deltaY
|
|
4645
4808
|
if ( $.MouseTracker.wheelEventName == "mousewheel" ) {
|
|
4646
|
-
simulatedEvent.deltaY = -
|
|
4809
|
+
simulatedEvent.deltaY = -event.wheelDelta / $.DEFAULT_SETTINGS.pixelsPerWheelLine;
|
|
4647
4810
|
} else {
|
|
4648
4811
|
simulatedEvent.deltaY = event.detail;
|
|
4649
4812
|
}
|
|
@@ -4941,23 +5104,26 @@ $.EventSource.prototype = {
|
|
|
4941
5104
|
* @private
|
|
4942
5105
|
* @inner
|
|
4943
5106
|
*/
|
|
4944
|
-
function
|
|
5107
|
+
function abortContacts( tracker, event, pointsList ) {
|
|
4945
5108
|
var i,
|
|
4946
5109
|
gPointCount = pointsList.getLength(),
|
|
4947
5110
|
abortGPoints = [];
|
|
4948
5111
|
|
|
4949
|
-
|
|
4950
|
-
|
|
4951
|
-
|
|
5112
|
+
// Check contact count for hoverable pointer types before aborting
|
|
5113
|
+
if (pointsList.type === 'touch' || pointsList.contacts > 0) {
|
|
5114
|
+
for ( i = 0; i < gPointCount; i++ ) {
|
|
5115
|
+
abortGPoints.push( pointsList.getByIndex( i ) );
|
|
5116
|
+
}
|
|
4952
5117
|
|
|
4953
|
-
|
|
4954
|
-
|
|
4955
|
-
|
|
4956
|
-
|
|
4957
|
-
|
|
4958
|
-
|
|
4959
|
-
|
|
4960
|
-
|
|
5118
|
+
if ( abortGPoints.length > 0 ) {
|
|
5119
|
+
// simulate touchend/mouseup
|
|
5120
|
+
updatePointersUp( tracker, event, abortGPoints, 0 ); // 0 means primary button press/release or touch contact
|
|
5121
|
+
// release pointer capture
|
|
5122
|
+
pointsList.captureCount = 1;
|
|
5123
|
+
releasePointer( tracker, pointsList.type );
|
|
5124
|
+
// simulate touchleave/mouseout
|
|
5125
|
+
updatePointersExit( tracker, event, abortGPoints );
|
|
5126
|
+
}
|
|
4961
5127
|
}
|
|
4962
5128
|
}
|
|
4963
5129
|
|
|
@@ -4979,7 +5145,7 @@ $.EventSource.prototype = {
|
|
|
4979
5145
|
|
|
4980
5146
|
if ( pointsList.getLength() > event.touches.length - touchCount ) {
|
|
4981
5147
|
$.console.warn('Tracked touch contact count doesn\'t match event.touches.length. Removing all tracked touch pointers.');
|
|
4982
|
-
|
|
5148
|
+
abortContacts( tracker, event, pointsList );
|
|
4983
5149
|
}
|
|
4984
5150
|
|
|
4985
5151
|
for ( i = 0; i < touchCount; i++ ) {
|
|
@@ -5147,12 +5313,9 @@ $.EventSource.prototype = {
|
|
|
5147
5313
|
* @inner
|
|
5148
5314
|
*/
|
|
5149
5315
|
function onTouchCancel( tracker, event ) {
|
|
5150
|
-
var
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
pointsList = tracker.getActivePointersListByType( 'touch' );
|
|
5154
|
-
|
|
5155
|
-
abortTouchContacts( tracker, event, pointsList );
|
|
5316
|
+
var pointsList = tracker.getActivePointersListByType('touch');
|
|
5317
|
+
|
|
5318
|
+
abortContacts( tracker, event, pointsList );
|
|
5156
5319
|
}
|
|
5157
5320
|
|
|
5158
5321
|
|
|
@@ -5505,8 +5668,7 @@ $.EventSource.prototype = {
|
|
|
5505
5668
|
* Gesture points associated with the event.
|
|
5506
5669
|
*/
|
|
5507
5670
|
function updatePointersExit( tracker, event, gPoints ) {
|
|
5508
|
-
var
|
|
5509
|
-
pointsList = tracker.getActivePointersListByType( gPoints[ 0 ].type ),
|
|
5671
|
+
var pointsList = tracker.getActivePointersListByType(gPoints[0].type),
|
|
5510
5672
|
i,
|
|
5511
5673
|
gPointCount = gPoints.length,
|
|
5512
5674
|
curGPoint,
|
|
@@ -5630,6 +5792,14 @@ $.EventSource.prototype = {
|
|
|
5630
5792
|
}
|
|
5631
5793
|
}
|
|
5632
5794
|
|
|
5795
|
+
// Some pointers may steal control from another pointer without firing the appropriate release events
|
|
5796
|
+
// e.g. Touching a screen while click-dragging with certain mice.
|
|
5797
|
+
var otherPointsLists = tracker.getActivePointersListsExceptType(gPoints[ 0 ].type);
|
|
5798
|
+
for (i = 0; i < otherPointsLists.length; i++) {
|
|
5799
|
+
//If another pointer has contact, simulate the release
|
|
5800
|
+
abortContacts(tracker, event, otherPointsLists[i]); // No-op if no active pointer
|
|
5801
|
+
}
|
|
5802
|
+
|
|
5633
5803
|
// Only capture and track primary button, pen, and touch contacts
|
|
5634
5804
|
if ( buttonChanged !== 0 ) {
|
|
5635
5805
|
// Aux Press
|
|
@@ -5680,7 +5850,7 @@ $.EventSource.prototype = {
|
|
|
5680
5850
|
startTrackingPointer( pointsList, curGPoint );
|
|
5681
5851
|
}
|
|
5682
5852
|
|
|
5683
|
-
pointsList.
|
|
5853
|
+
pointsList.addContact();
|
|
5684
5854
|
//$.console.log('contacts++ ', pointsList.contacts);
|
|
5685
5855
|
|
|
5686
5856
|
if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {
|
|
@@ -5741,7 +5911,6 @@ $.EventSource.prototype = {
|
|
|
5741
5911
|
var delegate = THIS[ tracker.hash ],
|
|
5742
5912
|
pointsList = tracker.getActivePointersListByType( gPoints[ 0 ].type ),
|
|
5743
5913
|
propagate,
|
|
5744
|
-
insideElementReleased,
|
|
5745
5914
|
releasePoint,
|
|
5746
5915
|
releaseTime,
|
|
5747
5916
|
i,
|
|
@@ -5806,7 +5975,7 @@ $.EventSource.prototype = {
|
|
|
5806
5975
|
{
|
|
5807
5976
|
eventSource: tracker,
|
|
5808
5977
|
pointerType: gPoints[ 0 ].type,
|
|
5809
|
-
position: getPointRelativeToAbsolute(
|
|
5978
|
+
position: getPointRelativeToAbsolute(gPoints[0].currentPos, tracker.element),
|
|
5810
5979
|
button: buttonChanged,
|
|
5811
5980
|
buttons: pointsList.buttons,
|
|
5812
5981
|
isTouchEvent: gPoints[ 0 ].type === 'touch',
|
|
@@ -5820,6 +5989,11 @@ $.EventSource.prototype = {
|
|
|
5820
5989
|
}
|
|
5821
5990
|
}
|
|
5822
5991
|
|
|
5992
|
+
// A primary mouse button may have been released while the non-primary button was down
|
|
5993
|
+
var otherPointsList = tracker.getActivePointersListByType("mouse");
|
|
5994
|
+
// Stop tracking the mouse; see https://github.com/openseadragon/openseadragon/pull/1223
|
|
5995
|
+
abortContacts(tracker, event, otherPointsList); // No-op if no active pointer
|
|
5996
|
+
|
|
5823
5997
|
return false;
|
|
5824
5998
|
}
|
|
5825
5999
|
|
|
@@ -5848,7 +6022,7 @@ $.EventSource.prototype = {
|
|
|
5848
6022
|
if ( wasCaptured ) {
|
|
5849
6023
|
// Pointer was activated in our element but could have been removed in any element since events are captured to our element
|
|
5850
6024
|
|
|
5851
|
-
pointsList.
|
|
6025
|
+
pointsList.removeContact();
|
|
5852
6026
|
//$.console.log('contacts-- ', pointsList.contacts);
|
|
5853
6027
|
|
|
5854
6028
|
if ( tracker.dragHandler || tracker.dragEndHandler || tracker.pinchHandler ) {
|
|
@@ -6207,7 +6381,7 @@ $.EventSource.prototype = {
|
|
|
6207
6381
|
} );
|
|
6208
6382
|
}
|
|
6209
6383
|
}
|
|
6210
|
-
|
|
6384
|
+
|
|
6211
6385
|
// True if inside an iframe, otherwise false.
|
|
6212
6386
|
// @member {Boolean} isInIframe
|
|
6213
6387
|
// @private
|
|
@@ -6219,7 +6393,7 @@ $.EventSource.prototype = {
|
|
|
6219
6393
|
return true;
|
|
6220
6394
|
}
|
|
6221
6395
|
})();
|
|
6222
|
-
|
|
6396
|
+
|
|
6223
6397
|
// @function
|
|
6224
6398
|
// @private
|
|
6225
6399
|
// @inner
|
|
@@ -6232,7 +6406,7 @@ $.EventSource.prototype = {
|
|
|
6232
6406
|
}
|
|
6233
6407
|
}
|
|
6234
6408
|
|
|
6235
|
-
}
|
|
6409
|
+
}(OpenSeadragon));
|
|
6236
6410
|
|
|
6237
6411
|
/*
|
|
6238
6412
|
* OpenSeadragon - Control
|
|
@@ -6351,10 +6525,10 @@ $.Control = function ( element, options, container ) {
|
|
|
6351
6525
|
if ( this.anchor == $.ControlAnchor.ABSOLUTE ) {
|
|
6352
6526
|
this.wrapper = $.makeNeutralElement( "div" );
|
|
6353
6527
|
this.wrapper.style.position = "absolute";
|
|
6354
|
-
this.wrapper.style.top = typeof (
|
|
6355
|
-
this.wrapper.style.left = typeof (
|
|
6356
|
-
this.wrapper.style.height = typeof (
|
|
6357
|
-
this.wrapper.style.width = typeof (
|
|
6528
|
+
this.wrapper.style.top = typeof (options.top) == "number" ? (options.top + 'px') : options.top;
|
|
6529
|
+
this.wrapper.style.left = typeof (options.left) == "number" ? (options.left + 'px') : options.left;
|
|
6530
|
+
this.wrapper.style.height = typeof (options.height) == "number" ? (options.height + 'px') : options.height;
|
|
6531
|
+
this.wrapper.style.width = typeof (options.width) == "number" ? (options.width + 'px') : options.width;
|
|
6358
6532
|
this.wrapper.style.margin = "0px";
|
|
6359
6533
|
this.wrapper.style.padding = "0px";
|
|
6360
6534
|
|
|
@@ -6483,7 +6657,7 @@ $.Control.prototype = {
|
|
|
6483
6657
|
i;
|
|
6484
6658
|
|
|
6485
6659
|
$.extend( true, this, {
|
|
6486
|
-
id: 'controldock-'
|
|
6660
|
+
id: 'controldock-' + $.now() + '-' + Math.floor(Math.random() * 1000000),
|
|
6487
6661
|
container: $.makeNeutralElement( 'div' ),
|
|
6488
6662
|
controls: []
|
|
6489
6663
|
}, options );
|
|
@@ -6903,6 +7077,12 @@ $.Viewer = function( options ) {
|
|
|
6903
7077
|
//internal state and dom identifiers
|
|
6904
7078
|
id: options.id,
|
|
6905
7079
|
hash: options.hash || nextHash++,
|
|
7080
|
+
/**
|
|
7081
|
+
* Index for page to be shown first next time open() is called (only used in sequenceMode).
|
|
7082
|
+
* @member {Number} initialPage
|
|
7083
|
+
* @memberof OpenSeadragon.Viewer#
|
|
7084
|
+
*/
|
|
7085
|
+
initialPage: 0,
|
|
6906
7086
|
|
|
6907
7087
|
//dom nodes
|
|
6908
7088
|
/**
|
|
@@ -7028,7 +7208,7 @@ $.Viewer = function( options ) {
|
|
|
7028
7208
|
$.ControlDock.call( this, options );
|
|
7029
7209
|
|
|
7030
7210
|
//Deal with tile sources
|
|
7031
|
-
if (
|
|
7211
|
+
if (this.xmlPath) {
|
|
7032
7212
|
//Deprecated option. Now it is preferred to use the tileSources option
|
|
7033
7213
|
this.tileSources = [ this.xmlPath ];
|
|
7034
7214
|
}
|
|
@@ -7075,7 +7255,7 @@ $.Viewer = function( options ) {
|
|
|
7075
7255
|
|
|
7076
7256
|
this.innerTracker = new $.MouseTracker({
|
|
7077
7257
|
element: this.canvas,
|
|
7078
|
-
startDisabled: this.mouseNavEnabled
|
|
7258
|
+
startDisabled: !this.mouseNavEnabled,
|
|
7079
7259
|
clickTimeThreshold: this.clickTimeThreshold,
|
|
7080
7260
|
clickDistThreshold: this.clickDistThreshold,
|
|
7081
7261
|
dblClickTimeThreshold: this.dblClickTimeThreshold,
|
|
@@ -7098,7 +7278,7 @@ $.Viewer = function( options ) {
|
|
|
7098
7278
|
|
|
7099
7279
|
this.outerTracker = new $.MouseTracker({
|
|
7100
7280
|
element: this.container,
|
|
7101
|
-
startDisabled: this.mouseNavEnabled
|
|
7281
|
+
startDisabled: !this.mouseNavEnabled,
|
|
7102
7282
|
clickTimeThreshold: this.clickTimeThreshold,
|
|
7103
7283
|
clickDistThreshold: this.clickDistThreshold,
|
|
7104
7284
|
dblClickTimeThreshold: this.dblClickTimeThreshold,
|
|
@@ -7177,7 +7357,8 @@ $.Viewer = function( options ) {
|
|
|
7177
7357
|
|
|
7178
7358
|
// Create the image loader
|
|
7179
7359
|
this.imageLoader = new $.ImageLoader({
|
|
7180
|
-
jobLimit: this.imageLoaderLimit
|
|
7360
|
+
jobLimit: this.imageLoaderLimit,
|
|
7361
|
+
timeout: options.timeout
|
|
7181
7362
|
});
|
|
7182
7363
|
|
|
7183
7364
|
// Create the tile cache
|
|
@@ -7288,11 +7469,13 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
7288
7469
|
* except for the index property; images are added in sequence.
|
|
7289
7470
|
* A TileSource specifier is anything you could pass as the tileSource property
|
|
7290
7471
|
* of the options parameter for {@link OpenSeadragon.Viewer#addTiledImage}.
|
|
7472
|
+
* @param {Number} initialPage - If sequenceMode is true, display this page initially
|
|
7473
|
+
* for the given tileSources. If specified, will overwrite the Viewer's existing initialPage property.
|
|
7291
7474
|
* @return {OpenSeadragon.Viewer} Chainable.
|
|
7292
7475
|
* @fires OpenSeadragon.Viewer.event:open
|
|
7293
7476
|
* @fires OpenSeadragon.Viewer.event:open-failed
|
|
7294
7477
|
*/
|
|
7295
|
-
open: function (tileSources) {
|
|
7478
|
+
open: function (tileSources, initialPage) {
|
|
7296
7479
|
var _this = this;
|
|
7297
7480
|
|
|
7298
7481
|
this.close();
|
|
@@ -7307,23 +7490,17 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
7307
7490
|
this.referenceStrip = null;
|
|
7308
7491
|
}
|
|
7309
7492
|
|
|
7493
|
+
if (typeof initialPage != 'undefined' && !isNaN(initialPage)) {
|
|
7494
|
+
this.initialPage = initialPage;
|
|
7495
|
+
}
|
|
7496
|
+
|
|
7310
7497
|
this.tileSources = tileSources;
|
|
7311
7498
|
this._sequenceIndex = Math.max(0, Math.min(this.tileSources.length - 1, this.initialPage));
|
|
7312
7499
|
if (this.tileSources.length) {
|
|
7313
7500
|
this.open(this.tileSources[this._sequenceIndex]);
|
|
7314
7501
|
|
|
7315
7502
|
if ( this.showReferenceStrip ){
|
|
7316
|
-
this.
|
|
7317
|
-
id: this.referenceStripElement,
|
|
7318
|
-
position: this.referenceStripPosition,
|
|
7319
|
-
sizeRatio: this.referenceStripSizeRatio,
|
|
7320
|
-
scroll: this.referenceStripScroll,
|
|
7321
|
-
height: this.referenceStripHeight,
|
|
7322
|
-
width: this.referenceStripWidth,
|
|
7323
|
-
tileSources: this.tileSources,
|
|
7324
|
-
prefixUrl: this.prefixUrl,
|
|
7325
|
-
viewer: this
|
|
7326
|
-
});
|
|
7503
|
+
this.addReferenceStrip();
|
|
7327
7504
|
}
|
|
7328
7505
|
}
|
|
7329
7506
|
|
|
@@ -7481,7 +7658,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
7481
7658
|
this.navigator.close();
|
|
7482
7659
|
}
|
|
7483
7660
|
|
|
7484
|
-
if(
|
|
7661
|
+
if (!this.preserveOverlays) {
|
|
7485
7662
|
this.clearOverlays();
|
|
7486
7663
|
this.overlaysContainer.innerHTML = "";
|
|
7487
7664
|
}
|
|
@@ -7652,6 +7829,22 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
7652
7829
|
return this;
|
|
7653
7830
|
},
|
|
7654
7831
|
|
|
7832
|
+
/**
|
|
7833
|
+
* Turns debugging mode on or off for this viewer.
|
|
7834
|
+
*
|
|
7835
|
+
* @function
|
|
7836
|
+
* @param {Boolean} true to turn debug on, false to turn debug off.
|
|
7837
|
+
*/
|
|
7838
|
+
setDebugMode: function(debugMode){
|
|
7839
|
+
|
|
7840
|
+
for (var i = 0; i < this.world.getItemCount(); i++) {
|
|
7841
|
+
this.world.getItemAt(i).debugMode = debugMode;
|
|
7842
|
+
}
|
|
7843
|
+
|
|
7844
|
+
this.debugMode = debugMode;
|
|
7845
|
+
this.forceRedraw();
|
|
7846
|
+
},
|
|
7847
|
+
|
|
7655
7848
|
/**
|
|
7656
7849
|
* @function
|
|
7657
7850
|
* @return {Boolean}
|
|
@@ -7676,7 +7869,6 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
7676
7869
|
bodyStyle = body.style,
|
|
7677
7870
|
docStyle = document.documentElement.style,
|
|
7678
7871
|
_this = this,
|
|
7679
|
-
hash,
|
|
7680
7872
|
nodes,
|
|
7681
7873
|
i;
|
|
7682
7874
|
|
|
@@ -7838,9 +8030,9 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
7838
8030
|
$.setPageScroll( _this.pageScroll );
|
|
7839
8031
|
var pageScroll = $.getPageScroll();
|
|
7840
8032
|
restoreScrollCounter++;
|
|
7841
|
-
if (
|
|
7842
|
-
pageScroll.x !== _this.pageScroll.x ||
|
|
7843
|
-
pageScroll.y !== _this.pageScroll.y
|
|
8033
|
+
if (restoreScrollCounter < 10 &&
|
|
8034
|
+
(pageScroll.x !== _this.pageScroll.x ||
|
|
8035
|
+
pageScroll.y !== _this.pageScroll.y)) {
|
|
7844
8036
|
$.requestAnimationFrame( restoreScroll );
|
|
7845
8037
|
}
|
|
7846
8038
|
};
|
|
@@ -8034,8 +8226,22 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8034
8226
|
* @param {OpenSeadragon.Rect} [options.clip] - An area, in image pixels, to clip to
|
|
8035
8227
|
* (portions of the image outside of this area will not be visible). Only works on
|
|
8036
8228
|
* browsers that support the HTML5 canvas.
|
|
8037
|
-
* @param {Number} [options.opacity]
|
|
8229
|
+
* @param {Number} [options.opacity=1] Proportional opacity of the tiled images (1=opaque, 0=hidden)
|
|
8230
|
+
* @param {Boolean} [options.preload=false] Default switch for loading hidden images (true loads, false blocks)
|
|
8231
|
+
* @param {Number} [options.degrees=0] Initial rotation of the tiled image around
|
|
8232
|
+
* its top left corner in degrees.
|
|
8038
8233
|
* @param {String} [options.compositeOperation] How the image is composited onto other images.
|
|
8234
|
+
* @param {String} [options.crossOriginPolicy] The crossOriginPolicy for this specific image,
|
|
8235
|
+
* overriding viewer.crossOriginPolicy.
|
|
8236
|
+
* @param {Boolean} [options.ajaxWithCredentials] Whether to set withCredentials on tile AJAX
|
|
8237
|
+
* @param {Boolean} [options.loadTilesWithAjax]
|
|
8238
|
+
* Whether to load tile data using AJAX requests.
|
|
8239
|
+
* Defaults to the setting in {@link OpenSeadragon.Options}.
|
|
8240
|
+
* @param {Object} [options.ajaxHeaders]
|
|
8241
|
+
* A set of headers to include when making tile AJAX requests.
|
|
8242
|
+
* Note that these headers will be merged over any headers specified in {@link OpenSeadragon.Options}.
|
|
8243
|
+
* Specifying a falsy value for a header will clear its existing value set at the Viewer level (if any).
|
|
8244
|
+
* requests.
|
|
8039
8245
|
* @param {Function} [options.success] A function that gets called when the image is
|
|
8040
8246
|
* successfully added. It's passed the event object which contains a single property:
|
|
8041
8247
|
* "item", the resulting TiledImage.
|
|
@@ -8068,9 +8274,26 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8068
8274
|
if (options.opacity === undefined) {
|
|
8069
8275
|
options.opacity = this.opacity;
|
|
8070
8276
|
}
|
|
8277
|
+
if (options.preload === undefined) {
|
|
8278
|
+
options.preload = this.preload;
|
|
8279
|
+
}
|
|
8071
8280
|
if (options.compositeOperation === undefined) {
|
|
8072
8281
|
options.compositeOperation = this.compositeOperation;
|
|
8073
8282
|
}
|
|
8283
|
+
if (options.crossOriginPolicy === undefined) {
|
|
8284
|
+
options.crossOriginPolicy = options.tileSource.crossOriginPolicy !== undefined ? options.tileSource.crossOriginPolicy : this.crossOriginPolicy;
|
|
8285
|
+
}
|
|
8286
|
+
if (options.ajaxWithCredentials === undefined) {
|
|
8287
|
+
options.ajaxWithCredentials = this.ajaxWithCredentials;
|
|
8288
|
+
}
|
|
8289
|
+
if (options.loadTilesWithAjax === undefined) {
|
|
8290
|
+
options.loadTilesWithAjax = this.loadTilesWithAjax;
|
|
8291
|
+
}
|
|
8292
|
+
if (options.ajaxHeaders === undefined || options.ajaxHeaders === null) {
|
|
8293
|
+
options.ajaxHeaders = this.ajaxHeaders;
|
|
8294
|
+
} else if ($.isPlainObject(options.ajaxHeaders) && $.isPlainObject(this.ajaxHeaders)) {
|
|
8295
|
+
options.ajaxHeaders = $.extend({}, this.ajaxHeaders, options.ajaxHeaders);
|
|
8296
|
+
}
|
|
8074
8297
|
|
|
8075
8298
|
var myQueueItem = {
|
|
8076
8299
|
options: options
|
|
@@ -8133,11 +8356,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8133
8356
|
|
|
8134
8357
|
this._loadQueue.push(myQueueItem);
|
|
8135
8358
|
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
myQueueItem.tileSource = tileSource;
|
|
8139
|
-
|
|
8140
|
-
// add everybody at the front of the queue that's ready to go
|
|
8359
|
+
function processReadyItems() {
|
|
8141
8360
|
var queueItem, tiledImage, optionsClone;
|
|
8142
8361
|
while (_this._loadQueue.length) {
|
|
8143
8362
|
queueItem = _this._loadQueue[0];
|
|
@@ -8171,6 +8390,8 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8171
8390
|
clip: queueItem.options.clip,
|
|
8172
8391
|
placeholderFillStyle: queueItem.options.placeholderFillStyle,
|
|
8173
8392
|
opacity: queueItem.options.opacity,
|
|
8393
|
+
preload: queueItem.options.preload,
|
|
8394
|
+
degrees: queueItem.options.degrees,
|
|
8174
8395
|
compositeOperation: queueItem.options.compositeOperation,
|
|
8175
8396
|
springStiffness: _this.springStiffness,
|
|
8176
8397
|
animationTime: _this.animationTime,
|
|
@@ -8183,7 +8404,10 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8183
8404
|
minPixelRatio: _this.minPixelRatio,
|
|
8184
8405
|
smoothTileEdgesMinZoom: _this.smoothTileEdgesMinZoom,
|
|
8185
8406
|
iOSDevice: _this.iOSDevice,
|
|
8186
|
-
crossOriginPolicy:
|
|
8407
|
+
crossOriginPolicy: queueItem.options.crossOriginPolicy,
|
|
8408
|
+
ajaxWithCredentials: queueItem.options.ajaxWithCredentials,
|
|
8409
|
+
loadTilesWithAjax: queueItem.options.loadTilesWithAjax,
|
|
8410
|
+
ajaxHeaders: queueItem.options.ajaxHeaders,
|
|
8187
8411
|
debugMode: _this.debugMode
|
|
8188
8412
|
});
|
|
8189
8413
|
|
|
@@ -8219,9 +8443,20 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8219
8443
|
});
|
|
8220
8444
|
}
|
|
8221
8445
|
}
|
|
8446
|
+
}
|
|
8447
|
+
|
|
8448
|
+
getTileSourceImplementation( this, options.tileSource, options, function( tileSource ) {
|
|
8449
|
+
|
|
8450
|
+
myQueueItem.tileSource = tileSource;
|
|
8451
|
+
|
|
8452
|
+
// add everybody at the front of the queue that's ready to go
|
|
8453
|
+
processReadyItems();
|
|
8222
8454
|
}, function( event ) {
|
|
8223
8455
|
event.options = options;
|
|
8224
8456
|
raiseAddItemFailed(event);
|
|
8457
|
+
|
|
8458
|
+
// add everybody at the front of the queue that's ready to go
|
|
8459
|
+
processReadyItems();
|
|
8225
8460
|
} );
|
|
8226
8461
|
},
|
|
8227
8462
|
|
|
@@ -8325,7 +8560,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8325
8560
|
onNextHandler = $.delegate( this, onNext ),
|
|
8326
8561
|
onPreviousHandler = $.delegate( this, onPrevious ),
|
|
8327
8562
|
navImages = this.navImages,
|
|
8328
|
-
useGroup = true
|
|
8563
|
+
useGroup = true;
|
|
8329
8564
|
|
|
8330
8565
|
if( this.showSequenceControl ){
|
|
8331
8566
|
|
|
@@ -8421,7 +8656,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8421
8656
|
onBlurHandler = $.delegate( this, onBlur ),
|
|
8422
8657
|
navImages = this.navImages,
|
|
8423
8658
|
buttons = [],
|
|
8424
|
-
useGroup = true
|
|
8659
|
+
useGroup = true;
|
|
8425
8660
|
|
|
8426
8661
|
|
|
8427
8662
|
if ( this.showNavigationControl ) {
|
|
@@ -8548,7 +8783,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8548
8783
|
if( this.toolbar ){
|
|
8549
8784
|
this.toolbar.addControl(
|
|
8550
8785
|
this.navControl,
|
|
8551
|
-
{anchor: $.ControlAnchor.TOP_LEFT}
|
|
8786
|
+
{anchor: this.navigationControlAnchor || $.ControlAnchor.TOP_LEFT}
|
|
8552
8787
|
);
|
|
8553
8788
|
} else {
|
|
8554
8789
|
this.addControl(
|
|
@@ -8792,7 +9027,7 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8792
9027
|
element = $.getElement( element );
|
|
8793
9028
|
i = getOverlayIndex( this.currentOverlays, element );
|
|
8794
9029
|
|
|
8795
|
-
if (i>=0) {
|
|
9030
|
+
if (i >= 0) {
|
|
8796
9031
|
return this.currentOverlays[i];
|
|
8797
9032
|
} else {
|
|
8798
9033
|
return null;
|
|
@@ -8894,6 +9129,52 @@ $.extend( $.Viewer.prototype, $.EventSource.prototype, $.ControlDock.prototype,
|
|
|
8894
9129
|
*/
|
|
8895
9130
|
_cancelPendingImages: function() {
|
|
8896
9131
|
this._loadQueue = [];
|
|
9132
|
+
},
|
|
9133
|
+
|
|
9134
|
+
/**
|
|
9135
|
+
* Removes the reference strip and disables displaying it.
|
|
9136
|
+
* @function
|
|
9137
|
+
*/
|
|
9138
|
+
removeReferenceStrip: function() {
|
|
9139
|
+
this.showReferenceStrip = false;
|
|
9140
|
+
|
|
9141
|
+
if (this.referenceStrip) {
|
|
9142
|
+
this.referenceStrip.destroy();
|
|
9143
|
+
this.referenceStrip = null;
|
|
9144
|
+
}
|
|
9145
|
+
},
|
|
9146
|
+
|
|
9147
|
+
/**
|
|
9148
|
+
* Enables and displays the reference strip based on the currently set tileSources.
|
|
9149
|
+
* Works only when the Viewer has sequenceMode set to true.
|
|
9150
|
+
* @function
|
|
9151
|
+
*/
|
|
9152
|
+
addReferenceStrip: function() {
|
|
9153
|
+
this.showReferenceStrip = true;
|
|
9154
|
+
|
|
9155
|
+
if (this.sequenceMode) {
|
|
9156
|
+
if (this.referenceStrip) {
|
|
9157
|
+
return;
|
|
9158
|
+
}
|
|
9159
|
+
|
|
9160
|
+
if (this.tileSources.length && this.tileSources.length > 1) {
|
|
9161
|
+
this.referenceStrip = new $.ReferenceStrip({
|
|
9162
|
+
id: this.referenceStripElement,
|
|
9163
|
+
position: this.referenceStripPosition,
|
|
9164
|
+
sizeRatio: this.referenceStripSizeRatio,
|
|
9165
|
+
scroll: this.referenceStripScroll,
|
|
9166
|
+
height: this.referenceStripHeight,
|
|
9167
|
+
width: this.referenceStripWidth,
|
|
9168
|
+
tileSources: this.tileSources,
|
|
9169
|
+
prefixUrl: this.prefixUrl,
|
|
9170
|
+
viewer: this
|
|
9171
|
+
});
|
|
9172
|
+
|
|
9173
|
+
this.referenceStrip.setFocus( this._sequenceIndex );
|
|
9174
|
+
}
|
|
9175
|
+
} else {
|
|
9176
|
+
$.console.warn('Attempting to display a reference strip while "sequenceMode" is off.');
|
|
9177
|
+
}
|
|
8897
9178
|
}
|
|
8898
9179
|
});
|
|
8899
9180
|
|
|
@@ -8913,20 +9194,28 @@ function _getSafeElemSize (oElement) {
|
|
|
8913
9194
|
);
|
|
8914
9195
|
}
|
|
8915
9196
|
|
|
9197
|
+
|
|
8916
9198
|
/**
|
|
8917
9199
|
* @function
|
|
8918
9200
|
* @private
|
|
8919
9201
|
*/
|
|
8920
|
-
function getTileSourceImplementation( viewer, tileSource, successCallback,
|
|
9202
|
+
function getTileSourceImplementation( viewer, tileSource, imgOptions, successCallback,
|
|
8921
9203
|
failCallback ) {
|
|
8922
9204
|
var _this = viewer;
|
|
8923
9205
|
|
|
8924
9206
|
//allow plain xml strings or json strings to be parsed here
|
|
8925
9207
|
if ( $.type( tileSource ) == 'string' ) {
|
|
8926
|
-
|
|
9208
|
+
//xml should start with "<" and end with ">"
|
|
9209
|
+
if ( tileSource.match( /^\s*<.*>\s*$/ ) ) {
|
|
8927
9210
|
tileSource = $.parseXml( tileSource );
|
|
8928
|
-
|
|
8929
|
-
|
|
9211
|
+
//json should start with "{" or "[" and end with "}" or "]"
|
|
9212
|
+
} else if ( tileSource.match(/^\s*[\{\[].*[\}\]]\s*$/ ) ) {
|
|
9213
|
+
try {
|
|
9214
|
+
var tileSourceJ = $.parseJSON(tileSource);
|
|
9215
|
+
tileSource = tileSourceJ;
|
|
9216
|
+
} catch (e) {
|
|
9217
|
+
//tileSource = tileSource;
|
|
9218
|
+
}
|
|
8930
9219
|
}
|
|
8931
9220
|
}
|
|
8932
9221
|
|
|
@@ -8951,8 +9240,10 @@ function getTileSourceImplementation( viewer, tileSource, successCallback,
|
|
|
8951
9240
|
//If its still a string it means it must be a url at this point
|
|
8952
9241
|
tileSource = new $.TileSource({
|
|
8953
9242
|
url: tileSource,
|
|
8954
|
-
crossOriginPolicy:
|
|
9243
|
+
crossOriginPolicy: imgOptions.crossOriginPolicy !== undefined ?
|
|
9244
|
+
imgOptions.crossOriginPolicy : viewer.crossOriginPolicy,
|
|
8955
9245
|
ajaxWithCredentials: viewer.ajaxWithCredentials,
|
|
9246
|
+
ajaxHeaders: viewer.ajaxHeaders,
|
|
8956
9247
|
useCanvas: viewer.useCanvas,
|
|
8957
9248
|
success: function( event ) {
|
|
8958
9249
|
successCallback( event.tileSource );
|
|
@@ -8963,8 +9254,10 @@ function getTileSourceImplementation( viewer, tileSource, successCallback,
|
|
|
8963
9254
|
} );
|
|
8964
9255
|
|
|
8965
9256
|
} else if ($.isPlainObject(tileSource) || tileSource.nodeType) {
|
|
8966
|
-
if (
|
|
8967
|
-
|
|
9257
|
+
if (tileSource.crossOriginPolicy === undefined &&
|
|
9258
|
+
(imgOptions.crossOriginPolicy !== undefined || viewer.crossOriginPolicy !== undefined)) {
|
|
9259
|
+
tileSource.crossOriginPolicy = imgOptions.crossOriginPolicy !== undefined ?
|
|
9260
|
+
imgOptions.crossOriginPolicy : viewer.crossOriginPolicy;
|
|
8968
9261
|
}
|
|
8969
9262
|
if (tileSource.ajaxWithCredentials === undefined) {
|
|
8970
9263
|
tileSource.ajaxWithCredentials = viewer.ajaxWithCredentials;
|
|
@@ -9258,16 +9551,15 @@ function onCanvasClick( event ) {
|
|
|
9258
9551
|
this.canvas.focus();
|
|
9259
9552
|
}
|
|
9260
9553
|
|
|
9261
|
-
|
|
9262
|
-
|
|
9263
|
-
|
|
9264
|
-
|
|
9265
|
-
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
|
|
9269
|
-
|
|
9270
|
-
}
|
|
9554
|
+
var canvasClickEventArgs = {
|
|
9555
|
+
tracker: event.eventSource,
|
|
9556
|
+
position: event.position,
|
|
9557
|
+
quick: event.quick,
|
|
9558
|
+
shift: event.shift,
|
|
9559
|
+
originalEvent: event.originalEvent,
|
|
9560
|
+
preventDefaultAction: event.preventDefaultAction
|
|
9561
|
+
};
|
|
9562
|
+
|
|
9271
9563
|
/**
|
|
9272
9564
|
* Raised when a mouse press/release or touch/remove occurs on the {@link OpenSeadragon.Viewer#canvas} element.
|
|
9273
9565
|
*
|
|
@@ -9280,15 +9572,21 @@ function onCanvasClick( event ) {
|
|
|
9280
9572
|
* @property {Boolean} quick - True only if the clickDistThreshold and clickTimeThreshold are both passed. Useful for differentiating between clicks and drags.
|
|
9281
9573
|
* @property {Boolean} shift - True if the shift key was pressed during this event.
|
|
9282
9574
|
* @property {Object} originalEvent - The original DOM event.
|
|
9575
|
+
* @property {Boolean} preventDefaultAction - Set to true to prevent default click to zoom behaviour. Default: false.
|
|
9283
9576
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
9284
9577
|
*/
|
|
9285
|
-
this.raiseEvent( 'canvas-click',
|
|
9286
|
-
|
|
9287
|
-
|
|
9288
|
-
|
|
9289
|
-
|
|
9290
|
-
|
|
9291
|
-
|
|
9578
|
+
this.raiseEvent( 'canvas-click', canvasClickEventArgs);
|
|
9579
|
+
|
|
9580
|
+
if ( !canvasClickEventArgs.preventDefaultAction && this.viewport && event.quick ) {
|
|
9581
|
+
gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );
|
|
9582
|
+
if ( gestureSettings.clickToZoom ) {
|
|
9583
|
+
this.viewport.zoomBy(
|
|
9584
|
+
event.shift ? 1.0 / this.zoomPerClick : this.zoomPerClick,
|
|
9585
|
+
this.viewport.pointFromPixel( event.position, true )
|
|
9586
|
+
);
|
|
9587
|
+
this.viewport.applyConstraints();
|
|
9588
|
+
}
|
|
9589
|
+
}
|
|
9292
9590
|
}
|
|
9293
9591
|
|
|
9294
9592
|
function onCanvasDblClick( event ) {
|
|
@@ -9328,19 +9626,16 @@ function onCanvasDblClick( event ) {
|
|
|
9328
9626
|
function onCanvasDrag( event ) {
|
|
9329
9627
|
var gestureSettings;
|
|
9330
9628
|
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9338
|
-
|
|
9339
|
-
|
|
9340
|
-
|
|
9341
|
-
this.viewport.applyConstraints();
|
|
9342
|
-
}
|
|
9343
|
-
}
|
|
9629
|
+
var canvasDragEventArgs = {
|
|
9630
|
+
tracker: event.eventSource,
|
|
9631
|
+
position: event.position,
|
|
9632
|
+
delta: event.delta,
|
|
9633
|
+
speed: event.speed,
|
|
9634
|
+
direction: event.direction,
|
|
9635
|
+
shift: event.shift,
|
|
9636
|
+
originalEvent: event.originalEvent,
|
|
9637
|
+
preventDefaultAction: event.preventDefaultAction
|
|
9638
|
+
};
|
|
9344
9639
|
/**
|
|
9345
9640
|
* Raised when a mouse or touch drag operation occurs on the {@link OpenSeadragon.Viewer#canvas} element.
|
|
9346
9641
|
*
|
|
@@ -9355,17 +9650,43 @@ function onCanvasDrag( event ) {
|
|
|
9355
9650
|
* @property {Number} direction - Current computed direction, expressed as an angle counterclockwise relative to the positive X axis (-pi to pi, in radians). Only valid if speed > 0.
|
|
9356
9651
|
* @property {Boolean} shift - True if the shift key was pressed during this event.
|
|
9357
9652
|
* @property {Object} originalEvent - The original DOM event.
|
|
9653
|
+
* @property {Boolean} preventDefaultAction - Set to true to prevent default drag behaviour. Default: false.
|
|
9358
9654
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
9359
9655
|
*/
|
|
9360
|
-
this.raiseEvent( 'canvas-drag',
|
|
9361
|
-
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
|
|
9366
|
-
|
|
9367
|
-
|
|
9368
|
-
|
|
9656
|
+
this.raiseEvent( 'canvas-drag', canvasDragEventArgs);
|
|
9657
|
+
|
|
9658
|
+
if ( !event.preventDefaultAction && this.viewport ) {
|
|
9659
|
+
gestureSettings = this.gestureSettingsByDeviceType( event.pointerType );
|
|
9660
|
+
if( !this.panHorizontal ){
|
|
9661
|
+
event.delta.x = 0;
|
|
9662
|
+
}
|
|
9663
|
+
if( !this.panVertical ){
|
|
9664
|
+
event.delta.y = 0;
|
|
9665
|
+
}
|
|
9666
|
+
|
|
9667
|
+
if( this.constrainDuringPan ){
|
|
9668
|
+
var delta = this.viewport.deltaPointsFromPixels( event.delta.negate() );
|
|
9669
|
+
|
|
9670
|
+
this.viewport.centerSpringX.target.value += delta.x;
|
|
9671
|
+
this.viewport.centerSpringY.target.value += delta.y;
|
|
9672
|
+
|
|
9673
|
+
var bounds = this.viewport.getBounds();
|
|
9674
|
+
var constrainedBounds = this.viewport.getConstrainedBounds();
|
|
9675
|
+
|
|
9676
|
+
this.viewport.centerSpringX.target.value -= delta.x;
|
|
9677
|
+
this.viewport.centerSpringY.target.value -= delta.y;
|
|
9678
|
+
|
|
9679
|
+
if (bounds.x != constrainedBounds.x) {
|
|
9680
|
+
event.delta.x = 0;
|
|
9681
|
+
}
|
|
9682
|
+
|
|
9683
|
+
if (bounds.y != constrainedBounds.y) {
|
|
9684
|
+
event.delta.y = 0;
|
|
9685
|
+
}
|
|
9686
|
+
}
|
|
9687
|
+
|
|
9688
|
+
this.viewport.panBy( this.viewport.deltaPointsFromPixels( event.delta.negate() ), gestureSettings.flickEnabled && !this.constrainDuringPan);
|
|
9689
|
+
}
|
|
9369
9690
|
}
|
|
9370
9691
|
|
|
9371
9692
|
function onCanvasDragEnd( event ) {
|
|
@@ -9447,6 +9768,11 @@ function onCanvasEnter( event ) {
|
|
|
9447
9768
|
}
|
|
9448
9769
|
|
|
9449
9770
|
function onCanvasExit( event ) {
|
|
9771
|
+
|
|
9772
|
+
if (window.location != window.parent.location){
|
|
9773
|
+
$.MouseTracker.resetAllMouseTrackers();
|
|
9774
|
+
}
|
|
9775
|
+
|
|
9450
9776
|
/**
|
|
9451
9777
|
* Raised when a pointer leaves the {@link OpenSeadragon.Viewer#canvas} element.
|
|
9452
9778
|
*
|
|
@@ -10195,7 +10521,7 @@ $.Navigator = function( options ){
|
|
|
10195
10521
|
//At some browser magnification levels the display regions lines up correctly, but at some there appears to
|
|
10196
10522
|
//be a one pixel gap.
|
|
10197
10523
|
this.fudge = new $.Point(1, 1);
|
|
10198
|
-
this.totalBorderWidths = new $.Point(this.borderWidth*2, this.borderWidth*2).minus(this.fudge);
|
|
10524
|
+
this.totalBorderWidths = new $.Point(this.borderWidth * 2, this.borderWidth * 2).minus(this.fudge);
|
|
10199
10525
|
|
|
10200
10526
|
|
|
10201
10527
|
if ( options.controlOptions.anchor != $.ControlAnchor.NONE ) {
|
|
@@ -10254,8 +10580,8 @@ $.Navigator = function( options ){
|
|
|
10254
10580
|
|
|
10255
10581
|
if ( this._resizeWithViewer ) {
|
|
10256
10582
|
if ( options.width && options.height ) {
|
|
10257
|
-
this.element.style.height = typeof (
|
|
10258
|
-
this.element.style.width = typeof (
|
|
10583
|
+
this.element.style.height = typeof (options.height) == "number" ? (options.height + 'px') : options.height;
|
|
10584
|
+
this.element.style.width = typeof (options.width) == "number" ? (options.width + 'px') : options.width;
|
|
10259
10585
|
} else {
|
|
10260
10586
|
viewerSize = $.getElementSize( viewer.element );
|
|
10261
10587
|
this.element.style.height = Math.round( viewerSize.y * options.sizeRatio ) + 'px';
|
|
@@ -10305,8 +10631,10 @@ $.Navigator = function( options ){
|
|
|
10305
10631
|
});
|
|
10306
10632
|
|
|
10307
10633
|
viewer.world.addHandler("item-index-change", function(event) {
|
|
10308
|
-
|
|
10309
|
-
|
|
10634
|
+
window.setTimeout(function(){
|
|
10635
|
+
var item = _this.world.getItemAt(event.previousIndex);
|
|
10636
|
+
_this.world.setItemIndex(item, event.newIndex);
|
|
10637
|
+
}, 1);
|
|
10310
10638
|
});
|
|
10311
10639
|
|
|
10312
10640
|
viewer.world.addHandler("remove-item", function(event) {
|
|
@@ -10415,9 +10743,22 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|
|
10415
10743
|
myItem._originalForNavigator = original;
|
|
10416
10744
|
_this._matchBounds(myItem, original, true);
|
|
10417
10745
|
|
|
10418
|
-
|
|
10746
|
+
function matchBounds() {
|
|
10419
10747
|
_this._matchBounds(myItem, original);
|
|
10420
|
-
}
|
|
10748
|
+
}
|
|
10749
|
+
|
|
10750
|
+
function matchOpacity() {
|
|
10751
|
+
_this._matchOpacity(myItem, original);
|
|
10752
|
+
}
|
|
10753
|
+
|
|
10754
|
+
function matchCompositeOperation() {
|
|
10755
|
+
_this._matchCompositeOperation(myItem, original);
|
|
10756
|
+
}
|
|
10757
|
+
|
|
10758
|
+
original.addHandler('bounds-change', matchBounds);
|
|
10759
|
+
original.addHandler('clip-change', matchBounds);
|
|
10760
|
+
original.addHandler('opacity-change', matchOpacity);
|
|
10761
|
+
original.addHandler('composite-operation-change', matchCompositeOperation);
|
|
10421
10762
|
}
|
|
10422
10763
|
});
|
|
10423
10764
|
|
|
@@ -10440,9 +10781,21 @@ $.extend( $.Navigator.prototype, $.EventSource.prototype, $.Viewer.prototype, /*
|
|
|
10440
10781
|
|
|
10441
10782
|
// private
|
|
10442
10783
|
_matchBounds: function(myItem, theirItem, immediately) {
|
|
10443
|
-
var bounds = theirItem.
|
|
10784
|
+
var bounds = theirItem.getBoundsNoRotate();
|
|
10444
10785
|
myItem.setPosition(bounds.getTopLeft(), immediately);
|
|
10445
10786
|
myItem.setWidth(bounds.width, immediately);
|
|
10787
|
+
myItem.setRotation(theirItem.getRotation(), immediately);
|
|
10788
|
+
myItem.setClip(theirItem.getClip());
|
|
10789
|
+
},
|
|
10790
|
+
|
|
10791
|
+
// private
|
|
10792
|
+
_matchOpacity: function(myItem, theirItem) {
|
|
10793
|
+
myItem.setOpacity(theirItem.opacity);
|
|
10794
|
+
},
|
|
10795
|
+
|
|
10796
|
+
// private
|
|
10797
|
+
_matchCompositeOperation: function(myItem, theirItem) {
|
|
10798
|
+
myItem.setCompositeOperation(theirItem.compositeOperation);
|
|
10446
10799
|
}
|
|
10447
10800
|
});
|
|
10448
10801
|
|
|
@@ -10476,6 +10829,9 @@ function onCanvasDrag( event ) {
|
|
|
10476
10829
|
event.delta
|
|
10477
10830
|
)
|
|
10478
10831
|
);
|
|
10832
|
+
if( this.viewer.constrainDuringPan ){
|
|
10833
|
+
this.viewer.viewport.applyConstraints();
|
|
10834
|
+
}
|
|
10479
10835
|
}
|
|
10480
10836
|
}
|
|
10481
10837
|
|
|
@@ -10618,14 +10974,14 @@ $.extend( $, /** @lends OpenSeadragon */{
|
|
|
10618
10974
|
container = I18N,
|
|
10619
10975
|
i;
|
|
10620
10976
|
|
|
10621
|
-
for (
|
|
10977
|
+
for (i = 0; i < props.length - 1; i++) {
|
|
10622
10978
|
// in case not a subproperty
|
|
10623
10979
|
container = container[ props[ i ] ] || {};
|
|
10624
10980
|
}
|
|
10625
10981
|
string = container[ props[ i ] ];
|
|
10626
10982
|
|
|
10627
10983
|
if ( typeof( string ) != "string" ) {
|
|
10628
|
-
$.console.
|
|
10984
|
+
$.console.log( "Untranslated source string:", prop );
|
|
10629
10985
|
string = ""; // FIXME: this breaks gettext()-style convention, which would return source
|
|
10630
10986
|
}
|
|
10631
10987
|
|
|
@@ -10812,6 +11168,18 @@ $.Point.prototype = {
|
|
|
10812
11168
|
);
|
|
10813
11169
|
},
|
|
10814
11170
|
|
|
11171
|
+
/**
|
|
11172
|
+
* Compute the squared distance between this point and another point.
|
|
11173
|
+
* Useful for optimizing things like comparing distances.
|
|
11174
|
+
* @function
|
|
11175
|
+
* @param {OpenSeadragon.Point} point The point to compute the squared distance with.
|
|
11176
|
+
* @returns {Number} The squared distance between the 2 points
|
|
11177
|
+
*/
|
|
11178
|
+
squaredDistanceTo: function( point ) {
|
|
11179
|
+
return Math.pow( this.x - point.x, 2 ) +
|
|
11180
|
+
Math.pow( this.y - point.y, 2 );
|
|
11181
|
+
},
|
|
11182
|
+
|
|
10815
11183
|
/**
|
|
10816
11184
|
* Apply a function to each coordinate of this point and return a new point.
|
|
10817
11185
|
* @function
|
|
@@ -10854,10 +11222,7 @@ $.Point.prototype = {
|
|
|
10854
11222
|
var sin;
|
|
10855
11223
|
// Avoid float computations when possible
|
|
10856
11224
|
if (degrees % 90 === 0) {
|
|
10857
|
-
var d = degrees
|
|
10858
|
-
if (d < 0) {
|
|
10859
|
-
d += 360;
|
|
10860
|
-
}
|
|
11225
|
+
var d = $.positiveModulo(degrees, 360);
|
|
10861
11226
|
switch (d) {
|
|
10862
11227
|
case 0:
|
|
10863
11228
|
cos = 1;
|
|
@@ -10961,11 +11326,15 @@ $.Point.prototype = {
|
|
|
10961
11326
|
* the extending classes implementation of 'configure'.
|
|
10962
11327
|
* @param {String} [options.url]
|
|
10963
11328
|
* The URL for the data necessary for this TileSource.
|
|
11329
|
+
* @param {String} [options.referenceStripThumbnailUrl]
|
|
11330
|
+
* The URL for a thumbnail image to be used by the reference strip
|
|
10964
11331
|
* @param {Function} [options.success]
|
|
10965
11332
|
* A function to be called upon successful creation.
|
|
10966
11333
|
* @param {Boolean} [options.ajaxWithCredentials]
|
|
10967
11334
|
* If this TileSource needs to make an AJAX call, this specifies whether to set
|
|
10968
11335
|
* the XHR's withCredentials (for accessing secure data).
|
|
11336
|
+
* @param {Object} [options.ajaxHeaders]
|
|
11337
|
+
* A set of headers to include in AJAX requests.
|
|
10969
11338
|
* @param {Number} [options.width]
|
|
10970
11339
|
* Width of the source image at max resolution in pixels.
|
|
10971
11340
|
* @param {Number} [options.height]
|
|
@@ -11088,8 +11457,8 @@ $.TileSource = function( width, height, tileSize, tileOverlap, minLevel, maxLeve
|
|
|
11088
11457
|
//explicit configuration via positional args in constructor
|
|
11089
11458
|
//or the more idiomatic 'options' object
|
|
11090
11459
|
this.ready = true;
|
|
11091
|
-
this.aspectRatio = (
|
|
11092
|
-
(
|
|
11460
|
+
this.aspectRatio = (options.width && options.height) ?
|
|
11461
|
+
(options.width / options.height) : 1;
|
|
11093
11462
|
this.dimensions = new $.Point( options.width, options.height );
|
|
11094
11463
|
|
|
11095
11464
|
if ( this.tileSize ){
|
|
@@ -11219,25 +11588,20 @@ $.TileSource.prototype = {
|
|
|
11219
11588
|
|
|
11220
11589
|
/**
|
|
11221
11590
|
* @function
|
|
11222
|
-
* @
|
|
11591
|
+
* @returns {Number} The highest level in this tile source that can be contained in a single tile.
|
|
11223
11592
|
*/
|
|
11224
|
-
getClosestLevel: function(
|
|
11593
|
+
getClosestLevel: function() {
|
|
11225
11594
|
var i,
|
|
11226
|
-
tilesPerSide,
|
|
11227
11595
|
tiles;
|
|
11228
11596
|
|
|
11229
|
-
for(
|
|
11230
|
-
tiles = this.getNumTiles(
|
|
11231
|
-
|
|
11232
|
-
Math.floor( rect.x / this.getTileWidth(i) ),
|
|
11233
|
-
Math.floor( rect.y / this.getTileHeight(i) )
|
|
11234
|
-
);
|
|
11235
|
-
|
|
11236
|
-
if( tiles.x + 1 >= tilesPerSide.x && tiles.y + 1 >= tilesPerSide.y ){
|
|
11597
|
+
for (i = this.minLevel + 1; i <= this.maxLevel; i++){
|
|
11598
|
+
tiles = this.getNumTiles(i);
|
|
11599
|
+
if (tiles.x > 1 || tiles.y > 1) {
|
|
11237
11600
|
break;
|
|
11238
11601
|
}
|
|
11239
11602
|
}
|
|
11240
|
-
|
|
11603
|
+
|
|
11604
|
+
return i - 1;
|
|
11241
11605
|
},
|
|
11242
11606
|
|
|
11243
11607
|
/**
|
|
@@ -11245,12 +11609,28 @@ $.TileSource.prototype = {
|
|
|
11245
11609
|
* @param {Number} level
|
|
11246
11610
|
* @param {OpenSeadragon.Point} point
|
|
11247
11611
|
*/
|
|
11248
|
-
getTileAtPoint: function(
|
|
11249
|
-
var
|
|
11250
|
-
|
|
11251
|
-
|
|
11612
|
+
getTileAtPoint: function(level, point) {
|
|
11613
|
+
var validPoint = point.x >= 0 && point.x <= 1 &&
|
|
11614
|
+
point.y >= 0 && point.y <= 1 / this.aspectRatio;
|
|
11615
|
+
$.console.assert(validPoint, "[TileSource.getTileAtPoint] must be called with a valid point.");
|
|
11616
|
+
|
|
11617
|
+
var widthScaled = this.dimensions.x * this.getLevelScale(level);
|
|
11618
|
+
var pixelX = point.x * widthScaled;
|
|
11619
|
+
var pixelY = point.y * widthScaled;
|
|
11620
|
+
|
|
11621
|
+
var x = Math.floor(pixelX / this.getTileWidth(level));
|
|
11622
|
+
var y = Math.floor(pixelY / this.getTileHeight(level));
|
|
11623
|
+
|
|
11624
|
+
// When point.x == 1 or point.y == 1 / this.aspectRatio we want to
|
|
11625
|
+
// return the last tile of the row/column
|
|
11626
|
+
if (point.x >= 1) {
|
|
11627
|
+
x = this.getNumTiles(level).x - 1;
|
|
11628
|
+
}
|
|
11629
|
+
if (point.y >= 1 / this.aspectRatio) {
|
|
11630
|
+
y = this.getNumTiles(level).y - 1;
|
|
11631
|
+
}
|
|
11252
11632
|
|
|
11253
|
-
return new $.Point(
|
|
11633
|
+
return new $.Point(x, y);
|
|
11254
11634
|
},
|
|
11255
11635
|
|
|
11256
11636
|
/**
|
|
@@ -11348,7 +11728,7 @@ $.TileSource.prototype = {
|
|
|
11348
11728
|
//TODO: Its not very flexible to require tile sources to end jsonp
|
|
11349
11729
|
// request for info with a url that ends with '.js' but for
|
|
11350
11730
|
// now it's the only way I see to distinguish uniformly.
|
|
11351
|
-
callbackName = url.split(
|
|
11731
|
+
callbackName = url.split('/').pop().replace('.js', '');
|
|
11352
11732
|
$.jsonp({
|
|
11353
11733
|
url: url,
|
|
11354
11734
|
async: false,
|
|
@@ -11360,6 +11740,7 @@ $.TileSource.prototype = {
|
|
|
11360
11740
|
$.makeAjaxRequest( {
|
|
11361
11741
|
url: url,
|
|
11362
11742
|
withCredentials: this.ajaxWithCredentials,
|
|
11743
|
+
headers: this.ajaxHeaders,
|
|
11363
11744
|
success: function( xhr ) {
|
|
11364
11745
|
var data = processResponse( xhr );
|
|
11365
11746
|
callback( data );
|
|
@@ -11444,7 +11825,7 @@ $.TileSource.prototype = {
|
|
|
11444
11825
|
},
|
|
11445
11826
|
|
|
11446
11827
|
/**
|
|
11447
|
-
* Responsible for
|
|
11828
|
+
* Responsible for retrieving the url which will return an image for the
|
|
11448
11829
|
* region specified by the given x, y, and level components.
|
|
11449
11830
|
* This method is not implemented by this class other than to throw an Error
|
|
11450
11831
|
* announcing you have to implement it. Because of the variety of tile
|
|
@@ -11460,6 +11841,23 @@ $.TileSource.prototype = {
|
|
|
11460
11841
|
throw new Error( "Method not implemented." );
|
|
11461
11842
|
},
|
|
11462
11843
|
|
|
11844
|
+
/**
|
|
11845
|
+
* Responsible for retrieving the headers which will be attached to the image request for the
|
|
11846
|
+
* region specified by the given x, y, and level components.
|
|
11847
|
+
* This option is only relevant if {@link OpenSeadragon.Options}.loadTilesWithAjax is set to true.
|
|
11848
|
+
* The headers returned here will override headers specified at the Viewer or TiledImage level.
|
|
11849
|
+
* Specifying a falsy value for a header will clear its existing value set at the Viewer or
|
|
11850
|
+
* TiledImage level (if any).
|
|
11851
|
+
* @function
|
|
11852
|
+
* @param {Number} level
|
|
11853
|
+
* @param {Number} x
|
|
11854
|
+
* @param {Number} y
|
|
11855
|
+
* @returns {Object}
|
|
11856
|
+
*/
|
|
11857
|
+
getTileAjaxHeaders: function( level, x, y ) {
|
|
11858
|
+
return {};
|
|
11859
|
+
},
|
|
11860
|
+
|
|
11463
11861
|
/**
|
|
11464
11862
|
* @function
|
|
11465
11863
|
* @param {Number} level
|
|
@@ -11468,12 +11866,12 @@ $.TileSource.prototype = {
|
|
|
11468
11866
|
*/
|
|
11469
11867
|
tileExists: function( level, x, y ) {
|
|
11470
11868
|
var numTiles = this.getNumTiles( level );
|
|
11471
|
-
return
|
|
11472
|
-
|
|
11473
|
-
|
|
11474
|
-
|
|
11475
|
-
|
|
11476
|
-
|
|
11869
|
+
return level >= this.minLevel &&
|
|
11870
|
+
level <= this.maxLevel &&
|
|
11871
|
+
x >= 0 &&
|
|
11872
|
+
y >= 0 &&
|
|
11873
|
+
x < numTiles.x &&
|
|
11874
|
+
y < numTiles.y;
|
|
11477
11875
|
}
|
|
11478
11876
|
};
|
|
11479
11877
|
|
|
@@ -11514,7 +11912,11 @@ function processResponse( xhr ){
|
|
|
11514
11912
|
data = xhr.responseText;
|
|
11515
11913
|
}
|
|
11516
11914
|
}else if( responseText.match(/\s*[\{\[].*/) ){
|
|
11517
|
-
|
|
11915
|
+
try{
|
|
11916
|
+
data = $.parseJSON(responseText);
|
|
11917
|
+
} catch(e){
|
|
11918
|
+
data = responseText;
|
|
11919
|
+
}
|
|
11518
11920
|
}else{
|
|
11519
11921
|
data = responseText;
|
|
11520
11922
|
}
|
|
@@ -11665,8 +12067,10 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead
|
|
|
11665
12067
|
}
|
|
11666
12068
|
}
|
|
11667
12069
|
|
|
11668
|
-
|
|
11669
|
-
|
|
12070
|
+
ns = (ns || '').toLowerCase();
|
|
12071
|
+
|
|
12072
|
+
return (ns.indexOf('schemas.microsoft.com/deepzoom/2008') !== -1 ||
|
|
12073
|
+
ns.indexOf('schemas.microsoft.com/deepzoom/2009') !== -1);
|
|
11670
12074
|
},
|
|
11671
12075
|
|
|
11672
12076
|
/**
|
|
@@ -11692,7 +12096,7 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead
|
|
|
11692
12096
|
|
|
11693
12097
|
if (url && !options.tilesUrl) {
|
|
11694
12098
|
options.tilesUrl = url.replace(
|
|
11695
|
-
/([^\/]+?)(\.(dzi|xml|js)
|
|
12099
|
+
/([^\/]+?)(\.(dzi|xml|js)?(\?[^\/]*)?)?\/?$/, '$1_files/');
|
|
11696
12100
|
|
|
11697
12101
|
if (url.search(/\.(dzi|xml|js)\?/) != -1) {
|
|
11698
12102
|
options.queryParams = url.match(/\?.*/);
|
|
@@ -11749,10 +12153,10 @@ $.extend( $.DziTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead
|
|
|
11749
12153
|
xMax = xMin + rect.width * scale;
|
|
11750
12154
|
yMax = yMin + rect.height * scale;
|
|
11751
12155
|
|
|
11752
|
-
xMin = Math.floor( xMin / this.
|
|
11753
|
-
yMin = Math.floor( yMin / this.
|
|
11754
|
-
xMax = Math.ceil( xMax / this.
|
|
11755
|
-
yMax = Math.ceil( yMax / this.
|
|
12156
|
+
xMin = Math.floor( xMin / this._tileWidth );
|
|
12157
|
+
yMin = Math.floor( yMin / this._tileWidth ); // DZI tiles are square, so we just use _tileWidth
|
|
12158
|
+
xMax = Math.ceil( xMax / this._tileWidth );
|
|
12159
|
+
yMax = Math.ceil( yMax / this._tileWidth );
|
|
11756
12160
|
|
|
11757
12161
|
if ( xMin <= x && x < xMax && yMin <= y && y < yMax ) {
|
|
11758
12162
|
return true;
|
|
@@ -11969,6 +12373,7 @@ function configureFromObject( tileSource, configuration ){
|
|
|
11969
12373
|
*/
|
|
11970
12374
|
$.IIIFTileSource = function( options ){
|
|
11971
12375
|
|
|
12376
|
+
/* eslint-disable camelcase */
|
|
11972
12377
|
|
|
11973
12378
|
$.extend( true, this, options );
|
|
11974
12379
|
|
|
@@ -12010,7 +12415,7 @@ $.IIIFTileSource = function( options ){
|
|
|
12010
12415
|
} else if ( canBeTiled(options.profile) ) {
|
|
12011
12416
|
// use the largest of tileOptions that is smaller than the short dimension
|
|
12012
12417
|
var shortDim = Math.min( this.height, this.width ),
|
|
12013
|
-
tileOptions = [256,512,1024],
|
|
12418
|
+
tileOptions = [256, 512, 1024],
|
|
12014
12419
|
smallerTiles = [];
|
|
12015
12420
|
|
|
12016
12421
|
for ( var c = 0; c < tileOptions.length; c++ ) {
|
|
@@ -12026,11 +12431,11 @@ $.IIIFTileSource = function( options ){
|
|
|
12026
12431
|
options.tileSize = shortDim;
|
|
12027
12432
|
}
|
|
12028
12433
|
} else if (this.sizes && this.sizes.length > 0) {
|
|
12029
|
-
// This info.json can't be tiled, but we can still construct a legacy pyramid from the sizes array.
|
|
12030
|
-
// In this mode, IIIFTileSource will call functions from the abstract baseTileSource or the
|
|
12031
|
-
// LegacyTileSource instead of performing IIIF tiling.
|
|
12434
|
+
// This info.json can't be tiled, but we can still construct a legacy pyramid from the sizes array.
|
|
12435
|
+
// In this mode, IIIFTileSource will call functions from the abstract baseTileSource or the
|
|
12436
|
+
// LegacyTileSource instead of performing IIIF tiling.
|
|
12032
12437
|
this.emulateLegacyImagePyramid = true;
|
|
12033
|
-
|
|
12438
|
+
|
|
12034
12439
|
options.levels = constructLevels( this );
|
|
12035
12440
|
// use the largest available size to define tiles
|
|
12036
12441
|
$.extend( true, options, {
|
|
@@ -12065,7 +12470,7 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|
|
12065
12470
|
* @param {Object|Array} data
|
|
12066
12471
|
* @param {String} optional - url
|
|
12067
12472
|
*/
|
|
12068
|
-
|
|
12473
|
+
|
|
12069
12474
|
supports: function( data, url ) {
|
|
12070
12475
|
// Version 2.0 and forwards
|
|
12071
12476
|
if (data.protocol && data.protocol == 'http://iiif.io/api/image') {
|
|
@@ -12317,14 +12722,16 @@ $.extend( $.IIIFTileSource.prototype, $.TileSource.prototype, /** @lends OpenSea
|
|
|
12317
12722
|
*/
|
|
12318
12723
|
function constructLevels(options) {
|
|
12319
12724
|
var levels = [];
|
|
12320
|
-
for(var i=0; i<options.sizes.length; i++) {
|
|
12725
|
+
for(var i = 0; i < options.sizes.length; i++) {
|
|
12321
12726
|
levels.push({
|
|
12322
12727
|
url: options['@id'] + '/full/' + options.sizes[i].width + ',/0/default.jpg',
|
|
12323
12728
|
width: options.sizes[i].width,
|
|
12324
12729
|
height: options.sizes[i].height
|
|
12325
12730
|
});
|
|
12326
12731
|
}
|
|
12327
|
-
return levels.sort(function(a,b){
|
|
12732
|
+
return levels.sort(function(a, b) {
|
|
12733
|
+
return a.width - b.width;
|
|
12734
|
+
});
|
|
12328
12735
|
}
|
|
12329
12736
|
|
|
12330
12737
|
|
|
@@ -12611,7 +13018,7 @@ $.TmsTileSource = function( width, height, tileSize, tileOverlap, tilesUrl ) {
|
|
|
12611
13018
|
} else {
|
|
12612
13019
|
max = bufferedHeight / 256;
|
|
12613
13020
|
}
|
|
12614
|
-
options.maxLevel = Math.ceil(Math.log(max)/Math.log(2)) - 1;
|
|
13021
|
+
options.maxLevel = Math.ceil(Math.log(max) / Math.log(2)) - 1;
|
|
12615
13022
|
options.tileSize = 256;
|
|
12616
13023
|
options.width = bufferedWidth;
|
|
12617
13024
|
options.height = bufferedHeight;
|
|
@@ -12657,13 +13064,156 @@ $.extend( $.TmsTileSource.prototype, $.TileSource.prototype, /** @lends OpenSead
|
|
|
12657
13064
|
// Convert from Deep Zoom definition to TMS zoom definition
|
|
12658
13065
|
var yTiles = this.getNumTiles( level ).y - 1;
|
|
12659
13066
|
|
|
12660
|
-
return this.tilesUrl + level + "/" + x + "/" +
|
|
13067
|
+
return this.tilesUrl + level + "/" + x + "/" + (yTiles - y) + ".png";
|
|
12661
13068
|
}
|
|
12662
13069
|
});
|
|
12663
13070
|
|
|
12664
13071
|
|
|
12665
13072
|
}( OpenSeadragon ));
|
|
12666
13073
|
|
|
13074
|
+
(function($) {
|
|
13075
|
+
|
|
13076
|
+
/**
|
|
13077
|
+
* @class ZoomifyTileSource
|
|
13078
|
+
* @classdesc A tilesource implementation for the zoomify format.
|
|
13079
|
+
*
|
|
13080
|
+
* A description of the format can be found here:
|
|
13081
|
+
* https://ecommons.cornell.edu/bitstream/handle/1813/5410/Introducing_Zoomify_Image.pdf
|
|
13082
|
+
*
|
|
13083
|
+
* There are two ways of creating a zoomify tilesource for openseadragon
|
|
13084
|
+
*
|
|
13085
|
+
* 1) Supplying all necessary information in the tilesource object. A minimal example object for this method looks like this:
|
|
13086
|
+
*
|
|
13087
|
+
* {
|
|
13088
|
+
* type: "zoomifytileservice",
|
|
13089
|
+
* width: 1000,
|
|
13090
|
+
* height: 1000,
|
|
13091
|
+
* tilesUrl: "/test/data/zoomify/"
|
|
13092
|
+
* }
|
|
13093
|
+
*
|
|
13094
|
+
* The tileSize is currently hardcoded to 256 (the usual Zoomify default). The tileUrl must the path to the image _directory_.
|
|
13095
|
+
*
|
|
13096
|
+
* 2) Loading image metadata from xml file: (CURRENTLY NOT SUPPORTED)
|
|
13097
|
+
*
|
|
13098
|
+
* When creating zoomify formatted images one "xml" like file with name ImageProperties.xml
|
|
13099
|
+
* will be created as well. Here is an example of such a file:
|
|
13100
|
+
*
|
|
13101
|
+
* <IMAGE_PROPERTIES WIDTH="1000" HEIGHT="1000" NUMTILES="21" NUMIMAGES="1" VERSION="1.8" TILESIZE="256" />
|
|
13102
|
+
*
|
|
13103
|
+
* To use this xml file as metadata source you must supply the path to the ImageProperties.xml file and leave out all other parameters:
|
|
13104
|
+
* As stated above, this method of loading a zoomify tilesource is currently not supported
|
|
13105
|
+
*
|
|
13106
|
+
* {
|
|
13107
|
+
* type: "zoomifytileservice",
|
|
13108
|
+
* tilesUrl: "/test/data/zoomify/ImageProperties.xml"
|
|
13109
|
+
* }
|
|
13110
|
+
|
|
13111
|
+
*
|
|
13112
|
+
* @memberof OpenSeadragon
|
|
13113
|
+
* @extends OpenSeadragon.TileSource
|
|
13114
|
+
* @param {Number} width - the pixel width of the image.
|
|
13115
|
+
* @param {Number} height
|
|
13116
|
+
* @param {Number} tileSize
|
|
13117
|
+
* @param {String} tilesUrl
|
|
13118
|
+
*/
|
|
13119
|
+
$.ZoomifyTileSource = function(options) {
|
|
13120
|
+
options.tileSize = 256;
|
|
13121
|
+
|
|
13122
|
+
var currentImageSize = {
|
|
13123
|
+
x: options.width,
|
|
13124
|
+
y: options.height
|
|
13125
|
+
};
|
|
13126
|
+
options.imageSizes = [{
|
|
13127
|
+
x: options.width,
|
|
13128
|
+
y: options.height
|
|
13129
|
+
}];
|
|
13130
|
+
options.gridSize = [this._getGridSize(options.width, options.height, options.tileSize)];
|
|
13131
|
+
|
|
13132
|
+
while (parseInt(currentImageSize.x, 10) > options.tileSize || parseInt(currentImageSize.y, 10) > options.tileSize) {
|
|
13133
|
+
currentImageSize.x = Math.floor(currentImageSize.x / 2);
|
|
13134
|
+
currentImageSize.y = Math.floor(currentImageSize.y / 2);
|
|
13135
|
+
options.imageSizes.push({
|
|
13136
|
+
x: currentImageSize.x,
|
|
13137
|
+
y: currentImageSize.y
|
|
13138
|
+
});
|
|
13139
|
+
options.gridSize.push(this._getGridSize(currentImageSize.x, currentImageSize.y, options.tileSize));
|
|
13140
|
+
}
|
|
13141
|
+
options.imageSizes.reverse();
|
|
13142
|
+
options.gridSize.reverse();
|
|
13143
|
+
options.minLevel = 0;
|
|
13144
|
+
options.maxLevel = options.gridSize.length - 1;
|
|
13145
|
+
|
|
13146
|
+
OpenSeadragon.TileSource.apply(this, [options]);
|
|
13147
|
+
};
|
|
13148
|
+
|
|
13149
|
+
$.extend($.ZoomifyTileSource.prototype, $.TileSource.prototype, /** @lends OpenSeadragon.ZoomifyTileSource.prototype */ {
|
|
13150
|
+
|
|
13151
|
+
//private
|
|
13152
|
+
_getGridSize: function(width, height, tileSize) {
|
|
13153
|
+
return {
|
|
13154
|
+
x: Math.ceil(width / tileSize),
|
|
13155
|
+
y: Math.ceil(height / tileSize)
|
|
13156
|
+
};
|
|
13157
|
+
},
|
|
13158
|
+
|
|
13159
|
+
//private
|
|
13160
|
+
_calculateAbsoluteTileNumber: function(level, x, y) {
|
|
13161
|
+
var num = 0;
|
|
13162
|
+
var size = {};
|
|
13163
|
+
|
|
13164
|
+
//Sum up all tiles below the level we want the number of tiles
|
|
13165
|
+
for (var z = 0; z < level; z++) {
|
|
13166
|
+
size = this.gridSize[z];
|
|
13167
|
+
num += size.x * size.y;
|
|
13168
|
+
}
|
|
13169
|
+
//Add the tiles of the level
|
|
13170
|
+
size = this.gridSize[level];
|
|
13171
|
+
num += size.x * y + x;
|
|
13172
|
+
return num;
|
|
13173
|
+
},
|
|
13174
|
+
|
|
13175
|
+
/**
|
|
13176
|
+
* Determine if the data and/or url imply the image service is supported by
|
|
13177
|
+
* this tile source.
|
|
13178
|
+
* @function
|
|
13179
|
+
* @param {Object|Array} data
|
|
13180
|
+
* @param {String} optional - url
|
|
13181
|
+
*/
|
|
13182
|
+
supports: function(data, url) {
|
|
13183
|
+
return (data.type && "zoomifytileservice" == data.type);
|
|
13184
|
+
},
|
|
13185
|
+
|
|
13186
|
+
/**
|
|
13187
|
+
*
|
|
13188
|
+
* @function
|
|
13189
|
+
* @param {Object} data - the raw configuration
|
|
13190
|
+
* @param {String} url - the url the data was retreived from if any.
|
|
13191
|
+
* @return {Object} options - A dictionary of keyword arguments sufficient
|
|
13192
|
+
* to configure this tile sources constructor.
|
|
13193
|
+
*/
|
|
13194
|
+
configure: function(data, url) {
|
|
13195
|
+
return data;
|
|
13196
|
+
},
|
|
13197
|
+
|
|
13198
|
+
/**
|
|
13199
|
+
* @function
|
|
13200
|
+
* @param {Number} level
|
|
13201
|
+
* @param {Number} x
|
|
13202
|
+
* @param {Number} y
|
|
13203
|
+
*/
|
|
13204
|
+
getTileUrl: function(level, x, y) {
|
|
13205
|
+
//console.log(level);
|
|
13206
|
+
var result = 0;
|
|
13207
|
+
var num = this._calculateAbsoluteTileNumber(level, x, y);
|
|
13208
|
+
result = Math.floor(num / 256);
|
|
13209
|
+
return this.tilesUrl + 'TileGroup' + result + '/' + level + '-' + x + '-' + y + '.jpg';
|
|
13210
|
+
|
|
13211
|
+
}
|
|
13212
|
+
});
|
|
13213
|
+
|
|
13214
|
+
}(OpenSeadragon));
|
|
13215
|
+
|
|
13216
|
+
|
|
12667
13217
|
/*
|
|
12668
13218
|
* OpenSeadragon - LegacyTileSource
|
|
12669
13219
|
*
|
|
@@ -12835,16 +13385,6 @@ $.extend( $.LegacyTileSource.prototype, $.TileSource.prototype, /** @lends OpenS
|
|
|
12835
13385
|
}
|
|
12836
13386
|
},
|
|
12837
13387
|
|
|
12838
|
-
/**
|
|
12839
|
-
* @function
|
|
12840
|
-
* @param {Number} level
|
|
12841
|
-
* @param {OpenSeadragon.Point} point
|
|
12842
|
-
*/
|
|
12843
|
-
getTileAtPoint: function( level, point ) {
|
|
12844
|
-
return new $.Point( 0, 0 );
|
|
12845
|
-
},
|
|
12846
|
-
|
|
12847
|
-
|
|
12848
13388
|
/**
|
|
12849
13389
|
* This method is not implemented by this class other than to throw an Error
|
|
12850
13390
|
* announcing you have to implement it. Because of the variety of tile
|
|
@@ -12880,12 +13420,7 @@ function filterFiles( files ){
|
|
|
12880
13420
|
file = files[ i ];
|
|
12881
13421
|
if( file.height &&
|
|
12882
13422
|
file.width &&
|
|
12883
|
-
file.url
|
|
12884
|
-
file.url.toLowerCase().match(/^.*\.(png|jpg|jpeg|gif)(?:\?.*)?$/) || (
|
|
12885
|
-
file.mimetype &&
|
|
12886
|
-
file.mimetype.toLowerCase().match(/^.*\/(png|jpg|jpeg|gif)$/)
|
|
12887
|
-
)
|
|
12888
|
-
) ){
|
|
13423
|
+
file.url ){
|
|
12889
13424
|
//This is sufficient to serve as a level
|
|
12890
13425
|
filtered.push({
|
|
12891
13426
|
url: file.url,
|
|
@@ -12898,7 +13433,7 @@ function filterFiles( files ){
|
|
|
12898
13433
|
}
|
|
12899
13434
|
}
|
|
12900
13435
|
|
|
12901
|
-
return filtered.sort(function(a,b){
|
|
13436
|
+
return filtered.sort(function(a, b) {
|
|
12902
13437
|
return a.height - b.height;
|
|
12903
13438
|
});
|
|
12904
13439
|
|
|
@@ -12934,7 +13469,7 @@ function configureFromXML( tileSource, xmlDoc ){
|
|
|
12934
13469
|
for ( i = 0; i < levels.length; i++ ) {
|
|
12935
13470
|
level = levels[ i ];
|
|
12936
13471
|
|
|
12937
|
-
conf.levels
|
|
13472
|
+
conf.levels.push({
|
|
12938
13473
|
url: level.getAttribute( "url" ),
|
|
12939
13474
|
width: parseInt( level.getAttribute( "width" ), 10 ),
|
|
12940
13475
|
height: parseInt( level.getAttribute( "height" ), 10 )
|
|
@@ -13086,8 +13621,9 @@ function configureFromObject( tileSource, configuration ){
|
|
|
13086
13621
|
}
|
|
13087
13622
|
|
|
13088
13623
|
$.addEvent(image, 'load', function () {
|
|
13089
|
-
|
|
13090
|
-
_this.
|
|
13624
|
+
/* IE8 fix since it has no naturalWidth and naturalHeight */
|
|
13625
|
+
_this.width = Object.prototype.hasOwnProperty.call(image, 'naturalWidth') ? image.naturalWidth : image.width;
|
|
13626
|
+
_this.height = Object.prototype.hasOwnProperty.call(image, 'naturalHeight') ? image.naturalHeight : image.height;
|
|
13091
13627
|
_this.aspectRatio = _this.width / _this.height;
|
|
13092
13628
|
_this.dimensions = new $.Point(_this.width, _this.height);
|
|
13093
13629
|
_this._tileWidth = _this.width;
|
|
@@ -13138,14 +13674,6 @@ function configureFromObject( tileSource, configuration ){
|
|
|
13138
13674
|
return new $.Point(0, 0);
|
|
13139
13675
|
}
|
|
13140
13676
|
},
|
|
13141
|
-
/**
|
|
13142
|
-
* @function
|
|
13143
|
-
* @param {Number} level
|
|
13144
|
-
* @param {OpenSeadragon.Point} point
|
|
13145
|
-
*/
|
|
13146
|
-
getTileAtPoint: function (level, point) {
|
|
13147
|
-
return new $.Point(0, 0);
|
|
13148
|
-
},
|
|
13149
13677
|
/**
|
|
13150
13678
|
* Retrieves a tile url
|
|
13151
13679
|
* @function
|
|
@@ -13182,8 +13710,9 @@ function configureFromObject( tileSource, configuration ){
|
|
|
13182
13710
|
_buildLevels: function () {
|
|
13183
13711
|
var levels = [{
|
|
13184
13712
|
url: this._image.src,
|
|
13185
|
-
|
|
13186
|
-
|
|
13713
|
+
/* IE8 fix since it has no naturalWidth and naturalHeight */
|
|
13714
|
+
width: Object.prototype.hasOwnProperty.call(this._image, 'naturalWidth') ? this._image.naturalWidth : this._image.width,
|
|
13715
|
+
height: Object.prototype.hasOwnProperty.call(this._image, 'naturalHeight') ? this._image.naturalHeight : this._image.height
|
|
13187
13716
|
}];
|
|
13188
13717
|
|
|
13189
13718
|
if (!this.buildPyramid || !$.supportsCanvas || !this.useCanvas) {
|
|
@@ -13192,8 +13721,10 @@ function configureFromObject( tileSource, configuration ){
|
|
|
13192
13721
|
return levels;
|
|
13193
13722
|
}
|
|
13194
13723
|
|
|
13195
|
-
|
|
13196
|
-
var
|
|
13724
|
+
/* IE8 fix since it has no naturalWidth and naturalHeight */
|
|
13725
|
+
var currentWidth = Object.prototype.hasOwnProperty.call(this._image, 'naturalWidth') ? this._image.naturalWidth : this._image.width;
|
|
13726
|
+
var currentHeight = Object.prototype.hasOwnProperty.call(this._image, 'naturalHeight') ? this._image.naturalHeight : this._image.height;
|
|
13727
|
+
|
|
13197
13728
|
|
|
13198
13729
|
var bigCanvas = document.createElement("canvas");
|
|
13199
13730
|
var bigContext = bigCanvas.getContext("2d");
|
|
@@ -13273,14 +13804,14 @@ function configureFromObject( tileSource, configuration ){
|
|
|
13273
13804
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
13274
13805
|
*/
|
|
13275
13806
|
|
|
13276
|
-
(function(
|
|
13807
|
+
(function($) {
|
|
13277
13808
|
|
|
13278
13809
|
// deprecated
|
|
13279
|
-
$.TileSourceCollection = function(
|
|
13810
|
+
$.TileSourceCollection = function(tileSize, tileSources, rows, layout) {
|
|
13280
13811
|
$.console.error('TileSourceCollection is deprecated; use World instead');
|
|
13281
13812
|
};
|
|
13282
13813
|
|
|
13283
|
-
}(
|
|
13814
|
+
}(OpenSeadragon));
|
|
13284
13815
|
|
|
13285
13816
|
/*
|
|
13286
13817
|
* OpenSeadragon - Button
|
|
@@ -13345,7 +13876,7 @@ $.ButtonState = {
|
|
|
13345
13876
|
* @memberof OpenSeadragon
|
|
13346
13877
|
* @extends OpenSeadragon.EventSource
|
|
13347
13878
|
* @param {Object} options
|
|
13348
|
-
* @param {Element} [options.element=null] Element to use as the button. If not specified, an HTML <
|
|
13879
|
+
* @param {Element} [options.element=null] Element to use as the button. If not specified, an HTML <div> element is created.
|
|
13349
13880
|
* @param {String} [options.tooltip=null] Provides context help for the button when the
|
|
13350
13881
|
* user hovers over it.
|
|
13351
13882
|
* @param {String} [options.srcRest=null] URL of image to use in 'rest' state.
|
|
@@ -13404,7 +13935,7 @@ $.Button = function( options ) {
|
|
|
13404
13935
|
* @member {Element} element
|
|
13405
13936
|
* @memberof OpenSeadragon.Button#
|
|
13406
13937
|
*/
|
|
13407
|
-
this.element
|
|
13938
|
+
this.element = options.element || $.makeNeutralElement("div");
|
|
13408
13939
|
|
|
13409
13940
|
//if the user has specified the element to bind the control to explicitly
|
|
13410
13941
|
//then do not add the default control images
|
|
@@ -13442,7 +13973,7 @@ $.Button = function( options ) {
|
|
|
13442
13973
|
this.imgDown.style.visibility =
|
|
13443
13974
|
"hidden";
|
|
13444
13975
|
|
|
13445
|
-
if (
|
|
13976
|
+
if ($.Browser.vendor == $.BROWSERS.FIREFOX && $.Browser.version < 3) {
|
|
13446
13977
|
this.imgGroup.style.top =
|
|
13447
13978
|
this.imgHover.style.top =
|
|
13448
13979
|
this.imgDown.style.top =
|
|
@@ -13456,13 +13987,13 @@ $.Button = function( options ) {
|
|
|
13456
13987
|
}
|
|
13457
13988
|
|
|
13458
13989
|
|
|
13459
|
-
this.addHandler(
|
|
13460
|
-
this.addHandler(
|
|
13461
|
-
this.addHandler(
|
|
13462
|
-
this.addHandler(
|
|
13463
|
-
this.addHandler(
|
|
13464
|
-
this.addHandler(
|
|
13465
|
-
this.addHandler(
|
|
13990
|
+
this.addHandler("press", this.onPress);
|
|
13991
|
+
this.addHandler("release", this.onRelease);
|
|
13992
|
+
this.addHandler("click", this.onClick);
|
|
13993
|
+
this.addHandler("enter", this.onEnter);
|
|
13994
|
+
this.addHandler("exit", this.onExit);
|
|
13995
|
+
this.addHandler("focus", this.onFocus);
|
|
13996
|
+
this.addHandler("blur", this.onBlur);
|
|
13466
13997
|
|
|
13467
13998
|
/**
|
|
13468
13999
|
* The button's current state.
|
|
@@ -14011,10 +14542,7 @@ $.Rect = function(x, y, width, height, degrees) {
|
|
|
14011
14542
|
this.degrees = typeof(degrees) === "number" ? degrees : 0;
|
|
14012
14543
|
|
|
14013
14544
|
// Normalizes the rectangle.
|
|
14014
|
-
this.degrees = this.degrees
|
|
14015
|
-
if (this.degrees < 0) {
|
|
14016
|
-
this.degrees += 360;
|
|
14017
|
-
}
|
|
14545
|
+
this.degrees = $.positiveModulo(this.degrees, 360);
|
|
14018
14546
|
var newTopLeft, newWidth;
|
|
14019
14547
|
if (this.degrees >= 270) {
|
|
14020
14548
|
newTopLeft = this.getTopRight();
|
|
@@ -14372,19 +14900,21 @@ $.Rect.prototype = {
|
|
|
14372
14900
|
* @return {OpenSeadragon.Rect}
|
|
14373
14901
|
*/
|
|
14374
14902
|
rotate: function(degrees, pivot) {
|
|
14375
|
-
degrees = degrees
|
|
14903
|
+
degrees = $.positiveModulo(degrees, 360);
|
|
14376
14904
|
if (degrees === 0) {
|
|
14377
14905
|
return this.clone();
|
|
14378
14906
|
}
|
|
14379
|
-
if (degrees < 0) {
|
|
14380
|
-
degrees += 360;
|
|
14381
|
-
}
|
|
14382
14907
|
|
|
14383
14908
|
pivot = pivot || this.getCenter();
|
|
14384
14909
|
var newTopLeft = this.getTopLeft().rotate(degrees, pivot);
|
|
14385
14910
|
var newTopRight = this.getTopRight().rotate(degrees, pivot);
|
|
14386
14911
|
|
|
14387
14912
|
var diff = newTopRight.minus(newTopLeft);
|
|
14913
|
+
// Handle floating point error
|
|
14914
|
+
diff = diff.apply(function(x) {
|
|
14915
|
+
var EPSILON = 1e-15;
|
|
14916
|
+
return Math.abs(x) < EPSILON ? 0 : x;
|
|
14917
|
+
});
|
|
14388
14918
|
var radians = Math.atan(diff.y / diff.x);
|
|
14389
14919
|
if (diff.x < 0) {
|
|
14390
14920
|
radians += Math.PI;
|
|
@@ -14668,6 +15198,7 @@ $.ReferenceStrip = function ( options ) {
|
|
|
14668
15198
|
this.panelWidth = ( viewerSize.x * this.sizeRatio ) + 8;
|
|
14669
15199
|
this.panelHeight = ( viewerSize.y * this.sizeRatio ) + 8;
|
|
14670
15200
|
this.panels = [];
|
|
15201
|
+
this.miniViewers = {};
|
|
14671
15202
|
|
|
14672
15203
|
/*jshint loopfunc:true*/
|
|
14673
15204
|
for ( i = 0; i < viewer.tileSources.length; i++ ) {
|
|
@@ -14783,6 +15314,12 @@ $.extend( $.ReferenceStrip.prototype, $.EventSource.prototype, $.Viewer.prototyp
|
|
|
14783
15314
|
|
|
14784
15315
|
// Overrides Viewer.destroy
|
|
14785
15316
|
destroy: function() {
|
|
15317
|
+
if (this.miniViewers) {
|
|
15318
|
+
for (var key in this.miniViewers) {
|
|
15319
|
+
this.miniViewers[key].destroy();
|
|
15320
|
+
}
|
|
15321
|
+
}
|
|
15322
|
+
|
|
14786
15323
|
if (this.element) {
|
|
14787
15324
|
this.element.parentNode.removeChild(this.element);
|
|
14788
15325
|
}
|
|
@@ -14911,9 +15448,19 @@ function loadPanels( strip, viewerSize, scroll ) {
|
|
|
14911
15448
|
for ( i = activePanelsStart; i < activePanelsEnd && i < strip.panels.length; i++ ) {
|
|
14912
15449
|
element = strip.panels[i];
|
|
14913
15450
|
if ( !element.activePanel ) {
|
|
15451
|
+
var miniTileSource;
|
|
15452
|
+
var originalTileSource = strip.viewer.tileSources[i];
|
|
15453
|
+
if (originalTileSource.referenceStripThumbnailUrl) {
|
|
15454
|
+
miniTileSource = {
|
|
15455
|
+
type: 'image',
|
|
15456
|
+
url: originalTileSource.referenceStripThumbnailUrl
|
|
15457
|
+
};
|
|
15458
|
+
} else {
|
|
15459
|
+
miniTileSource = originalTileSource;
|
|
15460
|
+
}
|
|
14914
15461
|
miniViewer = new $.Viewer( {
|
|
14915
15462
|
id: element.id,
|
|
14916
|
-
tileSources: [
|
|
15463
|
+
tileSources: [miniTileSource],
|
|
14917
15464
|
element: element,
|
|
14918
15465
|
navigatorSizeRatio: strip.sizeRatio,
|
|
14919
15466
|
showNavigator: false,
|
|
@@ -14953,6 +15500,8 @@ function loadPanels( strip, viewerSize, scroll ) {
|
|
|
14953
15500
|
miniViewer.displayRegion
|
|
14954
15501
|
);
|
|
14955
15502
|
|
|
15503
|
+
strip.miniViewers[element.id] = miniViewer;
|
|
15504
|
+
|
|
14956
15505
|
element.activePanel = true;
|
|
14957
15506
|
}
|
|
14958
15507
|
}
|
|
@@ -15082,9 +15631,7 @@ function onKeyPress( event ) {
|
|
|
15082
15631
|
}
|
|
15083
15632
|
}
|
|
15084
15633
|
|
|
15085
|
-
|
|
15086
|
-
|
|
15087
|
-
} ( OpenSeadragon ) );
|
|
15634
|
+
}(OpenSeadragon));
|
|
15088
15635
|
|
|
15089
15636
|
/*
|
|
15090
15637
|
* OpenSeadragon - DisplayRect
|
|
@@ -15366,6 +15913,7 @@ $.Spring.prototype = {
|
|
|
15366
15913
|
|
|
15367
15914
|
/**
|
|
15368
15915
|
* @function
|
|
15916
|
+
* @returns true if the value got updated, false otherwise
|
|
15369
15917
|
*/
|
|
15370
15918
|
update: function() {
|
|
15371
15919
|
this.current.time = $.now();
|
|
@@ -15386,14 +15934,17 @@ $.Spring.prototype = {
|
|
|
15386
15934
|
transform(
|
|
15387
15935
|
this.springStiffness,
|
|
15388
15936
|
( this.current.time - this.start.time ) /
|
|
15389
|
-
( this.target.time
|
|
15937
|
+
( this.target.time - this.start.time )
|
|
15390
15938
|
);
|
|
15391
15939
|
|
|
15940
|
+
var oldValue = this.current.value;
|
|
15392
15941
|
if (this._exponential) {
|
|
15393
15942
|
this.current.value = Math.exp(currentValue);
|
|
15394
15943
|
} else {
|
|
15395
15944
|
this.current.value = currentValue;
|
|
15396
15945
|
}
|
|
15946
|
+
|
|
15947
|
+
return oldValue != this.current.value;
|
|
15397
15948
|
},
|
|
15398
15949
|
|
|
15399
15950
|
/**
|
|
@@ -15450,15 +16001,27 @@ function transform( stiffness, x ) {
|
|
|
15450
16001
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
15451
16002
|
*/
|
|
15452
16003
|
|
|
15453
|
-
(function(
|
|
16004
|
+
(function($){
|
|
15454
16005
|
|
|
15455
|
-
|
|
15456
|
-
|
|
16006
|
+
/**
|
|
16007
|
+
* @private
|
|
16008
|
+
* @class ImageJob
|
|
16009
|
+
* @classdesc Handles downloading of a single image.
|
|
16010
|
+
* @param {Object} options - Options for this ImageJob.
|
|
16011
|
+
* @param {String} [options.src] - URL of image to download.
|
|
16012
|
+
* @param {String} [options.loadWithAjax] - Whether to load this image with AJAX.
|
|
16013
|
+
* @param {String} [options.ajaxHeaders] - Headers to add to the image request if using AJAX.
|
|
16014
|
+
* @param {String} [options.crossOriginPolicy] - CORS policy to use for downloads
|
|
16015
|
+
* @param {Function} [options.callback] - Called once image has been downloaded.
|
|
16016
|
+
* @param {Function} [options.abort] - Called when this image job is aborted.
|
|
16017
|
+
* @param {Number} [options.timeout] - The max number of milliseconds that this image job may take to complete.
|
|
16018
|
+
*/
|
|
16019
|
+
function ImageJob (options) {
|
|
15457
16020
|
|
|
15458
|
-
$.extend(
|
|
15459
|
-
timeout:
|
|
15460
|
-
jobId:
|
|
15461
|
-
}, options
|
|
16021
|
+
$.extend(true, this, {
|
|
16022
|
+
timeout: $.DEFAULT_SETTINGS.timeout,
|
|
16023
|
+
jobId: null
|
|
16024
|
+
}, options);
|
|
15462
16025
|
|
|
15463
16026
|
/**
|
|
15464
16027
|
* Image object which will contain downloaded image.
|
|
@@ -15470,42 +16033,103 @@ function ImageJob ( options ) {
|
|
|
15470
16033
|
|
|
15471
16034
|
ImageJob.prototype = {
|
|
15472
16035
|
errorMsg: null,
|
|
16036
|
+
|
|
16037
|
+
/**
|
|
16038
|
+
* Starts the image job.
|
|
16039
|
+
* @method
|
|
16040
|
+
*/
|
|
15473
16041
|
start: function(){
|
|
15474
|
-
var
|
|
16042
|
+
var self = this;
|
|
16043
|
+
var selfAbort = this.abort;
|
|
15475
16044
|
|
|
15476
16045
|
this.image = new Image();
|
|
15477
16046
|
|
|
15478
|
-
if ( this.crossOriginPolicy !== false ) {
|
|
15479
|
-
this.image.crossOrigin = this.crossOriginPolicy;
|
|
15480
|
-
}
|
|
15481
|
-
|
|
15482
16047
|
this.image.onload = function(){
|
|
15483
|
-
|
|
16048
|
+
self.finish(true);
|
|
15484
16049
|
};
|
|
15485
|
-
this.image.onabort = this.image.onerror = function(){
|
|
15486
|
-
|
|
15487
|
-
|
|
16050
|
+
this.image.onabort = this.image.onerror = function() {
|
|
16051
|
+
self.errorMsg = "Image load aborted";
|
|
16052
|
+
self.finish(false);
|
|
15488
16053
|
};
|
|
15489
16054
|
|
|
15490
|
-
this.jobId = window.setTimeout(
|
|
15491
|
-
|
|
15492
|
-
|
|
16055
|
+
this.jobId = window.setTimeout(function(){
|
|
16056
|
+
self.errorMsg = "Image load exceeded timeout";
|
|
16057
|
+
self.finish(false);
|
|
15493
16058
|
}, this.timeout);
|
|
15494
16059
|
|
|
15495
|
-
|
|
16060
|
+
// Load the tile with an AJAX request if the loadWithAjax option is
|
|
16061
|
+
// set. Otherwise load the image by setting the source proprety of the image object.
|
|
16062
|
+
if (this.loadWithAjax) {
|
|
16063
|
+
this.request = $.makeAjaxRequest({
|
|
16064
|
+
url: this.src,
|
|
16065
|
+
withCredentials: this.ajaxWithCredentials,
|
|
16066
|
+
headers: this.ajaxHeaders,
|
|
16067
|
+
responseType: "arraybuffer",
|
|
16068
|
+
success: function(request) {
|
|
16069
|
+
var blb;
|
|
16070
|
+
// Make the raw data into a blob.
|
|
16071
|
+
// BlobBuilder fallback adapted from
|
|
16072
|
+
// http://stackoverflow.com/questions/15293694/blob-constructor-browser-compatibility
|
|
16073
|
+
try {
|
|
16074
|
+
blb = new window.Blob([request.response]);
|
|
16075
|
+
} catch (e) {
|
|
16076
|
+
var BlobBuilder = (
|
|
16077
|
+
window.BlobBuilder ||
|
|
16078
|
+
window.WebKitBlobBuilder ||
|
|
16079
|
+
window.MozBlobBuilder ||
|
|
16080
|
+
window.MSBlobBuilder
|
|
16081
|
+
);
|
|
16082
|
+
if (e.name === 'TypeError' && BlobBuilder) {
|
|
16083
|
+
var bb = new BlobBuilder();
|
|
16084
|
+
bb.append(request.response);
|
|
16085
|
+
blb = bb.getBlob();
|
|
16086
|
+
}
|
|
16087
|
+
}
|
|
16088
|
+
// If the blob is empty for some reason consider the image load a failure.
|
|
16089
|
+
if (blb.size === 0) {
|
|
16090
|
+
self.errorMsg = "Empty image response.";
|
|
16091
|
+
self.finish(false);
|
|
16092
|
+
}
|
|
16093
|
+
// Create a URL for the blob data and make it the source of the image object.
|
|
16094
|
+
// This will still trigger Image.onload to indicate a successful tile load.
|
|
16095
|
+
var url = (window.URL || window.webkitURL).createObjectURL(blb);
|
|
16096
|
+
self.image.src = url;
|
|
16097
|
+
},
|
|
16098
|
+
error: function(request) {
|
|
16099
|
+
self.errorMsg = "Image load aborted - XHR error";
|
|
16100
|
+
self.finish(false);
|
|
16101
|
+
}
|
|
16102
|
+
});
|
|
16103
|
+
|
|
16104
|
+
// Provide a function to properly abort the request.
|
|
16105
|
+
this.abort = function() {
|
|
16106
|
+
self.request.abort();
|
|
16107
|
+
|
|
16108
|
+
// Call the existing abort function if available
|
|
16109
|
+
if (typeof selfAbort === "function") {
|
|
16110
|
+
selfAbort();
|
|
16111
|
+
}
|
|
16112
|
+
};
|
|
16113
|
+
} else {
|
|
16114
|
+
if (this.crossOriginPolicy !== false) {
|
|
16115
|
+
this.image.crossOrigin = this.crossOriginPolicy;
|
|
16116
|
+
}
|
|
16117
|
+
|
|
16118
|
+
this.image.src = this.src;
|
|
16119
|
+
}
|
|
15496
16120
|
},
|
|
15497
16121
|
|
|
15498
|
-
finish: function(
|
|
16122
|
+
finish: function(successful) {
|
|
15499
16123
|
this.image.onload = this.image.onerror = this.image.onabort = null;
|
|
15500
16124
|
if (!successful) {
|
|
15501
16125
|
this.image = null;
|
|
15502
16126
|
}
|
|
15503
16127
|
|
|
15504
|
-
if (
|
|
15505
|
-
window.clearTimeout(
|
|
16128
|
+
if (this.jobId) {
|
|
16129
|
+
window.clearTimeout(this.jobId);
|
|
15506
16130
|
}
|
|
15507
16131
|
|
|
15508
|
-
this.callback(
|
|
16132
|
+
this.callback(this);
|
|
15509
16133
|
}
|
|
15510
16134
|
|
|
15511
16135
|
};
|
|
@@ -15517,14 +16141,16 @@ ImageJob.prototype = {
|
|
|
15517
16141
|
* You generally won't have to interact with the ImageLoader directly.
|
|
15518
16142
|
* @param {Object} options - Options for this ImageLoader.
|
|
15519
16143
|
* @param {Number} [options.jobLimit] - The number of concurrent image requests. See imageLoaderLimit in {@link OpenSeadragon.Options} for details.
|
|
16144
|
+
* @param {Number} [options.timeout] - The max number of milliseconds that an image job may take to complete.
|
|
15520
16145
|
*/
|
|
15521
|
-
$.ImageLoader = function(
|
|
16146
|
+
$.ImageLoader = function(options) {
|
|
15522
16147
|
|
|
15523
|
-
$.extend(
|
|
16148
|
+
$.extend(true, this, {
|
|
15524
16149
|
jobLimit: $.DEFAULT_SETTINGS.imageLoaderLimit,
|
|
16150
|
+
timeout: $.DEFAULT_SETTINGS.timeout,
|
|
15525
16151
|
jobQueue: [],
|
|
15526
16152
|
jobsInProgress: 0
|
|
15527
|
-
}, options
|
|
16153
|
+
}, options);
|
|
15528
16154
|
|
|
15529
16155
|
};
|
|
15530
16156
|
|
|
@@ -15534,22 +16160,32 @@ $.ImageLoader.prototype = {
|
|
|
15534
16160
|
/**
|
|
15535
16161
|
* Add an unloaded image to the loader queue.
|
|
15536
16162
|
* @method
|
|
15537
|
-
* @param {
|
|
15538
|
-
* @param {String}
|
|
15539
|
-
* @param {
|
|
15540
|
-
|
|
15541
|
-
|
|
16163
|
+
* @param {Object} options - Options for this job.
|
|
16164
|
+
* @param {String} [options.src] - URL of image to download.
|
|
16165
|
+
* @param {String} [options.loadWithAjax] - Whether to load this image with AJAX.
|
|
16166
|
+
* @param {String} [options.ajaxHeaders] - Headers to add to the image request if using AJAX.
|
|
16167
|
+
* @param {String|Boolean} [options.crossOriginPolicy] - CORS policy to use for downloads
|
|
16168
|
+
* @param {Boolean} [options.ajaxWithCredentials] - Whether to set withCredentials on AJAX
|
|
16169
|
+
* requests.
|
|
16170
|
+
* @param {Function} [options.callback] - Called once image has been downloaded.
|
|
16171
|
+
* @param {Function} [options.abort] - Called when this image job is aborted.
|
|
16172
|
+
*/
|
|
16173
|
+
addJob: function(options) {
|
|
15542
16174
|
var _this = this,
|
|
15543
|
-
complete = function(
|
|
15544
|
-
completeJob(
|
|
16175
|
+
complete = function(job) {
|
|
16176
|
+
completeJob(_this, job, options.callback);
|
|
15545
16177
|
},
|
|
15546
16178
|
jobOptions = {
|
|
15547
16179
|
src: options.src,
|
|
16180
|
+
loadWithAjax: options.loadWithAjax,
|
|
16181
|
+
ajaxHeaders: options.loadWithAjax ? options.ajaxHeaders : null,
|
|
15548
16182
|
crossOriginPolicy: options.crossOriginPolicy,
|
|
16183
|
+
ajaxWithCredentials: options.ajaxWithCredentials,
|
|
15549
16184
|
callback: complete,
|
|
15550
|
-
abort: options.abort
|
|
16185
|
+
abort: options.abort,
|
|
16186
|
+
timeout: this.timeout
|
|
15551
16187
|
},
|
|
15552
|
-
newJob = new ImageJob(
|
|
16188
|
+
newJob = new ImageJob(jobOptions);
|
|
15553
16189
|
|
|
15554
16190
|
if ( !this.jobLimit || this.jobsInProgress < this.jobLimit ) {
|
|
15555
16191
|
newJob.start();
|
|
@@ -15584,21 +16220,21 @@ $.ImageLoader.prototype = {
|
|
|
15584
16220
|
* @param job - The ImageJob that has completed.
|
|
15585
16221
|
* @param callback - Called once cleanup is finished.
|
|
15586
16222
|
*/
|
|
15587
|
-
function completeJob(
|
|
16223
|
+
function completeJob(loader, job, callback) {
|
|
15588
16224
|
var nextJob;
|
|
15589
16225
|
|
|
15590
16226
|
loader.jobsInProgress--;
|
|
15591
16227
|
|
|
15592
|
-
if (
|
|
16228
|
+
if ((!loader.jobLimit || loader.jobsInProgress < loader.jobLimit) && loader.jobQueue.length > 0) {
|
|
15593
16229
|
nextJob = loader.jobQueue.shift();
|
|
15594
16230
|
nextJob.start();
|
|
15595
16231
|
loader.jobsInProgress++;
|
|
15596
16232
|
}
|
|
15597
16233
|
|
|
15598
|
-
callback(
|
|
16234
|
+
callback(job.image, job.errorMsg, job.request);
|
|
15599
16235
|
}
|
|
15600
16236
|
|
|
15601
|
-
}(
|
|
16237
|
+
}(OpenSeadragon));
|
|
15602
16238
|
|
|
15603
16239
|
/*
|
|
15604
16240
|
* OpenSeadragon - Tile
|
|
@@ -15649,8 +16285,10 @@ function completeJob( loader, job, callback ) {
|
|
|
15649
16285
|
* @param {String} url The URL of this tile's image.
|
|
15650
16286
|
* @param {CanvasRenderingContext2D} context2D The context2D of this tile if it
|
|
15651
16287
|
* is provided directly by the tile source.
|
|
16288
|
+
* @param {Boolean} loadWithAjax Whether this tile image should be loaded with an AJAX request .
|
|
16289
|
+
* @param {Object} ajaxHeaders The headers to send with this tile's AJAX request (if applicable).
|
|
15652
16290
|
*/
|
|
15653
|
-
$.Tile = function(level, x, y, bounds, exists, url, context2D) {
|
|
16291
|
+
$.Tile = function(level, x, y, bounds, exists, url, context2D, loadWithAjax, ajaxHeaders) {
|
|
15654
16292
|
/**
|
|
15655
16293
|
* The zoom level this tile belongs to.
|
|
15656
16294
|
* @member {Number} level
|
|
@@ -15693,6 +16331,29 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D) {
|
|
|
15693
16331
|
* @memberOf OpenSeadragon.Tile#
|
|
15694
16332
|
*/
|
|
15695
16333
|
this.context2D = context2D;
|
|
16334
|
+
/**
|
|
16335
|
+
* Whether to load this tile's image with an AJAX request.
|
|
16336
|
+
* @member {Boolean} loadWithAjax
|
|
16337
|
+
* @memberof OpenSeadragon.Tile#
|
|
16338
|
+
*/
|
|
16339
|
+
this.loadWithAjax = loadWithAjax;
|
|
16340
|
+
/**
|
|
16341
|
+
* The headers to be used in requesting this tile's image.
|
|
16342
|
+
* Only used if loadWithAjax is set to true.
|
|
16343
|
+
* @member {Object} ajaxHeaders
|
|
16344
|
+
* @memberof OpenSeadragon.Tile#
|
|
16345
|
+
*/
|
|
16346
|
+
this.ajaxHeaders = ajaxHeaders;
|
|
16347
|
+
/**
|
|
16348
|
+
* The unique cache key for this tile.
|
|
16349
|
+
* @member {String} cacheKey
|
|
16350
|
+
* @memberof OpenSeadragon.Tile#
|
|
16351
|
+
*/
|
|
16352
|
+
if (this.ajaxHeaders) {
|
|
16353
|
+
this.cacheKey = this.url + "+" + JSON.stringify(this.ajaxHeaders);
|
|
16354
|
+
} else {
|
|
16355
|
+
this.cacheKey = this.url;
|
|
16356
|
+
}
|
|
15696
16357
|
/**
|
|
15697
16358
|
* Is this tile loaded?
|
|
15698
16359
|
* @member {Boolean} loaded
|
|
@@ -15756,11 +16417,13 @@ $.Tile = function(level, x, y, bounds, exists, url, context2D) {
|
|
|
15756
16417
|
*/
|
|
15757
16418
|
this.opacity = null;
|
|
15758
16419
|
/**
|
|
15759
|
-
* The distance of this tile to the viewport center.
|
|
15760
|
-
*
|
|
16420
|
+
* The squared distance of this tile to the viewport center.
|
|
16421
|
+
* Use for comparing tiles.
|
|
16422
|
+
* @private
|
|
16423
|
+
* @member {Number} squaredDistance
|
|
15761
16424
|
* @memberof OpenSeadragon.Tile#
|
|
15762
16425
|
*/
|
|
15763
|
-
this.
|
|
16426
|
+
this.squaredDistance = null;
|
|
15764
16427
|
/**
|
|
15765
16428
|
* The visibility score of this tile.
|
|
15766
16429
|
* @member {Number} visibility
|
|
@@ -16040,6 +16703,7 @@ $.Tile.prototype = {
|
|
|
16040
16703
|
* compatibility.
|
|
16041
16704
|
* @member OverlayPlacement
|
|
16042
16705
|
* @memberof OpenSeadragon
|
|
16706
|
+
* @see OpenSeadragon.Placement
|
|
16043
16707
|
* @static
|
|
16044
16708
|
* @readonly
|
|
16045
16709
|
* @type {Object}
|
|
@@ -16246,6 +16910,8 @@ $.Tile.prototype = {
|
|
|
16246
16910
|
element.prevNextSibling = element.nextSibling;
|
|
16247
16911
|
container.appendChild(element);
|
|
16248
16912
|
|
|
16913
|
+
// have to set position before calculating size, fix #1116
|
|
16914
|
+
this.style.position = "absolute";
|
|
16249
16915
|
// this.size is used by overlays which don't get scaled in at
|
|
16250
16916
|
// least one direction when this.checkResize is set to false.
|
|
16251
16917
|
this.size = $.getElementSize(element);
|
|
@@ -16284,7 +16950,6 @@ $.Tile.prototype = {
|
|
|
16284
16950
|
style[transformProp] = "";
|
|
16285
16951
|
}
|
|
16286
16952
|
}
|
|
16287
|
-
style.position = "absolute";
|
|
16288
16953
|
|
|
16289
16954
|
if (style.display !== 'none') {
|
|
16290
16955
|
style.display = 'block';
|
|
@@ -16399,7 +17064,7 @@ $.Tile.prototype = {
|
|
|
16399
17064
|
* @param {OpenSeadragon.Point|OpenSeadragon.Rect|Object} location
|
|
16400
17065
|
* If an object is specified, the options are the same than the constructor
|
|
16401
17066
|
* except for the element which can not be changed.
|
|
16402
|
-
* @param {OpenSeadragon.Placement}
|
|
17067
|
+
* @param {OpenSeadragon.Placement} placement
|
|
16403
17068
|
*/
|
|
16404
17069
|
update: function(location, placement) {
|
|
16405
17070
|
var options = $.isPlainObject(location) ? location : {
|
|
@@ -16761,8 +17426,8 @@ $.Drawer.prototype = {
|
|
|
16761
17426
|
return new $.Rect(
|
|
16762
17427
|
topLeft.x * $.pixelDensityRatio,
|
|
16763
17428
|
topLeft.y * $.pixelDensityRatio,
|
|
16764
|
-
size.x
|
|
16765
|
-
size.y
|
|
17429
|
+
size.x * $.pixelDensityRatio,
|
|
17430
|
+
size.y * $.pixelDensityRatio
|
|
16766
17431
|
);
|
|
16767
17432
|
},
|
|
16768
17433
|
|
|
@@ -16805,6 +17470,9 @@ $.Drawer.prototype = {
|
|
|
16805
17470
|
if (this.viewport.getRotation() === 0) {
|
|
16806
17471
|
var self = this;
|
|
16807
17472
|
this.viewer.addHandler('rotate', function resizeSketchCanvas() {
|
|
17473
|
+
if (self.viewport.getRotation() === 0) {
|
|
17474
|
+
return;
|
|
17475
|
+
}
|
|
16808
17476
|
self.viewer.removeHandler('rotate', resizeSketchCanvas);
|
|
16809
17477
|
var sketchCanvasSize = self._calculateSketchCanvasSize();
|
|
16810
17478
|
self.sketchCanvas.width = sketchCanvasSize.x;
|
|
@@ -16899,6 +17567,24 @@ $.Drawer.prototype = {
|
|
|
16899
17567
|
this.context.globalCompositeOperation = compositeOperation;
|
|
16900
17568
|
}
|
|
16901
17569
|
if (bounds) {
|
|
17570
|
+
// Internet Explorer, Microsoft Edge, and Safari have problems
|
|
17571
|
+
// when you call context.drawImage with negative x or y
|
|
17572
|
+
// or x + width or y + height greater than the canvas width or height respectively.
|
|
17573
|
+
if (bounds.x < 0) {
|
|
17574
|
+
bounds.width += bounds.x;
|
|
17575
|
+
bounds.x = 0;
|
|
17576
|
+
}
|
|
17577
|
+
if (bounds.x + bounds.width > this.canvas.width) {
|
|
17578
|
+
bounds.width = this.canvas.width - bounds.x;
|
|
17579
|
+
}
|
|
17580
|
+
if (bounds.y < 0) {
|
|
17581
|
+
bounds.height += bounds.y;
|
|
17582
|
+
bounds.y = 0;
|
|
17583
|
+
}
|
|
17584
|
+
if (bounds.y + bounds.height > this.canvas.height) {
|
|
17585
|
+
bounds.height = this.canvas.height - bounds.y;
|
|
17586
|
+
}
|
|
17587
|
+
|
|
16902
17588
|
this.context.drawImage(
|
|
16903
17589
|
this.sketchCanvas,
|
|
16904
17590
|
bounds.x,
|
|
@@ -16929,7 +17615,7 @@ $.Drawer.prototype = {
|
|
|
16929
17615
|
position.x - widthExt * scale,
|
|
16930
17616
|
position.y - heightExt * scale,
|
|
16931
17617
|
(this.canvas.width + 2 * widthExt) * scale,
|
|
16932
|
-
(this.canvas.height
|
|
17618
|
+
(this.canvas.height + 2 * heightExt) * scale,
|
|
16933
17619
|
-widthExt,
|
|
16934
17620
|
-heightExt,
|
|
16935
17621
|
this.canvas.width + 2 * widthExt,
|
|
@@ -16940,7 +17626,7 @@ $.Drawer.prototype = {
|
|
|
16940
17626
|
},
|
|
16941
17627
|
|
|
16942
17628
|
// private
|
|
16943
|
-
drawDebugInfo: function(
|
|
17629
|
+
drawDebugInfo: function(tile, count, i, tiledImage) {
|
|
16944
17630
|
if ( !this.useCanvas ) {
|
|
16945
17631
|
return;
|
|
16946
17632
|
}
|
|
@@ -16953,7 +17639,14 @@ $.Drawer.prototype = {
|
|
|
16953
17639
|
context.fillStyle = this.debugGridColor;
|
|
16954
17640
|
|
|
16955
17641
|
if ( this.viewport.degrees !== 0 ) {
|
|
16956
|
-
this._offsetForRotation(this.viewport.degrees);
|
|
17642
|
+
this._offsetForRotation({degrees: this.viewport.degrees});
|
|
17643
|
+
}
|
|
17644
|
+
if (tiledImage.getRotation(true) % 360 !== 0) {
|
|
17645
|
+
this._offsetForRotation({
|
|
17646
|
+
degrees: tiledImage.getRotation(true),
|
|
17647
|
+
point: tiledImage.viewport.pixelFromPointNoRotate(
|
|
17648
|
+
tiledImage._getRotationPoint(true), true)
|
|
17649
|
+
});
|
|
16957
17650
|
}
|
|
16958
17651
|
|
|
16959
17652
|
context.strokeRect(
|
|
@@ -17017,6 +17710,9 @@ $.Drawer.prototype = {
|
|
|
17017
17710
|
if ( this.viewport.degrees !== 0 ) {
|
|
17018
17711
|
this._restoreRotationChanges();
|
|
17019
17712
|
}
|
|
17713
|
+
if (tiledImage.getRotation(true) % 360 !== 0) {
|
|
17714
|
+
this._restoreRotationChanges();
|
|
17715
|
+
}
|
|
17020
17716
|
context.restore();
|
|
17021
17717
|
},
|
|
17022
17718
|
|
|
@@ -17050,17 +17746,22 @@ $.Drawer.prototype = {
|
|
|
17050
17746
|
return new $.Point(canvas.width, canvas.height);
|
|
17051
17747
|
},
|
|
17052
17748
|
|
|
17749
|
+
getCanvasCenter: function() {
|
|
17750
|
+
return new $.Point(this.canvas.width / 2, this.canvas.height / 2);
|
|
17751
|
+
},
|
|
17752
|
+
|
|
17053
17753
|
// private
|
|
17054
|
-
_offsetForRotation: function(
|
|
17055
|
-
var
|
|
17056
|
-
|
|
17754
|
+
_offsetForRotation: function(options) {
|
|
17755
|
+
var point = options.point ?
|
|
17756
|
+
options.point.times($.pixelDensityRatio) :
|
|
17757
|
+
this.getCanvasCenter();
|
|
17057
17758
|
|
|
17058
|
-
var context = this._getContext(useSketch);
|
|
17759
|
+
var context = this._getContext(options.useSketch);
|
|
17059
17760
|
context.save();
|
|
17060
17761
|
|
|
17061
|
-
context.translate(
|
|
17062
|
-
context.rotate(Math.PI / 180 * degrees);
|
|
17063
|
-
context.translate(-
|
|
17762
|
+
context.translate(point.x, point.y);
|
|
17763
|
+
context.rotate(Math.PI / 180 * options.degrees);
|
|
17764
|
+
context.translate(-point.x, -point.y);
|
|
17064
17765
|
},
|
|
17065
17766
|
|
|
17066
17767
|
// private
|
|
@@ -17161,11 +17862,11 @@ $.Viewport = function( options ) {
|
|
|
17161
17862
|
//backward compatibility for positional args while prefering more
|
|
17162
17863
|
//idiomatic javascript options object as the only argument
|
|
17163
17864
|
var args = arguments;
|
|
17164
|
-
if(
|
|
17865
|
+
if (args.length && args[0] instanceof $.Point) {
|
|
17165
17866
|
options = {
|
|
17166
|
-
containerSize: args[
|
|
17167
|
-
contentSize: args[
|
|
17168
|
-
config: args[
|
|
17867
|
+
containerSize: args[0],
|
|
17868
|
+
contentSize: args[1],
|
|
17869
|
+
config: args[2]
|
|
17169
17870
|
};
|
|
17170
17871
|
}
|
|
17171
17872
|
|
|
@@ -17586,10 +18287,9 @@ $.Viewport.prototype = {
|
|
|
17586
18287
|
* @function
|
|
17587
18288
|
* @private
|
|
17588
18289
|
* @param {OpenSeadragon.Rect} bounds
|
|
17589
|
-
* @param {Boolean} immediately
|
|
17590
18290
|
* @return {OpenSeadragon.Rect} constrained bounds.
|
|
17591
18291
|
*/
|
|
17592
|
-
_applyBoundaryConstraints: function(bounds
|
|
18292
|
+
_applyBoundaryConstraints: function(bounds) {
|
|
17593
18293
|
var newBounds = new $.Rect(
|
|
17594
18294
|
bounds.x,
|
|
17595
18295
|
bounds.y,
|
|
@@ -17632,6 +18332,16 @@ $.Viewport.prototype = {
|
|
|
17632
18332
|
}
|
|
17633
18333
|
}
|
|
17634
18334
|
|
|
18335
|
+
return newBounds;
|
|
18336
|
+
},
|
|
18337
|
+
|
|
18338
|
+
/**
|
|
18339
|
+
* @function
|
|
18340
|
+
* @private
|
|
18341
|
+
* @param {Boolean} [immediately=false] - whether the function that triggered this event was
|
|
18342
|
+
* called with the "immediately" flag
|
|
18343
|
+
*/
|
|
18344
|
+
_raiseConstraintsEvent: function(immediately) {
|
|
17635
18345
|
if (this.viewer) {
|
|
17636
18346
|
/**
|
|
17637
18347
|
* Raised when the viewport constraints are applied (see {@link OpenSeadragon.Viewport#applyConstraints}).
|
|
@@ -17640,15 +18350,14 @@ $.Viewport.prototype = {
|
|
|
17640
18350
|
* @memberof OpenSeadragon.Viewer
|
|
17641
18351
|
* @type {object}
|
|
17642
18352
|
* @property {OpenSeadragon.Viewer} eventSource - A reference to the Viewer which raised this event.
|
|
17643
|
-
* @property {Boolean} immediately
|
|
18353
|
+
* @property {Boolean} immediately - whether the function that triggered this event was
|
|
18354
|
+
* called with the "immediately" flag
|
|
17644
18355
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
17645
18356
|
*/
|
|
17646
18357
|
this.viewer.raiseEvent( 'constrain', {
|
|
17647
18358
|
immediately: immediately
|
|
17648
18359
|
});
|
|
17649
18360
|
}
|
|
17650
|
-
|
|
17651
|
-
return newBounds;
|
|
17652
18361
|
},
|
|
17653
18362
|
|
|
17654
18363
|
/**
|
|
@@ -17668,8 +18377,8 @@ $.Viewport.prototype = {
|
|
|
17668
18377
|
}
|
|
17669
18378
|
|
|
17670
18379
|
var bounds = this.getBoundsNoRotate();
|
|
17671
|
-
var constrainedBounds = this._applyBoundaryConstraints(
|
|
17672
|
-
|
|
18380
|
+
var constrainedBounds = this._applyBoundaryConstraints(bounds);
|
|
18381
|
+
this._raiseConstraintsEvent(immediately);
|
|
17673
18382
|
|
|
17674
18383
|
if (bounds.x !== constrainedBounds.x ||
|
|
17675
18384
|
bounds.y !== constrainedBounds.y ||
|
|
@@ -17739,8 +18448,9 @@ $.Viewport.prototype = {
|
|
|
17739
18448
|
newBounds.y = center.y - newBounds.height / 2;
|
|
17740
18449
|
}
|
|
17741
18450
|
|
|
17742
|
-
newBounds = this._applyBoundaryConstraints(newBounds
|
|
18451
|
+
newBounds = this._applyBoundaryConstraints(newBounds);
|
|
17743
18452
|
center = newBounds.getCenter();
|
|
18453
|
+
this._raiseConstraintsEvent(immediately);
|
|
17744
18454
|
}
|
|
17745
18455
|
|
|
17746
18456
|
if (immediately) {
|
|
@@ -17834,6 +18544,23 @@ $.Viewport.prototype = {
|
|
|
17834
18544
|
},
|
|
17835
18545
|
|
|
17836
18546
|
|
|
18547
|
+
/**
|
|
18548
|
+
* Returns bounds taking constraints into account
|
|
18549
|
+
* Added to improve constrained panning
|
|
18550
|
+
* @param {Boolean} current - Pass true for the current location; defaults to false (target location).
|
|
18551
|
+
* @return {OpenSeadragon.Viewport} Chainable.
|
|
18552
|
+
*/
|
|
18553
|
+
getConstrainedBounds: function(current) {
|
|
18554
|
+
var bounds,
|
|
18555
|
+
constrainedBounds;
|
|
18556
|
+
|
|
18557
|
+
bounds = this.getBounds(current);
|
|
18558
|
+
|
|
18559
|
+
constrainedBounds = this._applyBoundaryConstraints(bounds);
|
|
18560
|
+
|
|
18561
|
+
return constrainedBounds;
|
|
18562
|
+
},
|
|
18563
|
+
|
|
17837
18564
|
/**
|
|
17838
18565
|
* @function
|
|
17839
18566
|
* @param {OpenSeadragon.Point} delta
|
|
@@ -17906,7 +18633,8 @@ $.Viewport.prototype = {
|
|
|
17906
18633
|
* @return {OpenSeadragon.Viewport} Chainable.
|
|
17907
18634
|
* @fires OpenSeadragon.Viewer.event:zoom
|
|
17908
18635
|
*/
|
|
17909
|
-
zoomTo: function(
|
|
18636
|
+
zoomTo: function(zoom, refPoint, immediately) {
|
|
18637
|
+
var _this = this;
|
|
17910
18638
|
|
|
17911
18639
|
this.zoomPoint = refPoint instanceof $.Point &&
|
|
17912
18640
|
!isNaN(refPoint.x) &&
|
|
@@ -17914,13 +18642,15 @@ $.Viewport.prototype = {
|
|
|
17914
18642
|
refPoint :
|
|
17915
18643
|
null;
|
|
17916
18644
|
|
|
17917
|
-
if (
|
|
17918
|
-
this.
|
|
18645
|
+
if (immediately) {
|
|
18646
|
+
this._adjustCenterSpringsForZoomPoint(function() {
|
|
18647
|
+
_this.zoomSpring.resetTo(zoom);
|
|
18648
|
+
});
|
|
17919
18649
|
} else {
|
|
17920
|
-
this.zoomSpring.springTo(
|
|
18650
|
+
this.zoomSpring.springTo(zoom);
|
|
17921
18651
|
}
|
|
17922
18652
|
|
|
17923
|
-
if(
|
|
18653
|
+
if (this.viewer) {
|
|
17924
18654
|
/**
|
|
17925
18655
|
* Raised when the viewport zoom level changes (see {@link OpenSeadragon.Viewport#zoomBy} and {@link OpenSeadragon.Viewport#zoomTo}).
|
|
17926
18656
|
*
|
|
@@ -17933,7 +18663,7 @@ $.Viewport.prototype = {
|
|
|
17933
18663
|
* @property {Boolean} immediately
|
|
17934
18664
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
17935
18665
|
*/
|
|
17936
|
-
this.viewer.raiseEvent(
|
|
18666
|
+
this.viewer.raiseEvent('zoom', {
|
|
17937
18667
|
zoom: zoom,
|
|
17938
18668
|
refPoint: refPoint,
|
|
17939
18669
|
immediately: immediately
|
|
@@ -17953,11 +18683,7 @@ $.Viewport.prototype = {
|
|
|
17953
18683
|
return this;
|
|
17954
18684
|
}
|
|
17955
18685
|
|
|
17956
|
-
degrees = degrees
|
|
17957
|
-
if (degrees < 0) {
|
|
17958
|
-
degrees += 360;
|
|
17959
|
-
}
|
|
17960
|
-
this.degrees = degrees;
|
|
18686
|
+
this.degrees = $.positiveModulo(degrees, 360);
|
|
17961
18687
|
this._setContentBounds(
|
|
17962
18688
|
this.viewer.world.getHomeBounds(),
|
|
17963
18689
|
this.viewer.world.getContentFactor());
|
|
@@ -18043,10 +18769,29 @@ $.Viewport.prototype = {
|
|
|
18043
18769
|
* @returns {Boolean} True if any change has been made, false otherwise.
|
|
18044
18770
|
*/
|
|
18045
18771
|
update: function() {
|
|
18772
|
+
var _this = this;
|
|
18773
|
+
this._adjustCenterSpringsForZoomPoint(function() {
|
|
18774
|
+
_this.zoomSpring.update();
|
|
18775
|
+
});
|
|
18776
|
+
|
|
18777
|
+
this.centerSpringX.update();
|
|
18778
|
+
this.centerSpringY.update();
|
|
18779
|
+
|
|
18780
|
+
var changed = this.centerSpringX.current.value !== this._oldCenterX ||
|
|
18781
|
+
this.centerSpringY.current.value !== this._oldCenterY ||
|
|
18782
|
+
this.zoomSpring.current.value !== this._oldZoom;
|
|
18783
|
+
|
|
18784
|
+
this._oldCenterX = this.centerSpringX.current.value;
|
|
18785
|
+
this._oldCenterY = this.centerSpringY.current.value;
|
|
18786
|
+
this._oldZoom = this.zoomSpring.current.value;
|
|
18787
|
+
|
|
18788
|
+
return changed;
|
|
18789
|
+
},
|
|
18046
18790
|
|
|
18791
|
+
_adjustCenterSpringsForZoomPoint: function(zoomSpringHandler) {
|
|
18047
18792
|
if (this.zoomPoint) {
|
|
18048
18793
|
var oldZoomPixel = this.pixelFromPoint(this.zoomPoint, true);
|
|
18049
|
-
|
|
18794
|
+
zoomSpringHandler();
|
|
18050
18795
|
var newZoomPixel = this.pixelFromPoint(this.zoomPoint, true);
|
|
18051
18796
|
|
|
18052
18797
|
var deltaZoomPixels = newZoomPixel.minus(oldZoomPixel);
|
|
@@ -18060,21 +18805,8 @@ $.Viewport.prototype = {
|
|
|
18060
18805
|
this.zoomPoint = null;
|
|
18061
18806
|
}
|
|
18062
18807
|
} else {
|
|
18063
|
-
|
|
18808
|
+
zoomSpringHandler();
|
|
18064
18809
|
}
|
|
18065
|
-
|
|
18066
|
-
this.centerSpringX.update();
|
|
18067
|
-
this.centerSpringY.update();
|
|
18068
|
-
|
|
18069
|
-
var changed = this.centerSpringX.current.value !== this._oldCenterX ||
|
|
18070
|
-
this.centerSpringY.current.value !== this._oldCenterY ||
|
|
18071
|
-
this.zoomSpring.current.value !== this._oldZoom;
|
|
18072
|
-
|
|
18073
|
-
this._oldCenterX = this.centerSpringX.current.value;
|
|
18074
|
-
this._oldCenterY = this.centerSpringY.current.value;
|
|
18075
|
-
this._oldZoom = this.zoomSpring.current.value;
|
|
18076
|
-
|
|
18077
|
-
return changed;
|
|
18078
18810
|
},
|
|
18079
18811
|
|
|
18080
18812
|
/**
|
|
@@ -18313,6 +19045,7 @@ $.Viewport.prototype = {
|
|
|
18313
19045
|
* in image coordinate system.
|
|
18314
19046
|
* @param {Number} [pixelWidth] the width in pixel of the rectangle.
|
|
18315
19047
|
* @param {Number} [pixelHeight] the height in pixel of the rectangle.
|
|
19048
|
+
* @returns {OpenSeadragon.Rect} This image's bounds in viewport coordinates
|
|
18316
19049
|
*/
|
|
18317
19050
|
imageToViewportRectangle: function(imageX, imageY, pixelWidth, pixelHeight) {
|
|
18318
19051
|
var rect = imageX;
|
|
@@ -18664,11 +19397,18 @@ $.Viewport.prototype = {
|
|
|
18664
19397
|
* @param {Number} [options.minPixelRatio] - See {@link OpenSeadragon.Options}.
|
|
18665
19398
|
* @param {Number} [options.smoothTileEdgesMinZoom] - See {@link OpenSeadragon.Options}.
|
|
18666
19399
|
* @param {Boolean} [options.iOSDevice] - See {@link OpenSeadragon.Options}.
|
|
18667
|
-
* @param {Number} [options.opacity=1] -
|
|
19400
|
+
* @param {Number} [options.opacity=1] - Set to draw at proportional opacity. If zero, images will not draw.
|
|
19401
|
+
* @param {Boolean} [options.preload=false] - Set true to load even when the image is hidden by zero opacity.
|
|
18668
19402
|
* @param {String} [options.compositeOperation] - How the image is composited onto other images; see compositeOperation in {@link OpenSeadragon.Options} for possible values.
|
|
18669
19403
|
* @param {Boolean} [options.debugMode] - See {@link OpenSeadragon.Options}.
|
|
18670
19404
|
* @param {String|CanvasGradient|CanvasPattern|Function} [options.placeholderFillStyle] - See {@link OpenSeadragon.Options}.
|
|
18671
19405
|
* @param {String|Boolean} [options.crossOriginPolicy] - See {@link OpenSeadragon.Options}.
|
|
19406
|
+
* @param {Boolean} [options.ajaxWithCredentials] - See {@link OpenSeadragon.Options}.
|
|
19407
|
+
* @param {Boolean} [options.loadTilesWithAjax]
|
|
19408
|
+
* Whether to load tile data using AJAX requests.
|
|
19409
|
+
* Defaults to the setting in {@link OpenSeadragon.Options}.
|
|
19410
|
+
* @param {Object} [options.ajaxHeaders={}]
|
|
19411
|
+
* A set of headers to include when making tile AJAX requests.
|
|
18672
19412
|
*/
|
|
18673
19413
|
$.TiledImage = function( options ) {
|
|
18674
19414
|
var _this = this;
|
|
@@ -18726,17 +19466,22 @@ $.TiledImage = function( options ) {
|
|
|
18726
19466
|
var fitBoundsPlacement = options.fitBoundsPlacement || OpenSeadragon.Placement.CENTER;
|
|
18727
19467
|
delete options.fitBoundsPlacement;
|
|
18728
19468
|
|
|
19469
|
+
var degrees = options.degrees || 0;
|
|
19470
|
+
delete options.degrees;
|
|
19471
|
+
|
|
18729
19472
|
$.extend( true, this, {
|
|
18730
19473
|
|
|
18731
19474
|
//internal state properties
|
|
18732
19475
|
viewer: null,
|
|
18733
19476
|
tilesMatrix: {}, // A '3d' dictionary [level][x][y] --> Tile.
|
|
18734
|
-
coverage: {}, // A '3d' dictionary [level][x][y] --> Boolean.
|
|
19477
|
+
coverage: {}, // A '3d' dictionary [level][x][y] --> Boolean; shows what areas have been drawn.
|
|
19478
|
+
loadingCoverage: {}, // A '3d' dictionary [level][x][y] --> Boolean; shows what areas are loaded or are being loaded/blended.
|
|
18735
19479
|
lastDrawn: [], // An unordered list of Tiles drawn last frame.
|
|
18736
19480
|
lastResetTime: 0, // Last time for which the tiledImage was reset.
|
|
18737
19481
|
_midDraw: false, // Is the tiledImage currently updating the viewport?
|
|
18738
19482
|
_needsDraw: true, // Does the tiledImage need to update the viewport again?
|
|
18739
19483
|
_hasOpaqueTile: false, // Do we have even one fully opaque tile?
|
|
19484
|
+
_tilesLoading: 0, // The number of pending tile requests.
|
|
18740
19485
|
//configurable settings
|
|
18741
19486
|
springStiffness: $.DEFAULT_SETTINGS.springStiffness,
|
|
18742
19487
|
animationTime: $.DEFAULT_SETTINGS.animationTime,
|
|
@@ -18751,12 +19496,18 @@ $.TiledImage = function( options ) {
|
|
|
18751
19496
|
iOSDevice: $.DEFAULT_SETTINGS.iOSDevice,
|
|
18752
19497
|
debugMode: $.DEFAULT_SETTINGS.debugMode,
|
|
18753
19498
|
crossOriginPolicy: $.DEFAULT_SETTINGS.crossOriginPolicy,
|
|
19499
|
+
ajaxWithCredentials: $.DEFAULT_SETTINGS.ajaxWithCredentials,
|
|
18754
19500
|
placeholderFillStyle: $.DEFAULT_SETTINGS.placeholderFillStyle,
|
|
18755
19501
|
opacity: $.DEFAULT_SETTINGS.opacity,
|
|
19502
|
+
preload: $.DEFAULT_SETTINGS.preload,
|
|
18756
19503
|
compositeOperation: $.DEFAULT_SETTINGS.compositeOperation
|
|
18757
|
-
|
|
18758
19504
|
}, options );
|
|
18759
19505
|
|
|
19506
|
+
this._preload = this.preload;
|
|
19507
|
+
delete this.preload;
|
|
19508
|
+
|
|
19509
|
+
this._fullyLoaded = false;
|
|
19510
|
+
|
|
18760
19511
|
this._xSpring = new $.Spring({
|
|
18761
19512
|
initial: x,
|
|
18762
19513
|
springStiffness: this.springStiffness,
|
|
@@ -18775,6 +19526,12 @@ $.TiledImage = function( options ) {
|
|
|
18775
19526
|
animationTime: this.animationTime
|
|
18776
19527
|
});
|
|
18777
19528
|
|
|
19529
|
+
this._degreesSpring = new $.Spring({
|
|
19530
|
+
initial: degrees,
|
|
19531
|
+
springStiffness: this.springStiffness,
|
|
19532
|
+
animationTime: this.animationTime
|
|
19533
|
+
});
|
|
19534
|
+
|
|
18778
19535
|
this._updateForScale();
|
|
18779
19536
|
|
|
18780
19537
|
if (fitBounds) {
|
|
@@ -18813,10 +19570,41 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18813
19570
|
},
|
|
18814
19571
|
|
|
18815
19572
|
/**
|
|
18816
|
-
*
|
|
18817
|
-
* {@link OpenSeadragon.TiledImage#update}.
|
|
19573
|
+
* @returns {Boolean} Whether all tiles necessary for this TiledImage to draw at the current view have been loaded.
|
|
18818
19574
|
*/
|
|
18819
|
-
|
|
19575
|
+
getFullyLoaded: function() {
|
|
19576
|
+
return this._fullyLoaded;
|
|
19577
|
+
},
|
|
19578
|
+
|
|
19579
|
+
// private
|
|
19580
|
+
_setFullyLoaded: function(flag) {
|
|
19581
|
+
if (flag === this._fullyLoaded) {
|
|
19582
|
+
return;
|
|
19583
|
+
}
|
|
19584
|
+
|
|
19585
|
+
this._fullyLoaded = flag;
|
|
19586
|
+
|
|
19587
|
+
/**
|
|
19588
|
+
* Fired when the TiledImage's "fully loaded" flag (whether all tiles necessary for this TiledImage
|
|
19589
|
+
* to draw at the current view have been loaded) changes.
|
|
19590
|
+
*
|
|
19591
|
+
* @event fully-loaded-change
|
|
19592
|
+
* @memberof OpenSeadragon.TiledImage
|
|
19593
|
+
* @type {object}
|
|
19594
|
+
* @property {Boolean} fullyLoaded - The new "fully loaded" value.
|
|
19595
|
+
* @property {OpenSeadragon.TiledImage} eventSource - A reference to the TiledImage which raised the event.
|
|
19596
|
+
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
19597
|
+
*/
|
|
19598
|
+
this.raiseEvent('fully-loaded-change', {
|
|
19599
|
+
fullyLoaded: this._fullyLoaded
|
|
19600
|
+
});
|
|
19601
|
+
},
|
|
19602
|
+
|
|
19603
|
+
/**
|
|
19604
|
+
* Clears all tiles and triggers an update on the next call to
|
|
19605
|
+
* {@link OpenSeadragon.TiledImage#update}.
|
|
19606
|
+
*/
|
|
19607
|
+
reset: function() {
|
|
18820
19608
|
this._tileCache.clearTilesFor(this);
|
|
18821
19609
|
this.lastResetTime = $.now();
|
|
18822
19610
|
this._needsDraw = true;
|
|
@@ -18827,16 +19615,12 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18827
19615
|
* @returns {Boolean} Whether the TiledImage animated.
|
|
18828
19616
|
*/
|
|
18829
19617
|
update: function() {
|
|
18830
|
-
var
|
|
18831
|
-
var
|
|
18832
|
-
var
|
|
18833
|
-
|
|
18834
|
-
this._xSpring.update();
|
|
18835
|
-
this._ySpring.update();
|
|
18836
|
-
this._scaleSpring.update();
|
|
19618
|
+
var xUpdated = this._xSpring.update();
|
|
19619
|
+
var yUpdated = this._ySpring.update();
|
|
19620
|
+
var scaleUpdated = this._scaleSpring.update();
|
|
19621
|
+
var degreesUpdated = this._degreesSpring.update();
|
|
18837
19622
|
|
|
18838
|
-
if (
|
|
18839
|
-
this._scaleSpring.current.value !== oldScale) {
|
|
19623
|
+
if (xUpdated || yUpdated || scaleUpdated || degreesUpdated) {
|
|
18840
19624
|
this._updateForScale();
|
|
18841
19625
|
this._needsDraw = true;
|
|
18842
19626
|
return true;
|
|
@@ -18849,9 +19633,9 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18849
19633
|
* Draws the TiledImage to its Drawer.
|
|
18850
19634
|
*/
|
|
18851
19635
|
draw: function() {
|
|
18852
|
-
if (this.opacity !== 0) {
|
|
19636
|
+
if (this.opacity !== 0 || this._preload) {
|
|
18853
19637
|
this._midDraw = true;
|
|
18854
|
-
|
|
19638
|
+
this._updateViewport();
|
|
18855
19639
|
this._midDraw = false;
|
|
18856
19640
|
}
|
|
18857
19641
|
},
|
|
@@ -18864,17 +19648,35 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18864
19648
|
},
|
|
18865
19649
|
|
|
18866
19650
|
/**
|
|
19651
|
+
* Get this TiledImage's bounds in viewport coordinates.
|
|
19652
|
+
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
19653
|
+
* false for target location.
|
|
18867
19654
|
* @returns {OpenSeadragon.Rect} This TiledImage's bounds in viewport coordinates.
|
|
18868
|
-
* @param {Boolean} [current=false] - Pass true for the current location; false for target location.
|
|
18869
19655
|
*/
|
|
18870
19656
|
getBounds: function(current) {
|
|
18871
|
-
|
|
18872
|
-
|
|
18873
|
-
|
|
18874
|
-
}
|
|
19657
|
+
return this.getBoundsNoRotate(current)
|
|
19658
|
+
.rotate(this.getRotation(current), this._getRotationPoint(current));
|
|
19659
|
+
},
|
|
18875
19660
|
|
|
18876
|
-
|
|
18877
|
-
|
|
19661
|
+
/**
|
|
19662
|
+
* Get this TiledImage's bounds in viewport coordinates without taking
|
|
19663
|
+
* rotation into account.
|
|
19664
|
+
* @param {Boolean} [current=false] - Pass true for the current location;
|
|
19665
|
+
* false for target location.
|
|
19666
|
+
* @returns {OpenSeadragon.Rect} This TiledImage's bounds in viewport coordinates.
|
|
19667
|
+
*/
|
|
19668
|
+
getBoundsNoRotate: function(current) {
|
|
19669
|
+
return current ?
|
|
19670
|
+
new $.Rect(
|
|
19671
|
+
this._xSpring.current.value,
|
|
19672
|
+
this._ySpring.current.value,
|
|
19673
|
+
this._worldWidthCurrent,
|
|
19674
|
+
this._worldHeightCurrent) :
|
|
19675
|
+
new $.Rect(
|
|
19676
|
+
this._xSpring.target.value,
|
|
19677
|
+
this._ySpring.target.value,
|
|
19678
|
+
this._worldWidthTarget,
|
|
19679
|
+
this._worldHeightTarget);
|
|
18878
19680
|
},
|
|
18879
19681
|
|
|
18880
19682
|
// deprecated
|
|
@@ -18890,9 +19692,11 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18890
19692
|
* @returns {$.Rect} The clipped bounds in viewport coordinates.
|
|
18891
19693
|
*/
|
|
18892
19694
|
getClippedBounds: function(current) {
|
|
18893
|
-
var bounds = this.
|
|
19695
|
+
var bounds = this.getBoundsNoRotate(current);
|
|
18894
19696
|
if (this._clip) {
|
|
18895
|
-
var
|
|
19697
|
+
var worldWidth = current ?
|
|
19698
|
+
this._worldWidthCurrent : this._worldWidthTarget;
|
|
19699
|
+
var ratio = worldWidth / this.source.dimensions.x;
|
|
18896
19700
|
var clip = this._clip.times(ratio);
|
|
18897
19701
|
bounds = new $.Rect(
|
|
18898
19702
|
bounds.x + clip.x,
|
|
@@ -18900,7 +19704,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18900
19704
|
clip.width,
|
|
18901
19705
|
clip.height);
|
|
18902
19706
|
}
|
|
18903
|
-
return bounds;
|
|
19707
|
+
return bounds.rotate(this.getRotation(current), this._getRotationPoint(current));
|
|
18904
19708
|
},
|
|
18905
19709
|
|
|
18906
19710
|
/**
|
|
@@ -18925,21 +19729,24 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18925
19729
|
* @param {Boolean} [current=false] - Pass true to use the current location; false for target location.
|
|
18926
19730
|
* @return {OpenSeadragon.Point} A point representing the coordinates in the image.
|
|
18927
19731
|
*/
|
|
18928
|
-
viewportToImageCoordinates: function(
|
|
19732
|
+
viewportToImageCoordinates: function(viewerX, viewerY, current) {
|
|
19733
|
+
var point;
|
|
18929
19734
|
if (viewerX instanceof $.Point) {
|
|
18930
19735
|
//they passed a point instead of individual components
|
|
18931
19736
|
current = viewerY;
|
|
18932
|
-
|
|
18933
|
-
|
|
18934
|
-
|
|
18935
|
-
|
|
18936
|
-
if (current) {
|
|
18937
|
-
return this._viewportToImageDelta(viewerX - this._xSpring.current.value,
|
|
18938
|
-
viewerY - this._ySpring.current.value);
|
|
19737
|
+
point = viewerX;
|
|
19738
|
+
} else {
|
|
19739
|
+
point = new $.Point(viewerX, viewerY);
|
|
18939
19740
|
}
|
|
18940
19741
|
|
|
18941
|
-
|
|
18942
|
-
|
|
19742
|
+
point = point.rotate(-this.getRotation(current), this._getRotationPoint(current));
|
|
19743
|
+
return current ?
|
|
19744
|
+
this._viewportToImageDelta(
|
|
19745
|
+
point.x - this._xSpring.current.value,
|
|
19746
|
+
point.y - this._ySpring.current.value) :
|
|
19747
|
+
this._viewportToImageDelta(
|
|
19748
|
+
point.x - this._xSpring.target.value,
|
|
19749
|
+
point.y - this._ySpring.target.value);
|
|
18943
19750
|
},
|
|
18944
19751
|
|
|
18945
19752
|
// private
|
|
@@ -18957,7 +19764,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18957
19764
|
* @param {Boolean} [current=false] - Pass true to use the current location; false for target location.
|
|
18958
19765
|
* @return {OpenSeadragon.Point} A point representing the coordinates in the viewport.
|
|
18959
19766
|
*/
|
|
18960
|
-
imageToViewportCoordinates: function(
|
|
19767
|
+
imageToViewportCoordinates: function(imageX, imageY, current) {
|
|
18961
19768
|
if (imageX instanceof $.Point) {
|
|
18962
19769
|
//they passed a point instead of individual components
|
|
18963
19770
|
current = imageY;
|
|
@@ -18974,7 +19781,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18974
19781
|
point.y += this._ySpring.target.value;
|
|
18975
19782
|
}
|
|
18976
19783
|
|
|
18977
|
-
return point;
|
|
19784
|
+
return point.rotate(this.getRotation(current), this._getRotationPoint(current));
|
|
18978
19785
|
},
|
|
18979
19786
|
|
|
18980
19787
|
/**
|
|
@@ -18988,7 +19795,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
18988
19795
|
* @param {Boolean} [current=false] - Pass true to use the current location; false for target location.
|
|
18989
19796
|
* @return {OpenSeadragon.Rect} A rect representing the coordinates in the viewport.
|
|
18990
19797
|
*/
|
|
18991
|
-
imageToViewportRectangle: function(
|
|
19798
|
+
imageToViewportRectangle: function(imageX, imageY, pixelWidth, pixelHeight, current) {
|
|
18992
19799
|
var rect = imageX;
|
|
18993
19800
|
if (rect instanceof $.Rect) {
|
|
18994
19801
|
//they passed a rect instead of individual components
|
|
@@ -19005,7 +19812,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19005
19812
|
coordA.y,
|
|
19006
19813
|
coordB.x,
|
|
19007
19814
|
coordB.y,
|
|
19008
|
-
rect.degrees
|
|
19815
|
+
rect.degrees + this.getRotation(current)
|
|
19009
19816
|
);
|
|
19010
19817
|
},
|
|
19011
19818
|
|
|
@@ -19037,7 +19844,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19037
19844
|
coordA.y,
|
|
19038
19845
|
coordB.x,
|
|
19039
19846
|
coordB.y,
|
|
19040
|
-
rect.degrees
|
|
19847
|
+
rect.degrees - this.getRotation(current)
|
|
19041
19848
|
);
|
|
19042
19849
|
},
|
|
19043
19850
|
|
|
@@ -19085,6 +19892,20 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19085
19892
|
OpenSeadragon.getElementPosition( this.viewer.element ));
|
|
19086
19893
|
},
|
|
19087
19894
|
|
|
19895
|
+
// private
|
|
19896
|
+
// Convert rectangle in viewport coordinates to this tiled image point
|
|
19897
|
+
// coordinates (x in [0, 1] and y in [0, aspectRatio])
|
|
19898
|
+
_viewportToTiledImageRectangle: function(rect) {
|
|
19899
|
+
var scale = this._scaleSpring.current.value;
|
|
19900
|
+
rect = rect.rotate(-this.getRotation(true), this._getRotationPoint(true));
|
|
19901
|
+
return new $.Rect(
|
|
19902
|
+
(rect.x - this._xSpring.current.value) / scale,
|
|
19903
|
+
(rect.y - this._ySpring.current.value) / scale,
|
|
19904
|
+
rect.width / scale,
|
|
19905
|
+
rect.height / scale,
|
|
19906
|
+
rect.degrees);
|
|
19907
|
+
},
|
|
19908
|
+
|
|
19088
19909
|
/**
|
|
19089
19910
|
* Convert a viewport zoom to an image zoom.
|
|
19090
19911
|
* Image zoom: ratio of the original image size to displayed image size.
|
|
@@ -19098,7 +19919,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19098
19919
|
viewportToImageZoom: function( viewportZoom ) {
|
|
19099
19920
|
var ratio = this._scaleSpring.current.value *
|
|
19100
19921
|
this.viewport._containerInnerSize.x / this.source.dimensions.x;
|
|
19101
|
-
return ratio * viewportZoom
|
|
19922
|
+
return ratio * viewportZoom;
|
|
19102
19923
|
},
|
|
19103
19924
|
|
|
19104
19925
|
/**
|
|
@@ -19249,6 +20070,7 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19249
20070
|
* @param {OpenSeadragon.Rect|null} newClip - An area, in image pixels, to clip to
|
|
19250
20071
|
* (portions of the image outside of this area will not be visible). Only works on
|
|
19251
20072
|
* browsers that support the HTML5 canvas.
|
|
20073
|
+
* @fires OpenSeadragon.TiledImage.event:clip-change
|
|
19252
20074
|
*/
|
|
19253
20075
|
setClip: function(newClip) {
|
|
19254
20076
|
$.console.assert(!newClip || newClip instanceof $.Rect,
|
|
@@ -19261,6 +20083,16 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19261
20083
|
}
|
|
19262
20084
|
|
|
19263
20085
|
this._needsDraw = true;
|
|
20086
|
+
/**
|
|
20087
|
+
* Raised when the TiledImage's clip is changed.
|
|
20088
|
+
* @event clip-change
|
|
20089
|
+
* @memberOf OpenSeadragon.TiledImage
|
|
20090
|
+
* @type {object}
|
|
20091
|
+
* @property {OpenSeadragon.TiledImage} eventSource - A reference to the
|
|
20092
|
+
* TiledImage which raised the event.
|
|
20093
|
+
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
20094
|
+
*/
|
|
20095
|
+
this.raiseEvent('clip-change');
|
|
19264
20096
|
},
|
|
19265
20097
|
|
|
19266
20098
|
/**
|
|
@@ -19272,10 +20104,85 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19272
20104
|
|
|
19273
20105
|
/**
|
|
19274
20106
|
* @param {Number} opacity Opacity the tiled image should be drawn at.
|
|
20107
|
+
* @fires OpenSeadragon.TiledImage.event:opacity-change
|
|
19275
20108
|
*/
|
|
19276
20109
|
setOpacity: function(opacity) {
|
|
20110
|
+
if (opacity === this.opacity) {
|
|
20111
|
+
return;
|
|
20112
|
+
}
|
|
20113
|
+
|
|
19277
20114
|
this.opacity = opacity;
|
|
19278
20115
|
this._needsDraw = true;
|
|
20116
|
+
/**
|
|
20117
|
+
* Raised when the TiledImage's opacity is changed.
|
|
20118
|
+
* @event opacity-change
|
|
20119
|
+
* @memberOf OpenSeadragon.TiledImage
|
|
20120
|
+
* @type {object}
|
|
20121
|
+
* @property {Number} opacity - The new opacity value.
|
|
20122
|
+
* @property {OpenSeadragon.TiledImage} eventSource - A reference to the
|
|
20123
|
+
* TiledImage which raised the event.
|
|
20124
|
+
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
20125
|
+
*/
|
|
20126
|
+
this.raiseEvent('opacity-change', {
|
|
20127
|
+
opacity: this.opacity
|
|
20128
|
+
});
|
|
20129
|
+
},
|
|
20130
|
+
|
|
20131
|
+
/**
|
|
20132
|
+
* @returns {Boolean} whether the tiledImage can load its tiles even when it has zero opacity.
|
|
20133
|
+
*/
|
|
20134
|
+
getPreload: function() {
|
|
20135
|
+
return this._preload;
|
|
20136
|
+
},
|
|
20137
|
+
|
|
20138
|
+
/**
|
|
20139
|
+
* Set true to load even when hidden. Set false to block loading when hidden.
|
|
20140
|
+
*/
|
|
20141
|
+
setPreload: function(preload) {
|
|
20142
|
+
this._preload = !!preload;
|
|
20143
|
+
this._needsDraw = true;
|
|
20144
|
+
},
|
|
20145
|
+
|
|
20146
|
+
/**
|
|
20147
|
+
* Get the rotation of this tiled image in degrees.
|
|
20148
|
+
* @param {Boolean} [current=false] True for current rotation, false for target.
|
|
20149
|
+
* @returns {Number} the rotation of this tiled image in degrees.
|
|
20150
|
+
*/
|
|
20151
|
+
getRotation: function(current) {
|
|
20152
|
+
return current ?
|
|
20153
|
+
this._degreesSpring.current.value :
|
|
20154
|
+
this._degreesSpring.target.value;
|
|
20155
|
+
},
|
|
20156
|
+
|
|
20157
|
+
/**
|
|
20158
|
+
* Set the current rotation of this tiled image in degrees.
|
|
20159
|
+
* @param {Number} degrees the rotation in degrees.
|
|
20160
|
+
* @param {Boolean} [immediately=false] Whether to animate to the new angle
|
|
20161
|
+
* or rotate immediately.
|
|
20162
|
+
* @fires OpenSeadragon.TiledImage.event:bounds-change
|
|
20163
|
+
*/
|
|
20164
|
+
setRotation: function(degrees, immediately) {
|
|
20165
|
+
if (this._degreesSpring.target.value === degrees &&
|
|
20166
|
+
this._degreesSpring.isAtTargetValue()) {
|
|
20167
|
+
return;
|
|
20168
|
+
}
|
|
20169
|
+
if (immediately) {
|
|
20170
|
+
this._degreesSpring.resetTo(degrees);
|
|
20171
|
+
} else {
|
|
20172
|
+
this._degreesSpring.springTo(degrees);
|
|
20173
|
+
}
|
|
20174
|
+
this._needsDraw = true;
|
|
20175
|
+
this._raiseBoundsChange();
|
|
20176
|
+
},
|
|
20177
|
+
|
|
20178
|
+
/**
|
|
20179
|
+
* @private
|
|
20180
|
+
* Get the point around which this tiled image is rotated
|
|
20181
|
+
* @param {Boolean} current True for current rotation point, false for target.
|
|
20182
|
+
* @returns {OpenSeadragon.Point}
|
|
20183
|
+
*/
|
|
20184
|
+
_getRotationPoint: function(current) {
|
|
20185
|
+
return this.getBoundsNoRotate(current).getCenter();
|
|
19279
20186
|
},
|
|
19280
20187
|
|
|
19281
20188
|
/**
|
|
@@ -19287,10 +20194,28 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19287
20194
|
|
|
19288
20195
|
/**
|
|
19289
20196
|
* @param {String} compositeOperation the tiled image should be drawn with this globalCompositeOperation.
|
|
20197
|
+
* @fires OpenSeadragon.TiledImage.event:composite-operation-change
|
|
19290
20198
|
*/
|
|
19291
20199
|
setCompositeOperation: function(compositeOperation) {
|
|
20200
|
+
if (compositeOperation === this.compositeOperation) {
|
|
20201
|
+
return;
|
|
20202
|
+
}
|
|
20203
|
+
|
|
19292
20204
|
this.compositeOperation = compositeOperation;
|
|
19293
20205
|
this._needsDraw = true;
|
|
20206
|
+
/**
|
|
20207
|
+
* Raised when the TiledImage's opacity is changed.
|
|
20208
|
+
* @event composite-operation-change
|
|
20209
|
+
* @memberOf OpenSeadragon.TiledImage
|
|
20210
|
+
* @type {object}
|
|
20211
|
+
* @property {String} compositeOperation - The new compositeOperation value.
|
|
20212
|
+
* @property {OpenSeadragon.TiledImage} eventSource - A reference to the
|
|
20213
|
+
* TiledImage which raised the event.
|
|
20214
|
+
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
20215
|
+
*/
|
|
20216
|
+
this.raiseEvent('composite-operation-change', {
|
|
20217
|
+
compositeOperation: this.compositeOperation
|
|
20218
|
+
});
|
|
19294
20219
|
},
|
|
19295
20220
|
|
|
19296
20221
|
// private
|
|
@@ -19336,7 +20261,8 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19336
20261
|
* @event bounds-change
|
|
19337
20262
|
* @memberOf OpenSeadragon.TiledImage
|
|
19338
20263
|
* @type {object}
|
|
19339
|
-
* @property {OpenSeadragon.
|
|
20264
|
+
* @property {OpenSeadragon.TiledImage} eventSource - A reference to the
|
|
20265
|
+
* TiledImage which raised the event.
|
|
19340
20266
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
19341
20267
|
*/
|
|
19342
20268
|
this.raiseEvent('bounds-change');
|
|
@@ -19345,184 +20271,208 @@ $.extend($.TiledImage.prototype, $.EventSource.prototype, /** @lends OpenSeadrag
|
|
|
19345
20271
|
// private
|
|
19346
20272
|
_isBottomItem: function() {
|
|
19347
20273
|
return this.viewer.world.getItemAt(0) === this;
|
|
19348
|
-
}
|
|
19349
|
-
});
|
|
19350
|
-
|
|
19351
|
-
/**
|
|
19352
|
-
* @private
|
|
19353
|
-
* @inner
|
|
19354
|
-
* Pretty much every other line in this needs to be documented so it's clear
|
|
19355
|
-
* how each piece of this routine contributes to the drawing process. That's
|
|
19356
|
-
* why there are so many TODO's inside this function.
|
|
19357
|
-
*/
|
|
19358
|
-
function updateViewport( tiledImage ) {
|
|
19359
|
-
|
|
19360
|
-
tiledImage._needsDraw = false;
|
|
20274
|
+
},
|
|
19361
20275
|
|
|
19362
|
-
|
|
19363
|
-
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
|
|
19367
|
-
|
|
19368
|
-
|
|
19369
|
-
|
|
19370
|
-
|
|
19371
|
-
|
|
19372
|
-
|
|
19373
|
-
tiledImage.source.minLevel,
|
|
19374
|
-
Math.floor(
|
|
19375
|
-
Math.log( tiledImage.minZoomImageRatio ) /
|
|
19376
|
-
Math.log( 2 )
|
|
19377
|
-
)
|
|
19378
|
-
),
|
|
19379
|
-
highestLevel = Math.min(
|
|
19380
|
-
Math.abs(tiledImage.source.maxLevel),
|
|
20276
|
+
// private
|
|
20277
|
+
_getLevelsInterval: function() {
|
|
20278
|
+
var lowestLevel = Math.max(
|
|
20279
|
+
this.source.minLevel,
|
|
20280
|
+
Math.floor(Math.log(this.minZoomImageRatio) / Math.log(2))
|
|
20281
|
+
);
|
|
20282
|
+
var currentZeroRatio = this.viewport.deltaPixelsFromPointsNoRotate(
|
|
20283
|
+
this.source.getPixelRatio(0), true).x *
|
|
20284
|
+
this._scaleSpring.current.value;
|
|
20285
|
+
var highestLevel = Math.min(
|
|
20286
|
+
Math.abs(this.source.maxLevel),
|
|
19381
20287
|
Math.abs(Math.floor(
|
|
19382
|
-
Math.log(
|
|
19383
|
-
Math.log( 2 )
|
|
20288
|
+
Math.log(currentZeroRatio / this.minPixelRatio) / Math.log(2)
|
|
19384
20289
|
))
|
|
19385
|
-
)
|
|
19386
|
-
renderPixelRatioC,
|
|
19387
|
-
renderPixelRatioT,
|
|
19388
|
-
zeroRatioT,
|
|
19389
|
-
optimalRatio,
|
|
19390
|
-
levelOpacity,
|
|
19391
|
-
levelVisibility;
|
|
19392
|
-
|
|
19393
|
-
// Reset tile's internal drawn state
|
|
19394
|
-
while (tiledImage.lastDrawn.length > 0) {
|
|
19395
|
-
tile = tiledImage.lastDrawn.pop();
|
|
19396
|
-
tile.beingDrawn = false;
|
|
19397
|
-
}
|
|
19398
|
-
|
|
19399
|
-
if (!tiledImage.wrapHorizontal && !tiledImage.wrapVertical) {
|
|
19400
|
-
var tiledImageBounds = tiledImage.getClippedBounds(true);
|
|
19401
|
-
var intersection = viewportBounds.intersection(tiledImageBounds);
|
|
19402
|
-
if (intersection === null) {
|
|
19403
|
-
return;
|
|
19404
|
-
}
|
|
19405
|
-
viewportBounds = intersection;
|
|
19406
|
-
}
|
|
19407
|
-
viewportBounds = viewportBounds.getBoundingBox();
|
|
19408
|
-
viewportBounds.x -= tiledImage._xSpring.current.value;
|
|
19409
|
-
viewportBounds.y -= tiledImage._ySpring.current.value;
|
|
19410
|
-
|
|
19411
|
-
var viewportTL = viewportBounds.getTopLeft();
|
|
19412
|
-
var viewportBR = viewportBounds.getBottomRight();
|
|
19413
|
-
|
|
19414
|
-
//Don't draw if completely outside of the viewport
|
|
19415
|
-
if ( !tiledImage.wrapHorizontal && (viewportBR.x < 0 || viewportTL.x > tiledImage._worldWidthCurrent ) ) {
|
|
19416
|
-
return;
|
|
19417
|
-
}
|
|
19418
|
-
|
|
19419
|
-
if ( !tiledImage.wrapVertical && ( viewportBR.y < 0 || viewportTL.y > tiledImage._worldHeightCurrent ) ) {
|
|
19420
|
-
return;
|
|
19421
|
-
}
|
|
19422
|
-
|
|
19423
|
-
// Calculate viewport rect / bounds
|
|
19424
|
-
if ( !tiledImage.wrapHorizontal ) {
|
|
19425
|
-
viewportTL.x = Math.max( viewportTL.x, 0 );
|
|
19426
|
-
viewportBR.x = Math.min( viewportBR.x, tiledImage._worldWidthCurrent );
|
|
19427
|
-
}
|
|
20290
|
+
);
|
|
19428
20291
|
|
|
19429
|
-
|
|
19430
|
-
|
|
19431
|
-
|
|
19432
|
-
|
|
20292
|
+
// Calculations for the interval of levels to draw
|
|
20293
|
+
// can return invalid intervals; fix that here if necessary
|
|
20294
|
+
lowestLevel = Math.min(lowestLevel, highestLevel);
|
|
20295
|
+
return {
|
|
20296
|
+
lowestLevel: lowestLevel,
|
|
20297
|
+
highestLevel: highestLevel
|
|
20298
|
+
};
|
|
20299
|
+
},
|
|
19433
20300
|
|
|
19434
|
-
|
|
19435
|
-
|
|
19436
|
-
|
|
19437
|
-
|
|
20301
|
+
/**
|
|
20302
|
+
* @private
|
|
20303
|
+
* @inner
|
|
20304
|
+
* Pretty much every other line in this needs to be documented so it's clear
|
|
20305
|
+
* how each piece of this routine contributes to the drawing process. That's
|
|
20306
|
+
* why there are so many TODO's inside this function.
|
|
20307
|
+
*/
|
|
20308
|
+
_updateViewport: function() {
|
|
20309
|
+
this._needsDraw = false;
|
|
20310
|
+
this._tilesLoading = 0;
|
|
20311
|
+
this.loadingCoverage = {};
|
|
19438
20312
|
|
|
19439
|
-
|
|
19440
|
-
|
|
19441
|
-
|
|
19442
|
-
|
|
20313
|
+
// Reset tile's internal drawn state
|
|
20314
|
+
while (this.lastDrawn.length > 0) {
|
|
20315
|
+
var tile = this.lastDrawn.pop();
|
|
20316
|
+
tile.beingDrawn = false;
|
|
20317
|
+
}
|
|
19443
20318
|
|
|
19444
|
-
|
|
19445
|
-
|
|
19446
|
-
|
|
19447
|
-
true
|
|
19448
|
-
).x * tiledImage._scaleSpring.current.value;
|
|
20319
|
+
var viewport = this.viewport;
|
|
20320
|
+
var drawArea = this._viewportToTiledImageRectangle(
|
|
20321
|
+
viewport.getBoundsWithMargins(true));
|
|
19449
20322
|
|
|
19450
|
-
if (
|
|
19451
|
-
|
|
19452
|
-
|
|
19453
|
-
|
|
19454
|
-
|
|
19455
|
-
|
|
20323
|
+
if (!this.wrapHorizontal && !this.wrapVertical) {
|
|
20324
|
+
var tiledImageBounds = this._viewportToTiledImageRectangle(
|
|
20325
|
+
this.getClippedBounds(true));
|
|
20326
|
+
drawArea = drawArea.intersection(tiledImageBounds);
|
|
20327
|
+
if (drawArea === null) {
|
|
20328
|
+
return;
|
|
20329
|
+
}
|
|
19456
20330
|
}
|
|
19457
20331
|
|
|
19458
|
-
|
|
19459
|
-
|
|
19460
|
-
|
|
19461
|
-
|
|
19462
|
-
|
|
20332
|
+
var levelsInterval = this._getLevelsInterval();
|
|
20333
|
+
var lowestLevel = levelsInterval.lowestLevel;
|
|
20334
|
+
var highestLevel = levelsInterval.highestLevel;
|
|
20335
|
+
var bestTile = null;
|
|
20336
|
+
var haveDrawn = false;
|
|
20337
|
+
var currentTime = $.now();
|
|
19463
20338
|
|
|
19464
|
-
|
|
19465
|
-
|
|
19466
|
-
|
|
19467
|
-
tiledImage.source.getClosestLevel( tiledImage.viewport.containerSize ) - 1,
|
|
19468
|
-
0
|
|
19469
|
-
)
|
|
19470
|
-
),
|
|
19471
|
-
false
|
|
19472
|
-
).x * tiledImage._scaleSpring.current.value;
|
|
20339
|
+
// Update any level that will be drawn
|
|
20340
|
+
for (var level = highestLevel; level >= lowestLevel; level--) {
|
|
20341
|
+
var drawLevel = false;
|
|
19473
20342
|
|
|
19474
|
-
|
|
19475
|
-
|
|
19476
|
-
|
|
20343
|
+
//Avoid calculations for draw if we have already drawn this
|
|
20344
|
+
var currentRenderPixelRatio = viewport.deltaPixelsFromPointsNoRotate(
|
|
20345
|
+
this.source.getPixelRatio(level),
|
|
20346
|
+
true
|
|
20347
|
+
).x * this._scaleSpring.current.value;
|
|
19477
20348
|
|
|
19478
|
-
|
|
20349
|
+
if (level === lowestLevel ||
|
|
20350
|
+
(!haveDrawn && currentRenderPixelRatio >= this.minPixelRatio)) {
|
|
20351
|
+
drawLevel = true;
|
|
20352
|
+
haveDrawn = true;
|
|
20353
|
+
} else if (!haveDrawn) {
|
|
20354
|
+
continue;
|
|
20355
|
+
}
|
|
19479
20356
|
|
|
19480
|
-
|
|
19481
|
-
|
|
19482
|
-
|
|
20357
|
+
//Perform calculations for draw if we haven't drawn this
|
|
20358
|
+
var targetRenderPixelRatio = viewport.deltaPixelsFromPointsNoRotate(
|
|
20359
|
+
this.source.getPixelRatio(level),
|
|
20360
|
+
false
|
|
20361
|
+
).x * this._scaleSpring.current.value;
|
|
20362
|
+
|
|
20363
|
+
var targetZeroRatio = viewport.deltaPixelsFromPointsNoRotate(
|
|
20364
|
+
this.source.getPixelRatio(
|
|
20365
|
+
Math.max(
|
|
20366
|
+
this.source.getClosestLevel(),
|
|
20367
|
+
0
|
|
20368
|
+
)
|
|
20369
|
+
),
|
|
20370
|
+
false
|
|
20371
|
+
).x * this._scaleSpring.current.value;
|
|
20372
|
+
|
|
20373
|
+
var optimalRatio = this.immediateRender ? 1 : targetZeroRatio;
|
|
20374
|
+
var levelOpacity = Math.min(1, (currentRenderPixelRatio - 0.5) / 0.5);
|
|
20375
|
+
var levelVisibility = optimalRatio / Math.abs(
|
|
20376
|
+
optimalRatio - targetRenderPixelRatio
|
|
20377
|
+
);
|
|
19483
20378
|
|
|
19484
|
-
|
|
19485
|
-
|
|
19486
|
-
|
|
19487
|
-
|
|
19488
|
-
|
|
19489
|
-
|
|
19490
|
-
|
|
19491
|
-
|
|
19492
|
-
|
|
19493
|
-
|
|
19494
|
-
|
|
19495
|
-
|
|
19496
|
-
);
|
|
20379
|
+
// Update the level and keep track of 'best' tile to load
|
|
20380
|
+
bestTile = updateLevel(
|
|
20381
|
+
this,
|
|
20382
|
+
haveDrawn,
|
|
20383
|
+
drawLevel,
|
|
20384
|
+
level,
|
|
20385
|
+
levelOpacity,
|
|
20386
|
+
levelVisibility,
|
|
20387
|
+
drawArea,
|
|
20388
|
+
currentTime,
|
|
20389
|
+
bestTile
|
|
20390
|
+
);
|
|
19497
20391
|
|
|
19498
|
-
|
|
19499
|
-
|
|
19500
|
-
|
|
19501
|
-
|
|
20392
|
+
// Stop the loop if lower-res tiles would all be covered by
|
|
20393
|
+
// already drawn tiles
|
|
20394
|
+
if (providesCoverage(this.coverage, level)) {
|
|
20395
|
+
break;
|
|
20396
|
+
}
|
|
19502
20397
|
}
|
|
19503
|
-
}
|
|
19504
20398
|
|
|
19505
|
-
|
|
19506
|
-
|
|
20399
|
+
// Perform the actual drawing
|
|
20400
|
+
drawTiles(this, this.lastDrawn);
|
|
19507
20401
|
|
|
19508
|
-
|
|
19509
|
-
|
|
19510
|
-
|
|
19511
|
-
|
|
20402
|
+
// Load the new 'best' tile
|
|
20403
|
+
if (bestTile && !bestTile.context2D) {
|
|
20404
|
+
loadTile(this, bestTile, currentTime);
|
|
20405
|
+
this._needsDraw = true;
|
|
20406
|
+
this._setFullyLoaded(false);
|
|
20407
|
+
} else {
|
|
20408
|
+
this._setFullyLoaded(this._tilesLoading === 0);
|
|
20409
|
+
}
|
|
20410
|
+
},
|
|
19512
20411
|
|
|
19513
|
-
|
|
20412
|
+
// private
|
|
20413
|
+
_getCornerTiles: function(level, topLeftBound, bottomRightBound) {
|
|
20414
|
+
var leftX;
|
|
20415
|
+
var rightX;
|
|
20416
|
+
if (this.wrapHorizontal) {
|
|
20417
|
+
leftX = $.positiveModulo(topLeftBound.x, 1);
|
|
20418
|
+
rightX = $.positiveModulo(bottomRightBound.x, 1);
|
|
20419
|
+
} else {
|
|
20420
|
+
leftX = Math.max(0, topLeftBound.x);
|
|
20421
|
+
rightX = Math.min(1, bottomRightBound.x);
|
|
20422
|
+
}
|
|
20423
|
+
var topY;
|
|
20424
|
+
var bottomY;
|
|
20425
|
+
var aspectRatio = 1 / this.source.aspectRatio;
|
|
20426
|
+
if (this.wrapVertical) {
|
|
20427
|
+
topY = $.positiveModulo(topLeftBound.y, aspectRatio);
|
|
20428
|
+
bottomY = $.positiveModulo(bottomRightBound.y, aspectRatio);
|
|
20429
|
+
} else {
|
|
20430
|
+
topY = Math.max(0, topLeftBound.y);
|
|
20431
|
+
bottomY = Math.min(aspectRatio, bottomRightBound.y);
|
|
20432
|
+
}
|
|
19514
20433
|
|
|
20434
|
+
var topLeftTile = this.source.getTileAtPoint(level, new $.Point(leftX, topY));
|
|
20435
|
+
var bottomRightTile = this.source.getTileAtPoint(level, new $.Point(rightX, bottomY));
|
|
20436
|
+
var numTiles = this.source.getNumTiles(level);
|
|
19515
20437
|
|
|
19516
|
-
|
|
20438
|
+
if (this.wrapHorizontal) {
|
|
20439
|
+
topLeftTile.x += numTiles.x * Math.floor(topLeftBound.x);
|
|
20440
|
+
bottomRightTile.x += numTiles.x * Math.floor(bottomRightBound.x);
|
|
20441
|
+
}
|
|
20442
|
+
if (this.wrapVertical) {
|
|
20443
|
+
topLeftTile.y += numTiles.y * Math.floor(topLeftBound.y / aspectRatio);
|
|
20444
|
+
bottomRightTile.y += numTiles.y * Math.floor(bottomRightBound.y / aspectRatio);
|
|
20445
|
+
}
|
|
19517
20446
|
|
|
19518
|
-
|
|
19519
|
-
|
|
19520
|
-
|
|
19521
|
-
|
|
19522
|
-
|
|
20447
|
+
return {
|
|
20448
|
+
topLeft: topLeftTile,
|
|
20449
|
+
bottomRight: bottomRightTile,
|
|
20450
|
+
};
|
|
20451
|
+
}
|
|
20452
|
+
});
|
|
19523
20453
|
|
|
20454
|
+
/**
|
|
20455
|
+
* @private
|
|
20456
|
+
* @inner
|
|
20457
|
+
* Updates all tiles at a given resolution level.
|
|
20458
|
+
* @param {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.
|
|
20459
|
+
* @param {Boolean} haveDrawn
|
|
20460
|
+
* @param {Boolean} drawLevel
|
|
20461
|
+
* @param {Number} level
|
|
20462
|
+
* @param {Number} levelOpacity
|
|
20463
|
+
* @param {Number} levelVisibility
|
|
20464
|
+
* @param {OpenSeadragon.Point} viewportTL - The index of the most top-left visible tile.
|
|
20465
|
+
* @param {OpenSeadragon.Point} viewportBR - The index of the most bottom-right visible tile.
|
|
20466
|
+
* @param {Number} currentTime
|
|
20467
|
+
* @param {OpenSeadragon.Tile} best - The current "best" tile to draw.
|
|
20468
|
+
*/
|
|
20469
|
+
function updateLevel(tiledImage, haveDrawn, drawLevel, level, levelOpacity,
|
|
20470
|
+
levelVisibility, drawArea, currentTime, best) {
|
|
19524
20471
|
|
|
19525
|
-
|
|
20472
|
+
var topLeftBound = drawArea.getBoundingBox().getTopLeft();
|
|
20473
|
+
var bottomRightBound = drawArea.getBoundingBox().getBottomRight();
|
|
20474
|
+
|
|
20475
|
+
if (tiledImage.viewer) {
|
|
19526
20476
|
/**
|
|
19527
20477
|
* <em>- Needs documentation -</em>
|
|
19528
20478
|
*
|
|
@@ -19535,41 +20485,50 @@ function updateLevel( tiledImage, haveDrawn, drawLevel, level, levelOpacity, lev
|
|
|
19535
20485
|
* @property {Object} level
|
|
19536
20486
|
* @property {Object} opacity
|
|
19537
20487
|
* @property {Object} visibility
|
|
19538
|
-
* @property {
|
|
19539
|
-
* @property {Object}
|
|
20488
|
+
* @property {OpenSeadragon.Rect} drawArea
|
|
20489
|
+
* @property {Object} topleft deprecated, use drawArea instead
|
|
20490
|
+
* @property {Object} bottomright deprecated, use drawArea instead
|
|
19540
20491
|
* @property {Object} currenttime
|
|
19541
20492
|
* @property {Object} best
|
|
19542
20493
|
* @property {?Object} userData - Arbitrary subscriber-defined object.
|
|
19543
20494
|
*/
|
|
19544
|
-
tiledImage.viewer.raiseEvent(
|
|
20495
|
+
tiledImage.viewer.raiseEvent('update-level', {
|
|
19545
20496
|
tiledImage: tiledImage,
|
|
19546
20497
|
havedrawn: haveDrawn,
|
|
19547
20498
|
level: level,
|
|
19548
20499
|
opacity: levelOpacity,
|
|
19549
20500
|
visibility: levelVisibility,
|
|
19550
|
-
|
|
19551
|
-
|
|
20501
|
+
drawArea: drawArea,
|
|
20502
|
+
topleft: topLeftBound,
|
|
20503
|
+
bottomright: bottomRightBound,
|
|
19552
20504
|
currenttime: currentTime,
|
|
19553
20505
|
best: best
|
|
19554
20506
|
});
|
|
19555
20507
|
}
|
|
19556
20508
|
|
|
19557
|
-
|
|
19558
|
-
|
|
19559
|
-
tileBR = tiledImage.source.getTileAtPoint( level, viewportBR.divide( tiledImage._scaleSpring.current.value ));
|
|
19560
|
-
numberOfTiles = tiledImage.source.getNumTiles( level );
|
|
19561
|
-
|
|
19562
|
-
resetCoverage( tiledImage.coverage, level );
|
|
19563
|
-
|
|
19564
|
-
if ( !tiledImage.wrapHorizontal ) {
|
|
19565
|
-
tileBR.x = Math.min( tileBR.x, numberOfTiles.x - 1 );
|
|
19566
|
-
}
|
|
19567
|
-
if ( !tiledImage.wrapVertical ) {
|
|
19568
|
-
tileBR.y = Math.min( tileBR.y, numberOfTiles.y - 1 );
|
|
19569
|
-
}
|
|
20509
|
+
resetCoverage(tiledImage.coverage, level);
|
|
20510
|
+
resetCoverage(tiledImage.loadingCoverage, level);
|
|
19570
20511
|
|
|
19571
|
-
|
|
19572
|
-
|
|
20512
|
+
//OK, a new drawing so do your calculations
|
|
20513
|
+
var cornerTiles = tiledImage._getCornerTiles(level, topLeftBound, bottomRightBound);
|
|
20514
|
+
var topLeftTile = cornerTiles.topLeft;
|
|
20515
|
+
var bottomRightTile = cornerTiles.bottomRight;
|
|
20516
|
+
var numberOfTiles = tiledImage.source.getNumTiles(level);
|
|
20517
|
+
|
|
20518
|
+
var viewportCenter = tiledImage.viewport.pixelFromPoint(
|
|
20519
|
+
tiledImage.viewport.getCenter());
|
|
20520
|
+
for (var x = topLeftTile.x; x <= bottomRightTile.x; x++) {
|
|
20521
|
+
for (var y = topLeftTile.y; y <= bottomRightTile.y; y++) {
|
|
20522
|
+
|
|
20523
|
+
// Optimisation disabled with wrapping because getTileBounds does not
|
|
20524
|
+
// work correctly with x and y outside of the number of tiles
|
|
20525
|
+
if (!tiledImage.wrapHorizontal && !tiledImage.wrapVertical) {
|
|
20526
|
+
var tileBounds = tiledImage.source.getTileBounds(level, x, y);
|
|
20527
|
+
if (drawArea.intersection(tileBounds) === null) {
|
|
20528
|
+
// This tile is outside of the viewport, no need to draw it
|
|
20529
|
+
continue;
|
|
20530
|
+
}
|
|
20531
|
+
}
|
|
19573
20532
|
|
|
19574
20533
|
best = updateTile(
|
|
19575
20534
|
tiledImage,
|
|
@@ -19591,11 +20550,29 @@ function updateLevel( tiledImage, haveDrawn, drawLevel, level, levelOpacity, lev
|
|
|
19591
20550
|
return best;
|
|
19592
20551
|
}
|
|
19593
20552
|
|
|
19594
|
-
|
|
20553
|
+
/**
|
|
20554
|
+
* @private
|
|
20555
|
+
* @inner
|
|
20556
|
+
* Update a single tile at a particular resolution level.
|
|
20557
|
+
* @param {OpenSeadragon.TiledImage} tiledImage - Which TiledImage is being drawn.
|
|
20558
|
+
* @param {Boolean} haveDrawn
|
|
20559
|
+
* @param {Boolean} drawLevel
|
|
20560
|
+
* @param {Number} x
|
|
20561
|
+
* @param {Number} y
|
|
20562
|
+
* @param {Number} level
|
|
20563
|
+
* @param {Number} levelOpacity
|
|
20564
|
+
* @param {Number} levelVisibility
|
|
20565
|
+
* @param {OpenSeadragon.Point} viewportCenter
|
|
20566
|
+
* @param {Number} numberOfTiles
|
|
20567
|
+
* @param {Number} currentTime
|
|
20568
|
+
* @param {OpenSeadragon.Tile} best - The current "best" tile to draw.
|
|
20569
|
+
*/
|
|
20570
|
+
function updateTile( tiledImage, haveDrawn, drawLevel, x, y, level, levelOpacity, levelVisibility, viewportCenter, numberOfTiles, currentTime, best){
|
|
19595
20571
|
|
|
19596
20572
|
var tile = getTile(
|
|
19597
20573
|
x, y,
|
|
19598
20574
|
level,
|
|
20575
|
+
tiledImage,
|
|
19599
20576
|
tiledImage.source,
|
|
19600
20577
|
tiledImage.tilesMatrix,
|
|
19601
20578
|
currentTime,
|
|
@@ -19625,6 +20602,9 @@ function updateTile( tiledImage, drawLevel, haveDrawn, x, y, level, levelOpacity
|
|
|
19625
20602
|
|
|
19626
20603
|
setCoverage( tiledImage.coverage, level, x, y, false );
|
|
19627
20604
|
|
|
20605
|
+
var loadingCoverage = tile.loaded || tile.loading || isCovered(tiledImage.loadingCoverage, level, x, y);
|
|
20606
|
+
setCoverage(tiledImage.loadingCoverage, level, x, y, loadingCoverage);
|
|
20607
|
+
|
|
19628
20608
|
if ( !tile.exists ) {
|
|
19629
20609
|
return best;
|
|
19630
20610
|
}
|
|
@@ -19654,7 +20634,7 @@ function updateTile( tiledImage, drawLevel, haveDrawn, x, y, level, levelOpacity
|
|
|
19654
20634
|
if (tile.context2D) {
|
|
19655
20635
|
setTileLoaded(tiledImage, tile);
|
|
19656
20636
|
} else {
|
|
19657
|
-
var imageRecord = tiledImage._tileCache.getImageRecord(tile.
|
|
20637
|
+
var imageRecord = tiledImage._tileCache.getImageRecord(tile.cacheKey);
|
|
19658
20638
|
if (imageRecord) {
|
|
19659
20639
|
var image = imageRecord.getImage();
|
|
19660
20640
|
setTileLoaded(tiledImage, tile, image);
|
|
@@ -19677,20 +20657,47 @@ function updateTile( tiledImage, drawLevel, haveDrawn, x, y, level, levelOpacity
|
|
|
19677
20657
|
}
|
|
19678
20658
|
} else if ( tile.loading ) {
|
|
19679
20659
|
// the tile is already in the download queue
|
|
19680
|
-
|
|
19681
|
-
} else {
|
|
20660
|
+
tiledImage._tilesLoading++;
|
|
20661
|
+
} else if (!loadingCoverage) {
|
|
19682
20662
|
best = compareTiles( best, tile );
|
|
19683
20663
|
}
|
|
19684
20664
|
|
|
19685
20665
|
return best;
|
|
19686
20666
|
}
|
|
19687
20667
|
|
|
19688
|
-
|
|
20668
|
+
/**
|
|
20669
|
+
* @private
|
|
20670
|
+
* @inner
|
|
20671
|
+
* Obtains a tile at the given location.
|
|
20672
|
+
* @param {Number} x
|
|
20673
|
+
* @param {Number} y
|
|
20674
|
+
* @param {Number} level
|
|
20675
|
+
* @param {OpenSeadragon.TiledImage} tiledImage
|
|
20676
|
+
* @param {OpenSeadragon.TileSource} tileSource
|
|
20677
|
+
* @param {Object} tilesMatrix - A '3d' dictionary [level][x][y] --> Tile.
|
|
20678
|
+
* @param {Number} time
|
|
20679
|
+
* @param {Number} numTiles
|
|
20680
|
+
* @param {Number} worldWidth
|
|
20681
|
+
* @param {Number} worldHeight
|
|
20682
|
+
* @returns {OpenSeadragon.Tile}
|
|
20683
|
+
*/
|
|
20684
|
+
function getTile(
|
|
20685
|
+
x, y,
|
|
20686
|
+
level,
|
|
20687
|
+
tiledImage,
|
|
20688
|
+
tileSource,
|
|
20689
|
+
tilesMatrix,
|
|
20690
|
+
time,
|
|
20691
|
+
numTiles,
|
|
20692
|
+
worldWidth,
|
|
20693
|
+
worldHeight
|
|
20694
|
+
) {
|
|
19689
20695
|
var xMod,
|
|
19690
20696
|
yMod,
|
|
19691
20697
|
bounds,
|
|
19692
20698
|
exists,
|
|
19693
20699
|
url,
|
|
20700
|
+
ajaxHeaders,
|
|
19694
20701
|
context2D,
|
|
19695
20702
|
tile;
|
|
19696
20703
|
|
|
@@ -19707,6 +20714,18 @@ function getTile( x, y, level, tileSource, tilesMatrix, time, numTiles, worldWid
|
|
|
19707
20714
|
bounds = tileSource.getTileBounds( level, xMod, yMod );
|
|
19708
20715
|
exists = tileSource.tileExists( level, xMod, yMod );
|
|
19709
20716
|
url = tileSource.getTileUrl( level, xMod, yMod );
|
|
20717
|
+
|
|
20718
|
+
// Headers are only applicable if loadTilesWithAjax is set
|
|
20719
|
+
if (tiledImage.loadTilesWithAjax) {
|
|
20720
|
+
ajaxHeaders = tileSource.getTileAjaxHeaders( level, xMod, yMod );
|
|
20721
|
+
// Combine tile AJAX headers with tiled image AJAX headers (if applicable)
|
|
20722
|
+
if ($.isPlainObject(tiledImage.ajaxHeaders)) {
|
|
20723
|
+
ajaxHeaders = $.extend({}, tiledImage.ajaxHeaders, ajaxHeaders);
|
|
20724
|
+
}
|
|
20725
|
+
} else {
|
|
20726
|
+
ajaxHeaders = null;
|
|
20727
|
+
}
|
|
20728
|
+
|
|
19710
20729
|
context2D = tileSource.getContext2D ?
|
|
19711
20730
|
tileSource.getContext2D(level, xMod, yMod) : undefined;
|
|
19712
20731
|
|
|
@@ -19720,7 +20739,9 @@ function getTile( x, y, level, tileSource, tilesMatrix, time, numTiles, worldWid
|
|
|
19720
20739
|
bounds,
|
|
19721
20740
|
exists,
|
|
19722
20741
|
url,
|
|
19723
|
-
context2D
|
|
20742
|
+
context2D,
|
|
20743
|
+
tiledImage.loadTilesWithAjax,
|
|
20744
|
+
ajaxHeaders
|
|
19724
20745
|
);
|
|
19725
20746
|
}
|
|
19726
20747
|
|
|
@@ -19730,13 +20751,24 @@ function getTile( x, y, level, tileSource, tilesMatrix, time, numTiles, worldWid
|
|
|
19730
20751
|
return tile;
|
|
19731
20752
|
}
|
|
19732
20753
|
|
|
20754
|
+
/**
|
|
20755
|
+
* @private
|
|
20756
|
+
* @inner
|
|
20757
|
+
* Dispatch a job to the ImageLoader to load the Image for a Tile.
|
|
20758
|
+
* @param {OpenSeadragon.TiledImage} tiledImage
|
|
20759
|
+
* @param {OpenSeadragon.Tile} tile
|
|
20760
|
+
* @param {Number} time
|
|
20761
|
+
*/
|
|
19733
20762
|
function loadTile( tiledImage, tile, time ) {
|
|
19734
20763
|
tile.loading = true;
|
|
19735
20764
|
tiledImage._imageLoader.addJob({
|
|
19736
20765
|
src: tile.url,
|
|
20766
|
+
loadWithAjax: tile.loadWithAjax,
|
|
20767
|
+
ajaxHeaders: tile.ajaxHeaders,
|
|
19737
20768
|
crossOriginPolicy: tiledImage.crossOriginPolicy,
|
|
19738
|
-
|
|
19739
|
-
|
|
20769
|
+
ajaxWithCredentials: tiledImage.ajaxWithCredentials,
|
|
20770
|
+
callback: function( image, errorMsg, tileRequest ){
|
|
20771
|
+
onTileLoad( tiledImage, tile, time, image, errorMsg, tileRequest );
|
|
19740
20772
|
},
|
|
19741
20773
|
abort: function() {
|
|
19742
20774
|
tile.loading = false;
|
|
@@ -19744,7 +20776,18 @@ function loadTile( tiledImage, tile, time ) {
|
|
|
19744
20776
|
});
|
|
19745
20777
|
}
|
|
19746
20778
|
|
|
19747
|
-
|
|
20779
|
+
/**
|
|
20780
|
+
* @private
|
|
20781
|
+
* @inner
|
|
20782
|
+
* Callback fired when a Tile's Image finished downloading.
|
|
20783
|
+
* @param {OpenSeadragon.TiledImage} tiledImage
|
|
20784
|
+
* @param {OpenSeadragon.Tile} tile
|
|
20785
|
+
* @param {Number} time
|
|
20786
|
+
* @param {Image} image
|
|
20787
|
+
* @param {String} errorMsg
|
|
20788
|
+
* @param {XMLHttpRequest} tileRequest
|
|
20789
|
+
*/
|
|
20790
|
+
function onTileLoad( tiledImage, tile, time, image, errorMsg, tileRequest ) {
|
|
19748
20791
|
if ( !image ) {
|
|
19749
20792
|
$.console.log( "Tile %s failed to load: %s - error: %s", tile, tile.url, errorMsg );
|
|
19750
20793
|
/**
|
|
@@ -19757,8 +20800,15 @@ function onTileLoad( tiledImage, tile, time, image, errorMsg ) {
|
|
|
19757
20800
|
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image the tile belongs to.
|
|
19758
20801
|
* @property {number} time - The time in milliseconds when the tile load began.
|
|
19759
20802
|
* @property {string} message - The error message.
|
|
20803
|
+
* @property {XMLHttpRequest} tileRequest - The XMLHttpRequest used to load the tile if available.
|
|
19760
20804
|
*/
|
|
19761
|
-
tiledImage.viewer.raiseEvent("tile-load-failed", {
|
|
20805
|
+
tiledImage.viewer.raiseEvent("tile-load-failed", {
|
|
20806
|
+
tile: tile,
|
|
20807
|
+
tiledImage: tiledImage,
|
|
20808
|
+
time: time,
|
|
20809
|
+
message: errorMsg,
|
|
20810
|
+
tileRequest: tileRequest
|
|
20811
|
+
});
|
|
19762
20812
|
tile.loading = false;
|
|
19763
20813
|
tile.exists = false;
|
|
19764
20814
|
return;
|
|
@@ -19771,9 +20821,8 @@ function onTileLoad( tiledImage, tile, time, image, errorMsg ) {
|
|
|
19771
20821
|
}
|
|
19772
20822
|
|
|
19773
20823
|
var finish = function() {
|
|
19774
|
-
var cutoff =
|
|
19775
|
-
|
|
19776
|
-
setTileLoaded(tiledImage, tile, image, cutoff);
|
|
20824
|
+
var cutoff = tiledImage.source.getClosestLevel();
|
|
20825
|
+
setTileLoaded(tiledImage, tile, image, cutoff, tileRequest);
|
|
19777
20826
|
};
|
|
19778
20827
|
|
|
19779
20828
|
// Check if we're mid-update; this can happen on IE8 because image load events for
|
|
@@ -19786,7 +20835,15 @@ function onTileLoad( tiledImage, tile, time, image, errorMsg ) {
|
|
|
19786
20835
|
}
|
|
19787
20836
|
}
|
|
19788
20837
|
|
|
19789
|
-
|
|
20838
|
+
/**
|
|
20839
|
+
* @private
|
|
20840
|
+
* @inner
|
|
20841
|
+
* @param {OpenSeadragon.TiledImage} tiledImage
|
|
20842
|
+
* @param {OpenSeadragon.Tile} tile
|
|
20843
|
+
* @param {Image} image
|
|
20844
|
+
* @param {Number} cutoff
|
|
20845
|
+
*/
|
|
20846
|
+
function setTileLoaded(tiledImage, tile, image, cutoff, tileRequest) {
|
|
19790
20847
|
var increment = 0;
|
|
19791
20848
|
|
|
19792
20849
|
function getCompletionCallback() {
|
|
@@ -19821,6 +20878,7 @@ function setTileLoaded(tiledImage, tile, image, cutoff) {
|
|
|
19821
20878
|
* @property {Image} image - The image of the tile.
|
|
19822
20879
|
* @property {OpenSeadragon.TiledImage} tiledImage - The tiled image of the loaded tile.
|
|
19823
20880
|
* @property {OpenSeadragon.Tile} tile - The tile which has been loaded.
|
|
20881
|
+
* @property {XMLHttpRequest} tiledImage - The AJAX request that loaded this tile (if applicable).
|
|
19824
20882
|
* @property {function} getCompletionCallback - A function giving a callback to call
|
|
19825
20883
|
* when the asynchronous processing of the image is done. The image will be
|
|
19826
20884
|
* marked as entirely loaded when the callback has been called once for each
|
|
@@ -19829,6 +20887,7 @@ function setTileLoaded(tiledImage, tile, image, cutoff) {
|
|
|
19829
20887
|
tiledImage.viewer.raiseEvent("tile-loaded", {
|
|
19830
20888
|
tile: tile,
|
|
19831
20889
|
tiledImage: tiledImage,
|
|
20890
|
+
tileRequest: tileRequest,
|
|
19832
20891
|
image: image,
|
|
19833
20892
|
getCompletionCallback: getCompletionCallback
|
|
19834
20893
|
});
|
|
@@ -19836,6 +20895,16 @@ function setTileLoaded(tiledImage, tile, image, cutoff) {
|
|
|
19836
20895
|
getCompletionCallback()();
|
|
19837
20896
|
}
|
|
19838
20897
|
|
|
20898
|
+
/**
|
|
20899
|
+
* @private
|
|
20900
|
+
* @inner
|
|
20901
|
+
* @param {OpenSeadragon.Tile} tile
|
|
20902
|
+
* @param {Boolean} overlap
|
|
20903
|
+
* @param {OpenSeadragon.Viewport} viewport
|
|
20904
|
+
* @param {OpenSeadragon.Point} viewportCenter
|
|
20905
|
+
* @param {Number} levelVisibility
|
|
20906
|
+
* @param {OpenSeadragon.TiledImage} tiledImage
|
|
20907
|
+
*/
|
|
19839
20908
|
function positionTile( tile, overlap, viewport, viewportCenter, levelVisibility, tiledImage ){
|
|
19840
20909
|
var boundsTL = tile.bounds.getTopLeft();
|
|
19841
20910
|
|
|
@@ -19849,12 +20918,12 @@ function positionTile( tile, overlap, viewport, viewportCenter, levelVisibility,
|
|
|
19849
20918
|
boundsSize.x *= tiledImage._scaleSpring.current.value;
|
|
19850
20919
|
boundsSize.y *= tiledImage._scaleSpring.current.value;
|
|
19851
20920
|
|
|
19852
|
-
var positionC
|
|
19853
|
-
positionT
|
|
19854
|
-
sizeC
|
|
19855
|
-
sizeT
|
|
19856
|
-
tileCenter
|
|
19857
|
-
|
|
20921
|
+
var positionC = viewport.pixelFromPointNoRotate(boundsTL, true),
|
|
20922
|
+
positionT = viewport.pixelFromPointNoRotate(boundsTL, false),
|
|
20923
|
+
sizeC = viewport.deltaPixelsFromPointsNoRotate(boundsSize, true),
|
|
20924
|
+
sizeT = viewport.deltaPixelsFromPointsNoRotate(boundsSize, false),
|
|
20925
|
+
tileCenter = positionT.plus( sizeT.divide( 2 ) ),
|
|
20926
|
+
tileSquaredDistance = viewportCenter.squaredDistanceTo( tileCenter );
|
|
19858
20927
|
|
|
19859
20928
|
if ( !overlap ) {
|
|
19860
20929
|
sizeC = sizeC.plus( new $.Point( 1, 1 ) );
|
|
@@ -19862,11 +20931,27 @@ function positionTile( tile, overlap, viewport, viewportCenter, levelVisibility,
|
|
|
19862
20931
|
|
|
19863
20932
|
tile.position = positionC;
|
|
19864
20933
|
tile.size = sizeC;
|
|
19865
|
-
tile.
|
|
20934
|
+
tile.squaredDistance = tileSquaredDistance;
|
|
19866
20935
|
tile.visibility = levelVisibility;
|
|
19867
20936
|
}
|
|
19868
20937
|
|
|
19869
|
-
|
|
20938
|
+
/**
|
|
20939
|
+
* @private
|
|
20940
|
+
* @inner
|
|
20941
|
+
* Updates the opacity of a tile according to the time it has been on screen
|
|
20942
|
+
* to perform a fade-in.
|
|
20943
|
+
* Updates coverage once a tile is fully opaque.
|
|
20944
|
+
* Returns whether the fade-in has completed.
|
|
20945
|
+
*
|
|
20946
|
+
* @param {OpenSeadragon.TiledImage} tiledImage
|
|
20947
|
+
* @param {OpenSeadragon.Tile} tile
|
|
20948
|
+
* @param {Number} x
|
|
20949
|
+
* @param {Number} y
|
|
20950
|
+
* @param {Number} level
|
|
20951
|
+
* @param {Number} levelOpacity
|
|
20952
|
+
* @param {Number} currentTime
|
|
20953
|
+
* @returns {Boolean}
|
|
20954
|
+
*/
|
|
19870
20955
|
function blendTile( tiledImage, tile, x, y, level, levelOpacity, currentTime ){
|
|
19871
20956
|
var blendTimeMillis = 1000 * tiledImage.blendTime,
|
|
19872
20957
|
deltaTime,
|
|
@@ -19907,6 +20992,12 @@ function blendTile( tiledImage, tile, x, y, level, levelOpacity, currentTime ){
|
|
|
19907
20992
|
* Note that out-of-bounds tiles provide coverage in this sense, since
|
|
19908
20993
|
* there's no content that they would need to cover. Tiles at non-existent
|
|
19909
20994
|
* levels that are within the image bounds, however, do not.
|
|
20995
|
+
*
|
|
20996
|
+
* @param {Object} coverage - A '3d' dictionary [level][x][y] --> Boolean.
|
|
20997
|
+
* @param {Number} level - The resolution level of the tile.
|
|
20998
|
+
* @param {Number} x - The X position of the tile.
|
|
20999
|
+
* @param {Number} y - The Y position of the tile.
|
|
21000
|
+
* @returns {Boolean}
|
|
19910
21001
|
*/
|
|
19911
21002
|
function providesCoverage( coverage, level, x, y ) {
|
|
19912
21003
|
var rows,
|
|
@@ -19946,6 +21037,12 @@ function providesCoverage( coverage, level, x, y ) {
|
|
|
19946
21037
|
* Returns true if the given tile is completely covered by higher-level
|
|
19947
21038
|
* tiles of higher resolution representing the same content. If neither x
|
|
19948
21039
|
* nor y is given, returns true if the entire visible level is covered.
|
|
21040
|
+
*
|
|
21041
|
+
* @param {Object} coverage - A '3d' dictionary [level][x][y] --> Boolean.
|
|
21042
|
+
* @param {Number} level - The resolution level of the tile.
|
|
21043
|
+
* @param {Number} x - The X position of the tile.
|
|
21044
|
+
* @param {Number} y - The Y position of the tile.
|
|
21045
|
+
* @returns {Boolean}
|
|
19949
21046
|
*/
|
|
19950
21047
|
function isCovered( coverage, level, x, y ) {
|
|
19951
21048
|
if ( x === undefined || y === undefined ) {
|
|
@@ -19964,6 +21061,12 @@ function isCovered( coverage, level, x, y ) {
|
|
|
19964
21061
|
* @private
|
|
19965
21062
|
* @inner
|
|
19966
21063
|
* Sets whether the given tile provides coverage or not.
|
|
21064
|
+
*
|
|
21065
|
+
* @param {Object} coverage - A '3d' dictionary [level][x][y] --> Boolean.
|
|
21066
|
+
* @param {Number} level - The resolution level of the tile.
|
|
21067
|
+
* @param {Number} x - The X position of the tile.
|
|
21068
|
+
* @param {Number} y - The Y position of the tile.
|
|
21069
|
+
* @param {Boolean} covers - Whether the tile provides coverage.
|
|
19967
21070
|
*/
|
|
19968
21071
|
function setCoverage( coverage, level, x, y, covers ) {
|
|
19969
21072
|
if ( !coverage[ level ] ) {
|
|
@@ -19987,6 +21090,9 @@ function setCoverage( coverage, level, x, y, covers ) {
|
|
|
19987
21090
|
* Resets coverage information for the given level. This should be called
|
|
19988
21091
|
* after every draw routine. Note that at the beginning of the next draw
|
|
19989
21092
|
* routine, coverage for every visible tile should be explicitly set.
|
|
21093
|
+
*
|
|
21094
|
+
* @param {Object} coverage - A '3d' dictionary [level][x][y] --> Boolean.
|
|
21095
|
+
* @param {Number} level - The resolution level of tiles to completely reset.
|
|
19990
21096
|
*/
|
|
19991
21097
|
function resetCoverage( coverage, level ) {
|
|
19992
21098
|
coverage[ level ] = {};
|
|
@@ -19997,6 +21103,10 @@ function resetCoverage( coverage, level ) {
|
|
|
19997
21103
|
* @inner
|
|
19998
21104
|
* Determines whether the 'last best' tile for the area is better than the
|
|
19999
21105
|
* tile in question.
|
|
21106
|
+
*
|
|
21107
|
+
* @param {OpenSeadragon.Tile} previousBest
|
|
21108
|
+
* @param {OpenSeadragon.Tile} tile
|
|
21109
|
+
* @returns {OpenSeadragon.Tile} The new best tile.
|
|
20000
21110
|
*/
|
|
20001
21111
|
function compareTiles( previousBest, tile ) {
|
|
20002
21112
|
if ( !previousBest ) {
|
|
@@ -20006,7 +21116,7 @@ function compareTiles( previousBest, tile ) {
|
|
|
20006
21116
|
if ( tile.visibility > previousBest.visibility ) {
|
|
20007
21117
|
return tile;
|
|
20008
21118
|
} else if ( tile.visibility == previousBest.visibility ) {
|
|
20009
|
-
if ( tile.
|
|
21119
|
+
if ( tile.squaredDistance < previousBest.squaredDistance ) {
|
|
20010
21120
|
return tile;
|
|
20011
21121
|
}
|
|
20012
21122
|
}
|
|
@@ -20014,8 +21124,15 @@ function compareTiles( previousBest, tile ) {
|
|
|
20014
21124
|
return previousBest;
|
|
20015
21125
|
}
|
|
20016
21126
|
|
|
21127
|
+
/**
|
|
21128
|
+
* @private
|
|
21129
|
+
* @inner
|
|
21130
|
+
* Draws a TiledImage.
|
|
21131
|
+
* @param {OpenSeadragon.TiledImage} tiledImage
|
|
21132
|
+
* @param {OpenSeadragon.Tile[]} lastDrawn - An unordered list of Tiles drawn last frame.
|
|
21133
|
+
*/
|
|
20017
21134
|
function drawTiles( tiledImage, lastDrawn ) {
|
|
20018
|
-
if (lastDrawn.length === 0) {
|
|
21135
|
+
if (tiledImage.opacity === 0 || lastDrawn.length === 0) {
|
|
20019
21136
|
return;
|
|
20020
21137
|
}
|
|
20021
21138
|
var tile = lastDrawn[0];
|
|
@@ -20030,7 +21147,12 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|
|
20030
21147
|
|
|
20031
21148
|
var zoom = tiledImage.viewport.getZoom(true);
|
|
20032
21149
|
var imageZoom = tiledImage.viewportToImageZoom(zoom);
|
|
20033
|
-
|
|
21150
|
+
|
|
21151
|
+
if (lastDrawn.length > 1 &&
|
|
21152
|
+
imageZoom > tiledImage.smoothTileEdgesMinZoom &&
|
|
21153
|
+
!tiledImage.iOSDevice &&
|
|
21154
|
+
tiledImage.getRotation(true) % 360 === 0 && // TODO: support tile edge smoothing with tiled image rotation.
|
|
21155
|
+
$.supportsCanvas) {
|
|
20034
21156
|
// When zoomed in a lot (>100%) the tile edges are visible.
|
|
20035
21157
|
// So we have to composite them at ~100% and scale them up together.
|
|
20036
21158
|
// Note: Disabled on iOS devices per default as it causes a native crash
|
|
@@ -20054,10 +21176,23 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|
|
20054
21176
|
tiledImage._drawer._clear(true, bounds);
|
|
20055
21177
|
}
|
|
20056
21178
|
|
|
20057
|
-
// When scaling, we must rotate only when blending the sketch canvas to
|
|
20058
|
-
// interpolation
|
|
20059
|
-
if (
|
|
20060
|
-
|
|
21179
|
+
// When scaling, we must rotate only when blending the sketch canvas to
|
|
21180
|
+
// avoid interpolation
|
|
21181
|
+
if (!sketchScale) {
|
|
21182
|
+
if (tiledImage.viewport.degrees !== 0) {
|
|
21183
|
+
tiledImage._drawer._offsetForRotation({
|
|
21184
|
+
degrees: tiledImage.viewport.degrees,
|
|
21185
|
+
useSketch: useSketch
|
|
21186
|
+
});
|
|
21187
|
+
}
|
|
21188
|
+
if (tiledImage.getRotation(true) % 360 !== 0) {
|
|
21189
|
+
tiledImage._drawer._offsetForRotation({
|
|
21190
|
+
degrees: tiledImage.getRotation(true),
|
|
21191
|
+
point: tiledImage.viewport.pixelFromPointNoRotate(
|
|
21192
|
+
tiledImage._getRotationPoint(true), true),
|
|
21193
|
+
useSketch: useSketch
|
|
21194
|
+
});
|
|
21195
|
+
}
|
|
20061
21196
|
}
|
|
20062
21197
|
|
|
20063
21198
|
var usedClip = false;
|
|
@@ -20065,6 +21200,7 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|
|
20065
21200
|
tiledImage._drawer.saveContext(useSketch);
|
|
20066
21201
|
|
|
20067
21202
|
var box = tiledImage.imageToViewportRectangle(tiledImage._clip, true);
|
|
21203
|
+
box = box.rotate(-tiledImage.getRotation(true), tiledImage._getRotationPoint(true));
|
|
20068
21204
|
var clipRect = tiledImage._drawer.viewportToDrawerRectangle(box);
|
|
20069
21205
|
if (sketchScale) {
|
|
20070
21206
|
clipRect = clipRect.times(sketchScale);
|
|
@@ -20125,14 +21261,31 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|
|
20125
21261
|
tiledImage._drawer.restoreContext( useSketch );
|
|
20126
21262
|
}
|
|
20127
21263
|
|
|
20128
|
-
if (
|
|
20129
|
-
tiledImage.
|
|
21264
|
+
if (!sketchScale) {
|
|
21265
|
+
if (tiledImage.getRotation(true) % 360 !== 0) {
|
|
21266
|
+
tiledImage._drawer._restoreRotationChanges(useSketch);
|
|
21267
|
+
}
|
|
21268
|
+
if (tiledImage.viewport.degrees !== 0) {
|
|
21269
|
+
tiledImage._drawer._restoreRotationChanges(useSketch);
|
|
21270
|
+
}
|
|
20130
21271
|
}
|
|
20131
21272
|
|
|
20132
21273
|
if (useSketch) {
|
|
20133
|
-
|
|
20134
|
-
|
|
20135
|
-
|
|
21274
|
+
if (sketchScale) {
|
|
21275
|
+
if (tiledImage.viewport.degrees !== 0) {
|
|
21276
|
+
tiledImage._drawer._offsetForRotation({
|
|
21277
|
+
degrees: tiledImage.viewport.degrees,
|
|
21278
|
+
useSketch: false
|
|
21279
|
+
});
|
|
21280
|
+
}
|
|
21281
|
+
if (tiledImage.getRotation(true) % 360 !== 0) {
|
|
21282
|
+
tiledImage._drawer._offsetForRotation({
|
|
21283
|
+
degrees: tiledImage.getRotation(true),
|
|
21284
|
+
point: tiledImage.viewport.pixelFromPointNoRotate(
|
|
21285
|
+
tiledImage._getRotationPoint(true), true),
|
|
21286
|
+
useSketch: false
|
|
21287
|
+
});
|
|
21288
|
+
}
|
|
20136
21289
|
}
|
|
20137
21290
|
tiledImage._drawer.blendSketch({
|
|
20138
21291
|
opacity: tiledImage.opacity,
|
|
@@ -20141,19 +21294,32 @@ function drawTiles( tiledImage, lastDrawn ) {
|
|
|
20141
21294
|
compositeOperation: tiledImage.compositeOperation,
|
|
20142
21295
|
bounds: bounds
|
|
20143
21296
|
});
|
|
20144
|
-
if (
|
|
20145
|
-
tiledImage.
|
|
21297
|
+
if (sketchScale) {
|
|
21298
|
+
if (tiledImage.getRotation(true) % 360 !== 0) {
|
|
21299
|
+
tiledImage._drawer._restoreRotationChanges(false);
|
|
21300
|
+
}
|
|
21301
|
+
if (tiledImage.viewport.degrees !== 0) {
|
|
21302
|
+
tiledImage._drawer._restoreRotationChanges(false);
|
|
21303
|
+
}
|
|
20146
21304
|
}
|
|
20147
21305
|
}
|
|
20148
21306
|
drawDebugInfo( tiledImage, lastDrawn );
|
|
20149
21307
|
}
|
|
20150
21308
|
|
|
21309
|
+
/**
|
|
21310
|
+
* @private
|
|
21311
|
+
* @inner
|
|
21312
|
+
* Draws special debug information for a TiledImage if in debug mode.
|
|
21313
|
+
* @param {OpenSeadragon.TiledImage} tiledImage
|
|
21314
|
+
* @param {OpenSeadragon.Tile[]} lastDrawn - An unordered list of Tiles drawn last frame.
|
|
21315
|
+
*/
|
|
20151
21316
|
function drawDebugInfo( tiledImage, lastDrawn ) {
|
|
20152
21317
|
if( tiledImage.debugMode ) {
|
|
20153
21318
|
for ( var i = lastDrawn.length - 1; i >= 0; i-- ) {
|
|
20154
21319
|
var tile = lastDrawn[ i ];
|
|
20155
21320
|
try {
|
|
20156
|
-
tiledImage._drawer.drawDebugInfo(
|
|
21321
|
+
tiledImage._drawer.drawDebugInfo(
|
|
21322
|
+
tile, lastDrawn.length, i, tiledImage);
|
|
20157
21323
|
} catch(e) {
|
|
20158
21324
|
$.console.error(e);
|
|
20159
21325
|
}
|
|
@@ -20305,6 +21471,7 @@ $.TileCache.prototype = {
|
|
|
20305
21471
|
* may temporarily surpass that number, but should eventually come back down to the max specified.
|
|
20306
21472
|
* @param {Object} options - Tile info.
|
|
20307
21473
|
* @param {OpenSeadragon.Tile} options.tile - The tile to cache.
|
|
21474
|
+
* @param {String} options.tile.cacheKey - The unique key used to identify this tile in the cache.
|
|
20308
21475
|
* @param {Image} options.image - The image of the tile to cache.
|
|
20309
21476
|
* @param {OpenSeadragon.TiledImage} options.tiledImage - The TiledImage that owns that tile.
|
|
20310
21477
|
* @param {Number} [options.cutoff=0] - If adding this tile goes over the cache max count, this
|
|
@@ -20314,16 +21481,16 @@ $.TileCache.prototype = {
|
|
|
20314
21481
|
cacheTile: function( options ) {
|
|
20315
21482
|
$.console.assert( options, "[TileCache.cacheTile] options is required" );
|
|
20316
21483
|
$.console.assert( options.tile, "[TileCache.cacheTile] options.tile is required" );
|
|
20317
|
-
$.console.assert( options.tile.
|
|
21484
|
+
$.console.assert( options.tile.cacheKey, "[TileCache.cacheTile] options.tile.cacheKey is required" );
|
|
20318
21485
|
$.console.assert( options.tiledImage, "[TileCache.cacheTile] options.tiledImage is required" );
|
|
20319
21486
|
|
|
20320
21487
|
var cutoff = options.cutoff || 0;
|
|
20321
21488
|
var insertionIndex = this._tilesLoaded.length;
|
|
20322
21489
|
|
|
20323
|
-
var imageRecord = this._imagesLoaded[options.tile.
|
|
21490
|
+
var imageRecord = this._imagesLoaded[options.tile.cacheKey];
|
|
20324
21491
|
if (!imageRecord) {
|
|
20325
21492
|
$.console.assert( options.image, "[TileCache.cacheTile] options.image is required to create an ImageRecord" );
|
|
20326
|
-
imageRecord = this._imagesLoaded[options.tile.
|
|
21493
|
+
imageRecord = this._imagesLoaded[options.tile.cacheKey] = new ImageRecord({
|
|
20327
21494
|
image: options.image
|
|
20328
21495
|
});
|
|
20329
21496
|
|
|
@@ -20397,9 +21564,9 @@ $.TileCache.prototype = {
|
|
|
20397
21564
|
},
|
|
20398
21565
|
|
|
20399
21566
|
// private
|
|
20400
|
-
getImageRecord: function(
|
|
20401
|
-
$.console.assert(
|
|
20402
|
-
return this._imagesLoaded[
|
|
21567
|
+
getImageRecord: function(cacheKey) {
|
|
21568
|
+
$.console.assert(cacheKey, '[TileCache.getImageRecord] cacheKey is required');
|
|
21569
|
+
return this._imagesLoaded[cacheKey];
|
|
20403
21570
|
},
|
|
20404
21571
|
|
|
20405
21572
|
// private
|
|
@@ -20411,11 +21578,11 @@ $.TileCache.prototype = {
|
|
|
20411
21578
|
tile.unload();
|
|
20412
21579
|
tile.cacheImageRecord = null;
|
|
20413
21580
|
|
|
20414
|
-
var imageRecord = this._imagesLoaded[tile.
|
|
21581
|
+
var imageRecord = this._imagesLoaded[tile.cacheKey];
|
|
20415
21582
|
imageRecord.removeTile(tile);
|
|
20416
21583
|
if (!imageRecord.getTileCount()) {
|
|
20417
21584
|
imageRecord.destroy();
|
|
20418
|
-
delete this._imagesLoaded[tile.
|
|
21585
|
+
delete this._imagesLoaded[tile.cacheKey];
|
|
20419
21586
|
this._imagesLoadedCount--;
|
|
20420
21587
|
}
|
|
20421
21588
|
|
|
@@ -20533,6 +21700,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|
|
20533
21700
|
this._needsDraw = true;
|
|
20534
21701
|
|
|
20535
21702
|
item.addHandler('bounds-change', this._delegatedFigureSizes);
|
|
21703
|
+
item.addHandler('clip-change', this._delegatedFigureSizes);
|
|
20536
21704
|
|
|
20537
21705
|
/**
|
|
20538
21706
|
* Raised when an item is added to the World.
|
|
@@ -20633,6 +21801,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|
|
20633
21801
|
}
|
|
20634
21802
|
|
|
20635
21803
|
item.removeHandler('bounds-change', this._delegatedFigureSizes);
|
|
21804
|
+
item.removeHandler('clip-change', this._delegatedFigureSizes);
|
|
20636
21805
|
item.destroy();
|
|
20637
21806
|
this._items.splice( index, 1 );
|
|
20638
21807
|
this._figureSizes();
|
|
@@ -20649,9 +21818,11 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|
|
20649
21818
|
// We need to make sure any pending images are canceled so the world items don't get messed up
|
|
20650
21819
|
this.viewer._cancelPendingImages();
|
|
20651
21820
|
var item;
|
|
20652
|
-
|
|
21821
|
+
var i;
|
|
21822
|
+
for (i = 0; i < this._items.length; i++) {
|
|
20653
21823
|
item = this._items[i];
|
|
20654
21824
|
item.removeHandler('bounds-change', this._delegatedFigureSizes);
|
|
21825
|
+
item.removeHandler('clip-change', this._delegatedFigureSizes);
|
|
20655
21826
|
item.destroy();
|
|
20656
21827
|
}
|
|
20657
21828
|
|
|
@@ -20822,7 +21993,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|
|
20822
21993
|
var item = this._items[0];
|
|
20823
21994
|
var bounds = item.getBounds();
|
|
20824
21995
|
this._contentFactor = item.getContentSize().x / bounds.width;
|
|
20825
|
-
var clippedBounds = item.getClippedBounds();
|
|
21996
|
+
var clippedBounds = item.getClippedBounds().getBoundingBox();
|
|
20826
21997
|
var left = clippedBounds.x;
|
|
20827
21998
|
var top = clippedBounds.y;
|
|
20828
21999
|
var right = clippedBounds.x + clippedBounds.width;
|
|
@@ -20832,7 +22003,7 @@ $.extend( $.World.prototype, $.EventSource.prototype, /** @lends OpenSeadragon.W
|
|
|
20832
22003
|
bounds = item.getBounds();
|
|
20833
22004
|
this._contentFactor = Math.max(this._contentFactor,
|
|
20834
22005
|
item.getContentSize().x / bounds.width);
|
|
20835
|
-
clippedBounds = item.getClippedBounds();
|
|
22006
|
+
clippedBounds = item.getClippedBounds().getBoundingBox();
|
|
20836
22007
|
left = Math.min(left, clippedBounds.x);
|
|
20837
22008
|
top = Math.min(top, clippedBounds.y);
|
|
20838
22009
|
right = Math.max(right, clippedBounds.x + clippedBounds.width);
|