Refactor backBuffer tile code out of generic Tile base class into Tile.Image to make it nicer when subclassing Tile for other needs. (Closes #1645) r=elemoine.
git-svn-id: http://svn.openlayers.org/trunk/openlayers@7667 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
+2
-128
@@ -80,38 +80,6 @@ OpenLayers.Tile = OpenLayers.Class({
|
|||||||
*/
|
*/
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
|
|
||||||
/**
|
|
||||||
* Property: isBackBuffer
|
|
||||||
* {Boolean} Is this tile a back buffer tile?
|
|
||||||
*/
|
|
||||||
isBackBuffer: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Property: lastRatio
|
|
||||||
* {Float} Used in transition code only. This is the previous ratio
|
|
||||||
* of the back buffer tile resolution to the map resolution. Compared
|
|
||||||
* with the current ratio to determine if zooming occurred.
|
|
||||||
*/
|
|
||||||
lastRatio: 1,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Property: isFirstDraw
|
|
||||||
* {Boolean} Is this the first time the tile is being drawn?
|
|
||||||
* This is used to force resetBackBuffer to synchronize
|
|
||||||
* the backBufferTile with the foreground tile the first time
|
|
||||||
* the foreground tile loads so that if the user zooms
|
|
||||||
* before the layer has fully loaded, the backBufferTile for
|
|
||||||
* tiles that have been loaded can be used.
|
|
||||||
*/
|
|
||||||
isFirstDraw: true,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Property: backBufferTile
|
|
||||||
* {<OpenLayers.Tile>} A clone of the tile used to create transition
|
|
||||||
* effects when the tile is moved or changes resolution.
|
|
||||||
*/
|
|
||||||
backBufferTile: null,
|
|
||||||
|
|
||||||
/** TBD 3.0 -- remove 'url' from the list of parameters to the constructor.
|
/** TBD 3.0 -- remove 'url' from the list of parameters to the constructor.
|
||||||
* there is no need for the base tile class to have a url.
|
* there is no need for the base tile class to have a url.
|
||||||
*
|
*
|
||||||
@@ -157,13 +125,6 @@ OpenLayers.Tile = OpenLayers.Class({
|
|||||||
* Nullify references to prevent circular references and memory leaks.
|
* Nullify references to prevent circular references and memory leaks.
|
||||||
*/
|
*/
|
||||||
destroy:function() {
|
destroy:function() {
|
||||||
if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS,
|
|
||||||
this.layer.transitionEffect) != -1) {
|
|
||||||
this.layer.events.unregister("loadend", this, this.resetBackBuffer);
|
|
||||||
this.events.unregister('loadend', this, this.resetBackBuffer);
|
|
||||||
} else {
|
|
||||||
this.events.unregister('loadend', this, this.showTile);
|
|
||||||
}
|
|
||||||
this.layer = null;
|
this.layer = null;
|
||||||
this.bounds = null;
|
this.bounds = null;
|
||||||
this.size = null;
|
this.size = null;
|
||||||
@@ -171,12 +132,6 @@ OpenLayers.Tile = OpenLayers.Class({
|
|||||||
|
|
||||||
this.events.destroy();
|
this.events.destroy();
|
||||||
this.events = null;
|
this.events = null;
|
||||||
|
|
||||||
/* clean up the backBufferTile if it exists */
|
|
||||||
if (this.backBufferTile) {
|
|
||||||
this.backBufferTile.destroy();
|
|
||||||
this.backBufferTile = null;
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -221,50 +176,12 @@ OpenLayers.Tile = OpenLayers.Class({
|
|||||||
|
|
||||||
// The only case where we *wouldn't* want to draw the tile is if the
|
// The only case where we *wouldn't* want to draw the tile is if the
|
||||||
// tile is outside its layer's maxExtent.
|
// tile is outside its layer's maxExtent.
|
||||||
var drawTile = (withinMaxExtent || this.layer.displayOutsideMaxExtent);
|
this.shouldDraw = (withinMaxExtent || this.layer.displayOutsideMaxExtent);
|
||||||
|
|
||||||
if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) {
|
|
||||||
if (drawTile) {
|
|
||||||
//we use a clone of this tile to create a double buffer for visual
|
|
||||||
//continuity. The backBufferTile is used to create transition
|
|
||||||
//effects while the tile in the grid is repositioned and redrawn
|
|
||||||
if (!this.backBufferTile) {
|
|
||||||
this.backBufferTile = this.clone();
|
|
||||||
this.backBufferTile.hide();
|
|
||||||
// this is important. It allows the backBuffer to place itself
|
|
||||||
// appropriately in the DOM. The Image subclass needs to put
|
|
||||||
// the backBufferTile behind the main tile so the tiles can
|
|
||||||
// load over top and display as soon as they are loaded.
|
|
||||||
this.backBufferTile.isBackBuffer = true;
|
|
||||||
|
|
||||||
// potentially end any transition effects when the tile loads
|
|
||||||
this.events.register('loadend', this, this.resetBackBuffer);
|
|
||||||
|
|
||||||
// clear transition back buffer tile only after all tiles in
|
|
||||||
// this layer have loaded to avoid visual glitches
|
|
||||||
this.layer.events.register("loadend", this, this.resetBackBuffer);
|
|
||||||
}
|
|
||||||
// run any transition effects
|
|
||||||
this.startTransition();
|
|
||||||
} else {
|
|
||||||
// if we aren't going to draw the tile, then the backBuffer should
|
|
||||||
// be hidden too!
|
|
||||||
if (this.backBufferTile) {
|
|
||||||
this.backBufferTile.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (drawTile && this.isFirstDraw) {
|
|
||||||
this.events.register('loadend', this, this.showTile);
|
|
||||||
this.isFirstDraw = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.shouldDraw = drawTile;
|
|
||||||
|
|
||||||
//clear tile's contents and mark as not drawn
|
//clear tile's contents and mark as not drawn
|
||||||
this.clear();
|
this.clear();
|
||||||
|
|
||||||
return drawTile;
|
return this.shouldDraw;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -336,49 +253,6 @@ OpenLayers.Tile = OpenLayers.Class({
|
|||||||
return bounds;
|
return bounds;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* Method: startTransition
|
|
||||||
* Prepare the tile for a transition effect. To be
|
|
||||||
* implemented by subclasses.
|
|
||||||
*/
|
|
||||||
startTransition: function() {},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Method: resetBackBuffer
|
|
||||||
* Triggered by two different events, layer loadend, and tile loadend.
|
|
||||||
* In any of these cases, we check to see if we can hide the
|
|
||||||
* backBufferTile yet and update its parameters to match the
|
|
||||||
* foreground tile.
|
|
||||||
*
|
|
||||||
* Basic logic:
|
|
||||||
* - If the backBufferTile hasn't been drawn yet, reset it
|
|
||||||
* - If layer is still loading, show foreground tile but don't hide
|
|
||||||
* the backBufferTile yet
|
|
||||||
* - If layer is done loading, reset backBuffer tile and show
|
|
||||||
* foreground tile
|
|
||||||
*/
|
|
||||||
resetBackBuffer: function() {
|
|
||||||
this.showTile();
|
|
||||||
if (this.backBufferTile &&
|
|
||||||
(this.isFirstDraw || !this.layer.numLoadingTiles)) {
|
|
||||||
this.isFirstDraw = false;
|
|
||||||
// check to see if the backBufferTile is within the max extents
|
|
||||||
// before rendering it
|
|
||||||
var maxExtent = this.layer.maxExtent;
|
|
||||||
var withinMaxExtent = (maxExtent &&
|
|
||||||
this.bounds.intersectsBounds(maxExtent, false));
|
|
||||||
if (withinMaxExtent) {
|
|
||||||
this.backBufferTile.position = this.position;
|
|
||||||
this.backBufferTile.bounds = this.bounds;
|
|
||||||
this.backBufferTile.size = this.size;
|
|
||||||
this.backBufferTile.imageSize = this.layer.imageSize || this.size;
|
|
||||||
this.backBufferTile.imageOffset = this.layer.imageOffset;
|
|
||||||
this.backBufferTile.resolution = this.layer.getResolution();
|
|
||||||
this.backBufferTile.renderTile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: showTile
|
* Method: showTile
|
||||||
* Show the tile only if it should be drawn.
|
* Show the tile only if it should be drawn.
|
||||||
|
|||||||
@@ -38,13 +38,44 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
*/
|
*/
|
||||||
frame: null,
|
frame: null,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Property: layerAlphaHack
|
* Property: layerAlphaHack
|
||||||
* {Boolean} True if the png alpha hack needs to be applied on the layer's div.
|
* {Boolean} True if the png alpha hack needs to be applied on the layer's div.
|
||||||
*/
|
*/
|
||||||
layerAlphaHack: null,
|
layerAlphaHack: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: isBackBuffer
|
||||||
|
* {Boolean} Is this tile a back buffer tile?
|
||||||
|
*/
|
||||||
|
isBackBuffer: false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: lastRatio
|
||||||
|
* {Float} Used in transition code only. This is the previous ratio
|
||||||
|
* of the back buffer tile resolution to the map resolution. Compared
|
||||||
|
* with the current ratio to determine if zooming occurred.
|
||||||
|
*/
|
||||||
|
lastRatio: 1,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: isFirstDraw
|
||||||
|
* {Boolean} Is this the first time the tile is being drawn?
|
||||||
|
* This is used to force resetBackBuffer to synchronize
|
||||||
|
* the backBufferTile with the foreground tile the first time
|
||||||
|
* the foreground tile loads so that if the user zooms
|
||||||
|
* before the layer has fully loaded, the backBufferTile for
|
||||||
|
* tiles that have been loaded can be used.
|
||||||
|
*/
|
||||||
|
isFirstDraw: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: backBufferTile
|
||||||
|
* {<OpenLayers.Tile>} A clone of the tile used to create transition
|
||||||
|
* effects when the tile is moved or changes resolution.
|
||||||
|
*/
|
||||||
|
backBufferTile: null,
|
||||||
|
|
||||||
/** TBD 3.0 - reorder the parameters to the init function to remove
|
/** TBD 3.0 - reorder the parameters to the init function to remove
|
||||||
* URL. the getUrl() function on the layer gets called on
|
* URL. the getUrl() function on the layer gets called on
|
||||||
* each draw(), so no need to specify it here.
|
* each draw(), so no need to specify it here.
|
||||||
@@ -93,6 +124,15 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
this.layer.div.removeChild(this.frame);
|
this.layer.div.removeChild(this.frame);
|
||||||
}
|
}
|
||||||
this.frame = null;
|
this.frame = null;
|
||||||
|
|
||||||
|
/* clean up the backBufferTile if it exists */
|
||||||
|
if (this.backBufferTile) {
|
||||||
|
this.backBufferTile.destroy();
|
||||||
|
this.backBufferTile = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.layer.events.unregister("loadend", this, this.resetBackBuffer);
|
||||||
|
|
||||||
OpenLayers.Tile.prototype.destroy.apply(this, arguments);
|
OpenLayers.Tile.prototype.destroy.apply(this, arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -135,7 +175,46 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
if (this.layer != this.layer.map.baseLayer && this.layer.reproject) {
|
if (this.layer != this.layer.map.baseLayer && this.layer.reproject) {
|
||||||
this.bounds = this.getBoundsFromBaseLayer(this.position);
|
this.bounds = this.getBoundsFromBaseLayer(this.position);
|
||||||
}
|
}
|
||||||
if (!OpenLayers.Tile.prototype.draw.apply(this, arguments)) {
|
var drawTile = OpenLayers.Tile.prototype.draw.apply(this, arguments);
|
||||||
|
|
||||||
|
if (OpenLayers.Util.indexOf(this.layer.SUPPORTED_TRANSITIONS, this.layer.transitionEffect) != -1) {
|
||||||
|
if (drawTile) {
|
||||||
|
//we use a clone of this tile to create a double buffer for visual
|
||||||
|
//continuity. The backBufferTile is used to create transition
|
||||||
|
//effects while the tile in the grid is repositioned and redrawn
|
||||||
|
if (!this.backBufferTile) {
|
||||||
|
this.backBufferTile = this.clone();
|
||||||
|
this.backBufferTile.hide();
|
||||||
|
// this is important. It allows the backBuffer to place itself
|
||||||
|
// appropriately in the DOM. The Image subclass needs to put
|
||||||
|
// the backBufferTile behind the main tile so the tiles can
|
||||||
|
// load over top and display as soon as they are loaded.
|
||||||
|
this.backBufferTile.isBackBuffer = true;
|
||||||
|
|
||||||
|
// potentially end any transition effects when the tile loads
|
||||||
|
this.events.register('loadend', this, this.resetBackBuffer);
|
||||||
|
|
||||||
|
// clear transition back buffer tile only after all tiles in
|
||||||
|
// this layer have loaded to avoid visual glitches
|
||||||
|
this.layer.events.register("loadend", this, this.resetBackBuffer);
|
||||||
|
}
|
||||||
|
// run any transition effects
|
||||||
|
this.startTransition();
|
||||||
|
} else {
|
||||||
|
// if we aren't going to draw the tile, then the backBuffer should
|
||||||
|
// be hidden too!
|
||||||
|
if (this.backBufferTile) {
|
||||||
|
this.backBufferTile.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (drawTile && this.isFirstDraw) {
|
||||||
|
this.events.register('loadend', this, this.showTile);
|
||||||
|
this.isFirstDraw = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!drawTile) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,6 +229,42 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
return this.renderTile();
|
return this.renderTile();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: resetBackBuffer
|
||||||
|
* Triggered by two different events, layer loadend, and tile loadend.
|
||||||
|
* In any of these cases, we check to see if we can hide the
|
||||||
|
* backBufferTile yet and update its parameters to match the
|
||||||
|
* foreground tile.
|
||||||
|
*
|
||||||
|
* Basic logic:
|
||||||
|
* - If the backBufferTile hasn't been drawn yet, reset it
|
||||||
|
* - If layer is still loading, show foreground tile but don't hide
|
||||||
|
* the backBufferTile yet
|
||||||
|
* - If layer is done loading, reset backBuffer tile and show
|
||||||
|
* foreground tile
|
||||||
|
*/
|
||||||
|
resetBackBuffer: function() {
|
||||||
|
this.showTile();
|
||||||
|
if (this.backBufferTile &&
|
||||||
|
(this.isFirstDraw || !this.layer.numLoadingTiles)) {
|
||||||
|
this.isFirstDraw = false;
|
||||||
|
// check to see if the backBufferTile is within the max extents
|
||||||
|
// before rendering it
|
||||||
|
var maxExtent = this.layer.maxExtent;
|
||||||
|
var withinMaxExtent = (maxExtent &&
|
||||||
|
this.bounds.intersectsBounds(maxExtent, false));
|
||||||
|
if (withinMaxExtent) {
|
||||||
|
this.backBufferTile.position = this.position;
|
||||||
|
this.backBufferTile.bounds = this.bounds;
|
||||||
|
this.backBufferTile.size = this.size;
|
||||||
|
this.backBufferTile.imageSize = this.layer.imageSize || this.size;
|
||||||
|
this.backBufferTile.imageOffset = this.layer.imageOffset;
|
||||||
|
this.backBufferTile.resolution = this.layer.getResolution();
|
||||||
|
this.backBufferTile.renderTile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: renderTile
|
* Method: renderTile
|
||||||
* Internal function to actually initialize the image tile,
|
* Internal function to actually initialize the image tile,
|
||||||
|
|||||||
Reference in New Issue
Block a user