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
483
openseadragon.js
483
openseadragon.js
@ -330,11 +330,13 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
getElementPosition: function( element ) {
|
||||
var element = $.getElement( element );
|
||||
var result = new $.Point(),
|
||||
isFixed,
|
||||
offsetParent;
|
||||
|
||||
var isFixed = $.getElementStyle( element ).position == "fixed",
|
||||
offsetParent = $.getOffsetParent( element, isFixed ),
|
||||
result = new $.Point();
|
||||
element = $.getElement( element );
|
||||
isFixed = $.getElementStyle( element ).position == "fixed";
|
||||
offsetParent = $.getOffsetParent( element, isFixed );
|
||||
|
||||
while ( offsetParent ) {
|
||||
|
||||
@ -354,7 +356,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
getElementSize: function( element ) {
|
||||
var element = $.getElement( element );
|
||||
element = $.getElement( element );
|
||||
|
||||
return new $.Point(
|
||||
element.clientWidth,
|
||||
@ -363,7 +365,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
getElementStyle: function( element ) {
|
||||
var element = $.getElement( element );
|
||||
element = $.getElement( element );
|
||||
|
||||
if ( element.currentStyle ) {
|
||||
return element.currentStyle;
|
||||
@ -379,15 +381,14 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
getMousePosition: function( event ) {
|
||||
var event = $.getEvent( event );
|
||||
|
||||
var result = new $.Point();
|
||||
|
||||
event = $.getEvent( event );
|
||||
|
||||
if ( typeof( event.pageX ) == "number" ) {
|
||||
result.x = event.pageX;
|
||||
result.y = event.pageY;
|
||||
} else if ( typeof( event.clientX ) == "number" ) {
|
||||
|
||||
result.x =
|
||||
event.clientX +
|
||||
document.body.scrollLeft +
|
||||
@ -446,18 +447,19 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
imageFormatSupported: function( extension ) {
|
||||
var extension = extension ? extension : "";
|
||||
extension = extension ? extension : "";
|
||||
return !!FILEFORMATS[ extension.toLowerCase() ];
|
||||
},
|
||||
|
||||
makeCenteredNode: function( element ) {
|
||||
var element = $.getElement( element );
|
||||
|
||||
var div = $.makeNeutralElement( "div" ),
|
||||
html = [],
|
||||
innerDiv,
|
||||
innerDivs;
|
||||
|
||||
element = $.getElement( element );
|
||||
|
||||
//TODO: I dont understand the use of # inside the style attributes
|
||||
// below. Invetigate the results of the constructed html in
|
||||
// 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 ) {
|
||||
var element = $.getElement( element );
|
||||
|
||||
var previousFilter,
|
||||
ieOpacity,
|
||||
ieFilter;
|
||||
|
||||
element = $.getElement( element );
|
||||
|
||||
if ( usesAlpha && !$.Browser.alpha ) {
|
||||
opacity = Math.round( opacity );
|
||||
}
|
||||
@ -573,7 +576,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
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
|
||||
// defining this function once based on the same logic
|
||||
@ -592,7 +595,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
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
|
||||
// defining this function once based on the same logic
|
||||
@ -611,7 +614,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
cancelEvent: function( event ) {
|
||||
var event = $.getEvent( event );
|
||||
event = $.getEvent( event );
|
||||
|
||||
if ( event.preventDefault ) {
|
||||
event.preventDefault(); // W3C for preventing default
|
||||
@ -622,7 +625,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
stopEvent: function( event ) {
|
||||
var event = $.getEvent( event );
|
||||
event = $.getEvent( event );
|
||||
|
||||
if ( event.stopPropagation ) {
|
||||
event.stopPropagation(); // W3C for stopping propagation
|
||||
@ -3508,6 +3511,13 @@ $.Drawer.prototype = {
|
||||
|
||||
|
||||
_getTile: function( level, x, y, time, numTilesX, numTilesY ) {
|
||||
var xMod,
|
||||
yMod,
|
||||
bounds,
|
||||
exists,
|
||||
url,
|
||||
tile;
|
||||
|
||||
if ( !this.tilesMatrix[ level ] ) {
|
||||
this.tilesMatrix[ level ] = {};
|
||||
}
|
||||
@ -3516,20 +3526,26 @@ $.Drawer.prototype = {
|
||||
}
|
||||
|
||||
if ( !this.tilesMatrix[ level ][ x ][ y ] ) {
|
||||
var xMod = (numTilesX + (x % numTilesX)) % numTilesX;
|
||||
var yMod = (numTilesY + (y % numTilesY)) % numTilesY;
|
||||
var bounds = this.source.getTileBounds(level, xMod, yMod);
|
||||
var exists = this.source.tileExists(level, xMod, yMod);
|
||||
var url = this.source.getTileUrl(level, xMod, yMod);
|
||||
xMod = ( numTilesX + ( x % numTilesX ) ) % numTilesX;
|
||||
yMod = ( numTilesY + ( y % numTilesY ) ) % numTilesY;
|
||||
bounds = this.source.getTileBounds( level, xMod, yMod );
|
||||
exists = this.source.tileExists( level, xMod, yMod );
|
||||
url = this.source.getTileUrl( level, xMod, yMod );
|
||||
|
||||
bounds.x += 1.0 * ( x - xMod ) / numTilesX;
|
||||
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;
|
||||
|
||||
return tile;
|
||||
@ -3548,6 +3564,17 @@ $.Drawer.prototype = {
|
||||
},
|
||||
|
||||
_onTileLoad: function(tile, time, image) {
|
||||
var insertionIndex,
|
||||
cutoff,
|
||||
worstTile,
|
||||
worstTime,
|
||||
worstLevel,
|
||||
worstTileIndex,
|
||||
prevTile,
|
||||
prevTime,
|
||||
prevLevel,
|
||||
i;
|
||||
|
||||
tile.loading = false;
|
||||
|
||||
if ( this.midUpdate ) {
|
||||
@ -3565,16 +3592,16 @@ $.Drawer.prototype = {
|
||||
tile.loaded = true;
|
||||
tile.image = image;
|
||||
|
||||
var insertionIndex = this.tilesLoaded.length;
|
||||
insertionIndex = this.tilesLoaded.length;
|
||||
|
||||
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;
|
||||
var worstTileIndex = -1;
|
||||
worstTile = null;
|
||||
worstTileIndex = -1;
|
||||
|
||||
for (var i = this.tilesLoaded.length - 1; i >= 0; i--) {
|
||||
var prevTile = this.tilesLoaded[i];
|
||||
for ( i = this.tilesLoaded.length - 1; i >= 0; i-- ) {
|
||||
prevTile = this.tilesLoaded[ i ];
|
||||
|
||||
if ( prevTile.level <= this.cutoff || prevTile.beingDrawn ) {
|
||||
continue;
|
||||
@ -3584,10 +3611,10 @@ $.Drawer.prototype = {
|
||||
continue;
|
||||
}
|
||||
|
||||
var prevTime = prevTile.lastTouchTime;
|
||||
var worstTime = worstTile.lastTouchTime;
|
||||
var prevLevel = prevTile.level;
|
||||
var worstLevel = worstTile.level;
|
||||
prevTime = prevTile.lastTouchTime;
|
||||
worstTime = worstTile.lastTouchTime;
|
||||
prevLevel = prevTile.level;
|
||||
worstLevel = worstTile.level;
|
||||
|
||||
if ( prevTime < worstTime ||
|
||||
( prevTime == worstTime && prevLevel > worstLevel ) ) {
|
||||
@ -3623,16 +3650,20 @@ $.Drawer.prototype = {
|
||||
* levels that are within the image bounds, however, do not.
|
||||
*/
|
||||
_providesCoverage: function( level, x, y ) {
|
||||
var rows,
|
||||
cols,
|
||||
i, j;
|
||||
|
||||
if ( !this.coverage[ level ] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( x === undefined || y === undefined ) {
|
||||
var rows = this.coverage[level];
|
||||
for (var i in rows) {
|
||||
rows = this.coverage[ level ];
|
||||
for ( i in rows ) {
|
||||
if ( rows.hasOwnProperty( i ) ) {
|
||||
var cols = rows[i];
|
||||
for (var j in cols) {
|
||||
cols = rows[ i ];
|
||||
for ( j in cols ) {
|
||||
if ( cols.hasOwnProperty( j ) && !cols[ j ] ) {
|
||||
return false;
|
||||
}
|
||||
@ -3643,9 +3674,11 @@ $.Drawer.prototype = {
|
||||
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] === true);
|
||||
this.coverage[ level ][ x ][ y ] === true
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -3657,10 +3690,12 @@ $.Drawer.prototype = {
|
||||
if ( x === undefined || y === undefined ) {
|
||||
return this._providesCoverage( level + 1 );
|
||||
} else {
|
||||
return (this._providesCoverage(level + 1, 2 * x, 2 * y) &&
|
||||
return (
|
||||
this._providesCoverage( level + 1, 2 * x, 2 * y ) &&
|
||||
this._providesCoverage( level + 1, 2 * x, 2 * y + 1 ) &&
|
||||
this._providesCoverage( level + 1, 2 * x + 1, 2 * y ) &&
|
||||
this._providesCoverage(level + 1, 2 * x + 1, 2 * y + 1));
|
||||
this._providesCoverage( level + 1, 2 * x + 1, 2 * y + 1 )
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@ -3669,8 +3704,9 @@ $.Drawer.prototype = {
|
||||
*/
|
||||
_setCoverage: function( level, x, y, covers ) {
|
||||
if ( !this.coverage[ level ] ) {
|
||||
$.Debug.error("Setting coverage for a tile before its " +
|
||||
"level's coverage has been reset: " + level);
|
||||
$.Debug.error(
|
||||
"Setting coverage for a tile before its level's coverage has been reset: " + level
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -3709,7 +3745,8 @@ $.Drawer.prototype = {
|
||||
|
||||
|
||||
_getOverlayIndex: function( elmt ) {
|
||||
for (var i = this.overlays.length - 1; i >= 0; i--) {
|
||||
var i;
|
||||
for ( i = this.overlays.length - 1; i >= 0; i-- ) {
|
||||
if ( this.overlays[ i ].elmt == elmt ) {
|
||||
return i;
|
||||
}
|
||||
@ -3722,30 +3759,68 @@ $.Drawer.prototype = {
|
||||
_updateActual: function() {
|
||||
this.updateAgain = false;
|
||||
|
||||
var _canvas = this.canvas;
|
||||
var _context = this.context;
|
||||
var _container = this.container;
|
||||
var _lastDrawn = this.lastDrawn;
|
||||
var i, x, y,
|
||||
tile,
|
||||
tileTL,
|
||||
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;
|
||||
}
|
||||
|
||||
var viewportSize = this.viewport.getContainerSize();
|
||||
var viewportWidth = viewportSize.x;
|
||||
var viewportHeight = viewportSize.y;
|
||||
|
||||
_canvas.innerHTML = "";
|
||||
this.canvas.innerHTML = "";
|
||||
if ( USE_CANVAS ) {
|
||||
_canvas.width = viewportWidth;
|
||||
_canvas.height = viewportHeight;
|
||||
_context.clearRect(0, 0, viewportWidth, viewportHeight);
|
||||
this.canvas.width = viewportWidth;
|
||||
this.canvas.height = viewportHeight;
|
||||
this.context.clearRect( 0, 0, viewportWidth, viewportHeight );
|
||||
}
|
||||
|
||||
var viewportBounds = this.viewport.getBounds(true);
|
||||
var viewportTL = viewportBounds.getTopLeft();
|
||||
var viewportBR = viewportBounds.getBottomRight();
|
||||
if ( !this.config.wrapHorizontal &&
|
||||
( viewportBR.x < 0 || viewportTL.x > 1 ) ) {
|
||||
return;
|
||||
@ -3755,51 +3830,31 @@ $.Drawer.prototype = {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var _abs = Math.abs;
|
||||
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 ( !this.config.wrapHorizontal ) {
|
||||
viewportTL.x = Math.max( viewportTL.x, 0 );
|
||||
viewportBR.x = Math.min( viewportBR.x, 1 );
|
||||
}
|
||||
if (!wrapVertical) {
|
||||
viewportTL.y = _max(viewportTL.y, 0);
|
||||
viewportBR.y = _min(viewportBR.y, this.normHeight);
|
||||
if ( !this.config.wrapVertical ) {
|
||||
viewportTL.y = Math.max( viewportTL.y, 0 );
|
||||
viewportBR.y = Math.min( viewportBR.y, this.normHeight );
|
||||
}
|
||||
|
||||
var best = null;
|
||||
var haveDrawn = false;
|
||||
var currentTime = new Date().getTime();
|
||||
lowestLevel = Math.min( lowestLevel, highestLevel );
|
||||
|
||||
var viewportCenter = this.viewport.pixelFromPoint(this.viewport.getCenter());
|
||||
var zeroRatioT = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), false).x;
|
||||
var optimalPixelRatio = immediateRender ? 1 : zeroRatioT;
|
||||
|
||||
var lowestLevel = _max(this.minLevel, _floor(_log(this.config.minZoomImageRatio) / _log(2)));
|
||||
var zeroRatioC = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), true).x;
|
||||
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!
|
||||
for ( level = highestLevel; level >= lowestLevel; level-- ) {
|
||||
drawLevel = false;
|
||||
// note the .x!
|
||||
renderPixelRatioC = this.viewport.deltaPixelsFromPoints(
|
||||
this.source.getPixelRatio( level ),
|
||||
true
|
||||
).x;
|
||||
renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
||||
this.source.getPixelRatio( level ),
|
||||
false
|
||||
).x;
|
||||
|
||||
if ( ( !haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO ) ||
|
||||
level == lowestLevel) {
|
||||
( level == lowestLevel ) ) {
|
||||
drawLevel = true;
|
||||
haveDrawn = true;
|
||||
} else if ( !haveDrawn ) {
|
||||
@ -3808,28 +3863,34 @@ $.Drawer.prototype = {
|
||||
|
||||
this._resetCoverage( level );
|
||||
|
||||
var levelOpacity = _min(1, (renderPixelRatioC - 0.5) / 0.5);
|
||||
var renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
||||
this.source.getPixelRatio(level), false).x;
|
||||
var levelVisibility = optimalPixelRatio /
|
||||
_abs(optimalPixelRatio - renderPixelRatioT);
|
||||
levelOpacity = Math.min( 1, ( renderPixelRatioC - 0.5 ) / 0.5 );
|
||||
levelVisibility = optimalRatio / Math.abs(
|
||||
optimalRatio - renderPixelRatioT
|
||||
);
|
||||
|
||||
var tileTL = this.source.getTileAtPoint(level, viewportTL);
|
||||
var tileBR = this.source.getTileAtPoint(level, viewportBR);
|
||||
var numTiles = numberOfTiles( this, level );
|
||||
var numTilesX = numTiles.x;
|
||||
var numTilesY = numTiles.y;
|
||||
if (!wrapHorizontal) {
|
||||
tileBR.x = _min(tileBR.x, numTilesX - 1);
|
||||
tileTL = this.source.getTileAtPoint( level, viewportTL );
|
||||
tileBR = this.source.getTileAtPoint( level, viewportBR );
|
||||
numTiles = numberOfTiles( this, level );
|
||||
numTilesX = numTiles.x;
|
||||
numTilesY = numTiles.y;
|
||||
|
||||
if ( !this.config.wrapHorizontal ) {
|
||||
tileBR.x = Math.min( tileBR.x, numTilesX - 1 );
|
||||
}
|
||||
if (!wrapVertical) {
|
||||
tileBR.y = _min(tileBR.y, numTilesY - 1);
|
||||
if ( !this.config.wrapVertical ) {
|
||||
tileBR.y = Math.min( tileBR.y, numTilesY - 1 );
|
||||
}
|
||||
|
||||
for (var x = tileTL.x; x <= tileBR.x; x++) {
|
||||
for (var y = tileTL.y; y <= tileBR.y; y++) {
|
||||
var tile = this._getTile(level, x, y, currentTime, numTilesX, numTilesY);
|
||||
var drawTile = drawLevel;
|
||||
for ( x = tileTL.x; x <= tileBR.x; x++ ) {
|
||||
for ( y = tileTL.y; y <= tileBR.y; y++ ) {
|
||||
drawTile = drawLevel;
|
||||
tile = this._getTile(
|
||||
level,
|
||||
x, y,
|
||||
currentTime,
|
||||
numTilesX,
|
||||
numTilesY
|
||||
);
|
||||
|
||||
this._setCoverage( level, x, y, false );
|
||||
|
||||
@ -3849,47 +3910,24 @@ $.Drawer.prototype = {
|
||||
continue;
|
||||
}
|
||||
|
||||
var boundsTL = tile.bounds.getTopLeft();
|
||||
var boundsSize = tile.bounds.getSize();
|
||||
var positionC = this.viewport.pixelFromPoint(boundsTL, true);
|
||||
var sizeC = this.viewport.deltaPixelsFromPoints(boundsSize, true);
|
||||
|
||||
if (!this.tileOverlap) {
|
||||
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;
|
||||
this._positionTile(
|
||||
tile,
|
||||
viewportCenter,
|
||||
levelVisibility
|
||||
);
|
||||
|
||||
if ( tile.loaded ) {
|
||||
if (!tile.blendStart) {
|
||||
tile.blendStart = currentTime;
|
||||
}
|
||||
|
||||
var deltaTime = currentTime - tile.blendStart;
|
||||
var opacity = _min(1, deltaTime / blendTimeMillis);
|
||||
updateAgain = this._blendTile(
|
||||
tile,
|
||||
x, y,
|
||||
level,
|
||||
levelOpacity,
|
||||
currentTime
|
||||
);
|
||||
|
||||
if (alwaysBlend) {
|
||||
opacity *= levelOpacity;
|
||||
}
|
||||
|
||||
tile.opacity = opacity;
|
||||
|
||||
_lastDrawn.push(tile);
|
||||
|
||||
if (opacity == 1) {
|
||||
this._setCoverage(level, x, y, true);
|
||||
} else if (deltaTime < blendTimeMillis) {
|
||||
updateAgain = true;
|
||||
}
|
||||
} else if ( tile.Loading ) {
|
||||
//do nothing
|
||||
} else {
|
||||
best = this._compareTiles( best, tile );
|
||||
}
|
||||
@ -3901,59 +3939,138 @@ $.Drawer.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = _lastDrawn.length - 1; i >= 0; i--) {
|
||||
var tile = _lastDrawn[i];
|
||||
this._drawTiles();
|
||||
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 ) {
|
||||
tile.drawCanvas(_context);
|
||||
tile.drawCanvas( this.context );
|
||||
} else {
|
||||
tile.drawHTML(_canvas);
|
||||
tile.drawHTML( this.canvas );
|
||||
}
|
||||
|
||||
tile.beingDrawn = true;
|
||||
}
|
||||
},
|
||||
|
||||
_drawOverlays: function(){
|
||||
var i,
|
||||
length = this.overlays.length;
|
||||
for ( i = 0; i < length; i++ ) {
|
||||
this._drawOverlay( this.overlays[ i ] );
|
||||
}
|
||||
},
|
||||
|
||||
_drawOverlay: function( overlay ){
|
||||
|
||||
var numOverlays = this.overlays.length;
|
||||
for (var i = 0; i < numOverlays; i++) {
|
||||
var overlay = this.overlays[i];
|
||||
var bounds = overlay.bounds;
|
||||
|
||||
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
|
||||
}
|
||||
overlay.position = this.viewport.pixelFromPoint(
|
||||
bounds.getTopLeft(),
|
||||
true
|
||||
);
|
||||
overlay.size = this.viewport.deltaPixelsFromPoints(
|
||||
bounds.getSize(),
|
||||
true
|
||||
);
|
||||
overlay.drawHTML( this.container );
|
||||
},
|
||||
|
||||
addOverlay: function( element, location, placement ) {
|
||||
element = $.getElement( element );
|
||||
|
||||
addOverlay: function(elmt, loc, placement) {
|
||||
var elmt = $.getElement(elmt);
|
||||
|
||||
if (this._getOverlayIndex(elmt) >= 0) {
|
||||
return; // they're trying to add a duplicate overlay
|
||||
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;
|
||||
},
|
||||
|
||||
updateOverlay: function(elmt, loc, placement) {
|
||||
var elmt = $.getElement(elmt);
|
||||
var i = this._getOverlayIndex(elmt);
|
||||
updateOverlay: function( element, location, placement ) {
|
||||
var i;
|
||||
|
||||
element = $.getElement( element );
|
||||
i = this._getOverlayIndex( element );
|
||||
|
||||
if ( i >= 0 ) {
|
||||
this.overlays[i].update(loc, placement);
|
||||
this.overlays[ i ].update( location, placement );
|
||||
this.updateAgain = true;
|
||||
}
|
||||
},
|
||||
|
||||
removeOverlay: function(elmt) {
|
||||
var elmt = $.getElement(elmt);
|
||||
var i = this._getOverlayIndex(elmt);
|
||||
removeOverlay: function( element ) {
|
||||
var i;
|
||||
|
||||
element = $.getElement( element );
|
||||
i = this._getOverlayIndex( element );
|
||||
|
||||
if ( i >= 0 ) {
|
||||
this.overlays[ i ].destroy();
|
||||
|
448
src/drawer.js
448
src/drawer.js
@ -84,6 +84,13 @@ $.Drawer.prototype = {
|
||||
|
||||
|
||||
_getTile: function( level, x, y, time, numTilesX, numTilesY ) {
|
||||
var xMod,
|
||||
yMod,
|
||||
bounds,
|
||||
exists,
|
||||
url,
|
||||
tile;
|
||||
|
||||
if ( !this.tilesMatrix[ level ] ) {
|
||||
this.tilesMatrix[ level ] = {};
|
||||
}
|
||||
@ -92,20 +99,26 @@ $.Drawer.prototype = {
|
||||
}
|
||||
|
||||
if ( !this.tilesMatrix[ level ][ x ][ y ] ) {
|
||||
var xMod = (numTilesX + (x % numTilesX)) % numTilesX;
|
||||
var yMod = (numTilesY + (y % numTilesY)) % numTilesY;
|
||||
var bounds = this.source.getTileBounds(level, xMod, yMod);
|
||||
var exists = this.source.tileExists(level, xMod, yMod);
|
||||
var url = this.source.getTileUrl(level, xMod, yMod);
|
||||
xMod = ( numTilesX + ( x % numTilesX ) ) % numTilesX;
|
||||
yMod = ( numTilesY + ( y % numTilesY ) ) % numTilesY;
|
||||
bounds = this.source.getTileBounds( level, xMod, yMod );
|
||||
exists = this.source.tileExists( level, xMod, yMod );
|
||||
url = this.source.getTileUrl( level, xMod, yMod );
|
||||
|
||||
bounds.x += 1.0 * ( x - xMod ) / numTilesX;
|
||||
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;
|
||||
|
||||
return tile;
|
||||
@ -124,6 +137,17 @@ $.Drawer.prototype = {
|
||||
},
|
||||
|
||||
_onTileLoad: function(tile, time, image) {
|
||||
var insertionIndex,
|
||||
cutoff,
|
||||
worstTile,
|
||||
worstTime,
|
||||
worstLevel,
|
||||
worstTileIndex,
|
||||
prevTile,
|
||||
prevTime,
|
||||
prevLevel,
|
||||
i;
|
||||
|
||||
tile.loading = false;
|
||||
|
||||
if ( this.midUpdate ) {
|
||||
@ -141,16 +165,16 @@ $.Drawer.prototype = {
|
||||
tile.loaded = true;
|
||||
tile.image = image;
|
||||
|
||||
var insertionIndex = this.tilesLoaded.length;
|
||||
insertionIndex = this.tilesLoaded.length;
|
||||
|
||||
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;
|
||||
var worstTileIndex = -1;
|
||||
worstTile = null;
|
||||
worstTileIndex = -1;
|
||||
|
||||
for (var i = this.tilesLoaded.length - 1; i >= 0; i--) {
|
||||
var prevTile = this.tilesLoaded[i];
|
||||
for ( i = this.tilesLoaded.length - 1; i >= 0; i-- ) {
|
||||
prevTile = this.tilesLoaded[ i ];
|
||||
|
||||
if ( prevTile.level <= this.cutoff || prevTile.beingDrawn ) {
|
||||
continue;
|
||||
@ -160,10 +184,10 @@ $.Drawer.prototype = {
|
||||
continue;
|
||||
}
|
||||
|
||||
var prevTime = prevTile.lastTouchTime;
|
||||
var worstTime = worstTile.lastTouchTime;
|
||||
var prevLevel = prevTile.level;
|
||||
var worstLevel = worstTile.level;
|
||||
prevTime = prevTile.lastTouchTime;
|
||||
worstTime = worstTile.lastTouchTime;
|
||||
prevLevel = prevTile.level;
|
||||
worstLevel = worstTile.level;
|
||||
|
||||
if ( prevTime < worstTime ||
|
||||
( prevTime == worstTime && prevLevel > worstLevel ) ) {
|
||||
@ -199,16 +223,20 @@ $.Drawer.prototype = {
|
||||
* levels that are within the image bounds, however, do not.
|
||||
*/
|
||||
_providesCoverage: function( level, x, y ) {
|
||||
var rows,
|
||||
cols,
|
||||
i, j;
|
||||
|
||||
if ( !this.coverage[ level ] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( x === undefined || y === undefined ) {
|
||||
var rows = this.coverage[level];
|
||||
for (var i in rows) {
|
||||
rows = this.coverage[ level ];
|
||||
for ( i in rows ) {
|
||||
if ( rows.hasOwnProperty( i ) ) {
|
||||
var cols = rows[i];
|
||||
for (var j in cols) {
|
||||
cols = rows[ i ];
|
||||
for ( j in cols ) {
|
||||
if ( cols.hasOwnProperty( j ) && !cols[ j ] ) {
|
||||
return false;
|
||||
}
|
||||
@ -219,9 +247,11 @@ $.Drawer.prototype = {
|
||||
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] === true);
|
||||
this.coverage[ level ][ x ][ y ] === true
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -233,10 +263,12 @@ $.Drawer.prototype = {
|
||||
if ( x === undefined || y === undefined ) {
|
||||
return this._providesCoverage( level + 1 );
|
||||
} else {
|
||||
return (this._providesCoverage(level + 1, 2 * x, 2 * y) &&
|
||||
return (
|
||||
this._providesCoverage( level + 1, 2 * x, 2 * y ) &&
|
||||
this._providesCoverage( level + 1, 2 * x, 2 * y + 1 ) &&
|
||||
this._providesCoverage( level + 1, 2 * x + 1, 2 * y ) &&
|
||||
this._providesCoverage(level + 1, 2 * x + 1, 2 * y + 1));
|
||||
this._providesCoverage( level + 1, 2 * x + 1, 2 * y + 1 )
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
@ -245,8 +277,9 @@ $.Drawer.prototype = {
|
||||
*/
|
||||
_setCoverage: function( level, x, y, covers ) {
|
||||
if ( !this.coverage[ level ] ) {
|
||||
$.Debug.error("Setting coverage for a tile before its " +
|
||||
"level's coverage has been reset: " + level);
|
||||
$.Debug.error(
|
||||
"Setting coverage for a tile before its level's coverage has been reset: " + level
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -285,7 +318,8 @@ $.Drawer.prototype = {
|
||||
|
||||
|
||||
_getOverlayIndex: function( elmt ) {
|
||||
for (var i = this.overlays.length - 1; i >= 0; i--) {
|
||||
var i;
|
||||
for ( i = this.overlays.length - 1; i >= 0; i-- ) {
|
||||
if ( this.overlays[ i ].elmt == elmt ) {
|
||||
return i;
|
||||
}
|
||||
@ -298,30 +332,68 @@ $.Drawer.prototype = {
|
||||
_updateActual: function() {
|
||||
this.updateAgain = false;
|
||||
|
||||
var _canvas = this.canvas;
|
||||
var _context = this.context;
|
||||
var _container = this.container;
|
||||
var _lastDrawn = this.lastDrawn;
|
||||
var i, x, y,
|
||||
tile,
|
||||
tileTL,
|
||||
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;
|
||||
}
|
||||
|
||||
var viewportSize = this.viewport.getContainerSize();
|
||||
var viewportWidth = viewportSize.x;
|
||||
var viewportHeight = viewportSize.y;
|
||||
|
||||
_canvas.innerHTML = "";
|
||||
this.canvas.innerHTML = "";
|
||||
if ( USE_CANVAS ) {
|
||||
_canvas.width = viewportWidth;
|
||||
_canvas.height = viewportHeight;
|
||||
_context.clearRect(0, 0, viewportWidth, viewportHeight);
|
||||
this.canvas.width = viewportWidth;
|
||||
this.canvas.height = viewportHeight;
|
||||
this.context.clearRect( 0, 0, viewportWidth, viewportHeight );
|
||||
}
|
||||
|
||||
var viewportBounds = this.viewport.getBounds(true);
|
||||
var viewportTL = viewportBounds.getTopLeft();
|
||||
var viewportBR = viewportBounds.getBottomRight();
|
||||
if ( !this.config.wrapHorizontal &&
|
||||
( viewportBR.x < 0 || viewportTL.x > 1 ) ) {
|
||||
return;
|
||||
@ -331,51 +403,31 @@ $.Drawer.prototype = {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
var _abs = Math.abs;
|
||||
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 ( !this.config.wrapHorizontal ) {
|
||||
viewportTL.x = Math.max( viewportTL.x, 0 );
|
||||
viewportBR.x = Math.min( viewportBR.x, 1 );
|
||||
}
|
||||
if (!wrapVertical) {
|
||||
viewportTL.y = _max(viewportTL.y, 0);
|
||||
viewportBR.y = _min(viewportBR.y, this.normHeight);
|
||||
if ( !this.config.wrapVertical ) {
|
||||
viewportTL.y = Math.max( viewportTL.y, 0 );
|
||||
viewportBR.y = Math.min( viewportBR.y, this.normHeight );
|
||||
}
|
||||
|
||||
var best = null;
|
||||
var haveDrawn = false;
|
||||
var currentTime = new Date().getTime();
|
||||
lowestLevel = Math.min( lowestLevel, highestLevel );
|
||||
|
||||
var viewportCenter = this.viewport.pixelFromPoint(this.viewport.getCenter());
|
||||
var zeroRatioT = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), false).x;
|
||||
var optimalPixelRatio = immediateRender ? 1 : zeroRatioT;
|
||||
|
||||
var lowestLevel = _max(this.minLevel, _floor(_log(this.config.minZoomImageRatio) / _log(2)));
|
||||
var zeroRatioC = this.viewport.deltaPixelsFromPoints(this.source.getPixelRatio(0), true).x;
|
||||
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!
|
||||
for ( level = highestLevel; level >= lowestLevel; level-- ) {
|
||||
drawLevel = false;
|
||||
// note the .x!
|
||||
renderPixelRatioC = this.viewport.deltaPixelsFromPoints(
|
||||
this.source.getPixelRatio( level ),
|
||||
true
|
||||
).x;
|
||||
renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
||||
this.source.getPixelRatio( level ),
|
||||
false
|
||||
).x;
|
||||
|
||||
if ( ( !haveDrawn && renderPixelRatioC >= MIN_PIXEL_RATIO ) ||
|
||||
level == lowestLevel) {
|
||||
( level == lowestLevel ) ) {
|
||||
drawLevel = true;
|
||||
haveDrawn = true;
|
||||
} else if ( !haveDrawn ) {
|
||||
@ -384,28 +436,34 @@ $.Drawer.prototype = {
|
||||
|
||||
this._resetCoverage( level );
|
||||
|
||||
var levelOpacity = _min(1, (renderPixelRatioC - 0.5) / 0.5);
|
||||
var renderPixelRatioT = this.viewport.deltaPixelsFromPoints(
|
||||
this.source.getPixelRatio(level), false).x;
|
||||
var levelVisibility = optimalPixelRatio /
|
||||
_abs(optimalPixelRatio - renderPixelRatioT);
|
||||
levelOpacity = Math.min( 1, ( renderPixelRatioC - 0.5 ) / 0.5 );
|
||||
levelVisibility = optimalRatio / Math.abs(
|
||||
optimalRatio - renderPixelRatioT
|
||||
);
|
||||
|
||||
var tileTL = this.source.getTileAtPoint(level, viewportTL);
|
||||
var tileBR = this.source.getTileAtPoint(level, viewportBR);
|
||||
var numTiles = numberOfTiles( this, level );
|
||||
var numTilesX = numTiles.x;
|
||||
var numTilesY = numTiles.y;
|
||||
if (!wrapHorizontal) {
|
||||
tileBR.x = _min(tileBR.x, numTilesX - 1);
|
||||
tileTL = this.source.getTileAtPoint( level, viewportTL );
|
||||
tileBR = this.source.getTileAtPoint( level, viewportBR );
|
||||
numTiles = numberOfTiles( this, level );
|
||||
numTilesX = numTiles.x;
|
||||
numTilesY = numTiles.y;
|
||||
|
||||
if ( !this.config.wrapHorizontal ) {
|
||||
tileBR.x = Math.min( tileBR.x, numTilesX - 1 );
|
||||
}
|
||||
if (!wrapVertical) {
|
||||
tileBR.y = _min(tileBR.y, numTilesY - 1);
|
||||
if ( !this.config.wrapVertical ) {
|
||||
tileBR.y = Math.min( tileBR.y, numTilesY - 1 );
|
||||
}
|
||||
|
||||
for (var x = tileTL.x; x <= tileBR.x; x++) {
|
||||
for (var y = tileTL.y; y <= tileBR.y; y++) {
|
||||
var tile = this._getTile(level, x, y, currentTime, numTilesX, numTilesY);
|
||||
var drawTile = drawLevel;
|
||||
for ( x = tileTL.x; x <= tileBR.x; x++ ) {
|
||||
for ( y = tileTL.y; y <= tileBR.y; y++ ) {
|
||||
drawTile = drawLevel;
|
||||
tile = this._getTile(
|
||||
level,
|
||||
x, y,
|
||||
currentTime,
|
||||
numTilesX,
|
||||
numTilesY
|
||||
);
|
||||
|
||||
this._setCoverage( level, x, y, false );
|
||||
|
||||
@ -425,47 +483,24 @@ $.Drawer.prototype = {
|
||||
continue;
|
||||
}
|
||||
|
||||
var boundsTL = tile.bounds.getTopLeft();
|
||||
var boundsSize = tile.bounds.getSize();
|
||||
var positionC = this.viewport.pixelFromPoint(boundsTL, true);
|
||||
var sizeC = this.viewport.deltaPixelsFromPoints(boundsSize, true);
|
||||
|
||||
if (!this.tileOverlap) {
|
||||
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;
|
||||
this._positionTile(
|
||||
tile,
|
||||
viewportCenter,
|
||||
levelVisibility
|
||||
);
|
||||
|
||||
if ( tile.loaded ) {
|
||||
if (!tile.blendStart) {
|
||||
tile.blendStart = currentTime;
|
||||
}
|
||||
|
||||
var deltaTime = currentTime - tile.blendStart;
|
||||
var opacity = _min(1, deltaTime / blendTimeMillis);
|
||||
updateAgain = this._blendTile(
|
||||
tile,
|
||||
x, y,
|
||||
level,
|
||||
levelOpacity,
|
||||
currentTime
|
||||
);
|
||||
|
||||
if (alwaysBlend) {
|
||||
opacity *= levelOpacity;
|
||||
}
|
||||
|
||||
tile.opacity = opacity;
|
||||
|
||||
_lastDrawn.push(tile);
|
||||
|
||||
if (opacity == 1) {
|
||||
this._setCoverage(level, x, y, true);
|
||||
} else if (deltaTime < blendTimeMillis) {
|
||||
updateAgain = true;
|
||||
}
|
||||
} else if ( tile.Loading ) {
|
||||
//do nothing
|
||||
} else {
|
||||
best = this._compareTiles( best, tile );
|
||||
}
|
||||
@ -477,59 +512,138 @@ $.Drawer.prototype = {
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = _lastDrawn.length - 1; i >= 0; i--) {
|
||||
var tile = _lastDrawn[i];
|
||||
this._drawTiles();
|
||||
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 ) {
|
||||
tile.drawCanvas(_context);
|
||||
tile.drawCanvas( this.context );
|
||||
} else {
|
||||
tile.drawHTML(_canvas);
|
||||
tile.drawHTML( this.canvas );
|
||||
}
|
||||
|
||||
tile.beingDrawn = true;
|
||||
}
|
||||
},
|
||||
|
||||
_drawOverlays: function(){
|
||||
var i,
|
||||
length = this.overlays.length;
|
||||
for ( i = 0; i < length; i++ ) {
|
||||
this._drawOverlay( this.overlays[ i ] );
|
||||
}
|
||||
},
|
||||
|
||||
_drawOverlay: function( overlay ){
|
||||
|
||||
var numOverlays = this.overlays.length;
|
||||
for (var i = 0; i < numOverlays; i++) {
|
||||
var overlay = this.overlays[i];
|
||||
var bounds = overlay.bounds;
|
||||
|
||||
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
|
||||
}
|
||||
overlay.position = this.viewport.pixelFromPoint(
|
||||
bounds.getTopLeft(),
|
||||
true
|
||||
);
|
||||
overlay.size = this.viewport.deltaPixelsFromPoints(
|
||||
bounds.getSize(),
|
||||
true
|
||||
);
|
||||
overlay.drawHTML( this.container );
|
||||
},
|
||||
|
||||
addOverlay: function( element, location, placement ) {
|
||||
element = $.getElement( element );
|
||||
|
||||
addOverlay: function(elmt, loc, placement) {
|
||||
var elmt = $.getElement(elmt);
|
||||
|
||||
if (this._getOverlayIndex(elmt) >= 0) {
|
||||
return; // they're trying to add a duplicate overlay
|
||||
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;
|
||||
},
|
||||
|
||||
updateOverlay: function(elmt, loc, placement) {
|
||||
var elmt = $.getElement(elmt);
|
||||
var i = this._getOverlayIndex(elmt);
|
||||
updateOverlay: function( element, location, placement ) {
|
||||
var i;
|
||||
|
||||
element = $.getElement( element );
|
||||
i = this._getOverlayIndex( element );
|
||||
|
||||
if ( i >= 0 ) {
|
||||
this.overlays[i].update(loc, placement);
|
||||
this.overlays[ i ].update( location, placement );
|
||||
this.updateAgain = true;
|
||||
}
|
||||
},
|
||||
|
||||
removeOverlay: function(elmt) {
|
||||
var elmt = $.getElement(elmt);
|
||||
var i = this._getOverlayIndex(elmt);
|
||||
removeOverlay: function( element ) {
|
||||
var i;
|
||||
|
||||
element = $.getElement( element );
|
||||
i = this._getOverlayIndex( element );
|
||||
|
||||
if ( i >= 0 ) {
|
||||
this.overlays[ i ].destroy();
|
||||
|
@ -330,11 +330,13 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
getElementPosition: function( element ) {
|
||||
var element = $.getElement( element );
|
||||
var result = new $.Point(),
|
||||
isFixed,
|
||||
offsetParent;
|
||||
|
||||
var isFixed = $.getElementStyle( element ).position == "fixed",
|
||||
offsetParent = $.getOffsetParent( element, isFixed ),
|
||||
result = new $.Point();
|
||||
element = $.getElement( element );
|
||||
isFixed = $.getElementStyle( element ).position == "fixed";
|
||||
offsetParent = $.getOffsetParent( element, isFixed );
|
||||
|
||||
while ( offsetParent ) {
|
||||
|
||||
@ -354,7 +356,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
getElementSize: function( element ) {
|
||||
var element = $.getElement( element );
|
||||
element = $.getElement( element );
|
||||
|
||||
return new $.Point(
|
||||
element.clientWidth,
|
||||
@ -363,7 +365,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
getElementStyle: function( element ) {
|
||||
var element = $.getElement( element );
|
||||
element = $.getElement( element );
|
||||
|
||||
if ( element.currentStyle ) {
|
||||
return element.currentStyle;
|
||||
@ -379,15 +381,14 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
getMousePosition: function( event ) {
|
||||
var event = $.getEvent( event );
|
||||
|
||||
var result = new $.Point();
|
||||
|
||||
event = $.getEvent( event );
|
||||
|
||||
if ( typeof( event.pageX ) == "number" ) {
|
||||
result.x = event.pageX;
|
||||
result.y = event.pageY;
|
||||
} else if ( typeof( event.clientX ) == "number" ) {
|
||||
|
||||
result.x =
|
||||
event.clientX +
|
||||
document.body.scrollLeft +
|
||||
@ -446,18 +447,19 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
imageFormatSupported: function( extension ) {
|
||||
var extension = extension ? extension : "";
|
||||
extension = extension ? extension : "";
|
||||
return !!FILEFORMATS[ extension.toLowerCase() ];
|
||||
},
|
||||
|
||||
makeCenteredNode: function( element ) {
|
||||
var element = $.getElement( element );
|
||||
|
||||
var div = $.makeNeutralElement( "div" ),
|
||||
html = [],
|
||||
innerDiv,
|
||||
innerDivs;
|
||||
|
||||
element = $.getElement( element );
|
||||
|
||||
//TODO: I dont understand the use of # inside the style attributes
|
||||
// below. Invetigate the results of the constructed html in
|
||||
// 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 ) {
|
||||
var element = $.getElement( element );
|
||||
|
||||
var previousFilter,
|
||||
ieOpacity,
|
||||
ieFilter;
|
||||
|
||||
element = $.getElement( element );
|
||||
|
||||
if ( usesAlpha && !$.Browser.alpha ) {
|
||||
opacity = Math.round( opacity );
|
||||
}
|
||||
@ -573,7 +576,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
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
|
||||
// defining this function once based on the same logic
|
||||
@ -592,7 +595,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
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
|
||||
// defining this function once based on the same logic
|
||||
@ -611,7 +614,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
cancelEvent: function( event ) {
|
||||
var event = $.getEvent( event );
|
||||
event = $.getEvent( event );
|
||||
|
||||
if ( event.preventDefault ) {
|
||||
event.preventDefault(); // W3C for preventing default
|
||||
@ -622,7 +625,7 @@ OpenSeadragon = window.OpenSeadragon || (function(){
|
||||
},
|
||||
|
||||
stopEvent: function( event ) {
|
||||
var event = $.getEvent( event );
|
||||
event = $.getEvent( event );
|
||||
|
||||
if ( event.stopPropagation ) {
|
||||
event.stopPropagation(); // W3C for stopping propagation
|
||||
|
Loading…
Reference in New Issue
Block a user