New beforeload event and slightly changed loading sequence
Having the TileManager remove an image from the DOM, then setting the cached image, and then having to position it felt a bit awkward. With the new beforeload event, the setImage method and putting renderTile before positionTile, providing the cached image feels way more natural.
This commit is contained in:
@@ -20,6 +20,23 @@
|
|||||||
*/
|
*/
|
||||||
OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIProperty: events
|
||||||
|
* {<OpenLayers.Events>} An events object that handles all
|
||||||
|
* events on the tile.
|
||||||
|
*
|
||||||
|
* Register a listener for a particular event with the following syntax:
|
||||||
|
* (code)
|
||||||
|
* tile.events.register(type, obj, listener);
|
||||||
|
* (end)
|
||||||
|
*
|
||||||
|
* Supported event types (in addition to the <OpenLayers.Tile> events):
|
||||||
|
* beforeload - Triggered before an image is prepared for loading, when the
|
||||||
|
* url for the image is known already. Listeners may call <setImage> on
|
||||||
|
* the tile instance. If they do so, that image will be used and no new
|
||||||
|
* one will be created.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APIProperty: url
|
* APIProperty: url
|
||||||
* {String} The URL of the image being requested. No default. Filled in by
|
* {String} The URL of the image being requested. No default. Filled in by
|
||||||
@@ -164,8 +181,8 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
this._loadEvent = "loadstart";
|
this._loadEvent = "loadstart";
|
||||||
}
|
}
|
||||||
this.positionTile();
|
|
||||||
this.renderTile();
|
this.renderTile();
|
||||||
|
this.positionTile();
|
||||||
} else if (shouldDraw === false) {
|
} else if (shouldDraw === false) {
|
||||||
this.unload();
|
this.unload();
|
||||||
}
|
}
|
||||||
@@ -178,7 +195,6 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
* position it correctly, and set its url.
|
* position it correctly, and set its url.
|
||||||
*/
|
*/
|
||||||
renderTile: function() {
|
renderTile: function() {
|
||||||
this.layer.div.appendChild(this.getTile());
|
|
||||||
if (this.layer.async) {
|
if (this.layer.async) {
|
||||||
// Asynchronous image requests call the asynchronous getURL method
|
// Asynchronous image requests call the asynchronous getURL method
|
||||||
// on the layer to fetch an image that covers 'this.bounds'.
|
// on the layer to fetch an image that covers 'this.bounds'.
|
||||||
@@ -279,12 +295,26 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
|
|||||||
|
|
||||||
return this.imgDiv;
|
return this.imgDiv;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIMethod: setImage
|
||||||
|
* Sets the image element or this tile. This method should only be called
|
||||||
|
* from beforeload listeners.
|
||||||
|
*
|
||||||
|
* Paramters
|
||||||
|
* img - {HTMLImageElement} The image to use for this tile.
|
||||||
|
*/
|
||||||
|
setImage: function(img) {
|
||||||
|
this.imgDiv = img;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: initImage
|
* Method: initImage
|
||||||
* Creates the content for the frame on the tile.
|
* Creates the content for the frame on the tile.
|
||||||
*/
|
*/
|
||||||
initImage: function() {
|
initImage: function() {
|
||||||
|
this.events.triggerEvent('beforeload');
|
||||||
|
this.layer.div.appendChild(this.getTile());
|
||||||
this.events.triggerEvent(this._loadEvent);
|
this.events.triggerEvent(this._loadEvent);
|
||||||
var img = this.getImage();
|
var img = this.getImage();
|
||||||
if (this.url && img.getAttribute("src") == this.url) {
|
if (this.url && img.getAttribute("src") == this.url) {
|
||||||
|
|||||||
@@ -255,8 +255,8 @@ OpenLayers.TileManager = OpenLayers.Class({
|
|||||||
addTile: function(evt) {
|
addTile: function(evt) {
|
||||||
evt.tile.events.on({
|
evt.tile.events.on({
|
||||||
beforedraw: this.queueTileDraw,
|
beforedraw: this.queueTileDraw,
|
||||||
loadstart: this.manageTileCache,
|
beforeload: this.manageTileCache,
|
||||||
reload: this.manageTileCache,
|
loadend: this.addToCache,
|
||||||
unload: this.unloadTile,
|
unload: this.unloadTile,
|
||||||
scope: this
|
scope: this
|
||||||
});
|
});
|
||||||
@@ -273,8 +273,7 @@ OpenLayers.TileManager = OpenLayers.Class({
|
|||||||
var tile = evt.object;
|
var tile = evt.object;
|
||||||
tile.events.un({
|
tile.events.un({
|
||||||
beforedraw: this.queueTileDraw,
|
beforedraw: this.queueTileDraw,
|
||||||
loadstart: this.manageTileCache,
|
beforeload: this.manageTileCache,
|
||||||
reload: this.manageTileCache,
|
|
||||||
loadend: this.addToCache,
|
loadend: this.addToCache,
|
||||||
unload: this.unloadTile,
|
unload: this.unloadTile,
|
||||||
scope: this
|
scope: this
|
||||||
@@ -330,16 +329,9 @@ OpenLayers.TileManager = OpenLayers.Class({
|
|||||||
// only use image from cache if it is not on a layer already
|
// only use image from cache if it is not on a layer already
|
||||||
if (img && (!img.parentNode ||
|
if (img && (!img.parentNode ||
|
||||||
OpenLayers.Element.hasClass(img.parentNode, 'olBackBuffer'))) {
|
OpenLayers.Element.hasClass(img.parentNode, 'olBackBuffer'))) {
|
||||||
if (tile.imgDiv) {
|
tile.setImage(img);
|
||||||
tile.layer.div.removeChild(tile.imgDiv);
|
|
||||||
}
|
|
||||||
tile.imgDiv = img;
|
|
||||||
OpenLayers.Util.removeItem(this.tileCacheIndex, tile.url);
|
OpenLayers.Util.removeItem(this.tileCacheIndex, tile.url);
|
||||||
this.tileCacheIndex.push(tile.url);
|
this.tileCacheIndex.push(tile.url);
|
||||||
tile.positionTile();
|
|
||||||
tile.layer.div.appendChild(tile.imgDiv);
|
|
||||||
} else if (evt.type === 'loadstart') {
|
|
||||||
tile.events.register('loadend', this, this.addToCache);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -351,7 +343,6 @@ OpenLayers.TileManager = OpenLayers.Class({
|
|||||||
*/
|
*/
|
||||||
addToCache: function(evt) {
|
addToCache: function(evt) {
|
||||||
var tile = evt.object;
|
var tile = evt.object;
|
||||||
tile.events.unregister('loadend', this, this.addToCache);
|
|
||||||
if (!this.tileCache[tile.url]) {
|
if (!this.tileCache[tile.url]) {
|
||||||
if (!OpenLayers.Element.hasClass(tile.imgDiv, 'olImageLoadError')) {
|
if (!OpenLayers.Element.hasClass(tile.imgDiv, 'olImageLoadError')) {
|
||||||
if (this.tileCacheIndex.length >= this.cacheSize) {
|
if (this.tileCacheIndex.length >= this.cacheSize) {
|
||||||
|
|||||||
@@ -31,11 +31,11 @@
|
|||||||
var layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');
|
var layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');
|
||||||
map.addLayer(layer);
|
map.addLayer(layer);
|
||||||
map.setCenter([16, 48], 9);
|
map.setCenter([16, 48], 9);
|
||||||
var numTileListeners = layer.grid[0][0].events.listeners.reload.length;
|
var numTileListeners = layer.grid[0][0].events.listeners.beforeload.length;
|
||||||
var numLayerListeners = layer.events.listeners.retile.length;
|
var numLayerListeners = layer.events.listeners.retile.length;
|
||||||
var numMapListeners = map.events.listeners.preremovelayer.length;
|
var numMapListeners = map.events.listeners.preremovelayer.length;
|
||||||
tileManager.destroy();
|
tileManager.destroy();
|
||||||
t.eq(layer.grid[0][0].events.listeners.reload.length, numTileListeners - 1, "no listener on tile after destroy");
|
t.eq(layer.grid[0][0].events.listeners.beforeload.length, numTileListeners - 1, "no listener on tile after destroy");
|
||||||
t.eq(layer.events.listeners.retile.length, numLayerListeners - 1, "no listeners on layer after destroy");
|
t.eq(layer.events.listeners.retile.length, numLayerListeners - 1, "no listeners on layer after destroy");
|
||||||
t.eq(map.events.listeners.preremovelayer.length, numMapListeners - 1, "no listeners on map after destroy");
|
t.eq(map.events.listeners.preremovelayer.length, numMapListeners - 1, "no listeners on map after destroy");
|
||||||
map.destroy();
|
map.destroy();
|
||||||
|
|||||||
Reference in New Issue
Block a user