Skip to content

Commit

Permalink
When the resolution does not change, remove backbuffer tile by tile
Browse files Browse the repository at this point in the history
This change introduces a new 'replace' mode for tile transitions: when the
resolution does not change, which happens when mergeNewParams is called,
the tile will be marked with the .olTileReplace class. If this class sets
the tile's imgDiv display to 'none', the backbuffer for the tile will
immediately be removed when the tile is loaded.
  • Loading branch information
ahocevar committed Jan 7, 2013
1 parent 18d548f commit c856483
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
36 changes: 34 additions & 2 deletions lib/OpenLayers/Layer/Grid.js
Expand Up @@ -336,6 +336,21 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments);
},

/**
* APIMethod: mergeNewParams
* Refetches tiles with new params merged, keeping a backbuffer. Each
* loading new tile will have a css class of '.olTileReplacing'. If a
* stylesheet applies a 'display: none' style to that class, any fade-in
* transition will not apply, and backbuffers for each tile will be removed
* as soon as the tile is loaded.
*
* Parameters:
* newParams - {Object}
*
* Returns:
* redrawn: {Boolean} whether the layer was actually redrawn.
*/

/**
* Method: clearGrid
* Go through and remove all tiles from the grid, calling
Expand Down Expand Up @@ -489,7 +504,8 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
});

if(forceReTile) {
if(zoomChanged && this.transitionEffect === 'resize') {
if(zoomChanged && (this.transitionEffect === 'resize' ||
this.gridResolution === resolution)) {
this.applyBackBuffer(resolution);
}
this.initGriddedTiles(bounds);
Expand Down Expand Up @@ -692,6 +708,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
markup._j = j;
markup._w = tile.size.w;
markup._h = tile.size.h;
markup.id = tile.id + '_bb';
backBuffer.appendChild(markup);
}
}
Expand Down Expand Up @@ -1053,6 +1070,8 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
*/
addTileMonitoringHooks: function(tile) {

var replacingCls = 'olTileReplacing';

tile.onLoadStart = function() {
//if that was first tile then trigger a 'loadstart' on the layer
if (this.loading === false) {
Expand All @@ -1061,14 +1080,27 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
this.events.triggerEvent("tileloadstart", {tile: tile});
this.numLoadingTiles++;
if (this.backBuffer && this.gridResolution === this.backBufferResolution) {
OpenLayers.Element.addClass(tile.imgDiv, replacingCls);
}
};

tile.onLoadEnd = function(evt) {
this.numLoadingTiles--;
var aborted = evt.type === 'unload';
this.events.triggerEvent("tileloaded", {
tile: tile,
aborted: evt.type === "unload"
aborted: aborted
});
if (!aborted && this.backBuffer && this.gridResolution === this.backBufferResolution) {
if (OpenLayers.Element.getStyle(tile.imgDiv, 'display') === 'none') {
var bufferTile = document.getElementById(tile.id + '_bb');
if (bufferTile) {
bufferTile.parentNode.removeChild(bufferTile);
}
}
OpenLayers.Element.removeClass(tile.imgDiv, replacingCls);
}
//if that was the last tile, then trigger a 'loadend' on the layer
if (this.numLoadingTiles === 0) {
this.loading = false;
Expand Down
28 changes: 27 additions & 1 deletion tests/Layer/Grid.html
Expand Up @@ -526,7 +526,8 @@
}
}
}
}
},
imgDiv: {className: ''}
}

g_registered = {};
Expand Down Expand Up @@ -1118,6 +1119,31 @@

map.destroy();
}

function test_backbuffer_replace(t) {
t.plan(6);
var map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS('', '../../img/blank.gif');
map.addLayer(layer);
map.zoomToMaxExtent();

t.delay_call(1, function() {
layer.mergeNewParams({foo: 'bar'});
var tile = layer.grid[1][1];
t.ok(OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile is marked for being replaced');
t.ok(document.getElementById(tile.id + '_bb'), 'backbuffer created for tile');
tile.onImageLoad();
t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile replaced, no longer marked');
t.ok(!document.getElementById(tile.id + '_bb'), 'backbuffer removed for tile');

layer.mergeNewParams({foo: 'baz'});
tile = layer.grid[1][1];
tile.imgDiv.style.display = 'block';
tile.onImageLoad();
t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile replaced, no longer marked');
t.ok(document.getElementById(tile.id + '_bb'), 'backbuffer not removed for visible tile');
});
}

function test_singleTile_move_and_zoom(t) {

Expand Down
5 changes: 5 additions & 0 deletions theme/default/style.css
Expand Up @@ -487,6 +487,11 @@ a.olControlZoomOut {
transition: opacity 0.2s linear;
}

/* when replacing tiles, do not show tile and backbuffer at the same time */
.olTileImage.olTileReplacing {
display: none;
}

/* override any max-width image settings (e.g. bootstrap.css) */
img.olTileImage {
max-width: none;
Expand Down

0 comments on commit c856483

Please sign in to comment.