mirror of
https://github.com/openseadragon/openseadragon.git
synced 2024-11-25 14:46:10 +03:00
work-in-progress refactor of Drawer.prototype._updateActual
This commit is contained in:
parent
b3d1fcdbb4
commit
f325804ff6
645
openseadragon.js
645
openseadragon.js
@ -314,8 +314,8 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
|
|
||||||
$.extend( $, {
|
$.extend( $, {
|
||||||
|
|
||||||
getElement: function( element ) {
|
getElement: function( element ) {
|
||||||
if (typeof ( element ) == "string") {
|
if ( typeof ( element ) == "string") {
|
||||||
element = document.getElementById( element );
|
element = document.getElementById( element );
|
||||||
}
|
}
|
||||||
return element;
|
return element;
|
||||||
@ -330,11 +330,13 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
getElementPosition: function( element ) {
|
getElementPosition: function( element ) {
|
||||||
var element = $.getElement( element );
|
var result = new $.Point(),
|
||||||
|
isFixed,
|
||||||
|
offsetParent;
|
||||||
|
|
||||||
var isFixed = $.getElementStyle( element ).position == "fixed",
|
element = $.getElement( element );
|
||||||
offsetParent = $.getOffsetParent( element, isFixed ),
|
isFixed = $.getElementStyle( element ).position == "fixed";
|
||||||
result = new $.Point();
|
offsetParent = $.getOffsetParent( element, isFixed );
|
||||||
|
|
||||||
while ( offsetParent ) {
|
while ( offsetParent ) {
|
||||||
|
|
||||||
@ -354,7 +356,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
getElementSize: function( element ) {
|
getElementSize: function( element ) {
|
||||||
var element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
return new $.Point(
|
return new $.Point(
|
||||||
element.clientWidth,
|
element.clientWidth,
|
||||||
@ -363,7 +365,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
getElementStyle: function( element ) {
|
getElementStyle: function( element ) {
|
||||||
var element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
if ( element.currentStyle ) {
|
if ( element.currentStyle ) {
|
||||||
return element.currentStyle;
|
return element.currentStyle;
|
||||||
@ -379,15 +381,14 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
getMousePosition: function( event ) {
|
getMousePosition: function( event ) {
|
||||||
var event = $.getEvent( event );
|
|
||||||
|
|
||||||
var result = new $.Point();
|
var result = new $.Point();
|
||||||
|
|
||||||
|
event = $.getEvent( event );
|
||||||
|
|
||||||
if ( typeof( event.pageX ) == "number" ) {
|
if ( typeof( event.pageX ) == "number" ) {
|
||||||
result.x = event.pageX;
|
result.x = event.pageX;
|
||||||
result.y = event.pageY;
|
result.y = event.pageY;
|
||||||
} else if ( typeof( event.clientX ) == "number" ) {
|
} else if ( typeof( event.clientX ) == "number" ) {
|
||||||
|
|
||||||
result.x =
|
result.x =
|
||||||
event.clientX +
|
event.clientX +
|
||||||
document.body.scrollLeft +
|
document.body.scrollLeft +
|
||||||
@ -446,18 +447,19 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
imageFormatSupported: function( extension ) {
|
imageFormatSupported: function( extension ) {
|
||||||
var extension = extension ? extension : "";
|
extension = extension ? extension : "";
|
||||||
return !!FILEFORMATS[ extension.toLowerCase() ];
|
return !!FILEFORMATS[ extension.toLowerCase() ];
|
||||||
},
|
},
|
||||||
|
|
||||||
makeCenteredNode: function( element ) {
|
makeCenteredNode: function( element ) {
|
||||||
var element = $.getElement( element );
|
|
||||||
|
|
||||||
var div = $.makeNeutralElement( "div" ),
|
var div = $.makeNeutralElement( "div" ),
|
||||||
html = [],
|
html = [],
|
||||||
innerDiv,
|
innerDiv,
|
||||||
innerDivs;
|
innerDivs;
|
||||||
|
|
||||||
|
element = $.getElement( element );
|
||||||
|
|
||||||
//TODO: I dont understand the use of # inside the style attributes
|
//TODO: I dont understand the use of # inside the style attributes
|
||||||
// below. Invetigate the results of the constructed html in
|
// below. Invetigate the results of the constructed html in
|
||||||
// the browser and clean up the mark-up to make this clearer.
|
// the browser and clean up the mark-up to make this clearer.
|
||||||
@ -534,12 +536,13 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
setElementOpacity: function( element, opacity, usesAlpha ) {
|
setElementOpacity: function( element, opacity, usesAlpha ) {
|
||||||
var element = $.getElement( element );
|
|
||||||
|
|
||||||
var previousFilter,
|
var previousFilter,
|
||||||
ieOpacity,
|
ieOpacity,
|
||||||
ieFilter;
|
ieFilter;
|
||||||
|
|
||||||
|
element = $.getElement( element );
|
||||||
|
|
||||||
if ( usesAlpha && !$.Browser.alpha ) {
|
if ( usesAlpha && !$.Browser.alpha ) {
|
||||||
opacity = Math.round( opacity );
|
opacity = Math.round( opacity );
|
||||||
}
|
}
|
||||||
@ -573,7 +576,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
addEvent: function( element, eventName, handler, useCapture ) {
|
addEvent: function( element, eventName, handler, useCapture ) {
|
||||||
var element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
//TODO: Why do this if/else on every method call instead of just
|
//TODO: Why do this if/else on every method call instead of just
|
||||||
// defining this function once based on the same logic
|
// defining this function once based on the same logic
|
||||||
@ -592,7 +595,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeEvent: function( element, eventName, handler, useCapture ) {
|
removeEvent: function( element, eventName, handler, useCapture ) {
|
||||||
var element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
//TODO: Why do this if/else on every method call instead of just
|
//TODO: Why do this if/else on every method call instead of just
|
||||||
// defining this function once based on the same logic
|
// defining this function once based on the same logic
|
||||||
@ -611,7 +614,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
cancelEvent: function( event ) {
|
cancelEvent: function( event ) {
|
||||||
var event = $.getEvent( event );
|
event = $.getEvent( event );
|
||||||
|
|
||||||
if ( event.preventDefault ) {
|
if ( event.preventDefault ) {
|
||||||
event.preventDefault(); // W3C for preventing default
|
event.preventDefault(); // W3C for preventing default
|
||||||
@ -622,7 +625,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
stopEvent: function( event ) {
|
stopEvent: function( event ) {
|
||||||
var event = $.getEvent( event );
|
event = $.getEvent( event );
|
||||||
|
|
||||||
if ( event.stopPropagation ) {
|
if ( event.stopPropagation ) {
|
||||||
event.stopPropagation(); // W3C for stopping propagation
|
event.stopPropagation(); // W3C for stopping propagation
|
||||||
@ -3498,49 +3501,62 @@ $.Drawer = function(source, viewport, elmt) {
|
|||||||
|
|
||||||
$.Drawer.prototype = {
|
$.Drawer.prototype = {
|
||||||
|
|
||||||
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]) {
|
var xMod,
|
||||||
this.tilesMatrix[level] = {};
|
yMod,
|
||||||
|
bounds,
|
||||||
|
exists,
|
||||||
|
url,
|
||||||
|
tile;
|
||||||
|
|
||||||
|
if ( !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;
|
xMod = ( numTilesX + ( x % numTilesX ) ) % numTilesX;
|
||||||
var yMod = (numTilesY + (y % numTilesY)) % numTilesY;
|
yMod = ( numTilesY + ( y % numTilesY ) ) % numTilesY;
|
||||||
var bounds = this.source.getTileBounds(level, xMod, yMod);
|
bounds = this.source.getTileBounds( level, xMod, yMod );
|
||||||
var exists = this.source.tileExists(level, xMod, yMod);
|
exists = this.source.tileExists( level, xMod, yMod );
|
||||||
var url = this.source.getTileUrl(level, xMod, yMod);
|
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];
|
tile = this.tilesMatrix[ level ][ x ][ y ];
|
||||||
|
|
||||||
tile.lastTouchTime = time;
|
tile.lastTouchTime = time;
|
||||||
|
|
||||||
return tile;
|
return tile;
|
||||||
},
|
},
|
||||||
|
|
||||||
_loadTile: function(tile, time) {
|
_loadTile: function( tile, time ) {
|
||||||
tile.loading = this.loadImage(
|
tile.loading = this.loadImage(
|
||||||
tile.url,
|
tile.url,
|
||||||
$.createCallback(
|
$.createCallback(
|
||||||
null,
|
null,
|
||||||
$.delegate(this, this._onTileLoad),
|
$.delegate( this, this._onTileLoad ),
|
||||||
tile,
|
tile,
|
||||||
time
|
time
|
||||||
)
|
)
|
||||||
@ -3548,61 +3564,72 @@ $.Drawer.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onTileLoad: function(tile, time, image) {
|
_onTileLoad: function(tile, time, image) {
|
||||||
|
var insertionIndex,
|
||||||
|
cutoff,
|
||||||
|
worstTile,
|
||||||
|
worstTime,
|
||||||
|
worstLevel,
|
||||||
|
worstTileIndex,
|
||||||
|
prevTile,
|
||||||
|
prevTime,
|
||||||
|
prevLevel,
|
||||||
|
i;
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.loaded = true;
|
tile.loaded = true;
|
||||||
tile.image = image;
|
tile.image = image;
|
||||||
|
|
||||||
var insertionIndex = this.tilesLoaded.length;
|
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));
|
cutoff = Math.ceil( Math.log( this.tileSize ) / Math.log( 2 ) );
|
||||||
|
|
||||||
var worstTile = null;
|
worstTile = null;
|
||||||
var worstTileIndex = -1;
|
worstTileIndex = -1;
|
||||||
|
|
||||||
for (var i = this.tilesLoaded.length - 1; i >= 0; i--) {
|
for ( i = this.tilesLoaded.length - 1; i >= 0; i-- ) {
|
||||||
var prevTile = this.tilesLoaded[i];
|
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;
|
||||||
worstTileIndex = i;
|
worstTileIndex = i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var prevTime = prevTile.lastTouchTime;
|
prevTime = prevTile.lastTouchTime;
|
||||||
var worstTime = worstTile.lastTouchTime;
|
worstTime = worstTile.lastTouchTime;
|
||||||
var prevLevel = prevTile.level;
|
prevLevel = prevTile.level;
|
||||||
var worstLevel = worstTile.level;
|
worstLevel = worstTile.level;
|
||||||
|
|
||||||
if (prevTime < worstTime ||
|
if ( prevTime < worstTime ||
|
||||||
(prevTime == worstTime && prevLevel > worstLevel)) {
|
( prevTime == worstTime && prevLevel > worstLevel ) ) {
|
||||||
worstTile = prevTile;
|
worstTile = prevTile;
|
||||||
worstTileIndex = i;
|
worstTileIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (worstTile && worstTileIndex >= 0) {
|
if ( worstTile && worstTileIndex >= 0 ) {
|
||||||
worstTile.unload();
|
worstTile.unload();
|
||||||
insertionIndex = worstTileIndex;
|
insertionIndex = worstTileIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tilesLoaded[insertionIndex] = tile;
|
this.tilesLoaded[ insertionIndex ] = tile;
|
||||||
this.updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -3622,18 +3649,22 @@ $.Drawer.prototype = {
|
|||||||
* there's no content that they would need to cover. Tiles at non-existent
|
* there's no content that they would need to cover. Tiles at non-existent
|
||||||
* levels that are within the image bounds, however, do not.
|
* levels that are within the image bounds, however, do not.
|
||||||
*/
|
*/
|
||||||
_providesCoverage: function(level, x, y) {
|
_providesCoverage: function( level, x, y ) {
|
||||||
if (!this.coverage[level]) {
|
var rows,
|
||||||
|
cols,
|
||||||
|
i, j;
|
||||||
|
|
||||||
|
if ( !this.coverage[ level ] ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x === undefined || y === undefined) {
|
if ( x === undefined || y === undefined ) {
|
||||||
var rows = this.coverage[level];
|
rows = this.coverage[ level ];
|
||||||
for (var i in rows) {
|
for ( i in rows ) {
|
||||||
if (rows.hasOwnProperty(i)) {
|
if ( rows.hasOwnProperty( i ) ) {
|
||||||
var cols = rows[i];
|
cols = rows[ i ];
|
||||||
for (var j in cols) {
|
for ( j in cols ) {
|
||||||
if (cols.hasOwnProperty(j) && !cols[j]) {
|
if ( cols.hasOwnProperty( j ) && !cols[ j ] ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3643,9 +3674,11 @@ $.Drawer.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (this.coverage[level][x] === undefined ||
|
return (
|
||||||
this.coverage[level][x][y] === undefined ||
|
this.coverage[ level ][ x] === undefined ||
|
||||||
this.coverage[level][x][y] === true);
|
this.coverage[ level ][ x ][ y ] === undefined ||
|
||||||
|
this.coverage[ level ][ x ][ y ] === true
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3653,32 +3686,35 @@ $.Drawer.prototype = {
|
|||||||
* tiles of higher resolution representing the same content. If neither x
|
* tiles of higher resolution representing the same content. If neither x
|
||||||
* nor y is given, returns true if the entire visible level is covered.
|
* nor y is given, returns true if the entire visible level is covered.
|
||||||
*/
|
*/
|
||||||
_isCovered: function(level, x, y) {
|
_isCovered: function( level, x, y ) {
|
||||||
if (x === undefined || y === undefined) {
|
if ( x === undefined || y === undefined ) {
|
||||||
return this._providesCoverage(level + 1);
|
return this._providesCoverage( level + 1 );
|
||||||
} else {
|
} else {
|
||||||
return (this._providesCoverage(level + 1, 2 * x, 2 * y) &&
|
return (
|
||||||
this._providesCoverage(level + 1, 2 * x, 2 * y + 1) &&
|
this._providesCoverage( level + 1, 2 * x, 2 * y ) &&
|
||||||
this._providesCoverage(level + 1, 2 * x + 1, 2 * y) &&
|
this._providesCoverage( level + 1, 2 * x, 2 * y + 1 ) &&
|
||||||
this._providesCoverage(level + 1, 2 * x + 1, 2 * y + 1));
|
this._providesCoverage( level + 1, 2 * x + 1, 2 * y ) &&
|
||||||
|
this._providesCoverage( level + 1, 2 * x + 1, 2 * y + 1 )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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(
|
||||||
"level's coverage has been reset: " + level);
|
"Setting coverage for a tile before its 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;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -3686,20 +3722,20 @@ $.Drawer.prototype = {
|
|||||||
* after every draw routine. Note that at the beginning of the next draw
|
* after every draw routine. Note that at the beginning of the next draw
|
||||||
* routine, coverage for every visible tile should be explicitly set.
|
* routine, coverage for every visible tile should be explicitly set.
|
||||||
*/
|
*/
|
||||||
_resetCoverage: function(level) {
|
_resetCoverage: function( level ) {
|
||||||
this.coverage[level] = {};
|
this.coverage[ level ] = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_compareTiles: function(prevBest, tile) {
|
_compareTiles: function( prevBest, tile ) {
|
||||||
if (!prevBest) {
|
if ( !prevBest ) {
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile.visibility > prevBest.visibility) {
|
if ( tile.visibility > prevBest.visibility ) {
|
||||||
return tile;
|
return tile;
|
||||||
} else if (tile.visibility == prevBest.visibility) {
|
} else if ( tile.visibility == prevBest.visibility ) {
|
||||||
if (tile.distance < prevBest.distance) {
|
if ( tile.distance < prevBest.distance ) {
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3708,9 +3744,10 @@ $.Drawer.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_getOverlayIndex: function(elmt) {
|
_getOverlayIndex: function( elmt ) {
|
||||||
for (var i = this.overlays.length - 1; i >= 0; i--) {
|
var i;
|
||||||
if (this.overlays[i].elmt == elmt) {
|
for ( i = this.overlays.length - 1; i >= 0; i-- ) {
|
||||||
|
if ( this.overlays[ i ].elmt == elmt ) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3722,248 +3759,328 @@ $.Drawer.prototype = {
|
|||||||
_updateActual: function() {
|
_updateActual: function() {
|
||||||
this.updateAgain = false;
|
this.updateAgain = false;
|
||||||
|
|
||||||
var _canvas = this.canvas;
|
var i, x, y,
|
||||||
var _context = this.context;
|
tile,
|
||||||
var _container = this.container;
|
tileTL,
|
||||||
var _lastDrawn = this.lastDrawn;
|
tileBR,
|
||||||
|
numTiles,
|
||||||
|
numTilesX,
|
||||||
|
numTilesY,
|
||||||
|
level,
|
||||||
|
drawLevel,
|
||||||
|
drawTile,
|
||||||
|
renderPixelRatioC,
|
||||||
|
renderPixelRatioT,
|
||||||
|
levelOpacity,
|
||||||
|
levelVisibility,
|
||||||
|
viewportSize = this.viewport.getContainerSize(),
|
||||||
|
viewportWidth = viewportSize.x,
|
||||||
|
viewportHeight = viewportSize.y,
|
||||||
|
viewportBounds = this.viewport.getBounds( true ),
|
||||||
|
viewportTL = viewportBounds.getTopLeft(),
|
||||||
|
viewportBR = viewportBounds.getBottomRight(),
|
||||||
|
viewportCenter = this.viewport.pixelFromPoint( this.viewport.getCenter() ),
|
||||||
|
best = null,
|
||||||
|
haveDrawn = false,
|
||||||
|
currentTime = new Date().getTime(),
|
||||||
|
zeroRatioT = this.viewport.deltaPixelsFromPoints(
|
||||||
|
this.source.getPixelRatio( 0 ),
|
||||||
|
false
|
||||||
|
).x,
|
||||||
|
zeroRatioC = this.viewport.deltaPixelsFromPoints(
|
||||||
|
this.source.getPixelRatio( 0 ),
|
||||||
|
true
|
||||||
|
).x,
|
||||||
|
optimalRatio = this.config.immediateRender ? 1 : zeroRatioT,
|
||||||
|
lowestLevel = Math.max(
|
||||||
|
this.minLevel,
|
||||||
|
Math.floor(
|
||||||
|
Math.log( this.config.minZoomImageRatio ) /
|
||||||
|
Math.log( 2 )
|
||||||
|
)
|
||||||
|
),
|
||||||
|
highestLevel = Math.min(
|
||||||
|
this.maxLevel,
|
||||||
|
Math.floor(
|
||||||
|
Math.log( zeroRatioC / MIN_PIXEL_RATIO ) /
|
||||||
|
Math.log( 2 )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
while (_lastDrawn.length > 0) {
|
|
||||||
var tile = _lastDrawn.pop();
|
while ( this.lastDrawn.length > 0 ) {
|
||||||
|
tile = this.lastDrawn.pop();
|
||||||
tile.beingDrawn = false;
|
tile.beingDrawn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportSize = this.viewport.getContainerSize();
|
|
||||||
var viewportWidth = viewportSize.x;
|
|
||||||
var viewportHeight = viewportSize.y;
|
|
||||||
|
|
||||||
_canvas.innerHTML = "";
|
this.canvas.innerHTML = "";
|
||||||
if ( USE_CANVAS ) {
|
if ( USE_CANVAS ) {
|
||||||
_canvas.width = viewportWidth;
|
this.canvas.width = viewportWidth;
|
||||||
_canvas.height = viewportHeight;
|
this.canvas.height = viewportHeight;
|
||||||
_context.clearRect(0, 0, viewportWidth, viewportHeight);
|
this.context.clearRect( 0, 0, viewportWidth, viewportHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportBounds = this.viewport.getBounds(true);
|
if ( !this.config.wrapHorizontal &&
|
||||||
var viewportTL = viewportBounds.getTopLeft();
|
( viewportBR.x < 0 || viewportTL.x > 1 ) ) {
|
||||||
var viewportBR = viewportBounds.getBottomRight();
|
|
||||||
if (!this.config.wrapHorizontal &&
|
|
||||||
(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( !this.config.wrapHorizontal ) {
|
||||||
|
viewportTL.x = Math.max( viewportTL.x, 0 );
|
||||||
var _abs = Math.abs;
|
viewportBR.x = Math.min( viewportBR.x, 1 );
|
||||||
var _ceil = Math.ceil;
|
|
||||||
var _floor = Math.floor;
|
|
||||||
var _log = Math.log;
|
|
||||||
var _max = Math.max;
|
|
||||||
var _min = Math.min;
|
|
||||||
var alwaysBlend = this.config.alwaysBlend;
|
|
||||||
var blendTimeMillis = 1000 * this.config.blendTime;
|
|
||||||
var immediateRender = this.config.immediateRender;
|
|
||||||
var wrapHorizontal = this.config.wrapHorizontal;
|
|
||||||
var wrapVertical = this.config.wrapVertical;
|
|
||||||
|
|
||||||
if (!wrapHorizontal) {
|
|
||||||
viewportTL.x = _max(viewportTL.x, 0);
|
|
||||||
viewportBR.x = _min(viewportBR.x, 1);
|
|
||||||
}
|
}
|
||||||
if (!wrapVertical) {
|
if ( !this.config.wrapVertical ) {
|
||||||
viewportTL.y = _max(viewportTL.y, 0);
|
viewportTL.y = Math.max( viewportTL.y, 0 );
|
||||||
viewportBR.y = _min(viewportBR.y, this.normHeight);
|
viewportBR.y = Math.min( viewportBR.y, this.normHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
var best = null;
|
lowestLevel = Math.min( lowestLevel, highestLevel );
|
||||||
var haveDrawn = false;
|
|
||||||
var currentTime = new Date().getTime();
|
|
||||||
|
|
||||||
var viewportCenter = this.viewport.pixelFromPoint(this.viewport.getCenter());
|
for ( level = highestLevel; level >= lowestLevel; level-- ) {
|
||||||
var zeroRatioT = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), false).x;
|
drawLevel = false;
|
||||||
var optimalPixelRatio = immediateRender ? 1 : zeroRatioT;
|
// note the .x!
|
||||||
|
renderPixelRatioC = this.viewport.deltaPixelsFromPoints(
|
||||||
|
this.source.getPixelRatio( level ),
|
||||||
|
true
|
||||||
|
).x;
|
||||||
|
renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
||||||
|
this.source.getPixelRatio( level ),
|
||||||
|
false
|
||||||
|
).x;
|
||||||
|
|
||||||
var lowestLevel = _max(this.minLevel, _floor(_log(this.config.minZoomImageRatio) / _log(2)));
|
if ( ( !haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO ) ||
|
||||||
var zeroRatioC = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), true).x;
|
( level == lowestLevel ) ) {
|
||||||
var highestLevel = _min(this.maxLevel,
|
|
||||||
_floor(_log(zeroRatioC / MIN_PIXEL_RATIO) / _log(2)));
|
|
||||||
|
|
||||||
lowestLevel = _min(lowestLevel, highestLevel);
|
|
||||||
|
|
||||||
for (var level = highestLevel; level >= lowestLevel; level--) {
|
|
||||||
var drawLevel = false;
|
|
||||||
var renderPixelRatioC = this.viewport.deltaPixelsFromPoints(
|
|
||||||
this.source.getPixelRatio(level), true).x; // note the .x!
|
|
||||||
|
|
||||||
if ((!haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO) ||
|
|
||||||
level == lowestLevel) {
|
|
||||||
drawLevel = true;
|
drawLevel = true;
|
||||||
haveDrawn = true;
|
haveDrawn = true;
|
||||||
} else if (!haveDrawn) {
|
} else if ( !haveDrawn ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._resetCoverage(level);
|
this._resetCoverage( level );
|
||||||
|
|
||||||
var levelOpacity = _min(1, (renderPixelRatioC - 0.5) / 0.5);
|
levelOpacity = Math.min( 1, ( renderPixelRatioC - 0.5 ) / 0.5 );
|
||||||
var renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
levelVisibility = optimalRatio / Math.abs(
|
||||||
this.source.getPixelRatio(level), false).x;
|
optimalRatio - renderPixelRatioT
|
||||||
var levelVisibility = optimalPixelRatio /
|
);
|
||||||
_abs(optimalPixelRatio - renderPixelRatioT);
|
|
||||||
|
|
||||||
var tileTL = this.source.getTileAtPoint(level, viewportTL);
|
tileTL = this.source.getTileAtPoint( level, viewportTL );
|
||||||
var tileBR = this.source.getTileAtPoint(level, viewportBR);
|
tileBR = this.source.getTileAtPoint( level, viewportBR );
|
||||||
var numTiles = numberOfTiles( this, level );
|
numTiles = numberOfTiles( this, level );
|
||||||
var numTilesX = numTiles.x;
|
numTilesX = numTiles.x;
|
||||||
var numTilesY = numTiles.y;
|
numTilesY = numTiles.y;
|
||||||
if (!wrapHorizontal) {
|
|
||||||
tileBR.x = _min(tileBR.x, numTilesX - 1);
|
if ( !this.config.wrapHorizontal ) {
|
||||||
|
tileBR.x = Math.min( tileBR.x, numTilesX - 1 );
|
||||||
}
|
}
|
||||||
if (!wrapVertical) {
|
if ( !this.config.wrapVertical ) {
|
||||||
tileBR.y = _min(tileBR.y, numTilesY - 1);
|
tileBR.y = Math.min( tileBR.y, numTilesY - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var x = tileTL.x; x <= tileBR.x; x++) {
|
for ( x = tileTL.x; x <= tileBR.x; x++ ) {
|
||||||
for (var y = tileTL.y; y <= tileBR.y; y++) {
|
for ( y = tileTL.y; y <= tileBR.y; y++ ) {
|
||||||
var tile = this._getTile(level, x, y, currentTime, numTilesX, numTilesY);
|
drawTile = drawLevel;
|
||||||
var drawTile = drawLevel;
|
tile = this._getTile(
|
||||||
|
level,
|
||||||
|
x, y,
|
||||||
|
currentTime,
|
||||||
|
numTilesX,
|
||||||
|
numTilesY
|
||||||
|
);
|
||||||
|
|
||||||
this._setCoverage(level, x, y, false);
|
this._setCoverage( level, x, y, false );
|
||||||
|
|
||||||
if (!tile.exists) {
|
if ( !tile.exists ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (haveDrawn && !drawTile) {
|
if ( haveDrawn && !drawTile ) {
|
||||||
if (this._isCovered(level, x, y)) {
|
if ( this._isCovered( level, x, y ) ) {
|
||||||
this._setCoverage(level, x, y, true);
|
this._setCoverage( level, x, y, true );
|
||||||
} else {
|
} else {
|
||||||
drawTile = true;
|
drawTile = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drawTile) {
|
if ( !drawTile ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var boundsTL = tile.bounds.getTopLeft();
|
this._positionTile(
|
||||||
var boundsSize = tile.bounds.getSize();
|
tile,
|
||||||
var positionC = this.viewport.pixelFromPoint(boundsTL, true);
|
viewportCenter,
|
||||||
var sizeC = this.viewport.deltaPixelsFromPoints(boundsSize, true);
|
levelVisibility
|
||||||
|
);
|
||||||
|
|
||||||
if (!this.tileOverlap) {
|
if ( tile.loaded ) {
|
||||||
sizeC = sizeC.plus(new $.Point(1, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
var positionT = this.viewport.pixelFromPoint(boundsTL, false);
|
|
||||||
var sizeT = this.viewport.deltaPixelsFromPoints(boundsSize, false);
|
|
||||||
var tileCenter = positionT.plus(sizeT.divide(2));
|
|
||||||
var tileDistance = viewportCenter.distanceTo(tileCenter);
|
|
||||||
|
|
||||||
tile.position = positionC;
|
|
||||||
tile.size = sizeC;
|
|
||||||
tile.distance = tileDistance;
|
|
||||||
tile.visibility = levelVisibility;
|
|
||||||
|
|
||||||
if (tile.loaded) {
|
|
||||||
if (!tile.blendStart) {
|
|
||||||
tile.blendStart = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
var deltaTime = currentTime - tile.blendStart;
|
|
||||||
var opacity = _min(1, deltaTime / blendTimeMillis);
|
|
||||||
|
|
||||||
if (alwaysBlend) {
|
updateAgain = this._blendTile(
|
||||||
opacity *= levelOpacity;
|
tile,
|
||||||
}
|
x, y,
|
||||||
|
level,
|
||||||
|
levelOpacity,
|
||||||
|
currentTime
|
||||||
|
);
|
||||||
|
|
||||||
tile.opacity = opacity;
|
} else if ( tile.Loading ) {
|
||||||
|
//do nothing
|
||||||
_lastDrawn.push(tile);
|
|
||||||
|
|
||||||
if (opacity == 1) {
|
|
||||||
this._setCoverage(level, x, y, true);
|
|
||||||
} else if (deltaTime < blendTimeMillis) {
|
|
||||||
updateAgain = true;
|
|
||||||
}
|
|
||||||
} else if (tile.Loading) {
|
|
||||||
} else {
|
} else {
|
||||||
best = this._compareTiles(best, tile);
|
best = this._compareTiles( best, tile );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._providesCoverage(level)) {
|
if ( this._providesCoverage( level ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = _lastDrawn.length - 1; i >= 0; i--) {
|
this._drawTiles();
|
||||||
var tile = _lastDrawn[i];
|
this._drawOverlays();
|
||||||
|
|
||||||
|
if ( best ) {
|
||||||
|
this._loadTile( best, currentTime );
|
||||||
|
// because we haven't finished drawing, so
|
||||||
|
this.updateAgain = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_drawLevel: function( ){
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionTile: function( tile, viewportCenter, levelVisibility ){
|
||||||
|
var boundsTL = tile.bounds.getTopLeft(),
|
||||||
|
boundsSize = tile.bounds.getSize(),
|
||||||
|
positionC = this.viewport.pixelFromPoint( boundsTL, true ),
|
||||||
|
sizeC = this.viewport.deltaPixelsFromPoints( boundsSize, true ),
|
||||||
|
positionT = this.viewport.pixelFromPoint( boundsTL, false ),
|
||||||
|
sizeT = this.viewport.deltaPixelsFromPoints( boundsSize, false ),
|
||||||
|
tileCenter = positionT.plus( sizeT.divide( 2 ) ),
|
||||||
|
tileDistance = viewportCenter.distanceTo( tileCenter );
|
||||||
|
|
||||||
|
if ( !this.tileOverlap ) {
|
||||||
|
sizeC = sizeC.plus( new $.Point( 1, 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.position = positionC;
|
||||||
|
tile.size = sizeC;
|
||||||
|
tile.distance = tileDistance;
|
||||||
|
tile.visibility = levelVisibility;
|
||||||
|
},
|
||||||
|
|
||||||
|
_blendTile: function( tile, x, y, level, levelOpacity, currentTime ){
|
||||||
|
var blendTimeMillis = 1000 * this.config.blendTime,
|
||||||
|
deltaTime,
|
||||||
|
opacity;
|
||||||
|
|
||||||
|
if ( !tile.blendStart ) {
|
||||||
|
tile.blendStart = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
deltaTime = currentTime - tile.blendStart;
|
||||||
|
opacity = Math.min( 1, deltaTime / blendTimeMillis );
|
||||||
|
|
||||||
|
if ( this.config.alwaysBlend ) {
|
||||||
|
opacity *= levelOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.opacity = opacity;
|
||||||
|
|
||||||
|
this.lastDrawn.push( tile );
|
||||||
|
|
||||||
|
if ( opacity == 1 ) {
|
||||||
|
this._setCoverage( level, x, y, true );
|
||||||
|
} else if ( deltaTime < blendTimeMillis ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_drawTiles: function(){
|
||||||
|
var i,
|
||||||
|
tile;
|
||||||
|
|
||||||
|
for ( i = this.lastDrawn.length - 1; i >= 0; i-- ) {
|
||||||
|
tile = this.lastDrawn[ i ];
|
||||||
|
|
||||||
if ( USE_CANVAS ) {
|
if ( USE_CANVAS ) {
|
||||||
tile.drawCanvas(_context);
|
tile.drawCanvas( this.context );
|
||||||
} else {
|
} else {
|
||||||
tile.drawHTML(_canvas);
|
tile.drawHTML( this.canvas );
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.beingDrawn = true;
|
tile.beingDrawn = true;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
var numOverlays = this.overlays.length;
|
_drawOverlays: function(){
|
||||||
for (var i = 0; i < numOverlays; i++) {
|
var i,
|
||||||
var overlay = this.overlays[i];
|
length = this.overlays.length;
|
||||||
var bounds = overlay.bounds;
|
for ( i = 0; i < length; i++ ) {
|
||||||
|
this._drawOverlay( this.overlays[ i ] );
|
||||||
overlay.position = this.viewport.pixelFromPoint(bounds.getTopLeft(), true);
|
|
||||||
overlay.size = this.viewport.deltaPixelsFromPoints(bounds.getSize(), true);
|
|
||||||
overlay.drawHTML(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best) {
|
|
||||||
this._loadTile(best, currentTime);
|
|
||||||
this.updateAgain = true; // because we haven't finished drawing, so
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_drawOverlay: function( overlay ){
|
||||||
|
|
||||||
|
var bounds = overlay.bounds;
|
||||||
|
|
||||||
addOverlay: function(elmt, loc, placement) {
|
overlay.position = this.viewport.pixelFromPoint(
|
||||||
var elmt = $.getElement(elmt);
|
bounds.getTopLeft(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
overlay.size = this.viewport.deltaPixelsFromPoints(
|
||||||
|
bounds.getSize(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
overlay.drawHTML( this.container );
|
||||||
|
},
|
||||||
|
|
||||||
if (this._getOverlayIndex(elmt) >= 0) {
|
addOverlay: function( element, location, placement ) {
|
||||||
return; // they're trying to add a duplicate overlay
|
element = $.getElement( element );
|
||||||
|
|
||||||
|
if ( this._getOverlayIndex( element ) >= 0 ) {
|
||||||
|
// they're trying to add a duplicate overlay
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.overlays.push(new $.Overlay(elmt, loc, placement));
|
this.overlays.push( new $.Overlay( element, location, placement ) );
|
||||||
this.updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateOverlay: function(elmt, loc, placement) {
|
updateOverlay: function( element, location, placement ) {
|
||||||
var elmt = $.getElement(elmt);
|
var i;
|
||||||
var i = this._getOverlayIndex(elmt);
|
|
||||||
|
|
||||||
if (i >= 0) {
|
element = $.getElement( element );
|
||||||
this.overlays[i].update(loc, placement);
|
i = this._getOverlayIndex( element );
|
||||||
|
|
||||||
|
if ( i >= 0 ) {
|
||||||
|
this.overlays[ i ].update( location, placement );
|
||||||
this.updateAgain = true;
|
this.updateAgain = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeOverlay: function(elmt) {
|
removeOverlay: function( element ) {
|
||||||
var elmt = $.getElement(elmt);
|
var i;
|
||||||
var i = this._getOverlayIndex(elmt);
|
|
||||||
|
|
||||||
if (i >= 0) {
|
element = $.getElement( element );
|
||||||
this.overlays[i].destroy();
|
i = this._getOverlayIndex( element );
|
||||||
this.overlays.splice(i, 1);
|
|
||||||
|
if ( i >= 0 ) {
|
||||||
|
this.overlays[ i ].destroy();
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
606
src/drawer.js
606
src/drawer.js
@ -74,49 +74,62 @@ $.Drawer = function(source, viewport, elmt) {
|
|||||||
|
|
||||||
$.Drawer.prototype = {
|
$.Drawer.prototype = {
|
||||||
|
|
||||||
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]) {
|
var xMod,
|
||||||
this.tilesMatrix[level] = {};
|
yMod,
|
||||||
|
bounds,
|
||||||
|
exists,
|
||||||
|
url,
|
||||||
|
tile;
|
||||||
|
|
||||||
|
if ( !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;
|
xMod = ( numTilesX + ( x % numTilesX ) ) % numTilesX;
|
||||||
var yMod = (numTilesY + (y % numTilesY)) % numTilesY;
|
yMod = ( numTilesY + ( y % numTilesY ) ) % numTilesY;
|
||||||
var bounds = this.source.getTileBounds(level, xMod, yMod);
|
bounds = this.source.getTileBounds( level, xMod, yMod );
|
||||||
var exists = this.source.tileExists(level, xMod, yMod);
|
exists = this.source.tileExists( level, xMod, yMod );
|
||||||
var url = this.source.getTileUrl(level, xMod, yMod);
|
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];
|
tile = this.tilesMatrix[ level ][ x ][ y ];
|
||||||
|
|
||||||
tile.lastTouchTime = time;
|
tile.lastTouchTime = time;
|
||||||
|
|
||||||
return tile;
|
return tile;
|
||||||
},
|
},
|
||||||
|
|
||||||
_loadTile: function(tile, time) {
|
_loadTile: function( tile, time ) {
|
||||||
tile.loading = this.loadImage(
|
tile.loading = this.loadImage(
|
||||||
tile.url,
|
tile.url,
|
||||||
$.createCallback(
|
$.createCallback(
|
||||||
null,
|
null,
|
||||||
$.delegate(this, this._onTileLoad),
|
$.delegate( this, this._onTileLoad ),
|
||||||
tile,
|
tile,
|
||||||
time
|
time
|
||||||
)
|
)
|
||||||
@ -124,61 +137,72 @@ $.Drawer.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_onTileLoad: function(tile, time, image) {
|
_onTileLoad: function(tile, time, image) {
|
||||||
|
var insertionIndex,
|
||||||
|
cutoff,
|
||||||
|
worstTile,
|
||||||
|
worstTime,
|
||||||
|
worstLevel,
|
||||||
|
worstTileIndex,
|
||||||
|
prevTile,
|
||||||
|
prevTime,
|
||||||
|
prevLevel,
|
||||||
|
i;
|
||||||
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.loaded = true;
|
tile.loaded = true;
|
||||||
tile.image = image;
|
tile.image = image;
|
||||||
|
|
||||||
var insertionIndex = this.tilesLoaded.length;
|
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));
|
cutoff = Math.ceil( Math.log( this.tileSize ) / Math.log( 2 ) );
|
||||||
|
|
||||||
var worstTile = null;
|
worstTile = null;
|
||||||
var worstTileIndex = -1;
|
worstTileIndex = -1;
|
||||||
|
|
||||||
for (var i = this.tilesLoaded.length - 1; i >= 0; i--) {
|
for ( i = this.tilesLoaded.length - 1; i >= 0; i-- ) {
|
||||||
var prevTile = this.tilesLoaded[i];
|
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;
|
||||||
worstTileIndex = i;
|
worstTileIndex = i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var prevTime = prevTile.lastTouchTime;
|
prevTime = prevTile.lastTouchTime;
|
||||||
var worstTime = worstTile.lastTouchTime;
|
worstTime = worstTile.lastTouchTime;
|
||||||
var prevLevel = prevTile.level;
|
prevLevel = prevTile.level;
|
||||||
var worstLevel = worstTile.level;
|
worstLevel = worstTile.level;
|
||||||
|
|
||||||
if (prevTime < worstTime ||
|
if ( prevTime < worstTime ||
|
||||||
(prevTime == worstTime && prevLevel > worstLevel)) {
|
( prevTime == worstTime && prevLevel > worstLevel ) ) {
|
||||||
worstTile = prevTile;
|
worstTile = prevTile;
|
||||||
worstTileIndex = i;
|
worstTileIndex = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (worstTile && worstTileIndex >= 0) {
|
if ( worstTile && worstTileIndex >= 0 ) {
|
||||||
worstTile.unload();
|
worstTile.unload();
|
||||||
insertionIndex = worstTileIndex;
|
insertionIndex = worstTileIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.tilesLoaded[insertionIndex] = tile;
|
this.tilesLoaded[ insertionIndex ] = tile;
|
||||||
this.updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -198,18 +222,22 @@ $.Drawer.prototype = {
|
|||||||
* there's no content that they would need to cover. Tiles at non-existent
|
* there's no content that they would need to cover. Tiles at non-existent
|
||||||
* levels that are within the image bounds, however, do not.
|
* levels that are within the image bounds, however, do not.
|
||||||
*/
|
*/
|
||||||
_providesCoverage: function(level, x, y) {
|
_providesCoverage: function( level, x, y ) {
|
||||||
if (!this.coverage[level]) {
|
var rows,
|
||||||
|
cols,
|
||||||
|
i, j;
|
||||||
|
|
||||||
|
if ( !this.coverage[ level ] ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x === undefined || y === undefined) {
|
if ( x === undefined || y === undefined ) {
|
||||||
var rows = this.coverage[level];
|
rows = this.coverage[ level ];
|
||||||
for (var i in rows) {
|
for ( i in rows ) {
|
||||||
if (rows.hasOwnProperty(i)) {
|
if ( rows.hasOwnProperty( i ) ) {
|
||||||
var cols = rows[i];
|
cols = rows[ i ];
|
||||||
for (var j in cols) {
|
for ( j in cols ) {
|
||||||
if (cols.hasOwnProperty(j) && !cols[j]) {
|
if ( cols.hasOwnProperty( j ) && !cols[ j ] ) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -219,9 +247,11 @@ $.Drawer.prototype = {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (this.coverage[level][x] === undefined ||
|
return (
|
||||||
this.coverage[level][x][y] === undefined ||
|
this.coverage[ level ][ x] === undefined ||
|
||||||
this.coverage[level][x][y] === true);
|
this.coverage[ level ][ x ][ y ] === undefined ||
|
||||||
|
this.coverage[ level ][ x ][ y ] === true
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -229,32 +259,35 @@ $.Drawer.prototype = {
|
|||||||
* tiles of higher resolution representing the same content. If neither x
|
* tiles of higher resolution representing the same content. If neither x
|
||||||
* nor y is given, returns true if the entire visible level is covered.
|
* nor y is given, returns true if the entire visible level is covered.
|
||||||
*/
|
*/
|
||||||
_isCovered: function(level, x, y) {
|
_isCovered: function( level, x, y ) {
|
||||||
if (x === undefined || y === undefined) {
|
if ( x === undefined || y === undefined ) {
|
||||||
return this._providesCoverage(level + 1);
|
return this._providesCoverage( level + 1 );
|
||||||
} else {
|
} else {
|
||||||
return (this._providesCoverage(level + 1, 2 * x, 2 * y) &&
|
return (
|
||||||
this._providesCoverage(level + 1, 2 * x, 2 * y + 1) &&
|
this._providesCoverage( level + 1, 2 * x, 2 * y ) &&
|
||||||
this._providesCoverage(level + 1, 2 * x + 1, 2 * y) &&
|
this._providesCoverage( level + 1, 2 * x, 2 * y + 1 ) &&
|
||||||
this._providesCoverage(level + 1, 2 * x + 1, 2 * y + 1));
|
this._providesCoverage( level + 1, 2 * x + 1, 2 * y ) &&
|
||||||
|
this._providesCoverage( level + 1, 2 * x + 1, 2 * y + 1 )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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(
|
||||||
"level's coverage has been reset: " + level);
|
"Setting coverage for a tile before its 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;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,20 +295,20 @@ $.Drawer.prototype = {
|
|||||||
* after every draw routine. Note that at the beginning of the next draw
|
* after every draw routine. Note that at the beginning of the next draw
|
||||||
* routine, coverage for every visible tile should be explicitly set.
|
* routine, coverage for every visible tile should be explicitly set.
|
||||||
*/
|
*/
|
||||||
_resetCoverage: function(level) {
|
_resetCoverage: function( level ) {
|
||||||
this.coverage[level] = {};
|
this.coverage[ level ] = {};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_compareTiles: function(prevBest, tile) {
|
_compareTiles: function( prevBest, tile ) {
|
||||||
if (!prevBest) {
|
if ( !prevBest ) {
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tile.visibility > prevBest.visibility) {
|
if ( tile.visibility > prevBest.visibility ) {
|
||||||
return tile;
|
return tile;
|
||||||
} else if (tile.visibility == prevBest.visibility) {
|
} else if ( tile.visibility == prevBest.visibility ) {
|
||||||
if (tile.distance < prevBest.distance) {
|
if ( tile.distance < prevBest.distance ) {
|
||||||
return tile;
|
return tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,9 +317,10 @@ $.Drawer.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
_getOverlayIndex: function(elmt) {
|
_getOverlayIndex: function( elmt ) {
|
||||||
for (var i = this.overlays.length - 1; i >= 0; i--) {
|
var i;
|
||||||
if (this.overlays[i].elmt == elmt) {
|
for ( i = this.overlays.length - 1; i >= 0; i-- ) {
|
||||||
|
if ( this.overlays[ i ].elmt == elmt ) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -298,248 +332,328 @@ $.Drawer.prototype = {
|
|||||||
_updateActual: function() {
|
_updateActual: function() {
|
||||||
this.updateAgain = false;
|
this.updateAgain = false;
|
||||||
|
|
||||||
var _canvas = this.canvas;
|
var i, x, y,
|
||||||
var _context = this.context;
|
tile,
|
||||||
var _container = this.container;
|
tileTL,
|
||||||
var _lastDrawn = this.lastDrawn;
|
tileBR,
|
||||||
|
numTiles,
|
||||||
|
numTilesX,
|
||||||
|
numTilesY,
|
||||||
|
level,
|
||||||
|
drawLevel,
|
||||||
|
drawTile,
|
||||||
|
renderPixelRatioC,
|
||||||
|
renderPixelRatioT,
|
||||||
|
levelOpacity,
|
||||||
|
levelVisibility,
|
||||||
|
viewportSize = this.viewport.getContainerSize(),
|
||||||
|
viewportWidth = viewportSize.x,
|
||||||
|
viewportHeight = viewportSize.y,
|
||||||
|
viewportBounds = this.viewport.getBounds( true ),
|
||||||
|
viewportTL = viewportBounds.getTopLeft(),
|
||||||
|
viewportBR = viewportBounds.getBottomRight(),
|
||||||
|
viewportCenter = this.viewport.pixelFromPoint( this.viewport.getCenter() ),
|
||||||
|
best = null,
|
||||||
|
haveDrawn = false,
|
||||||
|
currentTime = new Date().getTime(),
|
||||||
|
zeroRatioT = this.viewport.deltaPixelsFromPoints(
|
||||||
|
this.source.getPixelRatio( 0 ),
|
||||||
|
false
|
||||||
|
).x,
|
||||||
|
zeroRatioC = this.viewport.deltaPixelsFromPoints(
|
||||||
|
this.source.getPixelRatio( 0 ),
|
||||||
|
true
|
||||||
|
).x,
|
||||||
|
optimalRatio = this.config.immediateRender ? 1 : zeroRatioT,
|
||||||
|
lowestLevel = Math.max(
|
||||||
|
this.minLevel,
|
||||||
|
Math.floor(
|
||||||
|
Math.log( this.config.minZoomImageRatio ) /
|
||||||
|
Math.log( 2 )
|
||||||
|
)
|
||||||
|
),
|
||||||
|
highestLevel = Math.min(
|
||||||
|
this.maxLevel,
|
||||||
|
Math.floor(
|
||||||
|
Math.log( zeroRatioC / MIN_PIXEL_RATIO ) /
|
||||||
|
Math.log( 2 )
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
while (_lastDrawn.length > 0) {
|
|
||||||
var tile = _lastDrawn.pop();
|
while ( this.lastDrawn.length > 0 ) {
|
||||||
|
tile = this.lastDrawn.pop();
|
||||||
tile.beingDrawn = false;
|
tile.beingDrawn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportSize = this.viewport.getContainerSize();
|
|
||||||
var viewportWidth = viewportSize.x;
|
|
||||||
var viewportHeight = viewportSize.y;
|
|
||||||
|
|
||||||
_canvas.innerHTML = "";
|
this.canvas.innerHTML = "";
|
||||||
if ( USE_CANVAS ) {
|
if ( USE_CANVAS ) {
|
||||||
_canvas.width = viewportWidth;
|
this.canvas.width = viewportWidth;
|
||||||
_canvas.height = viewportHeight;
|
this.canvas.height = viewportHeight;
|
||||||
_context.clearRect(0, 0, viewportWidth, viewportHeight);
|
this.context.clearRect( 0, 0, viewportWidth, viewportHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
var viewportBounds = this.viewport.getBounds(true);
|
if ( !this.config.wrapHorizontal &&
|
||||||
var viewportTL = viewportBounds.getTopLeft();
|
( viewportBR.x < 0 || viewportTL.x > 1 ) ) {
|
||||||
var viewportBR = viewportBounds.getBottomRight();
|
|
||||||
if (!this.config.wrapHorizontal &&
|
|
||||||
(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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ( !this.config.wrapHorizontal ) {
|
||||||
|
viewportTL.x = Math.max( viewportTL.x, 0 );
|
||||||
var _abs = Math.abs;
|
viewportBR.x = Math.min( viewportBR.x, 1 );
|
||||||
var _ceil = Math.ceil;
|
|
||||||
var _floor = Math.floor;
|
|
||||||
var _log = Math.log;
|
|
||||||
var _max = Math.max;
|
|
||||||
var _min = Math.min;
|
|
||||||
var alwaysBlend = this.config.alwaysBlend;
|
|
||||||
var blendTimeMillis = 1000 * this.config.blendTime;
|
|
||||||
var immediateRender = this.config.immediateRender;
|
|
||||||
var wrapHorizontal = this.config.wrapHorizontal;
|
|
||||||
var wrapVertical = this.config.wrapVertical;
|
|
||||||
|
|
||||||
if (!wrapHorizontal) {
|
|
||||||
viewportTL.x = _max(viewportTL.x, 0);
|
|
||||||
viewportBR.x = _min(viewportBR.x, 1);
|
|
||||||
}
|
}
|
||||||
if (!wrapVertical) {
|
if ( !this.config.wrapVertical ) {
|
||||||
viewportTL.y = _max(viewportTL.y, 0);
|
viewportTL.y = Math.max( viewportTL.y, 0 );
|
||||||
viewportBR.y = _min(viewportBR.y, this.normHeight);
|
viewportBR.y = Math.min( viewportBR.y, this.normHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
var best = null;
|
lowestLevel = Math.min( lowestLevel, highestLevel );
|
||||||
var haveDrawn = false;
|
|
||||||
var currentTime = new Date().getTime();
|
|
||||||
|
|
||||||
var viewportCenter = this.viewport.pixelFromPoint(this.viewport.getCenter());
|
for ( level = highestLevel; level >= lowestLevel; level-- ) {
|
||||||
var zeroRatioT = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), false).x;
|
drawLevel = false;
|
||||||
var optimalPixelRatio = immediateRender ? 1 : zeroRatioT;
|
// note the .x!
|
||||||
|
renderPixelRatioC = this.viewport.deltaPixelsFromPoints(
|
||||||
|
this.source.getPixelRatio( level ),
|
||||||
|
true
|
||||||
|
).x;
|
||||||
|
renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
||||||
|
this.source.getPixelRatio( level ),
|
||||||
|
false
|
||||||
|
).x;
|
||||||
|
|
||||||
var lowestLevel = _max(this.minLevel, _floor(_log(this.config.minZoomImageRatio) / _log(2)));
|
if ( ( !haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO ) ||
|
||||||
var zeroRatioC = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), true).x;
|
( level == lowestLevel ) ) {
|
||||||
var highestLevel = _min(this.maxLevel,
|
|
||||||
_floor(_log(zeroRatioC / MIN_PIXEL_RATIO) / _log(2)));
|
|
||||||
|
|
||||||
lowestLevel = _min(lowestLevel, highestLevel);
|
|
||||||
|
|
||||||
for (var level = highestLevel; level >= lowestLevel; level--) {
|
|
||||||
var drawLevel = false;
|
|
||||||
var renderPixelRatioC = this.viewport.deltaPixelsFromPoints(
|
|
||||||
this.source.getPixelRatio(level), true).x; // note the .x!
|
|
||||||
|
|
||||||
if ((!haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO) ||
|
|
||||||
level == lowestLevel) {
|
|
||||||
drawLevel = true;
|
drawLevel = true;
|
||||||
haveDrawn = true;
|
haveDrawn = true;
|
||||||
} else if (!haveDrawn) {
|
} else if ( !haveDrawn ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._resetCoverage(level);
|
this._resetCoverage( level );
|
||||||
|
|
||||||
var levelOpacity = _min(1, (renderPixelRatioC - 0.5) / 0.5);
|
levelOpacity = Math.min( 1, ( renderPixelRatioC - 0.5 ) / 0.5 );
|
||||||
var renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
levelVisibility = optimalRatio / Math.abs(
|
||||||
this.source.getPixelRatio(level), false).x;
|
optimalRatio - renderPixelRatioT
|
||||||
var levelVisibility = optimalPixelRatio /
|
);
|
||||||
_abs(optimalPixelRatio - renderPixelRatioT);
|
|
||||||
|
|
||||||
var tileTL = this.source.getTileAtPoint(level, viewportTL);
|
tileTL = this.source.getTileAtPoint( level, viewportTL );
|
||||||
var tileBR = this.source.getTileAtPoint(level, viewportBR);
|
tileBR = this.source.getTileAtPoint( level, viewportBR );
|
||||||
var numTiles = numberOfTiles( this, level );
|
numTiles = numberOfTiles( this, level );
|
||||||
var numTilesX = numTiles.x;
|
numTilesX = numTiles.x;
|
||||||
var numTilesY = numTiles.y;
|
numTilesY = numTiles.y;
|
||||||
if (!wrapHorizontal) {
|
|
||||||
tileBR.x = _min(tileBR.x, numTilesX - 1);
|
if ( !this.config.wrapHorizontal ) {
|
||||||
|
tileBR.x = Math.min( tileBR.x, numTilesX - 1 );
|
||||||
}
|
}
|
||||||
if (!wrapVertical) {
|
if ( !this.config.wrapVertical ) {
|
||||||
tileBR.y = _min(tileBR.y, numTilesY - 1);
|
tileBR.y = Math.min( tileBR.y, numTilesY - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var x = tileTL.x; x <= tileBR.x; x++) {
|
for ( x = tileTL.x; x <= tileBR.x; x++ ) {
|
||||||
for (var y = tileTL.y; y <= tileBR.y; y++) {
|
for ( y = tileTL.y; y <= tileBR.y; y++ ) {
|
||||||
var tile = this._getTile(level, x, y, currentTime, numTilesX, numTilesY);
|
drawTile = drawLevel;
|
||||||
var drawTile = drawLevel;
|
tile = this._getTile(
|
||||||
|
level,
|
||||||
|
x, y,
|
||||||
|
currentTime,
|
||||||
|
numTilesX,
|
||||||
|
numTilesY
|
||||||
|
);
|
||||||
|
|
||||||
this._setCoverage(level, x, y, false);
|
this._setCoverage( level, x, y, false );
|
||||||
|
|
||||||
if (!tile.exists) {
|
if ( !tile.exists ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (haveDrawn && !drawTile) {
|
if ( haveDrawn && !drawTile ) {
|
||||||
if (this._isCovered(level, x, y)) {
|
if ( this._isCovered( level, x, y ) ) {
|
||||||
this._setCoverage(level, x, y, true);
|
this._setCoverage( level, x, y, true );
|
||||||
} else {
|
} else {
|
||||||
drawTile = true;
|
drawTile = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!drawTile) {
|
if ( !drawTile ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
var boundsTL = tile.bounds.getTopLeft();
|
this._positionTile(
|
||||||
var boundsSize = tile.bounds.getSize();
|
tile,
|
||||||
var positionC = this.viewport.pixelFromPoint(boundsTL, true);
|
viewportCenter,
|
||||||
var sizeC = this.viewport.deltaPixelsFromPoints(boundsSize, true);
|
levelVisibility
|
||||||
|
);
|
||||||
|
|
||||||
if (!this.tileOverlap) {
|
if ( tile.loaded ) {
|
||||||
sizeC = sizeC.plus(new $.Point(1, 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
var positionT = this.viewport.pixelFromPoint(boundsTL, false);
|
|
||||||
var sizeT = this.viewport.deltaPixelsFromPoints(boundsSize, false);
|
|
||||||
var tileCenter = positionT.plus(sizeT.divide(2));
|
|
||||||
var tileDistance = viewportCenter.distanceTo(tileCenter);
|
|
||||||
|
|
||||||
tile.position = positionC;
|
|
||||||
tile.size = sizeC;
|
|
||||||
tile.distance = tileDistance;
|
|
||||||
tile.visibility = levelVisibility;
|
|
||||||
|
|
||||||
if (tile.loaded) {
|
|
||||||
if (!tile.blendStart) {
|
|
||||||
tile.blendStart = currentTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
var deltaTime = currentTime - tile.blendStart;
|
|
||||||
var opacity = _min(1, deltaTime / blendTimeMillis);
|
|
||||||
|
|
||||||
if (alwaysBlend) {
|
updateAgain = this._blendTile(
|
||||||
opacity *= levelOpacity;
|
tile,
|
||||||
}
|
x, y,
|
||||||
|
level,
|
||||||
|
levelOpacity,
|
||||||
|
currentTime
|
||||||
|
);
|
||||||
|
|
||||||
tile.opacity = opacity;
|
} else if ( tile.Loading ) {
|
||||||
|
//do nothing
|
||||||
_lastDrawn.push(tile);
|
|
||||||
|
|
||||||
if (opacity == 1) {
|
|
||||||
this._setCoverage(level, x, y, true);
|
|
||||||
} else if (deltaTime < blendTimeMillis) {
|
|
||||||
updateAgain = true;
|
|
||||||
}
|
|
||||||
} else if (tile.Loading) {
|
|
||||||
} else {
|
} else {
|
||||||
best = this._compareTiles(best, tile);
|
best = this._compareTiles( best, tile );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._providesCoverage(level)) {
|
if ( this._providesCoverage( level ) ) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = _lastDrawn.length - 1; i >= 0; i--) {
|
this._drawTiles();
|
||||||
var tile = _lastDrawn[i];
|
this._drawOverlays();
|
||||||
|
|
||||||
|
if ( best ) {
|
||||||
|
this._loadTile( best, currentTime );
|
||||||
|
// because we haven't finished drawing, so
|
||||||
|
this.updateAgain = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_drawLevel: function( ){
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
_positionTile: function( tile, viewportCenter, levelVisibility ){
|
||||||
|
var boundsTL = tile.bounds.getTopLeft(),
|
||||||
|
boundsSize = tile.bounds.getSize(),
|
||||||
|
positionC = this.viewport.pixelFromPoint( boundsTL, true ),
|
||||||
|
sizeC = this.viewport.deltaPixelsFromPoints( boundsSize, true ),
|
||||||
|
positionT = this.viewport.pixelFromPoint( boundsTL, false ),
|
||||||
|
sizeT = this.viewport.deltaPixelsFromPoints( boundsSize, false ),
|
||||||
|
tileCenter = positionT.plus( sizeT.divide( 2 ) ),
|
||||||
|
tileDistance = viewportCenter.distanceTo( tileCenter );
|
||||||
|
|
||||||
|
if ( !this.tileOverlap ) {
|
||||||
|
sizeC = sizeC.plus( new $.Point( 1, 1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.position = positionC;
|
||||||
|
tile.size = sizeC;
|
||||||
|
tile.distance = tileDistance;
|
||||||
|
tile.visibility = levelVisibility;
|
||||||
|
},
|
||||||
|
|
||||||
|
_blendTile: function( tile, x, y, level, levelOpacity, currentTime ){
|
||||||
|
var blendTimeMillis = 1000 * this.config.blendTime,
|
||||||
|
deltaTime,
|
||||||
|
opacity;
|
||||||
|
|
||||||
|
if ( !tile.blendStart ) {
|
||||||
|
tile.blendStart = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
deltaTime = currentTime - tile.blendStart;
|
||||||
|
opacity = Math.min( 1, deltaTime / blendTimeMillis );
|
||||||
|
|
||||||
|
if ( this.config.alwaysBlend ) {
|
||||||
|
opacity *= levelOpacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.opacity = opacity;
|
||||||
|
|
||||||
|
this.lastDrawn.push( tile );
|
||||||
|
|
||||||
|
if ( opacity == 1 ) {
|
||||||
|
this._setCoverage( level, x, y, true );
|
||||||
|
} else if ( deltaTime < blendTimeMillis ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_drawTiles: function(){
|
||||||
|
var i,
|
||||||
|
tile;
|
||||||
|
|
||||||
|
for ( i = this.lastDrawn.length - 1; i >= 0; i-- ) {
|
||||||
|
tile = this.lastDrawn[ i ];
|
||||||
|
|
||||||
if ( USE_CANVAS ) {
|
if ( USE_CANVAS ) {
|
||||||
tile.drawCanvas(_context);
|
tile.drawCanvas( this.context );
|
||||||
} else {
|
} else {
|
||||||
tile.drawHTML(_canvas);
|
tile.drawHTML( this.canvas );
|
||||||
}
|
}
|
||||||
|
|
||||||
tile.beingDrawn = true;
|
tile.beingDrawn = true;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
|
||||||
var numOverlays = this.overlays.length;
|
_drawOverlays: function(){
|
||||||
for (var i = 0; i < numOverlays; i++) {
|
var i,
|
||||||
var overlay = this.overlays[i];
|
length = this.overlays.length;
|
||||||
var bounds = overlay.bounds;
|
for ( i = 0; i < length; i++ ) {
|
||||||
|
this._drawOverlay( this.overlays[ i ] );
|
||||||
overlay.position = this.viewport.pixelFromPoint(bounds.getTopLeft(), true);
|
|
||||||
overlay.size = this.viewport.deltaPixelsFromPoints(bounds.getSize(), true);
|
|
||||||
overlay.drawHTML(_container);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (best) {
|
|
||||||
this._loadTile(best, currentTime);
|
|
||||||
this.updateAgain = true; // because we haven't finished drawing, so
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_drawOverlay: function( overlay ){
|
||||||
|
|
||||||
|
var bounds = overlay.bounds;
|
||||||
|
|
||||||
addOverlay: function(elmt, loc, placement) {
|
overlay.position = this.viewport.pixelFromPoint(
|
||||||
var elmt = $.getElement(elmt);
|
bounds.getTopLeft(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
overlay.size = this.viewport.deltaPixelsFromPoints(
|
||||||
|
bounds.getSize(),
|
||||||
|
true
|
||||||
|
);
|
||||||
|
overlay.drawHTML( this.container );
|
||||||
|
},
|
||||||
|
|
||||||
if (this._getOverlayIndex(elmt) >= 0) {
|
addOverlay: function( element, location, placement ) {
|
||||||
return; // they're trying to add a duplicate overlay
|
element = $.getElement( element );
|
||||||
|
|
||||||
|
if ( this._getOverlayIndex( element ) >= 0 ) {
|
||||||
|
// they're trying to add a duplicate overlay
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.overlays.push(new $.Overlay(elmt, loc, placement));
|
this.overlays.push( new $.Overlay( element, location, placement ) );
|
||||||
this.updateAgain = true;
|
this.updateAgain = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
updateOverlay: function(elmt, loc, placement) {
|
updateOverlay: function( element, location, placement ) {
|
||||||
var elmt = $.getElement(elmt);
|
var i;
|
||||||
var i = this._getOverlayIndex(elmt);
|
|
||||||
|
|
||||||
if (i >= 0) {
|
element = $.getElement( element );
|
||||||
this.overlays[i].update(loc, placement);
|
i = this._getOverlayIndex( element );
|
||||||
|
|
||||||
|
if ( i >= 0 ) {
|
||||||
|
this.overlays[ i ].update( location, placement );
|
||||||
this.updateAgain = true;
|
this.updateAgain = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeOverlay: function(elmt) {
|
removeOverlay: function( element ) {
|
||||||
var elmt = $.getElement(elmt);
|
var i;
|
||||||
var i = this._getOverlayIndex(elmt);
|
|
||||||
|
|
||||||
if (i >= 0) {
|
element = $.getElement( element );
|
||||||
this.overlays[i].destroy();
|
i = this._getOverlayIndex( element );
|
||||||
this.overlays.splice(i, 1);
|
|
||||||
|
if ( i >= 0 ) {
|
||||||
|
this.overlays[ i ].destroy();
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
@ -314,8 +314,8 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
|
|
||||||
$.extend( $, {
|
$.extend( $, {
|
||||||
|
|
||||||
getElement: function( element ) {
|
getElement: function( element ) {
|
||||||
if (typeof ( element ) == "string") {
|
if ( typeof ( element ) == "string") {
|
||||||
element = document.getElementById( element );
|
element = document.getElementById( element );
|
||||||
}
|
}
|
||||||
return element;
|
return element;
|
||||||
@ -330,11 +330,13 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
getElementPosition: function( element ) {
|
getElementPosition: function( element ) {
|
||||||
var element = $.getElement( element );
|
var result = new $.Point(),
|
||||||
|
isFixed,
|
||||||
|
offsetParent;
|
||||||
|
|
||||||
var isFixed = $.getElementStyle( element ).position == "fixed",
|
element = $.getElement( element );
|
||||||
offsetParent = $.getOffsetParent( element, isFixed ),
|
isFixed = $.getElementStyle( element ).position == "fixed";
|
||||||
result = new $.Point();
|
offsetParent = $.getOffsetParent( element, isFixed );
|
||||||
|
|
||||||
while ( offsetParent ) {
|
while ( offsetParent ) {
|
||||||
|
|
||||||
@ -354,7 +356,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
getElementSize: function( element ) {
|
getElementSize: function( element ) {
|
||||||
var element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
return new $.Point(
|
return new $.Point(
|
||||||
element.clientWidth,
|
element.clientWidth,
|
||||||
@ -363,7 +365,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
getElementStyle: function( element ) {
|
getElementStyle: function( element ) {
|
||||||
var element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
if ( element.currentStyle ) {
|
if ( element.currentStyle ) {
|
||||||
return element.currentStyle;
|
return element.currentStyle;
|
||||||
@ -379,15 +381,14 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
getMousePosition: function( event ) {
|
getMousePosition: function( event ) {
|
||||||
var event = $.getEvent( event );
|
|
||||||
|
|
||||||
var result = new $.Point();
|
var result = new $.Point();
|
||||||
|
|
||||||
|
event = $.getEvent( event );
|
||||||
|
|
||||||
if ( typeof( event.pageX ) == "number" ) {
|
if ( typeof( event.pageX ) == "number" ) {
|
||||||
result.x = event.pageX;
|
result.x = event.pageX;
|
||||||
result.y = event.pageY;
|
result.y = event.pageY;
|
||||||
} else if ( typeof( event.clientX ) == "number" ) {
|
} else if ( typeof( event.clientX ) == "number" ) {
|
||||||
|
|
||||||
result.x =
|
result.x =
|
||||||
event.clientX +
|
event.clientX +
|
||||||
document.body.scrollLeft +
|
document.body.scrollLeft +
|
||||||
@ -446,18 +447,19 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
imageFormatSupported: function( extension ) {
|
imageFormatSupported: function( extension ) {
|
||||||
var extension = extension ? extension : "";
|
extension = extension ? extension : "";
|
||||||
return !!FILEFORMATS[ extension.toLowerCase() ];
|
return !!FILEFORMATS[ extension.toLowerCase() ];
|
||||||
},
|
},
|
||||||
|
|
||||||
makeCenteredNode: function( element ) {
|
makeCenteredNode: function( element ) {
|
||||||
var element = $.getElement( element );
|
|
||||||
|
|
||||||
var div = $.makeNeutralElement( "div" ),
|
var div = $.makeNeutralElement( "div" ),
|
||||||
html = [],
|
html = [],
|
||||||
innerDiv,
|
innerDiv,
|
||||||
innerDivs;
|
innerDivs;
|
||||||
|
|
||||||
|
element = $.getElement( element );
|
||||||
|
|
||||||
//TODO: I dont understand the use of # inside the style attributes
|
//TODO: I dont understand the use of # inside the style attributes
|
||||||
// below. Invetigate the results of the constructed html in
|
// below. Invetigate the results of the constructed html in
|
||||||
// the browser and clean up the mark-up to make this clearer.
|
// the browser and clean up the mark-up to make this clearer.
|
||||||
@ -534,12 +536,13 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
setElementOpacity: function( element, opacity, usesAlpha ) {
|
setElementOpacity: function( element, opacity, usesAlpha ) {
|
||||||
var element = $.getElement( element );
|
|
||||||
|
|
||||||
var previousFilter,
|
var previousFilter,
|
||||||
ieOpacity,
|
ieOpacity,
|
||||||
ieFilter;
|
ieFilter;
|
||||||
|
|
||||||
|
element = $.getElement( element );
|
||||||
|
|
||||||
if ( usesAlpha && !$.Browser.alpha ) {
|
if ( usesAlpha && !$.Browser.alpha ) {
|
||||||
opacity = Math.round( opacity );
|
opacity = Math.round( opacity );
|
||||||
}
|
}
|
||||||
@ -573,7 +576,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
addEvent: function( element, eventName, handler, useCapture ) {
|
addEvent: function( element, eventName, handler, useCapture ) {
|
||||||
var element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
//TODO: Why do this if/else on every method call instead of just
|
//TODO: Why do this if/else on every method call instead of just
|
||||||
// defining this function once based on the same logic
|
// defining this function once based on the same logic
|
||||||
@ -592,7 +595,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
removeEvent: function( element, eventName, handler, useCapture ) {
|
removeEvent: function( element, eventName, handler, useCapture ) {
|
||||||
var element = $.getElement( element );
|
element = $.getElement( element );
|
||||||
|
|
||||||
//TODO: Why do this if/else on every method call instead of just
|
//TODO: Why do this if/else on every method call instead of just
|
||||||
// defining this function once based on the same logic
|
// defining this function once based on the same logic
|
||||||
@ -611,7 +614,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
cancelEvent: function( event ) {
|
cancelEvent: function( event ) {
|
||||||
var event = $.getEvent( event );
|
event = $.getEvent( event );
|
||||||
|
|
||||||
if ( event.preventDefault ) {
|
if ( event.preventDefault ) {
|
||||||
event.preventDefault(); // W3C for preventing default
|
event.preventDefault(); // W3C for preventing default
|
||||||
@ -622,7 +625,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
|||||||
},
|
},
|
||||||
|
|
||||||
stopEvent: function( event ) {
|
stopEvent: function( event ) {
|
||||||
var event = $.getEvent( event );
|
event = $.getEvent( event );
|
||||||
|
|
||||||
if ( event.stopPropagation ) {
|
if ( event.stopPropagation ) {
|
||||||
event.stopPropagation(); // W3C for stopping propagation
|
event.stopPropagation(); // W3C for stopping propagation
|
||||||
|
Loading…
Reference in New Issue
Block a user