diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 0282feaba9..3852c30a2b 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -111,7 +111,17 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { */ timerId: null, - backBufferData: null, + /** + * Property: backBuffer + * {DOMElement} The back buffer. + */ + backBuffer: null, + + /** + * Property: lastResolution + * {Object} The last resolution of the grid. + */ + lastResolution: null, /** * Constructor: OpenLayers.Layer.Grid @@ -135,8 +145,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { this.events.addEventType("tileloaded"); this.grid = []; - this.backBufferData = {}; - + this._moveGriddedTiles = OpenLayers.Function.bind( this.moveGriddedTiles, this ); @@ -219,10 +228,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { return obj; }, - setBackBufferData: function() { - this.backBufferData.resolution = this.getServerResolution(); - }, - /** * Method: moveTo * This function is called whenever the map is moved. All the moving @@ -247,7 +252,13 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { // total bounds of the tiles var tilesBounds = this.getTilesBounds(); - + + // the new map resolution + var resolution = this.map.getResolution(); + + // the server-supported resolution for the new map resolution + var serverResolution = this.getServerResolution(resolution); + if (this.singleTile) { // We want to redraw whenever even the slightest part of the @@ -255,6 +266,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { // (thus, we do not specify partial -- its default is false) if ( forceReTile || (!dragging && !tilesBounds.containsBounds(bounds))) { + if(this.lastResolution === serverResolution || + (this.lastResolution && + this.transitionEffect === 'resize')) { + this.insertBackBuffer(serverResolution, tilesBounds); + } this.initSingleTile(bounds); } } else { @@ -267,10 +283,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { forceReTile = forceReTile || !tilesBounds.containsBounds(bounds, true); - var resolution = this.map.getResolution(); - var serverResolution = - this.getServerResolution(resolution); - if(resolution !== serverResolution) { bounds = this.map.calculateBounds(null, serverResolution); if(forceReTile) { @@ -288,30 +300,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } if(forceReTile) { - - if(OpenLayers.Util.indexOf( - this.SUPPORTED_TRANSITIONS, - this.transitionEffect) != -1) { - if(!this.backBufferData.backBuffer) { - this.backBufferData.backBuffer = this.createBackBuffer(); - if(this.backBufferData.backBuffer) { - this.div.insertBefore(this.backBufferData.backBuffer, - this.div.firstChild); - } - } - if(this.backBufferData.backBuffer && this.backBufferData.resolution) { - var resolution = this.getServerResolution(); - var scale = this.backBufferData.resolution / resolution; - this.backBufferData.backBuffer.style.width = 100 * scale + '%'; - this.backBufferData.backBuffer.style.height = 100 * scale + '%'; - var lonLat = {lon: tilesBounds.left, lat: tilesBounds.top}, - position = this.getViewPortPxFromLonLat(lonLat, resolution); - this.backBufferData.backBuffer.style.left = position.x + '%'; - this.backBufferData.backBuffer.style.top = position.y + '%'; - } - + if(this.transitionEffect === 'resize' && + (this.lastResolution && + (this.lastResolution !== serverResolution))) { + this.insertBackBuffer(serverResolution, tilesBounds); } - this.initGriddedTiles(bounds); } else { this.scheduleMoveGriddedTiles(); @@ -320,31 +313,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } }, - createBackBuffer: function() { - var backBuffer; - if(this.grid.length > 0) { - var backBuffer = document.createElement('div'); - backBuffer.id = this.div.id + '_bb'; - backBuffer.style.position = 'absolute'; - backBuffer.style.left = '0%'; - backBuffer.style.top = '0%'; - backBuffer.style.width = '100%'; - backBuffer.style.height = '100%'; - for(var i=0, lenI=this.grid.length; i} The current bounds of the tiles. + */ + insertBackBuffer: function(resolution, tilesBounds) { + var backBuffer = this.backBuffer; + if(!backBuffer) { + backBuffer = this.createBackBuffer(); + if(!backBuffer) { + return; + } + this.div.insertBefore(backBuffer, this.div.firstChild); + this.backBuffer = backBuffer; + } + + var style = backBuffer.style; + + // scale + var ratio = this.lastResolution / resolution; + style.width = 100 * ratio + '%'; + style.height = 100 * ratio + '%'; + + // and position + var position = this.getViewPortPxFromLonLat( + {lon: tilesBounds.left, lat: tilesBounds.top}, resolution); + var leftOffset = parseInt(this.map.layerContainerDiv.style.left, 10); + var topOffset = parseInt(this.map.layerContainerDiv.style.top, 10); + backBuffer.style.left = (position.x - leftOffset) + '%'; + backBuffer.style.top = (position.y - topOffset) + '%'; + }, + + /** + * Method: createBackBuffer + * Create a back buffer. We apply a best effort strategy here - if for any + * reason we cannot clone a tile's markup we give up right away. + * + * Returns: + * {DOMElement} The DOM element for the back buffer, undefined if the + * back buffer couldn't have been created. + */ + createBackBuffer: function() { + var backBuffer; + if(this.grid.length > 0) { + var backBuffer = document.createElement('div'); + backBuffer.id = this.div.id + '_bb'; + backBuffer.style.position = 'absolute'; + backBuffer.style.width = '100%'; + backBuffer.style.height = '100%'; + for(var i=0, lenI=this.grid.length; i