mirror of
https://github.com/openseadragon/openseadragon.git
synced 2025-01-31 23:21:42 +03:00
removed all psuedo-private properties from Drawer instance in favor of direct access.
This commit is contained in:
parent
4eba38dd86
commit
0041e32cbb
453
openseadragon.js
453
openseadragon.js
@ -2155,62 +2155,74 @@ function onFullPage() {
|
|||||||
|
|
||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
|
//TODO: I guess this is where the i18n needs to be reimplemented. I'll look
|
||||||
|
// into existing patterns for i18n in javascript but i think that mimicking
|
||||||
|
// pythons gettext might be a reasonable approach.
|
||||||
|
|
||||||
$.Strings = {
|
$.Strings = {
|
||||||
|
|
||||||
Errors: {
|
Errors: {
|
||||||
Failure: "Sorry, but Seadragon Ajax can't run on your browser!\n" +
|
Failure: "Sorry, but Seadragon Ajax can't run on your browser!\n" +
|
||||||
"Please try using IE 7 or Firefox 3.\n",
|
"Please try using IE 7 or Firefox 3.\n",
|
||||||
Dzc: "Sorry, we don't support Deep Zoom Collections!",
|
Dzc: "Sorry, we don't support Deep Zoom Collections!",
|
||||||
Dzi: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
Dzi: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
||||||
Xml: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
Xml: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
||||||
Empty: "You asked us to open nothing, so we did just that.",
|
Empty: "You asked us to open nothing, so we did just that.",
|
||||||
ImageFormat: "Sorry, we don't support {0}-based Deep Zoom Images.",
|
ImageFormat: "Sorry, we don't support {0}-based Deep Zoom Images.",
|
||||||
Security: "It looks like a security restriction stopped us from " +
|
Security: "It looks like a security restriction stopped us from " +
|
||||||
"loading this Deep Zoom Image.",
|
"loading this Deep Zoom Image.",
|
||||||
Status: "This space unintentionally left blank ({0} {1}).",
|
Status: "This space unintentionally left blank ({0} {1}).",
|
||||||
Unknown: "Whoops, something inexplicably went wrong. Sorry!"
|
Unknown: "Whoops, something inexplicably went wrong. Sorry!"
|
||||||
},
|
},
|
||||||
|
|
||||||
Messages: {
|
Messages: {
|
||||||
Loading: "Loading..."
|
Loading: "Loading..."
|
||||||
},
|
},
|
||||||
|
|
||||||
Tooltips: {
|
Tooltips: {
|
||||||
FullPage: "Toggle full page",
|
FullPage: "Toggle full page",
|
||||||
Home: "Go home",
|
Home: "Go home",
|
||||||
ZoomIn: "Zoom in",
|
ZoomIn: "Zoom in",
|
||||||
ZoomOut: "Zoom out"
|
ZoomOut: "Zoom out"
|
||||||
},
|
},
|
||||||
getString: function(prop) {
|
|
||||||
var props = prop.split('.');
|
|
||||||
var string = $.Strings;
|
|
||||||
|
|
||||||
for (var i = 0; i < props.length; i++) {
|
getString: function( prop ) {
|
||||||
string = string[props[i]] || {}; // in case not a subproperty
|
|
||||||
|
var props = prop.split('.'),
|
||||||
|
string = $.Strings,
|
||||||
|
args = arguments,
|
||||||
|
i;
|
||||||
|
|
||||||
|
for ( i = 0; i < props.length; i++ ) {
|
||||||
|
string = string[ props[ i ] ] || {}; // in case not a subproperty
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof (string) != "string") {
|
if ( typeof( string ) != "string" ) {
|
||||||
string = "";
|
string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
var args = arguments;
|
|
||||||
return string.replace(/\{\d+\}/g, function(capture) {
|
return string.replace(/\{\d+\}/g, function(capture) {
|
||||||
var i = parseInt(capture.match(/\d+/)) + 1;
|
var i = parseInt( capture.match( /\d+/ ) ) + 1;
|
||||||
return i < args.length ? args[i] : "";
|
return i < args.length ?
|
||||||
|
args[ i ] :
|
||||||
|
"";
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setString: function(prop, value) {
|
setString: function( prop, value ) {
|
||||||
var props = prop.split('.');
|
|
||||||
var container = $.Strings;
|
|
||||||
|
|
||||||
for (var i = 0; i < props.length - 1; i++) {
|
var props = prop.split('.'),
|
||||||
if (!container[props[i]]) {
|
container = $.Strings,
|
||||||
container[props[i]] = {};
|
i;
|
||||||
|
|
||||||
|
for ( i = 0; i < props.length - 1; i++ ) {
|
||||||
|
if ( !container[ props[ i ] ] ) {
|
||||||
|
container[ props[ i ] ] = {};
|
||||||
}
|
}
|
||||||
container = container[props[i]];
|
container = container[ props[ i ] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
container[props[i]] = value;
|
container[ props[ i ] ] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -3124,31 +3136,28 @@ function transform( stiffness, x ) {
|
|||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
$.Tile = function(level, x, y, bounds, exists, url) {
|
$.Tile = function(level, x, y, bounds, exists, url) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.bounds = bounds; // where this tile fits, in normalized coordinates
|
this.bounds = bounds; // where this tile fits, in normalized coordinates
|
||||||
this.exists = exists; // part of sparse image? tile hasn't failed to load?
|
this.exists = exists; // part of sparse image? tile hasn't failed to load?
|
||||||
this.loaded = false; // is this tile loaded?
|
this.loaded = false; // is this tile loaded?
|
||||||
this.loading = false; // or is this tile loading?
|
this.loading = false; // or is this tile loading?
|
||||||
|
|
||||||
|
this.elmt = null; // the HTML element for this tile
|
||||||
|
this.image = null; // the Image object for this tile
|
||||||
|
this.url = url; // the URL of this tile's image
|
||||||
|
|
||||||
|
this.style = null; // alias of this.elmt.style
|
||||||
this.elmt = null; // the HTML element for this tile
|
this.position = null; // this tile's position on screen, in pixels
|
||||||
this.image = null; // the Image object for this tile
|
this.size = null; // this tile's size on screen, in pixels
|
||||||
this.url = url; // the URL of this tile's image
|
|
||||||
|
|
||||||
|
|
||||||
this.style = null; // alias of this.elmt.style
|
|
||||||
this.position = null; // this tile's position on screen, in pixels
|
|
||||||
this.size = null; // this tile's size on screen, in pixels
|
|
||||||
this.blendStart = null; // the start time of this tile's blending
|
this.blendStart = null; // the start time of this tile's blending
|
||||||
this.opacity = null; // the current opacity this tile should be
|
this.opacity = null; // the current opacity this tile should be
|
||||||
this.distance = null; // the distance of this tile to the viewport center
|
this.distance = null; // the distance of this tile to the viewport center
|
||||||
this.visibility = null; // the visibility score of this tile
|
this.visibility = null; // the visibility score of this tile
|
||||||
|
|
||||||
this.beingDrawn = false; // whether this tile is currently being drawn
|
this.beingDrawn = false; // whether this tile is currently being drawn
|
||||||
this.lastTouchTime = 0; // the time that tile was last touched
|
this.lastTouchTime = 0; // the time that tile was last touched
|
||||||
};
|
};
|
||||||
|
|
||||||
$.Tile.prototype = {
|
$.Tile.prototype = {
|
||||||
@ -3156,42 +3165,51 @@ $.Tile.prototype = {
|
|||||||
toString: function() {
|
toString: function() {
|
||||||
return this.level + "/" + this.x + "_" + this.y;
|
return this.level + "/" + this.x + "_" + this.y;
|
||||||
},
|
},
|
||||||
drawHTML: function(container) {
|
|
||||||
if (!this.loaded) {
|
drawHTML: function( container ) {
|
||||||
$.Debug.error("Attempting to draw tile " + this.toString() +
|
|
||||||
" when it's not yet loaded.");
|
if ( !this.loaded ) {
|
||||||
|
$.Debug.error(
|
||||||
|
"Attempting to draw tile " +
|
||||||
|
this.toString() +
|
||||||
|
" when it's not yet loaded."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.elmt) {
|
if ( !this.elmt ) {
|
||||||
this.elmt = $.Utils.makeNeutralElement("img");
|
this.elmt = $.Utils.makeNeutralElement("img");
|
||||||
this.elmt.src = this.url;
|
this.elmt.src = this.url;
|
||||||
this.style = this.elmt.style;
|
this.style = this.elmt.style;
|
||||||
this.style.position = "absolute";
|
|
||||||
|
this.style.position = "absolute";
|
||||||
this.style.msInterpolationMode = "nearest-neighbor";
|
this.style.msInterpolationMode = "nearest-neighbor";
|
||||||
}
|
}
|
||||||
|
|
||||||
var elmt = this.elmt;
|
var position = this.position.apply( Math.floor );
|
||||||
var style = this.style;
|
var size = this.size.apply( Math.ceil );
|
||||||
var position = this.position.apply(Math.floor);
|
|
||||||
var size = this.size.apply(Math.ceil);
|
|
||||||
|
|
||||||
|
|
||||||
if (elmt.parentNode != container) {
|
if ( this.elmt.parentNode != container ) {
|
||||||
container.appendChild(elmt);
|
container.appendChild( this.elmt );
|
||||||
}
|
}
|
||||||
|
|
||||||
style.left = position.x + "px";
|
this.elmt.style.left = position.x + "px";
|
||||||
style.top = position.y + "px";
|
this.elmt.style.top = position.y + "px";
|
||||||
style.width = size.x + "px";
|
this.elmt.style.width = size.x + "px";
|
||||||
style.height = size.y + "px";
|
this.elmt.style.height = size.y + "px";
|
||||||
|
|
||||||
|
$.Utils.setElementOpacity( this.elmt, this.opacity );
|
||||||
|
|
||||||
$.Utils.setElementOpacity(elmt, this.opacity);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
drawCanvas: function(context) {
|
drawCanvas: function(context) {
|
||||||
if (!this.loaded) {
|
if (!this.loaded) {
|
||||||
$.Debug.error("Attempting to draw tile " + this.toString() +
|
$.Debug.error(
|
||||||
" when it's not yet loaded.");
|
"Attempting to draw tile " +
|
||||||
|
this.toString() +
|
||||||
|
" when it's not yet loaded."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3201,6 +3219,7 @@ $.Tile.prototype = {
|
|||||||
context.globalAlpha = this.opacity;
|
context.globalAlpha = this.opacity;
|
||||||
context.drawImage(this.image, position.x, position.y, size.x, size.y);
|
context.drawImage(this.image, position.x, position.y, size.x, size.y);
|
||||||
},
|
},
|
||||||
|
|
||||||
unload: function() {
|
unload: function() {
|
||||||
if (this.elmt && this.elmt.parentNode) {
|
if (this.elmt && this.elmt.parentNode) {
|
||||||
this.elmt.parentNode.removeChild(this.elmt);
|
this.elmt.parentNode.removeChild(this.elmt);
|
||||||
@ -3354,66 +3373,75 @@ $.Tile.prototype = {
|
|||||||
|
|
||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
var QUOTA = 100; // the max number of images we should keep in memory
|
var // the max number of images we should keep in memory
|
||||||
var MIN_PIXEL_RATIO = 0.5; // the most shrunk a tile should be
|
QUOTA = 100,
|
||||||
|
// the most shrunk a tile should be
|
||||||
|
MIN_PIXEL_RATIO = 0.5,
|
||||||
|
//TODO: make TIMEOUT configurable
|
||||||
|
TIMEOUT = 5000,
|
||||||
|
|
||||||
//TODO: make TIMEOUT configurable
|
BROWSER = $.Utils.getBrowser(),
|
||||||
var TIMEOUT = 5000;
|
BROWSER_VERSION = $.Utils.getBrowserVersion(),
|
||||||
|
|
||||||
var browser = $.Utils.getBrowser();
|
SUBPIXEL_RENDERING = (
|
||||||
var browserVer = $.Utils.getBrowserVersion();
|
( BROWSER == $.Browser.FIREFOX ) ||
|
||||||
|
( BROWSER == $.Browser.OPERA ) ||
|
||||||
|
( BROWSER == $.Browser.SAFARI && BROWSER_VERSION >= 4 ) ||
|
||||||
|
( BROWSER == $.Browser.CHROME && BROWSER_VERSION >= 2 )
|
||||||
|
),
|
||||||
|
|
||||||
var subpixelRenders = browser == $.Browser.FIREFOX ||
|
USE_CANVAS =
|
||||||
browser == $.Browser.OPERA ||
|
$.isFunction( document.createElement("canvas").getContext ) &&
|
||||||
(browser == $.Browser.SAFARI && browserVer >= 4) ||
|
SUBPIXEL_RENDERING;
|
||||||
(browser == $.Browser.CHROME && browserVer >= 2);
|
|
||||||
|
|
||||||
var useCanvas =
|
|
||||||
typeof (document.createElement("canvas").getContext) == "function" &&
|
|
||||||
subpixelRenders;
|
|
||||||
|
|
||||||
$.Drawer = function(source, viewport, elmt) {
|
$.Drawer = function(source, viewport, elmt) {
|
||||||
|
|
||||||
this._container = $.Utils.getElement(elmt);
|
this.container = $.Utils.getElement(elmt);
|
||||||
this._canvas = $.Utils.makeNeutralElement(useCanvas ? "canvas" : "div");
|
this.canvas = $.Utils.makeNeutralElement(USE_CANVAS ? "canvas" : "div");
|
||||||
this._context = useCanvas ? this._canvas.getContext("2d") : null;
|
this.context = USE_CANVAS ? this.canvas.getContext("2d") : null;
|
||||||
this._viewport = viewport;
|
this.viewport = viewport;
|
||||||
this._source = source;
|
this.source = source;
|
||||||
this.config = this._viewport.config;
|
this.config = this.viewport.config;
|
||||||
|
|
||||||
this.downloading = 0;
|
this.downloading = 0;
|
||||||
this.imageLoaderLimit = this.config.imageLoaderLimit;
|
this.imageLoaderLimit = this.config.imageLoaderLimit;
|
||||||
|
|
||||||
this._profiler = new $.Profiler();
|
|
||||||
|
|
||||||
this._minLevel = source.minLevel;
|
|
||||||
this._maxLevel = source.maxLevel;
|
|
||||||
this._tileSize = source.tileSize;
|
|
||||||
this._tileOverlap = source.tileOverlap;
|
|
||||||
this._normHeight = source.dimensions.y / source.dimensions.x;
|
|
||||||
|
|
||||||
this._cacheNumTiles = {}; // 1d dictionary [level] --> Point
|
|
||||||
this._cachePixelRatios = {}; // 1d dictionary [level] --> Point
|
|
||||||
this._tilesMatrix = {}; // 3d dictionary [level][x][y] --> Tile
|
|
||||||
this._tilesLoaded = []; // unordered list of Tiles with loaded images
|
|
||||||
this._coverage = {}; // 3d dictionary [level][x][y] --> Boolean
|
|
||||||
|
|
||||||
this._overlays = []; // unordered list of Overlays added
|
|
||||||
this._lastDrawn = []; // unordered list of Tiles drawn last frame
|
|
||||||
this._lastResetTime = 0;
|
|
||||||
this._midUpdate = false;
|
|
||||||
this._updateAgain = true;
|
|
||||||
|
|
||||||
|
|
||||||
this.elmt = this._container;
|
|
||||||
|
|
||||||
|
this.profiler = new $.Profiler();
|
||||||
|
|
||||||
|
this.minLevel = source.minLevel;
|
||||||
|
this.maxLevel = source.maxLevel;
|
||||||
|
this.tileSize = source.tileSize;
|
||||||
|
this.tileOverlap = source.tileOverlap;
|
||||||
|
this.normHeight = source.dimensions.y / source.dimensions.x;
|
||||||
|
|
||||||
this._canvas.style.width = "100%";
|
// 1d dictionary [level] --> Point
|
||||||
this._canvas.style.height = "100%";
|
this.cacheNumTiles = {};
|
||||||
this._canvas.style.position = "absolute";
|
// 1d dictionary [level] --> Point
|
||||||
this._container.style.textAlign = "left"; // explicit left-align
|
this.cachePixelRatios = {};
|
||||||
this._container.appendChild(this._canvas);
|
// 3d dictionary [level][x][y] --> Tile
|
||||||
|
this.tilesMatrix = {};
|
||||||
|
// unordered list of Tiles with loaded images
|
||||||
|
this.tilesLoaded = [];
|
||||||
|
// 3d dictionary [level][x][y] --> Boolean
|
||||||
|
this.coverage = {};
|
||||||
|
|
||||||
|
// unordered list of Overlays added
|
||||||
|
this.overlays = [];
|
||||||
|
// unordered list of Tiles drawn last frame
|
||||||
|
this.lastDrawn = [];
|
||||||
|
this.lastResetTime = 0;
|
||||||
|
this.midUpdate = false;
|
||||||
|
this.updateAgain = true;
|
||||||
|
|
||||||
|
this.elmt = this.container;
|
||||||
|
|
||||||
|
this.canvas.style.width = "100%";
|
||||||
|
this.canvas.style.height = "100%";
|
||||||
|
this.canvas.style.position = "absolute";
|
||||||
|
|
||||||
|
// explicit left-align
|
||||||
|
this.container.style.textAlign = "left";
|
||||||
|
this.container.appendChild(this.canvas);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.Drawer.prototype = {
|
$.Drawer.prototype = {
|
||||||
@ -3434,44 +3462,44 @@ $.Drawer.prototype = {
|
|||||||
return prevBest;
|
return prevBest;
|
||||||
},
|
},
|
||||||
_getNumTiles: function(level) {
|
_getNumTiles: function(level) {
|
||||||
if (!this._cacheNumTiles[level]) {
|
if (!this.cacheNumTiles[level]) {
|
||||||
this._cacheNumTiles[level] = this._source.getNumTiles(level);
|
this.cacheNumTiles[level] = this.source.getNumTiles(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._cacheNumTiles[level];
|
return this.cacheNumTiles[level];
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPixelRatio: function(level) {
|
_getPixelRatio: function(level) {
|
||||||
if (!this._cachePixelRatios[level]) {
|
if (!this.cachePixelRatios[level]) {
|
||||||
this._cachePixelRatios[level] = this._source.getPixelRatio(level);
|
this.cachePixelRatios[level] = this.source.getPixelRatio(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._cachePixelRatios[level];
|
return this.cachePixelRatios[level];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_getTile: function(level, x, y, time, numTilesX, numTilesY) {
|
_getTile: function(level, x, y, time, numTilesX, numTilesY) {
|
||||||
if (!this._tilesMatrix[level]) {
|
if (!this.tilesMatrix[level]) {
|
||||||
this._tilesMatrix[level] = {};
|
this.tilesMatrix[level] = {};
|
||||||
}
|
}
|
||||||
if (!this._tilesMatrix[level][x]) {
|
if (!this.tilesMatrix[level][x]) {
|
||||||
this._tilesMatrix[level][x] = {};
|
this.tilesMatrix[level][x] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._tilesMatrix[level][x][y]) {
|
if (!this.tilesMatrix[level][x][y]) {
|
||||||
var xMod = (numTilesX + (x % numTilesX)) % numTilesX;
|
var xMod = (numTilesX + (x % numTilesX)) % numTilesX;
|
||||||
var yMod = (numTilesY + (y % numTilesY)) % numTilesY;
|
var yMod = (numTilesY + (y % numTilesY)) % numTilesY;
|
||||||
var bounds = this._source.getTileBounds(level, xMod, yMod);
|
var bounds = this.source.getTileBounds(level, xMod, yMod);
|
||||||
var exists = this._source.tileExists(level, xMod, yMod);
|
var exists = this.source.tileExists(level, xMod, yMod);
|
||||||
var url = this._source.getTileUrl(level, xMod, yMod);
|
var url = this.source.getTileUrl(level, xMod, yMod);
|
||||||
|
|
||||||
bounds.x += 1.0 * (x - xMod) / numTilesX;
|
bounds.x += 1.0 * (x - xMod) / numTilesX;
|
||||||
bounds.y += this._normHeight * (y - yMod) / numTilesY;
|
bounds.y += this.normHeight * (y - yMod) / numTilesY;
|
||||||
|
|
||||||
this._tilesMatrix[level][x][y] = new $.Tile(level, x, y, bounds, exists, url);
|
this.tilesMatrix[level][x][y] = new $.Tile(level, x, y, bounds, exists, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tile = this._tilesMatrix[level][x][y];
|
var tile = this.tilesMatrix[level][x][y];
|
||||||
|
|
||||||
tile.lastTouchTime = time;
|
tile.lastTouchTime = time;
|
||||||
|
|
||||||
@ -3493,14 +3521,14 @@ $.Drawer.prototype = {
|
|||||||
_onTileLoad: function(tile, time, image) {
|
_onTileLoad: function(tile, time, image) {
|
||||||
tile.loading = false;
|
tile.loading = false;
|
||||||
|
|
||||||
if (this._midUpdate) {
|
if (this.midUpdate) {
|
||||||
$.Debug.error("Tile load callback in middle of drawing routine.");
|
$.Debug.error("Tile load callback in middle of drawing routine.");
|
||||||
return;
|
return;
|
||||||
} else if (!image) {
|
} else if (!image) {
|
||||||
$.Debug.log("Tile " + tile + " failed to load: " + tile.url);
|
$.Debug.log("Tile " + tile + " failed to load: " + tile.url);
|
||||||
tile.exists = false;
|
tile.exists = false;
|
||||||
return;
|
return;
|
||||||
} else if (time < this._lastResetTime) {
|
} else if (time < this.lastResetTime) {
|
||||||
$.Debug.log("Ignoring tile " + tile + " loaded before reset: " + tile.url);
|
$.Debug.log("Ignoring tile " + tile + " loaded before reset: " + tile.url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -3508,18 +3536,18 @@ $.Drawer.prototype = {
|
|||||||
tile.loaded = true;
|
tile.loaded = true;
|
||||||
tile.image = image;
|
tile.image = image;
|
||||||
|
|
||||||
var insertionIndex = this._tilesLoaded.length;
|
var insertionIndex = this.tilesLoaded.length;
|
||||||
|
|
||||||
if (this._tilesLoaded.length >= QUOTA) {
|
if (this.tilesLoaded.length >= QUOTA) {
|
||||||
var cutoff = Math.ceil(Math.log(this._tileSize) / Math.log(2));
|
var cutoff = Math.ceil(Math.log(this.tileSize) / Math.log(2));
|
||||||
|
|
||||||
var worstTile = null;
|
var worstTile = null;
|
||||||
var worstTileIndex = -1;
|
var worstTileIndex = -1;
|
||||||
|
|
||||||
for (var i = this._tilesLoaded.length - 1; i >= 0; i--) {
|
for (var i = this.tilesLoaded.length - 1; i >= 0; i--) {
|
||||||
var prevTile = this._tilesLoaded[i];
|
var prevTile = this.tilesLoaded[i];
|
||||||
|
|
||||||
if (prevTile.level <= this._cutoff || prevTile.beingDrawn) {
|
if (prevTile.level <= this.cutoff || prevTile.beingDrawn) {
|
||||||
continue;
|
continue;
|
||||||
} else if (!worstTile) {
|
} else if (!worstTile) {
|
||||||
worstTile = prevTile;
|
worstTile = prevTile;
|
||||||
@ -3545,13 +3573,13 @@ $.Drawer.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._tilesLoaded[insertionIndex] = tile;
|
this.tilesLoaded[insertionIndex] = tile;
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_clearTiles: function() {
|
_clearTiles: function() {
|
||||||
this._tilesMatrix = {};
|
this.tilesMatrix = {};
|
||||||
this._tilesLoaded = [];
|
this.tilesLoaded = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -3566,12 +3594,12 @@ $.Drawer.prototype = {
|
|||||||
* levels that are within the image bounds, however, do not.
|
* levels that are within the image bounds, however, do not.
|
||||||
*/
|
*/
|
||||||
_providesCoverage: function(level, x, y) {
|
_providesCoverage: function(level, x, y) {
|
||||||
if (!this._coverage[level]) {
|
if (!this.coverage[level]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x === undefined || y === undefined) {
|
if (x === undefined || y === undefined) {
|
||||||
var rows = this._coverage[level];
|
var rows = this.coverage[level];
|
||||||
for (var i in rows) {
|
for (var i in rows) {
|
||||||
if (rows.hasOwnProperty(i)) {
|
if (rows.hasOwnProperty(i)) {
|
||||||
var cols = rows[i];
|
var cols = rows[i];
|
||||||
@ -3586,9 +3614,9 @@ $.Drawer.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (this._coverage[level][x] === undefined ||
|
return (this.coverage[level][x] === undefined ||
|
||||||
this._coverage[level][x][y] === undefined ||
|
this.coverage[level][x][y] === undefined ||
|
||||||
this._coverage[level][x][y] === true);
|
this.coverage[level][x][y] === true);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3611,17 +3639,17 @@ $.Drawer.prototype = {
|
|||||||
* Sets whether the given tile provides coverage or not.
|
* Sets whether the given tile provides coverage or not.
|
||||||
*/
|
*/
|
||||||
_setCoverage: function(level, x, y, covers) {
|
_setCoverage: function(level, x, y, covers) {
|
||||||
if (!this._coverage[level]) {
|
if (!this.coverage[level]) {
|
||||||
$.Debug.error("Setting coverage for a tile before its " +
|
$.Debug.error("Setting coverage for a tile before its " +
|
||||||
"level's coverage has been reset: " + level);
|
"level's coverage has been reset: " + level);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._coverage[level][x]) {
|
if (!this.coverage[level][x]) {
|
||||||
this._coverage[level][x] = {};
|
this.coverage[level][x] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
this._coverage[level][x][y] = covers;
|
this.coverage[level][x][y] = covers;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3630,7 +3658,7 @@ $.Drawer.prototype = {
|
|||||||
* routine, coverage for every visible tile should be explicitly set.
|
* routine, coverage for every visible tile should be explicitly set.
|
||||||
*/
|
*/
|
||||||
_resetCoverage: function(level) {
|
_resetCoverage: function(level) {
|
||||||
this._coverage[level] = {};
|
this.coverage[level] = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -3652,8 +3680,8 @@ $.Drawer.prototype = {
|
|||||||
|
|
||||||
|
|
||||||
_getOverlayIndex: function(elmt) {
|
_getOverlayIndex: function(elmt) {
|
||||||
for (var i = this._overlays.length - 1; i >= 0; i--) {
|
for (var i = this.overlays.length - 1; i >= 0; i--) {
|
||||||
if (this._overlays[i].elmt == elmt) {
|
if (this.overlays[i].elmt == elmt) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3663,38 +3691,37 @@ $.Drawer.prototype = {
|
|||||||
|
|
||||||
|
|
||||||
_updateActual: function() {
|
_updateActual: function() {
|
||||||
this._updateAgain = false;
|
this.updateAgain = false;
|
||||||
|
|
||||||
var _canvas = this._canvas;
|
var _canvas = this.canvas;
|
||||||
var _context = this._context;
|
var _context = this.context;
|
||||||
var _container = this._container;
|
var _container = this.container;
|
||||||
var _useCanvas = useCanvas;
|
var _lastDrawn = this.lastDrawn;
|
||||||
var _lastDrawn = this._lastDrawn;
|
|
||||||
|
|
||||||
while (_lastDrawn.length > 0) {
|
while (_lastDrawn.length > 0) {
|
||||||
var tile = _lastDrawn.pop();
|
var tile = _lastDrawn.pop();
|
||||||
tile.beingDrawn = false;
|
tile.beingDrawn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportSize = this._viewport.getContainerSize();
|
var viewportSize = this.viewport.getContainerSize();
|
||||||
var viewportWidth = viewportSize.x;
|
var viewportWidth = viewportSize.x;
|
||||||
var viewportHeight = viewportSize.y;
|
var viewportHeight = viewportSize.y;
|
||||||
|
|
||||||
_canvas.innerHTML = "";
|
_canvas.innerHTML = "";
|
||||||
if (_useCanvas) {
|
if ( USE_CANVAS ) {
|
||||||
_canvas.width = viewportWidth;
|
_canvas.width = viewportWidth;
|
||||||
_canvas.height = viewportHeight;
|
_canvas.height = viewportHeight;
|
||||||
_context.clearRect(0, 0, viewportWidth, viewportHeight);
|
_context.clearRect(0, 0, viewportWidth, viewportHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportBounds = this._viewport.getBounds(true);
|
var viewportBounds = this.viewport.getBounds(true);
|
||||||
var viewportTL = viewportBounds.getTopLeft();
|
var viewportTL = viewportBounds.getTopLeft();
|
||||||
var viewportBR = viewportBounds.getBottomRight();
|
var viewportBR = viewportBounds.getBottomRight();
|
||||||
if (!this.config.wrapHorizontal &&
|
if (!this.config.wrapHorizontal &&
|
||||||
(viewportBR.x < 0 || viewportTL.x > 1)) {
|
(viewportBR.x < 0 || viewportTL.x > 1)) {
|
||||||
return;
|
return;
|
||||||
} else if (!this.config.wrapVertical &&
|
} else if (!this.config.wrapVertical &&
|
||||||
(viewportBR.y < 0 || viewportTL.y > this._normHeight)) {
|
(viewportBR.y < 0 || viewportTL.y > this.normHeight)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3719,28 +3746,28 @@ $.Drawer.prototype = {
|
|||||||
}
|
}
|
||||||
if (!wrapVertical) {
|
if (!wrapVertical) {
|
||||||
viewportTL.y = _max(viewportTL.y, 0);
|
viewportTL.y = _max(viewportTL.y, 0);
|
||||||
viewportBR.y = _min(viewportBR.y, this._normHeight);
|
viewportBR.y = _min(viewportBR.y, this.normHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
var best = null;
|
var best = null;
|
||||||
var haveDrawn = false;
|
var haveDrawn = false;
|
||||||
var currentTime = new Date().getTime();
|
var currentTime = new Date().getTime();
|
||||||
|
|
||||||
var viewportCenter = this._viewport.pixelFromPoint(this._viewport.getCenter());
|
var viewportCenter = this.viewport.pixelFromPoint(this.viewport.getCenter());
|
||||||
var zeroRatioT = this._viewport.deltaPixelsFromPoints(this._source.getPixelRatio(0), false).x;
|
var zeroRatioT = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), false).x;
|
||||||
var optimalPixelRatio = immediateRender ? 1 : zeroRatioT;
|
var optimalPixelRatio = immediateRender ? 1 : zeroRatioT;
|
||||||
|
|
||||||
var lowestLevel = _max(this._minLevel, _floor(_log(this.config.minZoomImageRatio) / _log(2)));
|
var lowestLevel = _max(this.minLevel, _floor(_log(this.config.minZoomImageRatio) / _log(2)));
|
||||||
var zeroRatioC = this._viewport.deltaPixelsFromPoints(this._source.getPixelRatio(0), true).x;
|
var zeroRatioC = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), true).x;
|
||||||
var highestLevel = _min(this._maxLevel,
|
var highestLevel = _min(this.maxLevel,
|
||||||
_floor(_log(zeroRatioC / MIN_PIXEL_RATIO) / _log(2)));
|
_floor(_log(zeroRatioC / MIN_PIXEL_RATIO) / _log(2)));
|
||||||
|
|
||||||
lowestLevel = _min(lowestLevel, highestLevel);
|
lowestLevel = _min(lowestLevel, highestLevel);
|
||||||
|
|
||||||
for (var level = highestLevel; level >= lowestLevel; level--) {
|
for (var level = highestLevel; level >= lowestLevel; level--) {
|
||||||
var drawLevel = false;
|
var drawLevel = false;
|
||||||
var renderPixelRatioC = this._viewport.deltaPixelsFromPoints(
|
var renderPixelRatioC = this.viewport.deltaPixelsFromPoints(
|
||||||
this._source.getPixelRatio(level), true).x; // note the .x!
|
this.source.getPixelRatio(level), true).x; // note the .x!
|
||||||
|
|
||||||
if ((!haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO) ||
|
if ((!haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO) ||
|
||||||
level == lowestLevel) {
|
level == lowestLevel) {
|
||||||
@ -3753,13 +3780,13 @@ $.Drawer.prototype = {
|
|||||||
this._resetCoverage(level);
|
this._resetCoverage(level);
|
||||||
|
|
||||||
var levelOpacity = _min(1, (renderPixelRatioC - 0.5) / 0.5);
|
var levelOpacity = _min(1, (renderPixelRatioC - 0.5) / 0.5);
|
||||||
var renderPixelRatioT = this._viewport.deltaPixelsFromPoints(
|
var renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
||||||
this._source.getPixelRatio(level), false).x;
|
this.source.getPixelRatio(level), false).x;
|
||||||
var levelVisibility = optimalPixelRatio /
|
var levelVisibility = optimalPixelRatio /
|
||||||
_abs(optimalPixelRatio - renderPixelRatioT);
|
_abs(optimalPixelRatio - renderPixelRatioT);
|
||||||
|
|
||||||
var tileTL = this._source.getTileAtPoint(level, viewportTL);
|
var tileTL = this.source.getTileAtPoint(level, viewportTL);
|
||||||
var tileBR = this._source.getTileAtPoint(level, viewportBR);
|
var tileBR = this.source.getTileAtPoint(level, viewportBR);
|
||||||
var numTiles = this._getNumTiles(level);
|
var numTiles = this._getNumTiles(level);
|
||||||
var numTilesX = numTiles.x;
|
var numTilesX = numTiles.x;
|
||||||
var numTilesY = numTiles.y;
|
var numTilesY = numTiles.y;
|
||||||
@ -3795,15 +3822,15 @@ $.Drawer.prototype = {
|
|||||||
|
|
||||||
var boundsTL = tile.bounds.getTopLeft();
|
var boundsTL = tile.bounds.getTopLeft();
|
||||||
var boundsSize = tile.bounds.getSize();
|
var boundsSize = tile.bounds.getSize();
|
||||||
var positionC = this._viewport.pixelFromPoint(boundsTL, true);
|
var positionC = this.viewport.pixelFromPoint(boundsTL, true);
|
||||||
var sizeC = this._viewport.deltaPixelsFromPoints(boundsSize, true);
|
var sizeC = this.viewport.deltaPixelsFromPoints(boundsSize, true);
|
||||||
|
|
||||||
if (!this._tileOverlap) {
|
if (!this.tileOverlap) {
|
||||||
sizeC = sizeC.plus(new $.Point(1, 1));
|
sizeC = sizeC.plus(new $.Point(1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
var positionT = this._viewport.pixelFromPoint(boundsTL, false);
|
var positionT = this.viewport.pixelFromPoint(boundsTL, false);
|
||||||
var sizeT = this._viewport.deltaPixelsFromPoints(boundsSize, false);
|
var sizeT = this.viewport.deltaPixelsFromPoints(boundsSize, false);
|
||||||
var tileCenter = positionT.plus(sizeT.divide(2));
|
var tileCenter = positionT.plus(sizeT.divide(2));
|
||||||
var tileDistance = viewportCenter.distanceTo(tileCenter);
|
var tileDistance = viewportCenter.distanceTo(tileCenter);
|
||||||
|
|
||||||
@ -3848,7 +3875,7 @@ $.Drawer.prototype = {
|
|||||||
for (var i = _lastDrawn.length - 1; i >= 0; i--) {
|
for (var i = _lastDrawn.length - 1; i >= 0; i--) {
|
||||||
var tile = _lastDrawn[i];
|
var tile = _lastDrawn[i];
|
||||||
|
|
||||||
if (_useCanvas) {
|
if ( USE_CANVAS ) {
|
||||||
tile.drawCanvas(_context);
|
tile.drawCanvas(_context);
|
||||||
} else {
|
} else {
|
||||||
tile.drawHTML(_canvas);
|
tile.drawHTML(_canvas);
|
||||||
@ -3857,19 +3884,19 @@ $.Drawer.prototype = {
|
|||||||
tile.beingDrawn = true;
|
tile.beingDrawn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var numOverlays = this._overlays.length;
|
var numOverlays = this.overlays.length;
|
||||||
for (var i = 0; i < numOverlays; i++) {
|
for (var i = 0; i < numOverlays; i++) {
|
||||||
var overlay = this._overlays[i];
|
var overlay = this.overlays[i];
|
||||||
var bounds = overlay.bounds;
|
var bounds = overlay.bounds;
|
||||||
|
|
||||||
overlay.position = this._viewport.pixelFromPoint(bounds.getTopLeft(), true);
|
overlay.position = this.viewport.pixelFromPoint(bounds.getTopLeft(), true);
|
||||||
overlay.size = this._viewport.deltaPixelsFromPoints(bounds.getSize(), true);
|
overlay.size = this.viewport.deltaPixelsFromPoints(bounds.getSize(), true);
|
||||||
overlay.drawHTML(_container);
|
overlay.drawHTML(_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best) {
|
if (best) {
|
||||||
this._loadTile(best, currentTime);
|
this._loadTile(best, currentTime);
|
||||||
this._updateAgain = true; // because we haven't finished drawing, so
|
this.updateAgain = true; // because we haven't finished drawing, so
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -3881,8 +3908,8 @@ $.Drawer.prototype = {
|
|||||||
return; // they're trying to add a duplicate overlay
|
return; // they're trying to add a duplicate overlay
|
||||||
}
|
}
|
||||||
|
|
||||||
this._overlays.push(new $.Overlay(elmt, loc, placement));
|
this.overlays.push(new $.Overlay(elmt, loc, placement));
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateOverlay: function(elmt, loc, placement) {
|
updateOverlay: function(elmt, loc, placement) {
|
||||||
@ -3890,8 +3917,8 @@ $.Drawer.prototype = {
|
|||||||
var i = this._getOverlayIndex(elmt);
|
var i = this._getOverlayIndex(elmt);
|
||||||
|
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
this._overlays[i].update(loc, placement);
|
this.overlays[i].update(loc, placement);
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -3900,40 +3927,40 @@ $.Drawer.prototype = {
|
|||||||
var i = this._getOverlayIndex(elmt);
|
var i = this._getOverlayIndex(elmt);
|
||||||
|
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
this._overlays[i].destroy();
|
this.overlays[i].destroy();
|
||||||
this._overlays.splice(i, 1);
|
this.overlays.splice(i, 1);
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clearOverlays: function() {
|
clearOverlays: function() {
|
||||||
while (this._overlays.length > 0) {
|
while (this.overlays.length > 0) {
|
||||||
this._overlays.pop().destroy();
|
this.overlays.pop().destroy();
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
needsUpdate: function() {
|
needsUpdate: function() {
|
||||||
return this._updateAgain;
|
return this.updateAgain;
|
||||||
},
|
},
|
||||||
|
|
||||||
numTilesLoaded: function() {
|
numTilesLoaded: function() {
|
||||||
return this._tilesLoaded.length;
|
return this.tilesLoaded.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
this._clearTiles();
|
this._clearTiles();
|
||||||
this._lastResetTime = new Date().getTime();
|
this.lastResetTime = new Date().getTime();
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function() {
|
update: function() {
|
||||||
//this._profiler.beginUpdate();
|
//this.profiler.beginUpdate();
|
||||||
this._midUpdate = true;
|
this.midUpdate = true;
|
||||||
this._updateActual();
|
this._updateActual();
|
||||||
this._midUpdate = false;
|
this.midUpdate = false;
|
||||||
//this._profiler.endUpdate();
|
//this.profiler.endUpdate();
|
||||||
},
|
},
|
||||||
|
|
||||||
loadImage: function(src, callback) {
|
loadImage: function(src, callback) {
|
||||||
|
292
src/drawer.js
292
src/drawer.js
@ -1,66 +1,75 @@
|
|||||||
|
|
||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
var QUOTA = 100; // the max number of images we should keep in memory
|
var // the max number of images we should keep in memory
|
||||||
var MIN_PIXEL_RATIO = 0.5; // the most shrunk a tile should be
|
QUOTA = 100,
|
||||||
|
// the most shrunk a tile should be
|
||||||
|
MIN_PIXEL_RATIO = 0.5,
|
||||||
|
//TODO: make TIMEOUT configurable
|
||||||
|
TIMEOUT = 5000,
|
||||||
|
|
||||||
//TODO: make TIMEOUT configurable
|
BROWSER = $.Utils.getBrowser(),
|
||||||
var TIMEOUT = 5000;
|
BROWSER_VERSION = $.Utils.getBrowserVersion(),
|
||||||
|
|
||||||
var browser = $.Utils.getBrowser();
|
SUBPIXEL_RENDERING = (
|
||||||
var browserVer = $.Utils.getBrowserVersion();
|
( BROWSER == $.Browser.FIREFOX ) ||
|
||||||
|
( BROWSER == $.Browser.OPERA ) ||
|
||||||
|
( BROWSER == $.Browser.SAFARI && BROWSER_VERSION >= 4 ) ||
|
||||||
|
( BROWSER == $.Browser.CHROME && BROWSER_VERSION >= 2 )
|
||||||
|
),
|
||||||
|
|
||||||
var subpixelRenders = browser == $.Browser.FIREFOX ||
|
USE_CANVAS =
|
||||||
browser == $.Browser.OPERA ||
|
$.isFunction( document.createElement("canvas").getContext ) &&
|
||||||
(browser == $.Browser.SAFARI && browserVer >= 4) ||
|
SUBPIXEL_RENDERING;
|
||||||
(browser == $.Browser.CHROME && browserVer >= 2);
|
|
||||||
|
|
||||||
var useCanvas =
|
|
||||||
typeof (document.createElement("canvas").getContext) == "function" &&
|
|
||||||
subpixelRenders;
|
|
||||||
|
|
||||||
$.Drawer = function(source, viewport, elmt) {
|
$.Drawer = function(source, viewport, elmt) {
|
||||||
|
|
||||||
this._container = $.Utils.getElement(elmt);
|
this.container = $.Utils.getElement(elmt);
|
||||||
this._canvas = $.Utils.makeNeutralElement(useCanvas ? "canvas" : "div");
|
this.canvas = $.Utils.makeNeutralElement(USE_CANVAS ? "canvas" : "div");
|
||||||
this._context = useCanvas ? this._canvas.getContext("2d") : null;
|
this.context = USE_CANVAS ? this.canvas.getContext("2d") : null;
|
||||||
this._viewport = viewport;
|
this.viewport = viewport;
|
||||||
this._source = source;
|
this.source = source;
|
||||||
this.config = this._viewport.config;
|
this.config = this.viewport.config;
|
||||||
|
|
||||||
this.downloading = 0;
|
this.downloading = 0;
|
||||||
this.imageLoaderLimit = this.config.imageLoaderLimit;
|
this.imageLoaderLimit = this.config.imageLoaderLimit;
|
||||||
|
|
||||||
this._profiler = new $.Profiler();
|
|
||||||
|
|
||||||
this._minLevel = source.minLevel;
|
|
||||||
this._maxLevel = source.maxLevel;
|
|
||||||
this._tileSize = source.tileSize;
|
|
||||||
this._tileOverlap = source.tileOverlap;
|
|
||||||
this._normHeight = source.dimensions.y / source.dimensions.x;
|
|
||||||
|
|
||||||
this._cacheNumTiles = {}; // 1d dictionary [level] --> Point
|
|
||||||
this._cachePixelRatios = {}; // 1d dictionary [level] --> Point
|
|
||||||
this._tilesMatrix = {}; // 3d dictionary [level][x][y] --> Tile
|
|
||||||
this._tilesLoaded = []; // unordered list of Tiles with loaded images
|
|
||||||
this._coverage = {}; // 3d dictionary [level][x][y] --> Boolean
|
|
||||||
|
|
||||||
this._overlays = []; // unordered list of Overlays added
|
|
||||||
this._lastDrawn = []; // unordered list of Tiles drawn last frame
|
|
||||||
this._lastResetTime = 0;
|
|
||||||
this._midUpdate = false;
|
|
||||||
this._updateAgain = true;
|
|
||||||
|
|
||||||
|
|
||||||
this.elmt = this._container;
|
|
||||||
|
|
||||||
|
this.profiler = new $.Profiler();
|
||||||
|
|
||||||
|
this.minLevel = source.minLevel;
|
||||||
|
this.maxLevel = source.maxLevel;
|
||||||
|
this.tileSize = source.tileSize;
|
||||||
|
this.tileOverlap = source.tileOverlap;
|
||||||
|
this.normHeight = source.dimensions.y / source.dimensions.x;
|
||||||
|
|
||||||
this._canvas.style.width = "100%";
|
// 1d dictionary [level] --> Point
|
||||||
this._canvas.style.height = "100%";
|
this.cacheNumTiles = {};
|
||||||
this._canvas.style.position = "absolute";
|
// 1d dictionary [level] --> Point
|
||||||
this._container.style.textAlign = "left"; // explicit left-align
|
this.cachePixelRatios = {};
|
||||||
this._container.appendChild(this._canvas);
|
// 3d dictionary [level][x][y] --> Tile
|
||||||
|
this.tilesMatrix = {};
|
||||||
|
// unordered list of Tiles with loaded images
|
||||||
|
this.tilesLoaded = [];
|
||||||
|
// 3d dictionary [level][x][y] --> Boolean
|
||||||
|
this.coverage = {};
|
||||||
|
|
||||||
|
// unordered list of Overlays added
|
||||||
|
this.overlays = [];
|
||||||
|
// unordered list of Tiles drawn last frame
|
||||||
|
this.lastDrawn = [];
|
||||||
|
this.lastResetTime = 0;
|
||||||
|
this.midUpdate = false;
|
||||||
|
this.updateAgain = true;
|
||||||
|
|
||||||
|
this.elmt = this.container;
|
||||||
|
|
||||||
|
this.canvas.style.width = "100%";
|
||||||
|
this.canvas.style.height = "100%";
|
||||||
|
this.canvas.style.position = "absolute";
|
||||||
|
|
||||||
|
// explicit left-align
|
||||||
|
this.container.style.textAlign = "left";
|
||||||
|
this.container.appendChild(this.canvas);
|
||||||
};
|
};
|
||||||
|
|
||||||
$.Drawer.prototype = {
|
$.Drawer.prototype = {
|
||||||
@ -81,44 +90,44 @@ $.Drawer.prototype = {
|
|||||||
return prevBest;
|
return prevBest;
|
||||||
},
|
},
|
||||||
_getNumTiles: function(level) {
|
_getNumTiles: function(level) {
|
||||||
if (!this._cacheNumTiles[level]) {
|
if (!this.cacheNumTiles[level]) {
|
||||||
this._cacheNumTiles[level] = this._source.getNumTiles(level);
|
this.cacheNumTiles[level] = this.source.getNumTiles(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._cacheNumTiles[level];
|
return this.cacheNumTiles[level];
|
||||||
},
|
},
|
||||||
|
|
||||||
_getPixelRatio: function(level) {
|
_getPixelRatio: function(level) {
|
||||||
if (!this._cachePixelRatios[level]) {
|
if (!this.cachePixelRatios[level]) {
|
||||||
this._cachePixelRatios[level] = this._source.getPixelRatio(level);
|
this.cachePixelRatios[level] = this.source.getPixelRatio(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this._cachePixelRatios[level];
|
return this.cachePixelRatios[level];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_getTile: function(level, x, y, time, numTilesX, numTilesY) {
|
_getTile: function(level, x, y, time, numTilesX, numTilesY) {
|
||||||
if (!this._tilesMatrix[level]) {
|
if (!this.tilesMatrix[level]) {
|
||||||
this._tilesMatrix[level] = {};
|
this.tilesMatrix[level] = {};
|
||||||
}
|
}
|
||||||
if (!this._tilesMatrix[level][x]) {
|
if (!this.tilesMatrix[level][x]) {
|
||||||
this._tilesMatrix[level][x] = {};
|
this.tilesMatrix[level][x] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._tilesMatrix[level][x][y]) {
|
if (!this.tilesMatrix[level][x][y]) {
|
||||||
var xMod = (numTilesX + (x % numTilesX)) % numTilesX;
|
var xMod = (numTilesX + (x % numTilesX)) % numTilesX;
|
||||||
var yMod = (numTilesY + (y % numTilesY)) % numTilesY;
|
var yMod = (numTilesY + (y % numTilesY)) % numTilesY;
|
||||||
var bounds = this._source.getTileBounds(level, xMod, yMod);
|
var bounds = this.source.getTileBounds(level, xMod, yMod);
|
||||||
var exists = this._source.tileExists(level, xMod, yMod);
|
var exists = this.source.tileExists(level, xMod, yMod);
|
||||||
var url = this._source.getTileUrl(level, xMod, yMod);
|
var url = this.source.getTileUrl(level, xMod, yMod);
|
||||||
|
|
||||||
bounds.x += 1.0 * (x - xMod) / numTilesX;
|
bounds.x += 1.0 * (x - xMod) / numTilesX;
|
||||||
bounds.y += this._normHeight * (y - yMod) / numTilesY;
|
bounds.y += this.normHeight * (y - yMod) / numTilesY;
|
||||||
|
|
||||||
this._tilesMatrix[level][x][y] = new $.Tile(level, x, y, bounds, exists, url);
|
this.tilesMatrix[level][x][y] = new $.Tile(level, x, y, bounds, exists, url);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tile = this._tilesMatrix[level][x][y];
|
var tile = this.tilesMatrix[level][x][y];
|
||||||
|
|
||||||
tile.lastTouchTime = time;
|
tile.lastTouchTime = time;
|
||||||
|
|
||||||
@ -140,14 +149,14 @@ $.Drawer.prototype = {
|
|||||||
_onTileLoad: function(tile, time, image) {
|
_onTileLoad: function(tile, time, image) {
|
||||||
tile.loading = false;
|
tile.loading = false;
|
||||||
|
|
||||||
if (this._midUpdate) {
|
if (this.midUpdate) {
|
||||||
$.Debug.error("Tile load callback in middle of drawing routine.");
|
$.Debug.error("Tile load callback in middle of drawing routine.");
|
||||||
return;
|
return;
|
||||||
} else if (!image) {
|
} else if (!image) {
|
||||||
$.Debug.log("Tile " + tile + " failed to load: " + tile.url);
|
$.Debug.log("Tile " + tile + " failed to load: " + tile.url);
|
||||||
tile.exists = false;
|
tile.exists = false;
|
||||||
return;
|
return;
|
||||||
} else if (time < this._lastResetTime) {
|
} else if (time < this.lastResetTime) {
|
||||||
$.Debug.log("Ignoring tile " + tile + " loaded before reset: " + tile.url);
|
$.Debug.log("Ignoring tile " + tile + " loaded before reset: " + tile.url);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -155,18 +164,18 @@ $.Drawer.prototype = {
|
|||||||
tile.loaded = true;
|
tile.loaded = true;
|
||||||
tile.image = image;
|
tile.image = image;
|
||||||
|
|
||||||
var insertionIndex = this._tilesLoaded.length;
|
var insertionIndex = this.tilesLoaded.length;
|
||||||
|
|
||||||
if (this._tilesLoaded.length >= QUOTA) {
|
if (this.tilesLoaded.length >= QUOTA) {
|
||||||
var cutoff = Math.ceil(Math.log(this._tileSize) / Math.log(2));
|
var cutoff = Math.ceil(Math.log(this.tileSize) / Math.log(2));
|
||||||
|
|
||||||
var worstTile = null;
|
var worstTile = null;
|
||||||
var worstTileIndex = -1;
|
var worstTileIndex = -1;
|
||||||
|
|
||||||
for (var i = this._tilesLoaded.length - 1; i >= 0; i--) {
|
for (var i = this.tilesLoaded.length - 1; i >= 0; i--) {
|
||||||
var prevTile = this._tilesLoaded[i];
|
var prevTile = this.tilesLoaded[i];
|
||||||
|
|
||||||
if (prevTile.level <= this._cutoff || prevTile.beingDrawn) {
|
if (prevTile.level <= this.cutoff || prevTile.beingDrawn) {
|
||||||
continue;
|
continue;
|
||||||
} else if (!worstTile) {
|
} else if (!worstTile) {
|
||||||
worstTile = prevTile;
|
worstTile = prevTile;
|
||||||
@ -192,13 +201,13 @@ $.Drawer.prototype = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._tilesLoaded[insertionIndex] = tile;
|
this.tilesLoaded[insertionIndex] = tile;
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
_clearTiles: function() {
|
_clearTiles: function() {
|
||||||
this._tilesMatrix = {};
|
this.tilesMatrix = {};
|
||||||
this._tilesLoaded = [];
|
this.tilesLoaded = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -213,12 +222,12 @@ $.Drawer.prototype = {
|
|||||||
* levels that are within the image bounds, however, do not.
|
* levels that are within the image bounds, however, do not.
|
||||||
*/
|
*/
|
||||||
_providesCoverage: function(level, x, y) {
|
_providesCoverage: function(level, x, y) {
|
||||||
if (!this._coverage[level]) {
|
if (!this.coverage[level]) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x === undefined || y === undefined) {
|
if (x === undefined || y === undefined) {
|
||||||
var rows = this._coverage[level];
|
var rows = this.coverage[level];
|
||||||
for (var i in rows) {
|
for (var i in rows) {
|
||||||
if (rows.hasOwnProperty(i)) {
|
if (rows.hasOwnProperty(i)) {
|
||||||
var cols = rows[i];
|
var cols = rows[i];
|
||||||
@ -233,9 +242,9 @@ $.Drawer.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (this._coverage[level][x] === undefined ||
|
return (this.coverage[level][x] === undefined ||
|
||||||
this._coverage[level][x][y] === undefined ||
|
this.coverage[level][x][y] === undefined ||
|
||||||
this._coverage[level][x][y] === true);
|
this.coverage[level][x][y] === true);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -258,17 +267,17 @@ $.Drawer.prototype = {
|
|||||||
* Sets whether the given tile provides coverage or not.
|
* Sets whether the given tile provides coverage or not.
|
||||||
*/
|
*/
|
||||||
_setCoverage: function(level, x, y, covers) {
|
_setCoverage: function(level, x, y, covers) {
|
||||||
if (!this._coverage[level]) {
|
if (!this.coverage[level]) {
|
||||||
$.Debug.error("Setting coverage for a tile before its " +
|
$.Debug.error("Setting coverage for a tile before its " +
|
||||||
"level's coverage has been reset: " + level);
|
"level's coverage has been reset: " + level);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this._coverage[level][x]) {
|
if (!this.coverage[level][x]) {
|
||||||
this._coverage[level][x] = {};
|
this.coverage[level][x] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
this._coverage[level][x][y] = covers;
|
this.coverage[level][x][y] = covers;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -277,7 +286,7 @@ $.Drawer.prototype = {
|
|||||||
* routine, coverage for every visible tile should be explicitly set.
|
* routine, coverage for every visible tile should be explicitly set.
|
||||||
*/
|
*/
|
||||||
_resetCoverage: function(level) {
|
_resetCoverage: function(level) {
|
||||||
this._coverage[level] = {};
|
this.coverage[level] = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
@ -299,8 +308,8 @@ $.Drawer.prototype = {
|
|||||||
|
|
||||||
|
|
||||||
_getOverlayIndex: function(elmt) {
|
_getOverlayIndex: function(elmt) {
|
||||||
for (var i = this._overlays.length - 1; i >= 0; i--) {
|
for (var i = this.overlays.length - 1; i >= 0; i--) {
|
||||||
if (this._overlays[i].elmt == elmt) {
|
if (this.overlays[i].elmt == elmt) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,38 +319,37 @@ $.Drawer.prototype = {
|
|||||||
|
|
||||||
|
|
||||||
_updateActual: function() {
|
_updateActual: function() {
|
||||||
this._updateAgain = false;
|
this.updateAgain = false;
|
||||||
|
|
||||||
var _canvas = this._canvas;
|
var _canvas = this.canvas;
|
||||||
var _context = this._context;
|
var _context = this.context;
|
||||||
var _container = this._container;
|
var _container = this.container;
|
||||||
var _useCanvas = useCanvas;
|
var _lastDrawn = this.lastDrawn;
|
||||||
var _lastDrawn = this._lastDrawn;
|
|
||||||
|
|
||||||
while (_lastDrawn.length > 0) {
|
while (_lastDrawn.length > 0) {
|
||||||
var tile = _lastDrawn.pop();
|
var tile = _lastDrawn.pop();
|
||||||
tile.beingDrawn = false;
|
tile.beingDrawn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportSize = this._viewport.getContainerSize();
|
var viewportSize = this.viewport.getContainerSize();
|
||||||
var viewportWidth = viewportSize.x;
|
var viewportWidth = viewportSize.x;
|
||||||
var viewportHeight = viewportSize.y;
|
var viewportHeight = viewportSize.y;
|
||||||
|
|
||||||
_canvas.innerHTML = "";
|
_canvas.innerHTML = "";
|
||||||
if (_useCanvas) {
|
if ( USE_CANVAS ) {
|
||||||
_canvas.width = viewportWidth;
|
_canvas.width = viewportWidth;
|
||||||
_canvas.height = viewportHeight;
|
_canvas.height = viewportHeight;
|
||||||
_context.clearRect(0, 0, viewportWidth, viewportHeight);
|
_context.clearRect(0, 0, viewportWidth, viewportHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportBounds = this._viewport.getBounds(true);
|
var viewportBounds = this.viewport.getBounds(true);
|
||||||
var viewportTL = viewportBounds.getTopLeft();
|
var viewportTL = viewportBounds.getTopLeft();
|
||||||
var viewportBR = viewportBounds.getBottomRight();
|
var viewportBR = viewportBounds.getBottomRight();
|
||||||
if (!this.config.wrapHorizontal &&
|
if (!this.config.wrapHorizontal &&
|
||||||
(viewportBR.x < 0 || viewportTL.x > 1)) {
|
(viewportBR.x < 0 || viewportTL.x > 1)) {
|
||||||
return;
|
return;
|
||||||
} else if (!this.config.wrapVertical &&
|
} else if (!this.config.wrapVertical &&
|
||||||
(viewportBR.y < 0 || viewportTL.y > this._normHeight)) {
|
(viewportBR.y < 0 || viewportTL.y > this.normHeight)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,28 +374,28 @@ $.Drawer.prototype = {
|
|||||||
}
|
}
|
||||||
if (!wrapVertical) {
|
if (!wrapVertical) {
|
||||||
viewportTL.y = _max(viewportTL.y, 0);
|
viewportTL.y = _max(viewportTL.y, 0);
|
||||||
viewportBR.y = _min(viewportBR.y, this._normHeight);
|
viewportBR.y = _min(viewportBR.y, this.normHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
var best = null;
|
var best = null;
|
||||||
var haveDrawn = false;
|
var haveDrawn = false;
|
||||||
var currentTime = new Date().getTime();
|
var currentTime = new Date().getTime();
|
||||||
|
|
||||||
var viewportCenter = this._viewport.pixelFromPoint(this._viewport.getCenter());
|
var viewportCenter = this.viewport.pixelFromPoint(this.viewport.getCenter());
|
||||||
var zeroRatioT = this._viewport.deltaPixelsFromPoints(this._source.getPixelRatio(0), false).x;
|
var zeroRatioT = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), false).x;
|
||||||
var optimalPixelRatio = immediateRender ? 1 : zeroRatioT;
|
var optimalPixelRatio = immediateRender ? 1 : zeroRatioT;
|
||||||
|
|
||||||
var lowestLevel = _max(this._minLevel, _floor(_log(this.config.minZoomImageRatio) / _log(2)));
|
var lowestLevel = _max(this.minLevel, _floor(_log(this.config.minZoomImageRatio) / _log(2)));
|
||||||
var zeroRatioC = this._viewport.deltaPixelsFromPoints(this._source.getPixelRatio(0), true).x;
|
var zeroRatioC = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), true).x;
|
||||||
var highestLevel = _min(this._maxLevel,
|
var highestLevel = _min(this.maxLevel,
|
||||||
_floor(_log(zeroRatioC / MIN_PIXEL_RATIO) / _log(2)));
|
_floor(_log(zeroRatioC / MIN_PIXEL_RATIO) / _log(2)));
|
||||||
|
|
||||||
lowestLevel = _min(lowestLevel, highestLevel);
|
lowestLevel = _min(lowestLevel, highestLevel);
|
||||||
|
|
||||||
for (var level = highestLevel; level >= lowestLevel; level--) {
|
for (var level = highestLevel; level >= lowestLevel; level--) {
|
||||||
var drawLevel = false;
|
var drawLevel = false;
|
||||||
var renderPixelRatioC = this._viewport.deltaPixelsFromPoints(
|
var renderPixelRatioC = this.viewport.deltaPixelsFromPoints(
|
||||||
this._source.getPixelRatio(level), true).x; // note the .x!
|
this.source.getPixelRatio(level), true).x; // note the .x!
|
||||||
|
|
||||||
if ((!haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO) ||
|
if ((!haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO) ||
|
||||||
level == lowestLevel) {
|
level == lowestLevel) {
|
||||||
@ -400,13 +408,13 @@ $.Drawer.prototype = {
|
|||||||
this._resetCoverage(level);
|
this._resetCoverage(level);
|
||||||
|
|
||||||
var levelOpacity = _min(1, (renderPixelRatioC - 0.5) / 0.5);
|
var levelOpacity = _min(1, (renderPixelRatioC - 0.5) / 0.5);
|
||||||
var renderPixelRatioT = this._viewport.deltaPixelsFromPoints(
|
var renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
||||||
this._source.getPixelRatio(level), false).x;
|
this.source.getPixelRatio(level), false).x;
|
||||||
var levelVisibility = optimalPixelRatio /
|
var levelVisibility = optimalPixelRatio /
|
||||||
_abs(optimalPixelRatio - renderPixelRatioT);
|
_abs(optimalPixelRatio - renderPixelRatioT);
|
||||||
|
|
||||||
var tileTL = this._source.getTileAtPoint(level, viewportTL);
|
var tileTL = this.source.getTileAtPoint(level, viewportTL);
|
||||||
var tileBR = this._source.getTileAtPoint(level, viewportBR);
|
var tileBR = this.source.getTileAtPoint(level, viewportBR);
|
||||||
var numTiles = this._getNumTiles(level);
|
var numTiles = this._getNumTiles(level);
|
||||||
var numTilesX = numTiles.x;
|
var numTilesX = numTiles.x;
|
||||||
var numTilesY = numTiles.y;
|
var numTilesY = numTiles.y;
|
||||||
@ -442,15 +450,15 @@ $.Drawer.prototype = {
|
|||||||
|
|
||||||
var boundsTL = tile.bounds.getTopLeft();
|
var boundsTL = tile.bounds.getTopLeft();
|
||||||
var boundsSize = tile.bounds.getSize();
|
var boundsSize = tile.bounds.getSize();
|
||||||
var positionC = this._viewport.pixelFromPoint(boundsTL, true);
|
var positionC = this.viewport.pixelFromPoint(boundsTL, true);
|
||||||
var sizeC = this._viewport.deltaPixelsFromPoints(boundsSize, true);
|
var sizeC = this.viewport.deltaPixelsFromPoints(boundsSize, true);
|
||||||
|
|
||||||
if (!this._tileOverlap) {
|
if (!this.tileOverlap) {
|
||||||
sizeC = sizeC.plus(new $.Point(1, 1));
|
sizeC = sizeC.plus(new $.Point(1, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
var positionT = this._viewport.pixelFromPoint(boundsTL, false);
|
var positionT = this.viewport.pixelFromPoint(boundsTL, false);
|
||||||
var sizeT = this._viewport.deltaPixelsFromPoints(boundsSize, false);
|
var sizeT = this.viewport.deltaPixelsFromPoints(boundsSize, false);
|
||||||
var tileCenter = positionT.plus(sizeT.divide(2));
|
var tileCenter = positionT.plus(sizeT.divide(2));
|
||||||
var tileDistance = viewportCenter.distanceTo(tileCenter);
|
var tileDistance = viewportCenter.distanceTo(tileCenter);
|
||||||
|
|
||||||
@ -495,7 +503,7 @@ $.Drawer.prototype = {
|
|||||||
for (var i = _lastDrawn.length - 1; i >= 0; i--) {
|
for (var i = _lastDrawn.length - 1; i >= 0; i--) {
|
||||||
var tile = _lastDrawn[i];
|
var tile = _lastDrawn[i];
|
||||||
|
|
||||||
if (_useCanvas) {
|
if ( USE_CANVAS ) {
|
||||||
tile.drawCanvas(_context);
|
tile.drawCanvas(_context);
|
||||||
} else {
|
} else {
|
||||||
tile.drawHTML(_canvas);
|
tile.drawHTML(_canvas);
|
||||||
@ -504,19 +512,19 @@ $.Drawer.prototype = {
|
|||||||
tile.beingDrawn = true;
|
tile.beingDrawn = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
var numOverlays = this._overlays.length;
|
var numOverlays = this.overlays.length;
|
||||||
for (var i = 0; i < numOverlays; i++) {
|
for (var i = 0; i < numOverlays; i++) {
|
||||||
var overlay = this._overlays[i];
|
var overlay = this.overlays[i];
|
||||||
var bounds = overlay.bounds;
|
var bounds = overlay.bounds;
|
||||||
|
|
||||||
overlay.position = this._viewport.pixelFromPoint(bounds.getTopLeft(), true);
|
overlay.position = this.viewport.pixelFromPoint(bounds.getTopLeft(), true);
|
||||||
overlay.size = this._viewport.deltaPixelsFromPoints(bounds.getSize(), true);
|
overlay.size = this.viewport.deltaPixelsFromPoints(bounds.getSize(), true);
|
||||||
overlay.drawHTML(_container);
|
overlay.drawHTML(_container);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (best) {
|
if (best) {
|
||||||
this._loadTile(best, currentTime);
|
this._loadTile(best, currentTime);
|
||||||
this._updateAgain = true; // because we haven't finished drawing, so
|
this.updateAgain = true; // because we haven't finished drawing, so
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -528,8 +536,8 @@ $.Drawer.prototype = {
|
|||||||
return; // they're trying to add a duplicate overlay
|
return; // they're trying to add a duplicate overlay
|
||||||
}
|
}
|
||||||
|
|
||||||
this._overlays.push(new $.Overlay(elmt, loc, placement));
|
this.overlays.push(new $.Overlay(elmt, loc, placement));
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateOverlay: function(elmt, loc, placement) {
|
updateOverlay: function(elmt, loc, placement) {
|
||||||
@ -537,8 +545,8 @@ $.Drawer.prototype = {
|
|||||||
var i = this._getOverlayIndex(elmt);
|
var i = this._getOverlayIndex(elmt);
|
||||||
|
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
this._overlays[i].update(loc, placement);
|
this.overlays[i].update(loc, placement);
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -547,40 +555,40 @@ $.Drawer.prototype = {
|
|||||||
var i = this._getOverlayIndex(elmt);
|
var i = this._getOverlayIndex(elmt);
|
||||||
|
|
||||||
if (i >= 0) {
|
if (i >= 0) {
|
||||||
this._overlays[i].destroy();
|
this.overlays[i].destroy();
|
||||||
this._overlays.splice(i, 1);
|
this.overlays.splice(i, 1);
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clearOverlays: function() {
|
clearOverlays: function() {
|
||||||
while (this._overlays.length > 0) {
|
while (this.overlays.length > 0) {
|
||||||
this._overlays.pop().destroy();
|
this.overlays.pop().destroy();
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
needsUpdate: function() {
|
needsUpdate: function() {
|
||||||
return this._updateAgain;
|
return this.updateAgain;
|
||||||
},
|
},
|
||||||
|
|
||||||
numTilesLoaded: function() {
|
numTilesLoaded: function() {
|
||||||
return this._tilesLoaded.length;
|
return this.tilesLoaded.length;
|
||||||
},
|
},
|
||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
this._clearTiles();
|
this._clearTiles();
|
||||||
this._lastResetTime = new Date().getTime();
|
this.lastResetTime = new Date().getTime();
|
||||||
this._updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
update: function() {
|
update: function() {
|
||||||
//this._profiler.beginUpdate();
|
//this.profiler.beginUpdate();
|
||||||
this._midUpdate = true;
|
this.midUpdate = true;
|
||||||
this._updateActual();
|
this._updateActual();
|
||||||
this._midUpdate = false;
|
this.midUpdate = false;
|
||||||
//this._profiler.endUpdate();
|
//this.profiler.endUpdate();
|
||||||
},
|
},
|
||||||
|
|
||||||
loadImage: function(src, callback) {
|
loadImage: function(src, callback) {
|
||||||
|
@ -1,62 +1,74 @@
|
|||||||
|
|
||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
|
//TODO: I guess this is where the i18n needs to be reimplemented. I'll look
|
||||||
|
// into existing patterns for i18n in javascript but i think that mimicking
|
||||||
|
// pythons gettext might be a reasonable approach.
|
||||||
|
|
||||||
$.Strings = {
|
$.Strings = {
|
||||||
|
|
||||||
Errors: {
|
Errors: {
|
||||||
Failure: "Sorry, but Seadragon Ajax can't run on your browser!\n" +
|
Failure: "Sorry, but Seadragon Ajax can't run on your browser!\n" +
|
||||||
"Please try using IE 7 or Firefox 3.\n",
|
"Please try using IE 7 or Firefox 3.\n",
|
||||||
Dzc: "Sorry, we don't support Deep Zoom Collections!",
|
Dzc: "Sorry, we don't support Deep Zoom Collections!",
|
||||||
Dzi: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
Dzi: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
||||||
Xml: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
Xml: "Hmm, this doesn't appear to be a valid Deep Zoom Image.",
|
||||||
Empty: "You asked us to open nothing, so we did just that.",
|
Empty: "You asked us to open nothing, so we did just that.",
|
||||||
ImageFormat: "Sorry, we don't support {0}-based Deep Zoom Images.",
|
ImageFormat: "Sorry, we don't support {0}-based Deep Zoom Images.",
|
||||||
Security: "It looks like a security restriction stopped us from " +
|
Security: "It looks like a security restriction stopped us from " +
|
||||||
"loading this Deep Zoom Image.",
|
"loading this Deep Zoom Image.",
|
||||||
Status: "This space unintentionally left blank ({0} {1}).",
|
Status: "This space unintentionally left blank ({0} {1}).",
|
||||||
Unknown: "Whoops, something inexplicably went wrong. Sorry!"
|
Unknown: "Whoops, something inexplicably went wrong. Sorry!"
|
||||||
},
|
},
|
||||||
|
|
||||||
Messages: {
|
Messages: {
|
||||||
Loading: "Loading..."
|
Loading: "Loading..."
|
||||||
},
|
},
|
||||||
|
|
||||||
Tooltips: {
|
Tooltips: {
|
||||||
FullPage: "Toggle full page",
|
FullPage: "Toggle full page",
|
||||||
Home: "Go home",
|
Home: "Go home",
|
||||||
ZoomIn: "Zoom in",
|
ZoomIn: "Zoom in",
|
||||||
ZoomOut: "Zoom out"
|
ZoomOut: "Zoom out"
|
||||||
},
|
},
|
||||||
getString: function(prop) {
|
|
||||||
var props = prop.split('.');
|
|
||||||
var string = $.Strings;
|
|
||||||
|
|
||||||
for (var i = 0; i < props.length; i++) {
|
getString: function( prop ) {
|
||||||
string = string[props[i]] || {}; // in case not a subproperty
|
|
||||||
|
var props = prop.split('.'),
|
||||||
|
string = $.Strings,
|
||||||
|
args = arguments,
|
||||||
|
i;
|
||||||
|
|
||||||
|
for ( i = 0; i < props.length; i++ ) {
|
||||||
|
string = string[ props[ i ] ] || {}; // in case not a subproperty
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof (string) != "string") {
|
if ( typeof( string ) != "string" ) {
|
||||||
string = "";
|
string = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
var args = arguments;
|
|
||||||
return string.replace(/\{\d+\}/g, function(capture) {
|
return string.replace(/\{\d+\}/g, function(capture) {
|
||||||
var i = parseInt(capture.match(/\d+/)) + 1;
|
var i = parseInt( capture.match( /\d+/ ) ) + 1;
|
||||||
return i < args.length ? args[i] : "";
|
return i < args.length ?
|
||||||
|
args[ i ] :
|
||||||
|
"";
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setString: function(prop, value) {
|
setString: function( prop, value ) {
|
||||||
var props = prop.split('.');
|
|
||||||
var container = $.Strings;
|
|
||||||
|
|
||||||
for (var i = 0; i < props.length - 1; i++) {
|
var props = prop.split('.'),
|
||||||
if (!container[props[i]]) {
|
container = $.Strings,
|
||||||
container[props[i]] = {};
|
i;
|
||||||
|
|
||||||
|
for ( i = 0; i < props.length - 1; i++ ) {
|
||||||
|
if ( !container[ props[ i ] ] ) {
|
||||||
|
container[ props[ i ] ] = {};
|
||||||
}
|
}
|
||||||
container = container[props[i]];
|
container = container[ props[ i ] ];
|
||||||
}
|
}
|
||||||
|
|
||||||
container[props[i]] = value;
|
container[ props[ i ] ] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
89
src/tile.js
89
src/tile.js
@ -2,31 +2,28 @@
|
|||||||
(function( $ ){
|
(function( $ ){
|
||||||
|
|
||||||
$.Tile = function(level, x, y, bounds, exists, url) {
|
$.Tile = function(level, x, y, bounds, exists, url) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.bounds = bounds; // where this tile fits, in normalized coordinates
|
this.bounds = bounds; // where this tile fits, in normalized coordinates
|
||||||
this.exists = exists; // part of sparse image? tile hasn't failed to load?
|
this.exists = exists; // part of sparse image? tile hasn't failed to load?
|
||||||
this.loaded = false; // is this tile loaded?
|
this.loaded = false; // is this tile loaded?
|
||||||
this.loading = false; // or is this tile loading?
|
this.loading = false; // or is this tile loading?
|
||||||
|
|
||||||
|
this.elmt = null; // the HTML element for this tile
|
||||||
|
this.image = null; // the Image object for this tile
|
||||||
|
this.url = url; // the URL of this tile's image
|
||||||
|
|
||||||
|
this.style = null; // alias of this.elmt.style
|
||||||
this.elmt = null; // the HTML element for this tile
|
this.position = null; // this tile's position on screen, in pixels
|
||||||
this.image = null; // the Image object for this tile
|
this.size = null; // this tile's size on screen, in pixels
|
||||||
this.url = url; // the URL of this tile's image
|
|
||||||
|
|
||||||
|
|
||||||
this.style = null; // alias of this.elmt.style
|
|
||||||
this.position = null; // this tile's position on screen, in pixels
|
|
||||||
this.size = null; // this tile's size on screen, in pixels
|
|
||||||
this.blendStart = null; // the start time of this tile's blending
|
this.blendStart = null; // the start time of this tile's blending
|
||||||
this.opacity = null; // the current opacity this tile should be
|
this.opacity = null; // the current opacity this tile should be
|
||||||
this.distance = null; // the distance of this tile to the viewport center
|
this.distance = null; // the distance of this tile to the viewport center
|
||||||
this.visibility = null; // the visibility score of this tile
|
this.visibility = null; // the visibility score of this tile
|
||||||
|
|
||||||
this.beingDrawn = false; // whether this tile is currently being drawn
|
this.beingDrawn = false; // whether this tile is currently being drawn
|
||||||
this.lastTouchTime = 0; // the time that tile was last touched
|
this.lastTouchTime = 0; // the time that tile was last touched
|
||||||
};
|
};
|
||||||
|
|
||||||
$.Tile.prototype = {
|
$.Tile.prototype = {
|
||||||
@ -34,42 +31,51 @@ $.Tile.prototype = {
|
|||||||
toString: function() {
|
toString: function() {
|
||||||
return this.level + "/" + this.x + "_" + this.y;
|
return this.level + "/" + this.x + "_" + this.y;
|
||||||
},
|
},
|
||||||
drawHTML: function(container) {
|
|
||||||
if (!this.loaded) {
|
drawHTML: function( container ) {
|
||||||
$.Debug.error("Attempting to draw tile " + this.toString() +
|
|
||||||
" when it's not yet loaded.");
|
if ( !this.loaded ) {
|
||||||
|
$.Debug.error(
|
||||||
|
"Attempting to draw tile " +
|
||||||
|
this.toString() +
|
||||||
|
" when it's not yet loaded."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.elmt) {
|
if ( !this.elmt ) {
|
||||||
this.elmt = $.Utils.makeNeutralElement("img");
|
this.elmt = $.Utils.makeNeutralElement("img");
|
||||||
this.elmt.src = this.url;
|
this.elmt.src = this.url;
|
||||||
this.style = this.elmt.style;
|
this.style = this.elmt.style;
|
||||||
this.style.position = "absolute";
|
|
||||||
|
this.style.position = "absolute";
|
||||||
this.style.msInterpolationMode = "nearest-neighbor";
|
this.style.msInterpolationMode = "nearest-neighbor";
|
||||||
}
|
}
|
||||||
|
|
||||||
var elmt = this.elmt;
|
var position = this.position.apply( Math.floor );
|
||||||
var style = this.style;
|
var size = this.size.apply( Math.ceil );
|
||||||
var position = this.position.apply(Math.floor);
|
|
||||||
var size = this.size.apply(Math.ceil);
|
|
||||||
|
|
||||||
|
|
||||||
if (elmt.parentNode != container) {
|
if ( this.elmt.parentNode != container ) {
|
||||||
container.appendChild(elmt);
|
container.appendChild( this.elmt );
|
||||||
}
|
}
|
||||||
|
|
||||||
style.left = position.x + "px";
|
this.elmt.style.left = position.x + "px";
|
||||||
style.top = position.y + "px";
|
this.elmt.style.top = position.y + "px";
|
||||||
style.width = size.x + "px";
|
this.elmt.style.width = size.x + "px";
|
||||||
style.height = size.y + "px";
|
this.elmt.style.height = size.y + "px";
|
||||||
|
|
||||||
|
$.Utils.setElementOpacity( this.elmt, this.opacity );
|
||||||
|
|
||||||
$.Utils.setElementOpacity(elmt, this.opacity);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
drawCanvas: function(context) {
|
drawCanvas: function(context) {
|
||||||
if (!this.loaded) {
|
if (!this.loaded) {
|
||||||
$.Debug.error("Attempting to draw tile " + this.toString() +
|
$.Debug.error(
|
||||||
" when it's not yet loaded.");
|
"Attempting to draw tile " +
|
||||||
|
this.toString() +
|
||||||
|
" when it's not yet loaded."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +85,7 @@ $.Tile.prototype = {
|
|||||||
context.globalAlpha = this.opacity;
|
context.globalAlpha = this.opacity;
|
||||||
context.drawImage(this.image, position.x, position.y, size.x, size.y);
|
context.drawImage(this.image, position.x, position.y, size.x, size.y);
|
||||||
},
|
},
|
||||||
|
|
||||||
unload: function() {
|
unload: function() {
|
||||||
if (this.elmt && this.elmt.parentNode) {
|
if (this.elmt && this.elmt.parentNode) {
|
||||||
this.elmt.parentNode.removeChild(this.elmt);
|
this.elmt.parentNode.removeChild(this.elmt);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user